aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore15
-rw-r--r--.travis.yml2
-rw-r--r--CMakeLists.txt29
-rw-r--r--Makefile26
-rw-r--r--README.md68
-rw-r--r--cmake/FindLibUV.cmake24
-rw-r--r--cmake/LibFindMacros.cmake112
-rw-r--r--config/config.h.in1
-rw-r--r--neovim.rb16
-rw-r--r--scripts/common.sh50
-rw-r--r--scripts/compile-libuv.sh10
-rw-r--r--scripts/get-libuv.sh16
-rw-r--r--src/CMakeLists.txt23
-rw-r--r--src/arabic.c72
-rw-r--r--src/ascii.h5
-rw-r--r--src/blowfish.c48
-rw-r--r--src/blowfish.h (renamed from src/proto/blowfish.pro)3
-rw-r--r--src/buffer.c429
-rw-r--r--src/buffer.h (renamed from src/proto/buffer.pro)3
-rw-r--r--src/charset.c238
-rw-r--r--src/charset.h (renamed from src/proto/charset.pro)3
-rw-r--r--src/diff.c196
-rw-r--r--src/diff.h (renamed from src/proto/diff.pro)3
-rw-r--r--src/digraph.c47
-rw-r--r--src/digraph.h (renamed from src/proto/digraph.pro)3
-rw-r--r--src/edit.c540
-rw-r--r--src/edit.h (renamed from src/proto/edit.pro)3
-rw-r--r--src/eval.c2559
-rw-r--r--src/eval.h (renamed from src/proto/eval.pro)3
-rw-r--r--src/ex_cmds.c341
-rw-r--r--src/ex_cmds.h1267
-rw-r--r--src/ex_cmds2.c355
-rw-r--r--src/ex_cmds2.h (renamed from src/proto/ex_cmds2.pro)3
-rw-r--r--src/ex_cmds_defs.h1191
-rw-r--r--src/ex_docmd.c806
-rw-r--r--src/ex_docmd.h (renamed from src/proto/ex_docmd.pro)3
-rw-r--r--src/ex_eval.c139
-rw-r--r--src/ex_eval.h (renamed from src/proto/ex_eval.pro)3
-rw-r--r--src/ex_getln.c440
-rw-r--r--src/ex_getln.h (renamed from src/proto/ex_getln.pro)3
-rw-r--r--src/farsi.c94
-rw-r--r--src/farsi.h5
-rw-r--r--src/fileio.c567
-rw-r--r--src/fileio.h (renamed from src/proto/fileio.pro)3
-rw-r--r--src/fold.c369
-rw-r--r--src/fold.h (renamed from src/proto/fold.pro)3
-rw-r--r--src/getchar.c374
-rw-r--r--src/getchar.h (renamed from src/proto/getchar.pro)3
-rw-r--r--src/globals.h7
-rw-r--r--src/hangulin.c75
-rw-r--r--src/hangulin.h (renamed from src/proto/hangulin.pro)3
-rw-r--r--src/hardcopy.c285
-rw-r--r--src/hardcopy.h (renamed from src/proto/hardcopy.pro)3
-rw-r--r--src/hashtab.c57
-rw-r--r--src/hashtab.h (renamed from src/proto/hashtab.pro)3
-rw-r--r--src/if_cscope.c195
-rw-r--r--src/if_cscope.h88
-rw-r--r--src/if_cscope_defs.h72
-rw-r--r--src/keymap.h2
-rw-r--r--src/main.c451
-rw-r--r--src/main.h (renamed from src/proto/main.pro)3
-rw-r--r--src/mark.c170
-rw-r--r--src/mark.h (renamed from src/proto/mark.pro)3
-rw-r--r--src/mbyte.c912
-rw-r--r--src/mbyte.h (renamed from src/proto/mbyte.pro)3
-rw-r--r--src/memfile.c164
-rw-r--r--src/memfile.h (renamed from src/proto/memfile.pro)3
-rw-r--r--src/memline.c319
-rw-r--r--src/memline.h (renamed from src/proto/memline.pro)3
-rw-r--r--src/menu.c147
-rw-r--r--src/menu.h (renamed from src/proto/menu.pro)3
-rw-r--r--src/message.c402
-rw-r--r--src/message.h (renamed from src/proto/message.pro)3
-rw-r--r--src/misc1.c760
-rw-r--r--src/misc1.h (renamed from src/proto/misc1.pro)3
-rw-r--r--src/misc2.c614
-rw-r--r--src/misc2.h (renamed from src/proto/misc2.pro)3
-rw-r--r--src/move.c169
-rw-r--r--src/move.h (renamed from src/proto/move.pro)3
-rw-r--r--src/normal.c490
-rw-r--r--src/normal.h (renamed from src/proto/normal.pro)3
-rw-r--r--src/ops.c384
-rw-r--r--src/ops.h (renamed from src/proto/ops.pro)3
-rw-r--r--src/option.c518
-rw-r--r--src/option.h845
-rw-r--r--src/option_defs.h768
-rw-r--r--src/os/fs.c129
-rw-r--r--src/os/mem.c26
-rw-r--r--src/os/os.h12
-rw-r--r--src/os_unix.c527
-rw-r--r--src/os_unix.h450
-rw-r--r--src/os_unix_defs.h351
-rw-r--r--src/po/Makefile4
-rw-r--r--src/po/sjiscorr.c13
-rw-r--r--src/popupmnu.c35
-rw-r--r--src/popupmnu.h (renamed from src/proto/popupmnu.pro)3
-rw-r--r--src/proto.h75
-rw-r--r--src/proto/ex_cmds.pro72
-rw-r--r--src/proto/if_cscope.pro13
-rw-r--r--src/proto/option.pro74
-rw-r--r--src/proto/os_unix.pro80
-rw-r--r--src/proto/regexp.pro24
-rw-r--r--src/proto/term.pro65
-rw-r--r--src/proto/version.pro10
-rw-r--r--src/quickfix.c289
-rw-r--r--src/quickfix.h (renamed from src/proto/quickfix.pro)3
-rw-r--r--src/regexp.c357
-rw-r--r--src/regexp.h179
-rw-r--r--src/regexp_defs.h152
-rw-r--r--src/regexp_nfa.c305
-rw-r--r--src/screen.c427
-rw-r--r--src/screen.h (renamed from src/proto/screen.pro)3
-rw-r--r--src/search.c355
-rw-r--r--src/search.h (renamed from src/proto/search.pro)3
-rw-r--r--src/sha256.c39
-rw-r--r--src/sha256.h (renamed from src/proto/sha256.pro)3
-rw-r--r--src/spell.c1007
-rw-r--r--src/spell.h (renamed from src/proto/spell.pro)3
-rw-r--r--src/structs.h4
-rw-r--r--src/syntax.c692
-rw-r--r--src/syntax.h (renamed from src/proto/syntax.pro)3
-rw-r--r--src/tag.c171
-rw-r--r--src/tag.h (renamed from src/proto/tag.pro)3
-rw-r--r--src/term.c276
-rw-r--r--src/term.h224
-rw-r--r--src/term_defs.h156
-rw-r--r--src/testdir/Makefile2
-rw-r--r--src/testdir/test49.vim2
-rw-r--r--src/ui.c133
-rw-r--r--src/ui.h (renamed from src/proto/ui.pro)3
-rw-r--r--src/undo.c240
-rw-r--r--src/undo.h (renamed from src/proto/undo.pro)3
-rw-r--r--src/version.c41
-rw-r--r--src/version.h53
-rw-r--r--src/version_defs.h40
-rw-r--r--src/vim.h24
-rw-r--r--src/window.c618
-rw-r--r--src/window.h (renamed from src/proto/window.pro)3
-rw-r--r--third-party/README.md9
-rw-r--r--third-party/libuv/.gitignore62
-rw-r--r--third-party/libuv/.mailmap24
-rw-r--r--third-party/libuv/AUTHORS114
-rw-r--r--third-party/libuv/CONTRIBUTING.md177
-rw-r--r--third-party/libuv/ChangeLog1012
-rw-r--r--third-party/libuv/LICENSE42
-rw-r--r--third-party/libuv/Makefile.am302
-rw-r--r--third-party/libuv/Makefile.mingw77
-rw-r--r--third-party/libuv/README.md143
-rwxr-xr-xthird-party/libuv/android-configure20
-rwxr-xr-xthird-party/libuv/autogen.sh46
-rwxr-xr-xthird-party/libuv/checksparse.sh231
-rw-r--r--third-party/libuv/common.gypi208
-rw-r--r--third-party/libuv/configure.ac55
-rwxr-xr-xthird-party/libuv/gyp_uv.py99
-rw-r--r--third-party/libuv/include/pthread-fixes.h59
-rw-r--r--third-party/libuv/include/stdint-msvc2008.h247
-rw-r--r--third-party/libuv/include/tree.h768
-rw-r--r--third-party/libuv/include/uv-bsd.h34
-rw-r--r--third-party/libuv/include/uv-darwin.h63
-rw-r--r--third-party/libuv/include/uv-errno.h373
-rw-r--r--third-party/libuv/include/uv-linux.h36
-rw-r--r--third-party/libuv/include/uv-sunos.h44
-rw-r--r--third-party/libuv/include/uv-unix.h329
-rw-r--r--third-party/libuv/include/uv-win.h589
-rw-r--r--third-party/libuv/include/uv.h2135
-rw-r--r--third-party/libuv/libuv.pc.in11
-rw-r--r--third-party/libuv/m4/.gitignore2
-rw-r--r--third-party/libuv/m4/dtrace.m458
-rw-r--r--third-party/libuv/samples/.gitignore22
-rw-r--r--third-party/libuv/samples/socks5-proxy/.gitignore21
-rw-r--r--third-party/libuv/samples/socks5-proxy/LICENSE53
-rw-r--r--third-party/libuv/samples/socks5-proxy/Makefile46
-rw-r--r--third-party/libuv/samples/socks5-proxy/build.gyp46
-rw-r--r--third-party/libuv/samples/socks5-proxy/client.c737
-rw-r--r--third-party/libuv/samples/socks5-proxy/defs.h139
-rw-r--r--third-party/libuv/samples/socks5-proxy/getopt.c131
-rw-r--r--third-party/libuv/samples/socks5-proxy/main.c99
-rw-r--r--third-party/libuv/samples/socks5-proxy/s5.c271
-rw-r--r--third-party/libuv/samples/socks5-proxy/s5.h94
-rw-r--r--third-party/libuv/samples/socks5-proxy/server.c241
-rw-r--r--third-party/libuv/samples/socks5-proxy/util.c72
-rw-r--r--third-party/libuv/src/fs-poll.c223
-rw-r--r--third-party/libuv/src/inet.c294
-rw-r--r--third-party/libuv/src/queue.h92
-rw-r--r--third-party/libuv/src/unix/aix.c399
-rw-r--r--third-party/libuv/src/unix/async.c290
-rw-r--r--third-party/libuv/src/unix/atomic-ops.h60
-rw-r--r--third-party/libuv/src/unix/core.c787
-rw-r--r--third-party/libuv/src/unix/darwin-proctitle.c203
-rw-r--r--third-party/libuv/src/unix/darwin.c324
-rw-r--r--third-party/libuv/src/unix/dl.c83
-rw-r--r--third-party/libuv/src/unix/freebsd.c425
-rw-r--r--third-party/libuv/src/unix/fs.c971
-rw-r--r--third-party/libuv/src/unix/fsevents.c899
-rw-r--r--third-party/libuv/src/unix/getaddrinfo.c135
-rw-r--r--third-party/libuv/src/unix/internal.h296
-rw-r--r--third-party/libuv/src/unix/kqueue.c403
-rw-r--r--third-party/libuv/src/unix/linux-core.c816
-rw-r--r--third-party/libuv/src/unix/linux-inotify.c257
-rw-r--r--third-party/libuv/src/unix/linux-syscalls.c388
-rw-r--r--third-party/libuv/src/unix/linux-syscalls.h151
-rw-r--r--third-party/libuv/src/unix/loop-watcher.c63
-rw-r--r--third-party/libuv/src/unix/loop.c163
-rw-r--r--third-party/libuv/src/unix/netbsd.c367
-rw-r--r--third-party/libuv/src/unix/openbsd.c388
-rw-r--r--third-party/libuv/src/unix/pipe.c216
-rw-r--r--third-party/libuv/src/unix/poll.c107
-rw-r--r--third-party/libuv/src/unix/process.c517
-rw-r--r--third-party/libuv/src/unix/proctitle.c102
-rw-r--r--third-party/libuv/src/unix/pthread-fixes.c80
-rw-r--r--third-party/libuv/src/unix/signal.c465
-rw-r--r--third-party/libuv/src/unix/spinlock.h53
-rw-r--r--third-party/libuv/src/unix/stream.c1511
-rw-r--r--third-party/libuv/src/unix/sunos.c734
-rw-r--r--third-party/libuv/src/unix/tcp.c312
-rw-r--r--third-party/libuv/src/unix/thread.c464
-rw-r--r--third-party/libuv/src/unix/threadpool.c280
-rw-r--r--third-party/libuv/src/unix/timer.c153
-rw-r--r--third-party/libuv/src/unix/tty.c184
-rw-r--r--third-party/libuv/src/unix/udp.c595
-rw-r--r--third-party/libuv/src/unix/uv-dtrace.d25
-rw-r--r--third-party/libuv/src/uv-common.c446
-rw-r--r--third-party/libuv/src/uv-common.h187
-rw-r--r--third-party/libuv/src/version.c63
-rw-r--r--third-party/libuv/src/win/async.c99
-rw-r--r--third-party/libuv/src/win/atomicops-inl.h56
-rw-r--r--third-party/libuv/src/win/core.c362
-rw-r--r--third-party/libuv/src/win/dl.c86
-rw-r--r--third-party/libuv/src/win/error.c169
-rw-r--r--third-party/libuv/src/win/fs-event.c527
-rw-r--r--third-party/libuv/src/win/fs.c2043
-rw-r--r--third-party/libuv/src/win/getaddrinfo.c344
-rw-r--r--third-party/libuv/src/win/handle-inl.h179
-rw-r--r--third-party/libuv/src/win/handle.c154
-rw-r--r--third-party/libuv/src/win/internal.h379
-rw-r--r--third-party/libuv/src/win/loop-watcher.c124
-rw-r--r--third-party/libuv/src/win/pipe.c1747
-rw-r--r--third-party/libuv/src/win/poll.c617
-rw-r--r--third-party/libuv/src/win/process-stdio.c510
-rw-r--r--third-party/libuv/src/win/process.c1120
-rw-r--r--third-party/libuv/src/win/req-inl.h224
-rw-r--r--third-party/libuv/src/win/req.c25
-rw-r--r--third-party/libuv/src/win/signal.c352
-rw-r--r--third-party/libuv/src/win/stream-inl.h67
-rw-r--r--third-party/libuv/src/win/stream.c253
-rw-r--r--third-party/libuv/src/win/tcp.c1417
-rw-r--r--third-party/libuv/src/win/thread.c716
-rw-r--r--third-party/libuv/src/win/threadpool.c81
-rw-r--r--third-party/libuv/src/win/timer.c254
-rw-r--r--third-party/libuv/src/win/tty.c1873
-rw-r--r--third-party/libuv/src/win/udp.c749
-rw-r--r--third-party/libuv/src/win/util.c990
-rw-r--r--third-party/libuv/src/win/winapi.c159
-rw-r--r--third-party/libuv/src/win/winapi.h4648
-rw-r--r--third-party/libuv/src/win/winsock.c560
-rw-r--r--third-party/libuv/src/win/winsock.h171
-rw-r--r--third-party/libuv/test/benchmark-async-pummel.c119
-rw-r--r--third-party/libuv/test/benchmark-async.c141
-rw-r--r--third-party/libuv/test/benchmark-fs-stat.c136
-rw-r--r--third-party/libuv/test/benchmark-getaddrinfo.c91
-rw-r--r--third-party/libuv/test/benchmark-list.h163
-rw-r--r--third-party/libuv/test/benchmark-loop-count.c90
-rw-r--r--third-party/libuv/test/benchmark-million-async.c112
-rw-r--r--third-party/libuv/test/benchmark-million-timers.c85
-rw-r--r--third-party/libuv/test/benchmark-multi-accept.c445
-rw-r--r--third-party/libuv/test/benchmark-ping-pongs.c220
-rw-r--r--third-party/libuv/test/benchmark-pound.c350
-rw-r--r--third-party/libuv/test/benchmark-pump.c470
-rw-r--r--third-party/libuv/test/benchmark-sizes.c45
-rw-r--r--third-party/libuv/test/benchmark-spawn.c163
-rw-r--r--third-party/libuv/test/benchmark-tcp-write-batch.c144
-rw-r--r--third-party/libuv/test/benchmark-thread.c64
-rw-r--r--third-party/libuv/test/benchmark-udp-pummel.c243
-rw-r--r--third-party/libuv/test/blackhole-server.c121
-rw-r--r--third-party/libuv/test/dns-server.c340
-rw-r--r--third-party/libuv/test/echo-server.c384
-rw-r--r--third-party/libuv/test/fixtures/empty_file0
-rw-r--r--third-party/libuv/test/fixtures/load_error.node1
-rw-r--r--third-party/libuv/test/run-benchmarks.c64
-rw-r--r--third-party/libuv/test/run-tests.c159
-rw-r--r--third-party/libuv/test/runner-unix.c356
-rw-r--r--third-party/libuv/test/runner-unix.h36
-rw-r--r--third-party/libuv/test/runner-win.c369
-rw-r--r--third-party/libuv/test/runner-win.h43
-rw-r--r--third-party/libuv/test/runner.c455
-rw-r--r--third-party/libuv/test/runner.h170
-rw-r--r--third-party/libuv/test/task.h207
-rw-r--r--third-party/libuv/test/test-active.c84
-rw-r--r--third-party/libuv/test/test-async-null-cb.c55
-rw-r--r--third-party/libuv/test/test-async.c136
-rw-r--r--third-party/libuv/test/test-barrier.c98
-rw-r--r--third-party/libuv/test/test-callback-order.c77
-rw-r--r--third-party/libuv/test/test-callback-stack.c206
-rw-r--r--third-party/libuv/test/test-close-fd.c77
-rw-r--r--third-party/libuv/test/test-close-order.c80
-rw-r--r--third-party/libuv/test/test-condvar.c173
-rw-r--r--third-party/libuv/test/test-connection-fail.c152
-rw-r--r--third-party/libuv/test/test-cwd-and-chdir.c64
-rw-r--r--third-party/libuv/test/test-delayed-accept.c190
-rw-r--r--third-party/libuv/test/test-dlerror.c58
-rw-r--r--third-party/libuv/test/test-embed.c139
-rw-r--r--third-party/libuv/test/test-emfile.c111
-rw-r--r--third-party/libuv/test/test-error.c50
-rw-r--r--third-party/libuv/test/test-fail-always.c29
-rw-r--r--third-party/libuv/test/test-fs-event.c730
-rw-r--r--third-party/libuv/test/test-fs-poll.c146
-rw-r--r--third-party/libuv/test/test-fs.c1955
-rw-r--r--third-party/libuv/test/test-get-currentexe.c65
-rw-r--r--third-party/libuv/test/test-get-loadavg.c36
-rw-r--r--third-party/libuv/test/test-get-memory.c38
-rw-r--r--third-party/libuv/test/test-getaddrinfo.c149
-rw-r--r--third-party/libuv/test/test-getsockname.c358
-rw-r--r--third-party/libuv/test/test-hrtime.c54
-rw-r--r--third-party/libuv/test/test-idle.c99
-rw-r--r--third-party/libuv/test/test-ip4-addr.c46
-rw-r--r--third-party/libuv/test/test-ip6-addr.c99
-rw-r--r--third-party/libuv/test/test-ipc-send-recv.c226
-rw-r--r--third-party/libuv/test/test-ipc.c648
-rw-r--r--third-party/libuv/test/test-list.h537
-rw-r--r--third-party/libuv/test/test-loop-alive.c68
-rw-r--r--third-party/libuv/test/test-loop-handles.c337
-rw-r--r--third-party/libuv/test/test-loop-stop.c73
-rw-r--r--third-party/libuv/test/test-loop-time.c34
-rw-r--r--third-party/libuv/test/test-multiple-listen.c109
-rw-r--r--third-party/libuv/test/test-mutexes.c63
-rw-r--r--third-party/libuv/test/test-osx-select.c82
-rw-r--r--third-party/libuv/test/test-pass-always.c28
-rw-r--r--third-party/libuv/test/test-ping-pong.c263
-rw-r--r--third-party/libuv/test/test-pipe-bind-error.c136
-rw-r--r--third-party/libuv/test/test-pipe-connect-error.c95
-rw-r--r--third-party/libuv/test/test-pipe-server-close.c91
-rw-r--r--third-party/libuv/test/test-platform-output.c103
-rw-r--r--third-party/libuv/test/test-poll-close.c73
-rw-r--r--third-party/libuv/test/test-poll.c581
-rw-r--r--third-party/libuv/test/test-process-title.c53
-rw-r--r--third-party/libuv/test/test-ref.c443
-rw-r--r--third-party/libuv/test/test-run-nowait.c46
-rw-r--r--third-party/libuv/test/test-run-once.c49
-rw-r--r--third-party/libuv/test/test-semaphore.c111
-rw-r--r--third-party/libuv/test/test-shutdown-close.c108
-rw-r--r--third-party/libuv/test/test-shutdown-eof.c182
-rw-r--r--third-party/libuv/test/test-signal-multiple-loops.c289
-rw-r--r--third-party/libuv/test/test-signal.c152
-rw-r--r--third-party/libuv/test/test-spawn.c1051
-rw-r--r--third-party/libuv/test/test-stdio-over-pipes.c255
-rw-r--r--third-party/libuv/test/test-tcp-bind-error.c199
-rw-r--r--third-party/libuv/test/test-tcp-bind6-error.c161
-rw-r--r--third-party/libuv/test/test-tcp-close-accept.c183
-rw-r--r--third-party/libuv/test/test-tcp-close-while-connecting.c82
-rw-r--r--third-party/libuv/test/test-tcp-close.c136
-rw-r--r--third-party/libuv/test/test-tcp-connect-error-after-write.c98
-rw-r--r--third-party/libuv/test/test-tcp-connect-error.c73
-rw-r--r--third-party/libuv/test/test-tcp-connect-timeout.c89
-rw-r--r--third-party/libuv/test/test-tcp-connect6-error.c71
-rw-r--r--third-party/libuv/test/test-tcp-flags.c52
-rw-r--r--third-party/libuv/test/test-tcp-open.c182
-rw-r--r--third-party/libuv/test/test-tcp-read-stop.c76
-rw-r--r--third-party/libuv/test/test-tcp-shutdown-after-write.c138
-rw-r--r--third-party/libuv/test/test-tcp-try-write.c144
-rw-r--r--third-party/libuv/test/test-tcp-unexpected-read.c117
-rw-r--r--third-party/libuv/test/test-tcp-write-to-half-open-connection.c141
-rw-r--r--third-party/libuv/test/test-tcp-writealot.c176
-rw-r--r--third-party/libuv/test/test-thread.c209
-rw-r--r--third-party/libuv/test/test-threadpool-cancel.c311
-rw-r--r--third-party/libuv/test/test-threadpool.c76
-rw-r--r--third-party/libuv/test/test-timer-again.c140
-rw-r--r--third-party/libuv/test/test-timer-from-check.c80
-rw-r--r--third-party/libuv/test/test-timer.c294
-rw-r--r--third-party/libuv/test/test-tty.c123
-rw-r--r--third-party/libuv/test/test-udp-dgram-too-big.c91
-rw-r--r--third-party/libuv/test/test-udp-ipv6.c166
-rw-r--r--third-party/libuv/test/test-udp-multicast-join.c148
-rw-r--r--third-party/libuv/test/test-udp-multicast-ttl.c94
-rw-r--r--third-party/libuv/test/test-udp-open.c164
-rw-r--r--third-party/libuv/test/test-udp-options.c88
-rw-r--r--third-party/libuv/test/test-udp-send-and-recv.c211
-rw-r--r--third-party/libuv/test/test-walk-handles.c78
-rw-r--r--third-party/libuv/test/test-watcher-cross-stop.c101
-rw-r--r--third-party/libuv/uv.gyp532
-rw-r--r--third-party/libuv/vcbuild.bat144
-rw-r--r--vim-license.txt78
381 files changed, 79974 insertions, 14499 deletions
diff --git a/.gitignore b/.gitignore
index c0ce35dc48..a36e19fe97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,16 +10,19 @@ build/
*.pyc
src/po/vim.pot
-src/po/*.ck
+src/po/*.ck
# Files generated by the tests
-src/testdir/mbyte.vim
-src/testdir/mzscheme.vim
-src/testdir/lua.vim
-src/testdir/small.vim
-src/testdir/tiny.vim
+src/testdir/mbyte.vim
+src/testdir/mzscheme.vim
+src/testdir/lua.vim
+src/testdir/small.vim
+src/testdir/tiny.vim
src/testdir/test*.out
src/testdir/test.log
src/testdir/test.ok
src/testdir/*.failed
src/testdir/X*
+
+# local make targets
+local.mk
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..d1a0445925
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,2 @@
+language: c
+script: make cmake CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$PWD/dist" && make && make test > /dev/null 2>&1 && make install
diff --git a/CMakeLists.txt b/CMakeLists.txt
index adb9894a3c..04df162f07 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,9 @@
cmake_minimum_required (VERSION 2.6)
project (NEOVIM)
+# Point CMake at any custom modules we may ship
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
+
set(NEOVIM_VERSION_MAJOR 0)
set(NEOVIM_VERSION_MINOR 0)
set(NEOVIM_VERSION_PATCH 0)
@@ -15,11 +18,29 @@ else()
set(DEBUG 0)
endif()
-# add dependencies to include/lib directories
-link_directories ("${PROJECT_SOURCE_DIR}/.deps/usr/lib")
-include_directories ("${PROJECT_SOURCE_DIR}/.deps/usr/include")
+# Modules used by platform auto-detection
+include(CheckLibraryExists)
+
+# Determine platform's threading library. Set CMAKE_THREAD_PREFER_PTHREAD
+# explicitly to indicate a strong preference for pthread. It is an error to not
+# have pthread installed even if, for example, the Win32 threading API is found.
+set(CMAKE_THREAD_PREFER_PTHREAD ON)
+find_package(Threads REQUIRED)
+if(NOT CMAKE_USE_PTHREADS_INIT)
+ message(SEND_ERROR "The pthread library must be installed on your system.")
+endif(NOT CMAKE_USE_PTHREADS_INIT)
+
+# Detect if clock_gettime exists in -lrt. If so we need to link with it because
+# the static libuv doesn't but uses clock_gettime.
+check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME)
+
+# Require libuv
+find_package(LibUV REQUIRED)
+include_directories(${LibUV_INCLUDE_DIRS})
+
+include_directories ("${PROJECT_BINARY_DIR}/config")
-include_directories ("${PROJECT_BINARY_DIR}/config")
+set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_subdirectory(src)
add_subdirectory(config)
diff --git a/Makefile b/Makefile
index 6e456022c2..41d26b69ec 100644
--- a/Makefile
+++ b/Makefile
@@ -1,19 +1,24 @@
-CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug
+-include local.mk
-build/src/vim: deps
- cd build && make
+CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=.deps/usr
-test: build/src/vim
+# Extra CMake flags which extend the default set
+CMAKE_EXTRA_FLAGS :=
+
+build/bin/nvim: deps
+ ${MAKE} -C build
+
+test: build/bin/nvim
cd src/testdir && make
deps: .deps/usr/lib/libuv.a
.deps/usr/lib/libuv.a:
- sh -e scripts/get-libuv.sh
+ sh -e scripts/compile-libuv.sh
-cmake: clean
+cmake: clean deps
mkdir build
- cd build && cmake $(CMAKE_FLAGS) ../
+ cd build && cmake $(CMAKE_FLAGS) $(CMAKE_EXTRA_FLAGS) ../
clean:
rm -rf build
@@ -21,6 +26,9 @@ clean:
rm -f src/testdir/$$file.vim; \
done
-.PHONY: test deps cmake
+install: build/bin/nvim
+ ${MAKE} -C build install
+
+.PHONY: test deps cmake install
-.DEFAULT: build/src/vim
+.DEFAULT: build/bin/nvim
diff --git a/README.md b/README.md
index 3da54f4249..059527d6f7 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,27 @@
# neovim ([bountysource fundraiser](https://www.bountysource.com/fundraisers/539-neovim-first-iteration))
+[![Build Status](https://travis-ci.org/neovim/neovim.png?branch=master)](https://travis-ci.org/neovim/neovim)
+[![Stories in Ready](https://badge.waffle.io/neovim/neovim.png?label=ready)](https://waffle.io/neovim/neovim)
+
+* [Introduction](#introduction)
+* [Problem](#problem)
+* [Solution](#solution)
+ * [Migrate to a cmake-based build](#migrate-to-a-cmake-based-build)
+ * [Legacy support and compile-time features](#legacy-support-and-compile-time-features)
+ * [Platform-specific code](#platform-specific-code)
+ * [New plugin architecture](#new-plugin-architecture)
+ * [New GUI architecture](#new-gui-architecture)
+ * [Development on github](#development-on-github)
+* [Status](#status)
+* [Dependencies](#dependencies)
+ * [For Debian/Ubuntu](#for-debianubuntu)
+ * [For FreeBSD 10](#for-freebsd-10)
+ * [For OS X](#for-os-x)
+ * [For Arch Linux](#for-arch-linux)
+* [Building](#building)
+* [Community](#community)
+* [Contributing](#contributing)
+* [License](#license)
## Introduction
@@ -252,7 +274,11 @@ and what is currently being worked on:
#### Ubuntu/Debian
- sudo apt-get install build-essential cmake libncurses5-dev
+ sudo apt-get install libtool autoconf cmake libncurses5-dev g++
+
+#### FreeBSD 10
+
+ sudo pkg install cmake libtool sha
#### Arch Linux
@@ -263,16 +289,18 @@ and what is currently being worked on:
* Install [Xcode](https://developer.apple.com/)
* Install sha1sum
+If you run into wget certificate errors, you may be missing the root SSL
+certificates or have not set them up correctly:
+
Via MacPorts:
- sudo port install md5sha1sum cmake libtool
+ sudo port install curl-ca-bundle
+ echo CA_CERTIFICATE=/opt/local/share/curl/curl-ca-bundle.crt >> ~/.wgetrc
Via Homebrew:
- brew install md5sha1sum cmake libtool
-
-#### TODO
-* Release the Dockerfile which has this in it.
+ brew install curl-ca-bundle
+ echo CA_CERTIFICATE=/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt >> ~/.wgetrc
### Building
@@ -285,8 +313,34 @@ To build and run the tests:
make test
+Using Homebrew on Mac:
+
+ brew install neovim/neovim/neovim
+
### Community
-Join the community on IRC in #neovim on freenode.
+Join the community on IRC in #neovim on Freenode or the [mailing list](https://groups.google.com/forum/#!forum/neovim)
+
+### Contributing
+
+...would be awesome! See [the wiki](https://github.com/neovim/neovim/wiki/Contributing) for more details.
+
+### License
+
+Vim itself is distributed under the terms of the Vim License.
+See vim-license.txt for details.
+
+Vim also includes a message along the following lines:
+
+ Vim is Charityware. You can use and copy it as much as you like, but you are
+ encouraged to make a donation for needy children in Uganda. Please see the
+ kcc section of the vim docs or visit the ICCF web site, available at these URLs:
+
+ http://iccf-holland.org/
+ http://www.vim.org/iccf/
+ http://www.iccf.nl/
+
+ You can also sponsor the development of Vim. Vim sponsors can vote for
+ features. The money goes to Uganda anyway.
<!-- vim: set tw=80: -->
diff --git a/cmake/FindLibUV.cmake b/cmake/FindLibUV.cmake
new file mode 100644
index 0000000000..d0cedfb37d
--- /dev/null
+++ b/cmake/FindLibUV.cmake
@@ -0,0 +1,24 @@
+# - Try to find libuv
+# Once done, this will define
+#
+# LibUV_FOUND - system has libuv
+# LibUV_INCLUDE_DIRS - the libuv include directories
+# LibUV_LIBRARIES - link these to use libuv
+
+include(LibFindMacros)
+
+# Include dir
+find_path(LibUV_INCLUDE_DIR
+ NAMES uv.h
+)
+
+# The library itself. Note that we prefer the static version.
+find_library(LibUV_LIBRARY
+ NAMES libuv.a uv
+)
+
+# Set the include dir variables and the libraries and let libfind_process do the rest.
+# NOTE: Singular variables for this library, plural for libraries this this lib depends on.
+set(LibUV_PROCESS_INCLUDES LibUV_INCLUDE_DIR)
+set(LibUV_PROCESS_LIBS LibUV_LIBRARY)
+libfind_process(LibUV)
diff --git a/cmake/LibFindMacros.cmake b/cmake/LibFindMacros.cmake
new file mode 100644
index 0000000000..aa2143c82d
--- /dev/null
+++ b/cmake/LibFindMacros.cmake
@@ -0,0 +1,112 @@
+# Version 1.0 (2013-04-12)
+# Public Domain, originally written by Lasse Kärkkäinen <tronic@zi.fi>
+# Published at http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
+
+# If you improve the script, please modify the forementioned wiki page because
+# I no longer maintain my scripts (hosted as static files at zi.fi). Feel free
+# to remove this entire header if you use real version control instead.
+
+# Changelog:
+# 2013-04-12 Added version number (1.0) and this header, no other changes
+# 2009-10-08 Originally published
+
+
+# Works the same as find_package, but forwards the "REQUIRED" and "QUIET" arguments
+# used for the current package. For this to work, the first parameter must be the
+# prefix of the current package, then the prefix of the new package etc, which are
+# passed to find_package.
+macro (libfind_package PREFIX)
+ set (LIBFIND_PACKAGE_ARGS ${ARGN})
+ if (${PREFIX}_FIND_QUIETLY)
+ set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} QUIET)
+ endif (${PREFIX}_FIND_QUIETLY)
+ if (${PREFIX}_FIND_REQUIRED)
+ set (LIBFIND_PACKAGE_ARGS ${LIBFIND_PACKAGE_ARGS} REQUIRED)
+ endif (${PREFIX}_FIND_REQUIRED)
+ find_package(${LIBFIND_PACKAGE_ARGS})
+endmacro (libfind_package)
+
+# CMake developers made the UsePkgConfig system deprecated in the same release (2.6)
+# where they added pkg_check_modules. Consequently I need to support both in my scripts
+# to avoid those deprecated warnings. Here's a helper that does just that.
+# Works identically to pkg_check_modules, except that no checks are needed prior to use.
+macro (libfind_pkg_check_modules PREFIX PKGNAME)
+ if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+ include(UsePkgConfig)
+ pkgconfig(${PKGNAME} ${PREFIX}_INCLUDE_DIRS ${PREFIX}_LIBRARY_DIRS ${PREFIX}_LDFLAGS ${PREFIX}_CFLAGS)
+ else (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+ find_package(PkgConfig)
+ if (PKG_CONFIG_FOUND)
+ pkg_check_modules(${PREFIX} ${PKGNAME})
+ endif (PKG_CONFIG_FOUND)
+ endif (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
+endmacro (libfind_pkg_check_modules)
+
+# Do the final processing once the paths have been detected.
+# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
+# all the variables, each of which contain one include directory.
+# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
+# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
+# Also handles errors in case library detection was required, etc.
+macro (libfind_process PREFIX)
+ # Skip processing if already processed during this run
+ if (NOT ${PREFIX}_FOUND)
+ # Start with the assumption that the library was found
+ set (${PREFIX}_FOUND TRUE)
+
+ # Process all includes and set _FOUND to false if any are missing
+ foreach (i ${${PREFIX}_PROCESS_INCLUDES})
+ if (${i})
+ set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIRS} ${${i}})
+ mark_as_advanced(${i})
+ else (${i})
+ set (${PREFIX}_FOUND FALSE)
+ endif (${i})
+ endforeach (i)
+
+ # Process all libraries and set _FOUND to false if any are missing
+ foreach (i ${${PREFIX}_PROCESS_LIBS})
+ if (${i})
+ set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARIES} ${${i}})
+ mark_as_advanced(${i})
+ else (${i})
+ set (${PREFIX}_FOUND FALSE)
+ endif (${i})
+ endforeach (i)
+
+ # Print message and/or exit on fatal error
+ if (${PREFIX}_FOUND)
+ if (NOT ${PREFIX}_FIND_QUIETLY)
+ message (STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
+ endif (NOT ${PREFIX}_FIND_QUIETLY)
+ else (${PREFIX}_FOUND)
+ if (${PREFIX}_FIND_REQUIRED)
+ foreach (i ${${PREFIX}_PROCESS_INCLUDES} ${${PREFIX}_PROCESS_LIBS})
+ message("${i}=${${i}}")
+ endforeach (i)
+ message (FATAL_ERROR "Required library ${PREFIX} NOT FOUND.\nInstall the library (dev version) and try again. If the library is already installed, use ccmake to set the missing variables manually.")
+ endif (${PREFIX}_FIND_REQUIRED)
+ endif (${PREFIX}_FOUND)
+ endif (NOT ${PREFIX}_FOUND)
+endmacro (libfind_process)
+
+macro(libfind_library PREFIX basename)
+ set(TMP "")
+ if(MSVC80)
+ set(TMP -vc80)
+ endif(MSVC80)
+ if(MSVC90)
+ set(TMP -vc90)
+ endif(MSVC90)
+ set(${PREFIX}_LIBNAMES ${basename}${TMP})
+ if(${ARGC} GREATER 2)
+ set(${PREFIX}_LIBNAMES ${basename}${TMP}-${ARGV2})
+ string(REGEX REPLACE "\\." "_" TMP ${${PREFIX}_LIBNAMES})
+ set(${PREFIX}_LIBNAMES ${${PREFIX}_LIBNAMES} ${TMP})
+ endif(${ARGC} GREATER 2)
+ find_library(${PREFIX}_LIBRARY
+ NAMES ${${PREFIX}_LIBNAMES}
+ PATHS ${${PREFIX}_PKGCONF_LIBRARY_DIRS}
+ )
+endmacro(libfind_library)
+
diff --git a/config/config.h.in b/config/config.h.in
index 60729562af..34aa72a52f 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -12,7 +12,6 @@
#define SIZEOF_OFF_T @SIZEOF_OFF_T@
#define _FILE_OFFSET_BITS 64
-#define HAVE_ATTRIBUTE_UNUSED 1
#define HAVE_BCMP 1
#define HAVE_DATE_TIME 1
#define HAVE_DIRENT_H 1
diff --git a/neovim.rb b/neovim.rb
new file mode 100644
index 0000000000..45e8b4018a
--- /dev/null
+++ b/neovim.rb
@@ -0,0 +1,16 @@
+require 'formula'
+
+class Neovim < Formula
+ homepage 'http://neovim.org'
+ head 'https://github.com/neovim/neovim.git'
+
+ depends_on 'md5sha1sum'
+ depends_on 'cmake'
+ depends_on 'libtool'
+ depends_on 'automake'
+
+ def install
+ system "make", "PREFIX=#{prefix}", "cmake"
+ system "make", "PREFIX=#{prefix}"
+ end
+end
diff --git a/scripts/common.sh b/scripts/common.sh
index d7653c6aa1..9efa3d5e6c 100644
--- a/scripts/common.sh
+++ b/scripts/common.sh
@@ -1,3 +1,16 @@
+platform='unknown'
+unameval=`uname`
+if [ "$unameval" = 'Linux' ]; then
+ platform='linux'
+elif [ "$unameval" = 'FreeBSD' ]; then
+ platform='freebsd'
+fi
+
+sha1sumcmd='sha1sum'
+if [ "$platform" = 'freebsd' ]; then
+ sha1sumcmd='shasum'
+fi
+
pkgroot="$(pwd)"
deps="$pkgroot/.deps"
prefix="$deps/usr"
@@ -10,23 +23,34 @@ download() {
if [ ! -d "$tgt" ]; then
mkdir -p "$tgt"
+ local download_command=""
if which wget > /dev/null 2>&1; then
- tmp_dir=$(mktemp -d "/tmp/download_sha1check_XXXXXXX")
- fifo="$tmp_dir/fifo"
- mkfifo "$fifo"
- # download, untar and calculate sha1 sum in one pass
- (wget "$url" -O - | tee "$fifo" | \
- (cd "$tgt"; tar --strip-components=1 -xvzf -)) &
- sum=$(sha1sum < "$fifo" | cut -d ' ' -f1)
- rm -rf "$tmp_dir"
- if [ "$sum" != "$sha1" ]; then
- echo "SHA1 sum doesn't match, expected '$sha1' got '$sum'"
- exit 1
- fi
+ # -O - to send output to stdout
+ download_command="wget --no-verbose $url -O -"
+ elif which curl >/dev/null 2>&1; then
+ # -L to follow the redirects that github will send us
+ # -sS to supress the progress bar, but show errors
+ # curl sends output to stdout by default
+ download_command="curl -L -sS $url"
else
- echo "Missing wget utility"
+ echo "Missing wget utility and curl utility"
exit 1
fi
+ local tmp_dir=$(mktemp -d "/tmp/download_sha1check_XXXXXXX")
+ local fifo="$tmp_dir/fifo"
+ mkfifo "$fifo"
+ echo "Downloading $url..."
+ # download, untar and calculate sha1 sum in one pass
+ ($download_command | tee "$fifo" | \
+ (cd "$tgt"; tar --strip-components=1 -xzf -)) &
+ local sum=$("$sha1sumcmd" < "$fifo" | cut -d ' ' -f1)
+ rm -rf "$tmp_dir"
+ if [ "$sum" != "$sha1" ]; then
+ echo "SHA1 sum doesn't match, expected '$sha1' got '$sum'"
+ exit 1
+ else
+ echo "Download complete."
+ fi
fi
}
diff --git a/scripts/compile-libuv.sh b/scripts/compile-libuv.sh
new file mode 100644
index 0000000000..f07120ed56
--- /dev/null
+++ b/scripts/compile-libuv.sh
@@ -0,0 +1,10 @@
+. scripts/common.sh
+
+uv_dir="third-party/libuv"
+
+cd "$uv_dir"
+sh autogen.sh
+./configure --prefix="$prefix"
+make
+make install
+rm "$prefix/lib/"libuv*.{so,dylib} "$prefix/lib/"libuv*.{so,dylib}.* || true
diff --git a/scripts/get-libuv.sh b/scripts/get-libuv.sh
deleted file mode 100644
index 9f3eceb218..0000000000
--- a/scripts/get-libuv.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-. scripts/common.sh
-
-uv_repo=joyent/libuv
-uv_ver=v0.11.19
-uv_dir="$deps/uv-$uv_ver"
-uv_sha1=5539d8e99e22b438cf4a412d4cec70ac6bb519fc
-
-rm -rf "$uv_dir"
-
-github_download "$uv_repo" "$uv_ver" "$uv_dir" "$uv_sha1"
-cd "$uv_dir"
-sh autogen.sh
-./configure --prefix="$prefix"
-make
-make install
-rm "$prefix/lib/"libuv*.{so,dylib} "$prefix/lib/"libuv*.{so,dylib}.* || true
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1c7829e7d6..a7e815fd7c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,24 +10,35 @@ endforeach()
list(REMOVE_ITEM NEOVIM_SOURCES ${to_remove})
list(APPEND NEOVIM_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c")
-file( GLOB IO_SOURCES io/*.c )
+file( GLOB OS_SOURCES os/*.c )
-add_executable (vim ${NEOVIM_SOURCES} ${IO_SOURCES})
+add_executable (nvim ${NEOVIM_SOURCES} ${OS_SOURCES})
-target_link_libraries (vim m uv pthread)
+# The libraries we link against for nvim
+set(NVIM_LINK_LIBRARIES m ${LibUV_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+
+# Add any libraries needed for a specific platform
+if(HAVE_CLOCK_GETTIME)
+ # Work around libuv.a not linking in rt.
+ list(APPEND NVIM_LINK_LIBRARIES rt)
+endif(HAVE_CLOCK_GETTIME)
+
+target_link_libraries (nvim ${NVIM_LINK_LIBRARIES})
include(CheckLibraryExists)
check_library_exists(termcap tgetent "" HAVE_LIBTERMCAP)
if (HAVE_LIBTERMCAP)
- target_link_libraries(vim termcap)
+ target_link_libraries(nvim termcap)
else()
check_library_exists(curses tgetent "" HAVE_LIBCURSES)
if (HAVE_LIBCURSES)
- target_link_libraries(vim curses)
+ target_link_libraries(nvim curses)
else()
message(FATAL_ERROR "can't find something resembling -ltermcap")
endif()
endif()
-include_directories ("${PROJECT_SOURCE_DIR}/src/proto")
+include_directories ("${PROJECT_SOURCE_DIR}/src/proto")
+
+install(TARGETS nvim RUNTIME DESTINATION bin)
diff --git a/src/arabic.c b/src/arabic.c
index c8d3fc2a69..5359b83a43 100644
--- a/src/arabic.c
+++ b/src/arabic.c
@@ -7,6 +7,8 @@
* See README.txt for an overview of the Vim source code.
*/
+#include "arabic.h"
+
/*
* arabic.c: functions for Arabic language
*
@@ -42,8 +44,7 @@ static int A_is_special __ARGS((int c));
/*
* Returns True if c is an ISO-8859-6 shaped ARABIC letter (user entered)
*/
-static int A_is_a(cur_c)
-int cur_c;
+static int A_is_a(int cur_c)
{
switch (cur_c) {
case a_HAMZA:
@@ -93,8 +94,7 @@ int cur_c;
/*
* Returns True if c is an Isolated Form-B ARABIC letter
*/
-static int A_is_s(cur_c)
-int cur_c;
+static int A_is_s(int cur_c)
{
switch (cur_c) {
case a_s_HAMZA:
@@ -143,8 +143,7 @@ int cur_c;
/*
* Returns True if c is a Final shape of an ARABIC letter
*/
-static int A_is_f(cur_c)
-int cur_c;
+static int A_is_f(int cur_c)
{
switch (cur_c) {
case a_f_ALEF_MADDA:
@@ -195,8 +194,7 @@ int cur_c;
/*
* Change shape - from ISO-8859-6/Isolated to Form-B Isolated
*/
-static int chg_c_a2s(cur_c)
-int cur_c;
+static int chg_c_a2s(int cur_c)
{
int tempc;
@@ -323,8 +321,7 @@ int cur_c;
/*
* Change shape - from ISO-8859-6/Isolated to Initial
*/
-static int chg_c_a2i(cur_c)
-int cur_c;
+static int chg_c_a2i(int cur_c)
{
int tempc;
@@ -451,8 +448,7 @@ int cur_c;
/*
* Change shape - from ISO-8859-6/Isolated to Medial
*/
-static int chg_c_a2m(cur_c)
-int cur_c;
+static int chg_c_a2m(int cur_c)
{
int tempc;
@@ -579,8 +575,7 @@ int cur_c;
/*
* Change shape - from ISO-8859-6/Isolated to final
*/
-static int chg_c_a2f(cur_c)
-int cur_c;
+static int chg_c_a2f(int cur_c)
{
int tempc;
@@ -717,8 +712,7 @@ int cur_c;
/*
* Change shape - from Initial to Medial
*/
-static int chg_c_i2m(cur_c)
-int cur_c;
+static int chg_c_i2m(int cur_c)
{
int tempc;
@@ -803,8 +797,7 @@ int cur_c;
/*
* Change shape - from Final to Medial
*/
-static int chg_c_f2m(cur_c)
-int cur_c;
+static int chg_c_f2m(int cur_c)
{
int tempc;
@@ -911,8 +904,7 @@ int cur_c;
/*
* Change shape - from Combination (2 char) to an Isolated
*/
-static int chg_c_laa2i(hid_c)
-int hid_c;
+static int chg_c_laa2i(int hid_c)
{
int tempc;
@@ -940,8 +932,7 @@ int hid_c;
/*
* Change shape - from Combination-Isolated to Final
*/
-static int chg_c_laa2f(hid_c)
-int hid_c;
+static int chg_c_laa2f(int hid_c)
{
int tempc;
@@ -968,8 +959,7 @@ int hid_c;
/*
* Do "half-shaping" on character "c". Return zero if no shaping.
*/
-static int half_shape(c)
-int c;
+static int half_shape(int c)
{
if (A_is_a(c))
return chg_c_a2i(c);
@@ -987,13 +977,7 @@ int c;
* (not shaped)
* in: "next_c" is the next character (not shaped).
*/
-int arabic_shape(c, ccp, c1p, prev_c, prev_c1, next_c)
-int c;
-int *ccp;
-int *c1p;
-int prev_c;
-int prev_c1;
-int next_c;
+int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1, int next_c)
{
int curr_c;
int shape_c;
@@ -1054,9 +1038,11 @@ int next_c;
/*
* A_firstc_laa returns first character of LAA combination if it exists
*/
-static int A_firstc_laa(c, c1)
-int c; /* base character */
-int c1; /* first composing character */
+static int
+A_firstc_laa (
+ int c, /* base character */
+ int c1 /* first composing character */
+)
{
if (c1 != NUL && c == a_LAM && !A_is_harakat(c1))
return c1;
@@ -1068,8 +1054,7 @@ int c1; /* first composing character */
* A_is_harakat returns TRUE if 'c' is an Arabic Harakat character
* (harakat/tanween)
*/
-static int A_is_harakat(c)
-int c;
+static int A_is_harakat(int c)
{
return c >= a_FATHATAN && c <= a_SUKUN;
}
@@ -1079,8 +1064,7 @@ int c;
* A_is_iso returns TRUE if 'c' is an Arabic ISO-8859-6 character
* (alphabet/number/punctuation)
*/
-static int A_is_iso(c)
-int c;
+static int A_is_iso(int c)
{
return (c >= a_HAMZA && c <= a_GHAIN)
|| (c >= a_TATWEEL && c <= a_HAMZA_BELOW)
@@ -1092,8 +1076,7 @@ int c;
* A_is_formb returns TRUE if 'c' is an Arabic 10646-1 FormB character
* (alphabet/number/punctuation)
*/
-static int A_is_formb(c)
-int c;
+static int A_is_formb(int c)
{
return (c >= a_s_FATHATAN && c <= a_s_DAMMATAN)
|| c == a_s_KASRATAN
@@ -1105,8 +1088,7 @@ int c;
/*
* A_is_ok returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
*/
-static int A_is_ok(c)
-int c;
+static int A_is_ok(int c)
{
return A_is_iso(c) || A_is_formb(c);
}
@@ -1116,8 +1098,7 @@ int c;
* A_is_valid returns TRUE if 'c' is an Arabic 10646 (8859-6 or Form-B)
* with some exceptions/exclusions
*/
-static int A_is_valid(c)
-int c;
+static int A_is_valid(int c)
{
return A_is_ok(c) && !A_is_special(c);
}
@@ -1127,8 +1108,7 @@ int c;
* A_is_special returns TRUE if 'c' is not a special Arabic character.
* Specials don't adhere to most of the rules.
*/
-static int A_is_special(c)
-int c;
+static int A_is_special(int c)
{
return c == a_HAMZA || c == a_s_HAMZA;
}
diff --git a/src/ascii.h b/src/ascii.h
index 0904521ccf..50ca04f443 100644
--- a/src/ascii.h
+++ b/src/ascii.h
@@ -6,6 +6,9 @@
* Do ":help credits" in Vim to see a list of people who contributed.
*/
+#ifndef NEOVIM_ASCII_H
+#define NEOVIM_ASCII_H
+
/*
* Definitions of various common control characters.
* For EBCDIC we have to use different values.
@@ -94,3 +97,5 @@
# define PATHSEP '/'
# define PATHSEPSTR "/"
#endif
+
+#endif /* NEOVIM_ASCII_H */
diff --git a/src/blowfish.c b/src/blowfish.c
index 2e4d8cf1af..d7074bd42c 100644
--- a/src/blowfish.c
+++ b/src/blowfish.c
@@ -12,7 +12,9 @@
*/
#include "vim.h"
-
+#include "blowfish.h"
+#include "message.h"
+#include "sha256.h"
#define ARRAY_LENGTH(A) (sizeof(A)/sizeof(A[0]))
@@ -319,9 +321,7 @@ static UINT32_T sbi[4][256] = {
sbx[3][xr & 0xFF];
-static void bf_e_block(p_xl, p_xr)
-UINT32_T *p_xl;
-UINT32_T *p_xr;
+static void bf_e_block(UINT32_T *p_xl, UINT32_T *p_xr)
{
UINT32_T temp, xl = *p_xl, xr = *p_xr;
@@ -346,8 +346,7 @@ UINT32_T *p_xr;
# define htonl2(x)
#endif
-static void bf_e_cblock(block)
-char_u *block;
+static void bf_e_cblock(char_u *block)
{
block8 bk;
@@ -365,10 +364,7 @@ char_u *block;
* Initialize the crypt method using "password" as the encryption key and
* "salt[salt_len]" as the salt.
*/
-void bf_key_init(password, salt, salt_len)
-char_u *password;
-char_u *salt;
-int salt_len;
+void bf_key_init(char_u *password, char_u *salt, int salt_len)
{
int i, j, keypos = 0;
unsigned u;
@@ -421,10 +417,7 @@ int salt_len;
/*
* BF Self test for corrupted tables or instructions
*/
-static int bf_check_tables(a_ipa, a_sbi, val)
-UINT32_T a_ipa[18];
-UINT32_T a_sbi[4][256];
-UINT32_T val;
+static int bf_check_tables(UINT32_T a_ipa[18], UINT32_T a_sbi[4][256], UINT32_T val)
{
int i, j;
UINT32_T c = 0;
@@ -464,7 +457,7 @@ static struct_bf_test_data bf_test_data[] = {
/*
* Return FAIL when there is something wrong with blowfish encryption.
*/
-static int bf_self_test() {
+static int bf_self_test(void) {
int i, bn;
int err = 0;
block8 bk;
@@ -509,9 +502,7 @@ static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */
/*
* Initialize with seed "iv[iv_len]".
*/
-void bf_ofb_init(iv, iv_len)
-char_u *iv;
-int iv_len;
+void bf_ofb_init(char_u *iv, int iv_len)
{
int i, mi;
@@ -542,10 +533,7 @@ int iv_len;
* Encrypt "from[len]" into "to[len]".
* "from" and "to" can be equal to encrypt in place.
*/
-void bf_crypt_encode(from, len, to)
-char_u *from;
-size_t len;
-char_u *to;
+void bf_crypt_encode(char_u *from, size_t len, char_u *to)
{
size_t i;
int ztemp, t;
@@ -561,9 +549,7 @@ char_u *to;
/*
* Decrypt "ptr[len]" in place.
*/
-void bf_crypt_decode(ptr, len)
-char_u *ptr;
-long len;
+void bf_crypt_decode(char_u *ptr, long len)
{
char_u *p;
int t;
@@ -579,8 +565,10 @@ long len;
* Initialize the encryption keys and the random header according to
* the given password.
*/
-void bf_crypt_init_keys(passwd)
-char_u *passwd; /* password string with which to modify keys */
+void
+bf_crypt_init_keys (
+ char_u *passwd /* password string with which to modify keys */
+)
{
char_u *p;
@@ -599,7 +587,7 @@ static UINT32_T save_sbx[4][256];
* Save the current crypt state. Can only be used once before
* bf_crypt_restore().
*/
-void bf_crypt_save() {
+void bf_crypt_save(void) {
save_randbyte_offset = randbyte_offset;
save_update_offset = update_offset;
mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN);
@@ -611,7 +599,7 @@ void bf_crypt_save() {
* Restore the current crypt state. Can only be used after
* bf_crypt_save().
*/
-void bf_crypt_restore() {
+void bf_crypt_restore(void) {
randbyte_offset = save_randbyte_offset;
update_offset = save_update_offset;
mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN);
@@ -623,7 +611,7 @@ void bf_crypt_restore() {
* Run a test to check if the encryption works as expected.
* Give an error and return FAIL when not.
*/
-int blowfish_self_test() {
+int blowfish_self_test(void) {
if (sha256_self_test() == FAIL) {
EMSG(_("E818: sha256 test failed"));
return FAIL;
diff --git a/src/proto/blowfish.pro b/src/blowfish.h
index 51e4fa9ec5..d4d8f36429 100644
--- a/src/proto/blowfish.pro
+++ b/src/blowfish.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_BLOWFISH_H
+#define NEOVIM_BLOWFISH_H
/* blowfish.c */
void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len));
void bf_ofb_init __ARGS((char_u *iv, int iv_len));
@@ -8,3 +10,4 @@ void bf_crypt_save __ARGS((void));
void bf_crypt_restore __ARGS((void));
int blowfish_self_test __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_BLOWFISH_H */
diff --git a/src/buffer.c b/src/buffer.c
index bffae5388d..401dc40333 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -26,6 +26,39 @@
*/
#include "vim.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "digraph.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_cmds.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "spell.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
static char_u *buflist_match __ARGS((regprog_T *prog, buf_T *buf));
# define HAVE_BUFLIST_MATCH
@@ -64,10 +97,12 @@ static char *e_auabort = N_("E855: Autocommands caused command to abort");
* memory.
* Return FAIL for failure, OK otherwise.
*/
-int open_buffer(read_stdin, eap, flags)
-int read_stdin; /* read file from stdin */
-exarg_T *eap; /* for forced 'ff' and 'fenc' or NULL */
-int flags; /* extra flags for readfile() */
+int
+open_buffer (
+ int read_stdin, /* read file from stdin */
+ exarg_T *eap, /* for forced 'ff' and 'fenc' or NULL */
+ int flags /* extra flags for readfile() */
+)
{
int retval = OK;
buf_T *old_curbuf;
@@ -231,8 +266,7 @@ int flags; /* extra flags for readfile() */
/*
* Return TRUE if "buf" points to a valid buffer (in the buffer list).
*/
-int buf_valid(buf)
-buf_T *buf;
+int buf_valid(buf_T *buf)
{
buf_T *bp;
@@ -259,11 +293,13 @@ buf_T *buf;
* cause there to be only one window with this buffer. e.g. when ":quit" is
* supposed to close the window but autocommands close all other windows.
*/
-void close_buffer(win, buf, action, abort_if_last)
-win_T *win; /* if not NULL, set b_last_cursor */
-buf_T *buf;
-int action;
-int abort_if_last UNUSED;
+void
+close_buffer (
+ win_T *win, /* if not NULL, set b_last_cursor */
+ buf_T *buf,
+ int action,
+ int abort_if_last
+)
{
int is_curbuf;
int nwindows;
@@ -421,8 +457,7 @@ aucmd_abort:
/*
* Make buffer not contain a file.
*/
-void buf_clear_file(buf)
-buf_T *buf;
+void buf_clear_file(buf_T *buf)
{
buf->b_ml.ml_line_count = 1;
unchanged(buf, TRUE);
@@ -444,9 +479,7 @@ buf_T *buf;
* BFA_WIPE buffer is going to be wiped out
* BFA_KEEP_UNDO do not free undo information
*/
-void buf_freeall(buf, flags)
-buf_T *buf;
-int flags;
+void buf_freeall(buf_T *buf, int flags)
{
int is_curbuf = (buf == curbuf);
@@ -506,8 +539,7 @@ int flags;
* Free a buffer structure and the things it contains related to the buffer
* itself (not the file, that must have been done already).
*/
-static void free_buffer(buf)
-buf_T *buf;
+static void free_buffer(buf_T *buf)
{
free_buffer_stuff(buf, TRUE);
unref_var_dict(buf->b_vars);
@@ -518,9 +550,11 @@ buf_T *buf;
/*
* Free stuff in the buffer for ":bdel" and when wiping out the buffer.
*/
-static void free_buffer_stuff(buf, free_options)
-buf_T *buf;
-int free_options; /* free options as well */
+static void
+free_buffer_stuff (
+ buf_T *buf,
+ int free_options /* free options as well */
+)
{
if (free_options) {
clear_wininfo(buf); /* including window-local options */
@@ -539,8 +573,7 @@ int free_options; /* free options as well */
/*
* Free the b_wininfo list for buffer "buf".
*/
-static void clear_wininfo(buf)
-buf_T *buf;
+static void clear_wininfo(buf_T *buf)
{
wininfo_T *wip;
@@ -558,11 +591,7 @@ buf_T *buf;
/*
* Go to another buffer. Handles the result of the ATTENTION dialog.
*/
-void goto_buffer(eap, start, dir, count)
-exarg_T *eap;
-int start;
-int dir;
-int count;
+void goto_buffer(exarg_T *eap, int start, int dir, int count)
{
# if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION)
buf_T *old_curbuf = curbuf;
@@ -597,8 +626,7 @@ int count;
* Handle the situation of swap_exists_action being set.
* It is allowed for "old_curbuf" to be NULL or invalid.
*/
-void handle_swap_exists(old_curbuf)
-buf_T *old_curbuf;
+void handle_swap_exists(buf_T *old_curbuf)
{
cleanup_T cs;
long old_tw = curbuf->b_p_tw;
@@ -659,13 +687,15 @@ buf_T *old_curbuf;
*
* Returns error message or NULL
*/
-char_u * do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
-int command;
-char_u *arg; /* pointer to extra arguments */
-int addr_count;
-int start_bnr; /* first buffer number in a range */
-int end_bnr; /* buffer nr or last buffer nr in a range */
-int forceit;
+char_u *
+do_bufdel (
+ int command,
+ char_u *arg, /* pointer to extra arguments */
+ int addr_count,
+ int start_bnr, /* first buffer number in a range */
+ int end_bnr, /* buffer nr or last buffer nr in a range */
+ int forceit
+)
{
int do_current = 0; /* delete current buffer? */
int deleted = 0; /* number of buffers deleted */
@@ -762,10 +792,7 @@ static int empty_curbuf __ARGS((int close_others, int forceit, int action));
* Make the current buffer empty.
* Used when it is wiped out and it's the last buffer.
*/
-static int empty_curbuf(close_others, forceit, action)
-int close_others;
-int forceit;
-int action;
+static int empty_curbuf(int close_others, int forceit, int action)
{
int retval;
buf_T *buf = curbuf;
@@ -811,12 +838,14 @@ int action;
*
* Return FAIL or OK.
*/
-int do_buffer(action, start, dir, count, forceit)
-int action;
-int start;
-int dir; /* FORWARD or BACKWARD */
-int count; /* buffer number or number of buffers */
-int forceit; /* TRUE for :...! */
+int
+do_buffer (
+ int action,
+ int start,
+ int dir, /* FORWARD or BACKWARD */
+ int count, /* buffer number or number of buffers */
+ int forceit /* TRUE for :...! */
+)
{
buf_T *buf;
buf_T *bp;
@@ -1100,9 +1129,7 @@ int forceit; /* TRUE for :...! */
* DOBUF_DEL delete it
* DOBUF_WIPE wipe it out
*/
-void set_curbuf(buf, action)
-buf_T *buf;
-int action;
+void set_curbuf(buf_T *buf, int action)
{
buf_T *prevbuf;
int unload = (action == DOBUF_UNLOAD || action == DOBUF_DEL
@@ -1158,8 +1185,7 @@ int action;
* Old curbuf must have been abandoned already! This also means "curbuf" may
* be pointing to freed memory.
*/
-void enter_buffer(buf)
-buf_T *buf;
+void enter_buffer(buf_T *buf)
{
/* Copy buffer and window local option values. Not for a help buffer. */
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
@@ -1237,7 +1263,7 @@ buf_T *buf;
/*
* Change to the directory of the current buffer.
*/
-void do_autochdir() {
+void do_autochdir(void) {
if (curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK)
shorten_fnames(TRUE);
}
@@ -1257,11 +1283,13 @@ void do_autochdir() {
*/
static int top_file_num = 1; /* highest file number */
-buf_T * buflist_new(ffname, sfname, lnum, flags)
-char_u *ffname; /* full path of fname or relative */
-char_u *sfname; /* short fname or NULL */
-linenr_T lnum; /* preferred cursor line */
-int flags; /* BLN_ defines */
+buf_T *
+buflist_new (
+ char_u *ffname, /* full path of fname or relative */
+ char_u *sfname, /* short fname or NULL */
+ linenr_T lnum, /* preferred cursor line */
+ int flags /* BLN_ defines */
+)
{
buf_T *buf;
#ifdef UNIX
@@ -1451,9 +1479,7 @@ int flags; /* BLN_ defines */
* If "free_p_ff" is TRUE also free 'fileformat', 'buftype' and
* 'fileencoding'.
*/
-void free_buf_options(buf, free_p_ff)
-buf_T *buf;
-int free_p_ff;
+void free_buf_options(buf_T *buf, int free_p_ff)
{
if (free_p_ff) {
clear_string_option(&buf->b_p_fenc);
@@ -1516,11 +1542,7 @@ int free_p_ff;
*
* return FAIL for failure, OK for success
*/
-int buflist_getfile(n, lnum, options, forceit)
-int n;
-linenr_T lnum;
-int options;
-int forceit;
+int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
{
buf_T *buf;
win_T *wp = NULL;
@@ -1596,7 +1618,7 @@ int forceit;
/*
* go to the last know line number for the current buffer
*/
-void buflist_getfpos() {
+void buflist_getfpos(void) {
pos_T *fpos;
fpos = buflist_findfpos(curbuf);
@@ -1618,8 +1640,7 @@ void buflist_getfpos() {
* Find file in buffer list by name (it has to be for the current window).
* Returns NULL if not found.
*/
-buf_T * buflist_findname_exp(fname)
-char_u *fname;
+buf_T *buflist_findname_exp(char_u *fname)
{
char_u *ffname;
buf_T *buf = NULL;
@@ -1645,8 +1666,7 @@ char_u *fname;
* Skips dummy buffers.
* Returns NULL if not found.
*/
-buf_T * buflist_findname(ffname)
-char_u *ffname;
+buf_T *buflist_findname(char_u *ffname)
{
#ifdef UNIX
struct stat st;
@@ -1661,9 +1681,7 @@ char_u *ffname;
* twice for the same file.
* Returns NULL if not found.
*/
-static buf_T * buflist_findname_stat(ffname, stp)
-char_u *ffname;
-struct stat *stp;
+static buf_T *buflist_findname_stat(char_u *ffname, struct stat *stp)
{
#endif
buf_T *buf;
@@ -1685,12 +1703,14 @@ struct stat *stp;
* Return fnum of the found buffer.
* Return < 0 for error.
*/
-int buflist_findpat(pattern, pattern_end, unlisted, diffmode, curtab_only)
-char_u *pattern;
-char_u *pattern_end; /* pointer to first char after pattern */
-int unlisted; /* find unlisted buffers */
-int diffmode UNUSED; /* find diff-mode buffers only */
-int curtab_only; /* find buffers in current tab only */
+int
+buflist_findpat (
+ char_u *pattern,
+ char_u *pattern_end, /* pointer to first char after pattern */
+ int unlisted, /* find unlisted buffers */
+ int diffmode, /* find diff-mode buffers only */
+ int curtab_only /* find buffers in current tab only */
+)
{
buf_T *buf;
regprog_T *prog;
@@ -1794,11 +1814,7 @@ int curtab_only; /* find buffers in current tab only */
* For command line expansion of ":buf" and ":sbuf".
* Return OK if matches found, FAIL otherwise.
*/
-int ExpandBufnames(pat, num_file, file, options)
-char_u *pat;
-int *num_file;
-char_u ***file;
-int options;
+int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
{
int count = 0;
buf_T *buf;
@@ -1886,9 +1902,7 @@ int options;
/*
* Check for a match on the file name for buffer "buf" with regprog "prog".
*/
-static char_u * buflist_match(prog, buf)
-regprog_T *prog;
-buf_T *buf;
+static char_u *buflist_match(regprog_T *prog, buf_T *buf)
{
char_u *match;
@@ -1904,9 +1918,7 @@ buf_T *buf;
* Try matching the regexp in "prog" with file name "name".
* Return "name" when there is a match, NULL when not.
*/
-static char_u * fname_match(prog, name)
-regprog_T *prog;
-char_u *name;
+static char_u *fname_match(regprog_T *prog, char_u *name)
{
char_u *match = NULL;
char_u *p;
@@ -1933,8 +1945,7 @@ char_u *name;
/*
* find file in buffer list by number
*/
-buf_T * buflist_findnr(nr)
-int nr;
+buf_T *buflist_findnr(int nr)
{
buf_T *buf;
@@ -1952,10 +1963,12 @@ int nr;
* home_replace() is used to shorten the file name (used for marks).
* Returns a pointer to allocated memory, of NULL when failed.
*/
-char_u * buflist_nr2name(n, fullname, helptail)
-int n;
-int fullname;
-int helptail; /* for help buffers return tail only */
+char_u *
+buflist_nr2name (
+ int n,
+ int fullname,
+ int helptail /* for help buffers return tail only */
+)
{
buf_T *buf;
@@ -1971,12 +1984,7 @@ int helptail; /* for help buffers return tail only */
* When "copy_options" is TRUE save the local window option values.
* When "lnum" is 0 only do the options.
*/
-static void buflist_setfpos(buf, win, lnum, col, copy_options)
-buf_T *buf;
-win_T *win;
-linenr_T lnum;
-colnr_T col;
-int copy_options;
+static void buflist_setfpos(buf_T *buf, win_T *win, linenr_T lnum, colnr_T col, int copy_options)
{
wininfo_T *wip;
@@ -2032,8 +2040,7 @@ static int wininfo_other_tab_diff __ARGS((wininfo_T *wip));
* Return TRUE when "wip" has 'diff' set and the diff is only for another tab
* page. That's because a diff is local to a tab page.
*/
-static int wininfo_other_tab_diff(wip)
-wininfo_T *wip;
+static int wininfo_other_tab_diff(wininfo_T *wip)
{
win_T *wp;
@@ -2055,9 +2062,7 @@ wininfo_T *wip;
* another tab page.
* Returns NULL when there isn't any info.
*/
-static wininfo_T * find_wininfo(buf, skip_diff_buffer)
-buf_T *buf;
-int skip_diff_buffer UNUSED;
+static wininfo_T *find_wininfo(buf_T *buf, int skip_diff_buffer)
{
wininfo_T *wip;
@@ -2086,8 +2091,7 @@ int skip_diff_buffer UNUSED;
* the most recently used window. If the values were never set, use the
* global values for the window.
*/
-void get_winopts(buf)
-buf_T *buf;
+void get_winopts(buf_T *buf)
{
wininfo_T *wip;
@@ -2114,8 +2118,7 @@ buf_T *buf;
* window.
* Returns a pointer to no_position if no position is found.
*/
-pos_T * buflist_findfpos(buf)
-buf_T *buf;
+pos_T *buflist_findfpos(buf_T *buf)
{
wininfo_T *wip;
static pos_T no_position = INIT_POS_T(1, 0, 0);
@@ -2130,8 +2133,7 @@ buf_T *buf;
/*
* Find the lnum for the buffer 'buf' for the current window.
*/
-linenr_T buflist_findlnum(buf)
-buf_T *buf;
+linenr_T buflist_findlnum(buf_T *buf)
{
return buflist_findfpos(buf)->lnum;
}
@@ -2139,8 +2141,7 @@ buf_T *buf;
/*
* List all know file names (for :files and :buffers command).
*/
-void buflist_list(eap)
-exarg_T *eap;
+void buflist_list(exarg_T *eap)
{
buf_T *buf;
int len;
@@ -2188,10 +2189,7 @@ exarg_T *eap;
* Used by insert_reg() and cmdline_paste() for '#' register.
* Return FAIL if not found, OK for success.
*/
-int buflist_name_nr(fnum, fname, lnum)
-int fnum;
-char_u **fname;
-linenr_T *lnum;
+int buflist_name_nr(int fnum, char_u **fname, linenr_T *lnum)
{
buf_T *buf;
@@ -2211,10 +2209,13 @@ linenr_T *lnum;
* Returns FAIL for failure (file name already in use by other buffer)
* OK otherwise.
*/
-int setfname(buf, ffname, sfname, message)
-buf_T *buf;
-char_u *ffname, *sfname;
-int message; /* give message when buffer already exists */
+int
+setfname (
+ buf_T *buf,
+ char_u *ffname,
+ char_u *sfname,
+ int message /* give message when buffer already exists */
+)
{
buf_T *obuf = NULL;
#ifdef UNIX
@@ -2300,9 +2301,7 @@ int message; /* give message when buffer already exists */
* Crude way of changing the name of a buffer. Use with care!
* The name should be relative to the current directory.
*/
-void buf_set_name(fnum, name)
-int fnum;
-char_u *name;
+void buf_set_name(int fnum, char_u *name)
{
buf_T *buf;
@@ -2323,8 +2322,7 @@ char_u *name;
* Take care of what needs to be done when the name of buffer "buf" has
* changed.
*/
-void buf_name_changed(buf)
-buf_T *buf;
+void buf_name_changed(buf_T *buf)
{
/*
* If the file name changed, also change the name of the swapfile
@@ -2346,10 +2344,7 @@ buf_T *buf;
* Used by do_one_cmd(), do_write() and do_ecmd().
* Return the buffer.
*/
-buf_T * setaltfname(ffname, sfname, lnum)
-char_u *ffname;
-char_u *sfname;
-linenr_T lnum;
+buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
{
buf_T *buf;
@@ -2364,8 +2359,10 @@ linenr_T lnum;
* Get alternate file name for current window.
* Return NULL if there isn't any, and give error message if requested.
*/
-char_u * getaltfname(errmsg)
-int errmsg; /* give error message */
+char_u *
+getaltfname (
+ int errmsg /* give error message */
+)
{
char_u *fname;
linenr_T dummy;
@@ -2384,9 +2381,7 @@ int errmsg; /* give error message */
*
* used by qf_init(), main() and doarglist()
*/
-int buflist_add(fname, flags)
-char_u *fname;
-int flags;
+int buflist_add(char_u *fname, int flags)
{
buf_T *buf;
@@ -2400,7 +2395,7 @@ int flags;
/*
* Adjust slashes in file names. Called after 'shellslash' was set.
*/
-void buflist_slash_adjust() {
+void buflist_slash_adjust(void) {
buf_T *bp;
for (bp = firstbuf; bp != NULL; bp = bp->b_next) {
@@ -2417,8 +2412,7 @@ void buflist_slash_adjust() {
* Set alternate cursor position for the current buffer and window "win".
* Also save the local window option values.
*/
-void buflist_altfpos(win)
-win_T *win;
+void buflist_altfpos(win_T *win)
{
buflist_setfpos(curbuf, win, win->w_cursor.lnum, win->w_cursor.col, TRUE);
}
@@ -2427,8 +2421,7 @@ win_T *win;
* Return TRUE if 'ffname' is not the same file as current file.
* Fname must have a full path (expanded by mch_FullName()).
*/
-int otherfile(ffname)
-char_u *ffname;
+int otherfile(char_u *ffname)
{
return otherfile_buf(curbuf, ffname
#ifdef UNIX
@@ -2437,16 +2430,11 @@ char_u *ffname;
);
}
-static int otherfile_buf(buf, ffname
+static int otherfile_buf(buf_T *buf, char_u *ffname
#ifdef UNIX
- , stp
-#endif
- )
-buf_T *buf;
-char_u *ffname;
-#ifdef UNIX
-struct stat *stp;
+ , struct stat *stp
#endif
+)
{
/* no name is different */
if (ffname == NULL || *ffname == NUL || buf->b_ffname == NULL)
@@ -2487,8 +2475,7 @@ struct stat *stp;
* Set inode and device number for a buffer.
* Must always be called when b_fname is changed!.
*/
-void buf_setino(buf)
-buf_T *buf;
+void buf_setino(buf_T *buf)
{
struct stat st;
@@ -2503,9 +2490,7 @@ buf_T *buf;
/*
* Return TRUE if dev/ino in buffer "buf" matches with "stp".
*/
-static int buf_same_ino(buf, stp)
-buf_T *buf;
-struct stat *stp;
+static int buf_same_ino(buf_T *buf, struct stat *stp)
{
return buf->b_dev_valid
&& stp->st_dev == buf->b_dev
@@ -2516,10 +2501,12 @@ struct stat *stp;
/*
* Print info about the current buffer.
*/
-void fileinfo(fullname, shorthelp, dont_truncate)
-int fullname; /* when non-zero print full path */
-int shorthelp;
-int dont_truncate;
+void
+fileinfo (
+ int fullname, /* when non-zero print full path */
+ int shorthelp,
+ int dont_truncate
+)
{
char_u *name;
int n;
@@ -2617,11 +2604,7 @@ int dont_truncate;
vim_free(buffer);
}
-void col_print(buf, buflen, col, vcol)
-char_u *buf;
-size_t buflen;
-int col;
-int vcol;
+void col_print(char_u *buf, size_t buflen, int col, int vcol)
{
if (col == vcol)
vim_snprintf((char *)buf, buflen, "%d", col);
@@ -2636,7 +2619,7 @@ int vcol;
static char_u *lasttitle = NULL;
static char_u *lasticon = NULL;
-void maketitle() {
+void maketitle(void) {
char_u *p;
char_u *t_str = NULL;
char_u *i_name;
@@ -2803,9 +2786,7 @@ void maketitle() {
* from "str" if it does.
* Return TRUE when "*last" changed.
*/
-static int ti_change(str, last)
-char_u *str;
-char_u **last;
+static int ti_change(char_u *str, char_u **last)
{
if ((str == NULL) != (*last == NULL)
|| (str != NULL && *last != NULL && STRCMP(str, *last) != 0)) {
@@ -2822,12 +2803,12 @@ char_u **last;
/*
* Put current window title back (used after calling a shell)
*/
-void resettitle() {
+void resettitle(void) {
mch_settitle(lasttitle, lasticon);
}
# if defined(EXITFREE) || defined(PROTO)
-void free_titles() {
+void free_titles(void) {
vim_free(lasttitle);
vim_free(lasticon);
}
@@ -2849,17 +2830,18 @@ void free_titles() {
* If maxwidth is not zero, the string will be filled at any middle marker
* or truncated if too long, fillchar is used for all whitespace.
*/
-int build_stl_str_hl(wp, out, outlen, fmt, use_sandbox, fillchar,
- maxwidth, hltab, tabtab)
-win_T *wp;
-char_u *out; /* buffer to write into != NameBuff */
-size_t outlen; /* length of out[] */
-char_u *fmt;
-int use_sandbox UNUSED; /* "fmt" was set insecurely, use sandbox */
-int fillchar;
-int maxwidth;
-struct stl_hlrec *hltab; /* return: HL attributes (can be NULL) */
-struct stl_hlrec *tabtab; /* return: tab page nrs (can be NULL) */
+int
+build_stl_str_hl (
+ win_T *wp,
+ char_u *out, /* buffer to write into != NameBuff */
+ size_t outlen, /* length of out[] */
+ char_u *fmt,
+ int use_sandbox, /* "fmt" was set insecurely, use sandbox */
+ int fillchar,
+ int maxwidth,
+ struct stl_hlrec *hltab, /* return: HL attributes (can be NULL) */
+ struct stl_hlrec *tabtab /* return: tab page nrs (can be NULL) */
+)
{
char_u *p;
char_u *s;
@@ -3574,10 +3556,7 @@ struct stl_hlrec *tabtab; /* return: tab page nrs (can be NULL) */
* Get relative cursor position in window into "buf[buflen]", in the form 99%,
* using "Top", "Bot" or "All" when appropriate.
*/
-void get_rel_pos(wp, buf, buflen)
-win_T *wp;
-char_u *buf;
-int buflen;
+void get_rel_pos(win_T *wp, char_u *buf, int buflen)
{
long above; /* number of lines above window */
long below; /* number of lines below window */
@@ -3601,11 +3580,13 @@ int buflen;
* Append (file 2 of 8) to "buf[buflen]", if editing more than one file.
* Return TRUE if it was appended.
*/
-static int append_arg_number(wp, buf, buflen, add_file)
-win_T *wp;
-char_u *buf;
-int buflen;
-int add_file; /* Add "file" before the arg number */
+static int
+append_arg_number (
+ win_T *wp,
+ char_u *buf,
+ int buflen,
+ int add_file /* Add "file" before the arg number */
+)
{
char_u *p;
@@ -3631,8 +3612,7 @@ int add_file; /* Add "file" before the arg number */
* If fname is not a full path, make it a full path.
* Returns pointer to allocated memory (NULL for failure).
*/
-char_u * fix_fname(fname)
-char_u *fname;
+char_u *fix_fname(char_u *fname)
{
/*
* Force expanding the path always for Unix, because symbolic links may
@@ -3674,10 +3654,7 @@ char_u *fname;
* Make "ffname" a full file name, set "sfname" to "ffname" if not NULL.
* "ffname" becomes a pointer to allocated memory (or NULL).
*/
-void fname_expand(buf, ffname, sfname)
-buf_T *buf UNUSED;
-char_u **ffname;
-char_u **sfname;
+void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname)
{
if (*ffname == NULL) /* if no file name given, nothing to do */
return;
@@ -3703,8 +3680,7 @@ char_u **sfname;
/*
* Get the file name for an argument list entry.
*/
-char_u * alist_name(aep)
-aentry_T *aep;
+char_u *alist_name(aentry_T *aep)
{
buf_T *bp;
@@ -3718,10 +3694,12 @@ aentry_T *aep;
/*
* do_arg_all(): Open up to 'count' windows, one for each argument.
*/
-void do_arg_all(count, forceit, keep_tabs)
-int count;
-int forceit; /* hide buffers in current windows */
-int keep_tabs; /* keep current tabs, for ":tab drop file" */
+void
+do_arg_all (
+ int count,
+ int forceit, /* hide buffers in current windows */
+ int keep_tabs /* keep current tabs, for ":tab drop file" */
+)
{
int i;
win_T *wp, *wpnext;
@@ -3957,8 +3935,7 @@ int keep_tabs; /* keep current tabs, for ":tab drop file" */
/*
* Open a window for a number of buffers.
*/
-void ex_buffer_all(eap)
-exarg_T *eap;
+void ex_buffer_all(exarg_T *eap)
{
buf_T *buf;
win_T *wp, *wpnext;
@@ -4140,8 +4117,7 @@ static int chk_modeline __ARGS((linenr_T, int));
*
* Returns immediately if the "ml" option isn't set.
*/
-void do_modelines(flags)
-int flags;
+void do_modelines(int flags)
{
linenr_T lnum;
int nmlines;
@@ -4168,15 +4144,17 @@ int flags;
--entered;
}
-#include "version.h" /* for version number */
+#include "version_defs.h" /* for version number */
/*
* chk_modeline() - check a single line for a mode string
* Return FAIL if an error encountered.
*/
-static int chk_modeline(lnum, flags)
-linenr_T lnum;
-int flags; /* Same as for do_modelines(). */
+static int
+chk_modeline (
+ linenr_T lnum,
+ int flags /* Same as for do_modelines(). */
+)
{
char_u *s;
char_u *e;
@@ -4281,9 +4259,7 @@ int flags; /* Same as for do_modelines(). */
return retval;
}
-int read_viminfo_bufferlist(virp, writing)
-vir_T *virp;
-int writing;
+int read_viminfo_bufferlist(vir_T *virp, int writing)
{
char_u *tab;
linenr_T lnum;
@@ -4330,8 +4306,7 @@ int writing;
return viminfo_readline(virp);
}
-void write_viminfo_bufferlist(fp)
-FILE *fp;
+void write_viminfo_bufferlist(FILE *fp)
{
buf_T *buf;
win_T *win;
@@ -4379,8 +4354,7 @@ FILE *fp;
* Return special buffer name.
* Returns NULL when the buffer has a normal file name.
*/
-char_u * buf_spname(buf)
-buf_T *buf;
+char_u *buf_spname(buf_T *buf)
{
if (bt_quickfix(buf)) {
win_T *win;
@@ -4415,10 +4389,7 @@ buf_T *buf;
* If found OK is returned and "wp" and "tp" are set to the window and tabpage.
* If not found FAIL is returned.
*/
-int find_win_for_buf(buf, wp, tp)
-buf_T *buf;
-win_T **wp;
-tabpage_T **tp;
+int find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
{
FOR_ALL_TAB_WINDOWS(*tp, *wp)
if ((*wp)->w_buffer == buf)
@@ -4433,8 +4404,7 @@ win_found:
/*
* Set 'buflisted' for curbuf to "on" and trigger autocommands if it changed.
*/
-void set_buflisted(on)
-int on;
+void set_buflisted(int on)
{
if (on != curbuf->b_p_bl) {
curbuf->b_p_bl = on;
@@ -4449,8 +4419,7 @@ int on;
* Read the file for "buf" again and check if the contents changed.
* Return TRUE if it changed or this could not be checked.
*/
-int buf_contents_changed(buf)
-buf_T *buf;
+int buf_contents_changed(buf_T *buf)
{
buf_T *newbuf;
int differ = TRUE;
@@ -4502,9 +4471,11 @@ buf_T *buf;
* this buffer. Call this to wipe out a temp buffer that does not contain any
* marks.
*/
-void wipe_buffer(buf, aucmd)
-buf_T *buf;
-int aucmd UNUSED; /* When TRUE trigger autocommands. */
+void
+wipe_buffer (
+ buf_T *buf,
+ int aucmd /* When TRUE trigger autocommands. */
+)
{
if (buf->b_fnum == top_file_num - 1)
--top_file_num;
diff --git a/src/proto/buffer.pro b/src/buffer.h
index 060008db77..3ca525612d 100644
--- a/src/proto/buffer.pro
+++ b/src/buffer.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_BUFFER_H
+#define NEOVIM_BUFFER_H
/* buffer.c */
int open_buffer __ARGS((int read_stdin, exarg_T *eap, int flags));
int buf_valid __ARGS((buf_T *buf));
@@ -79,3 +81,4 @@ void set_buflisted __ARGS((int on));
int buf_contents_changed __ARGS((buf_T *buf));
void wipe_buffer __ARGS((buf_T *buf, int aucmd));
/* vim: set ft=c : */
+#endif /* NEOVIM_BUFFER_H */
diff --git a/src/charset.c b/src/charset.c
index 1eee20f66c..271df2c7f4 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -8,6 +8,14 @@
*/
#include "vim.h"
+#include "charset.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "os_unix.h"
static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col));
@@ -56,13 +64,15 @@ static int chartab_initialized = FALSE;
* Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an
* error, OK otherwise.
*/
-int init_chartab() {
+int init_chartab(void) {
return buf_init_chartab(curbuf, TRUE);
}
-int buf_init_chartab(buf, global)
-buf_T *buf;
-int global; /* FALSE: only set buf->b_chartab[] */
+int
+buf_init_chartab (
+ buf_T *buf,
+ int global /* FALSE: only set buf->b_chartab[] */
+)
{
int c;
int c2;
@@ -246,9 +256,7 @@ int global; /* FALSE: only set buf->b_chartab[] */
* The result is a string with only printable characters, but if there is not
* enough room, not all characters will be translated.
*/
-void trans_characters(buf, bufsize)
-char_u *buf;
-int bufsize;
+void trans_characters(char_u *buf, int bufsize)
{
int len; /* length of string needing translation */
int room; /* room in buffer after string */
@@ -283,8 +291,7 @@ int bufsize;
* Translate a string into allocated memory, replacing special chars with
* printable chars. Returns NULL when out of memory.
*/
-char_u * transstr(s)
-char_u *s;
+char_u *transstr(char_u *s)
{
char_u *res;
char_u *p;
@@ -342,11 +349,7 @@ char_u *s;
* When "buf" is NULL returns an allocated string (NULL for out-of-memory).
* Otherwise puts the result in "buf[buflen]".
*/
-char_u * str_foldcase(str, orglen, buf, buflen)
-char_u *str;
-int orglen;
-char_u *buf;
-int buflen;
+char_u *str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
{
garray_T ga;
int i;
@@ -440,8 +443,7 @@ int buflen;
*/
static char_u transchar_buf[7];
-char_u * transchar(c)
-int c;
+char_u *transchar(int c)
{
int i;
@@ -469,8 +471,7 @@ int c;
* Like transchar(), but called with a byte instead of a character. Checks
* for an illegal UTF-8 byte.
*/
-char_u * transchar_byte(c)
-int c;
+char_u *transchar_byte(int c)
{
if (enc_utf8 && c >= 0x80) {
transchar_nonprint(transchar_buf, c);
@@ -484,9 +485,7 @@ int c;
* "buf[]". "buf" needs to be able to hold five bytes.
* Does NOT work for multi-byte characters, c must be <= 255.
*/
-void transchar_nonprint(buf, c)
-char_u *buf;
-int c;
+void transchar_nonprint(char_u *buf, int c)
{
if (c == NL)
c = NUL; /* we use newline in place of a NUL */
@@ -518,9 +517,7 @@ int c;
}
}
-void transchar_hex(buf, c)
-char_u *buf;
-int c;
+void transchar_hex(char_u *buf, int c)
{
int i = 0;
@@ -540,8 +537,7 @@ int c;
* Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
* function key 1.
*/
-static unsigned nr2hex(c)
-unsigned c;
+static unsigned nr2hex(unsigned c)
{
if ((c & 0xf) <= 9)
return (c & 0xf) + '0';
@@ -556,8 +552,7 @@ unsigned c;
* For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
* cells depends on further bytes.
*/
-int byte2cells(b)
-int b;
+int byte2cells(int b)
{
if (enc_utf8 && b >= 0x80)
return 0;
@@ -569,8 +564,7 @@ int b;
* "c" can be a special key (negative number) in which case 3 or 4 is returned.
* A TAB is counted as two cells: "^I" or four: "<09>".
*/
-int char2cells(c)
-int c;
+int char2cells(int c)
{
if (IS_SPECIAL(c))
return char2cells(K_SECOND(c)) + 2;
@@ -593,8 +587,7 @@ int c;
* Return number of display cells occupied by character at "*p".
* A TAB is counted as two cells: "^I" or four: "<09>".
*/
-int ptr2cells(p)
-char_u *p;
+int ptr2cells(char_u *p)
{
/* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */
if (enc_utf8 && *p >= 0x80)
@@ -607,8 +600,7 @@ char_u *p;
* Return the number of character cells string "s" will take on the screen,
* counting TABs as two characters: "^I".
*/
-int vim_strsize(s)
-char_u *s;
+int vim_strsize(char_u *s)
{
return vim_strnsize(s, (int)MAXCOL);
}
@@ -617,9 +609,7 @@ char_u *s;
* Return the number of character cells string "s[len]" will take on the
* screen, counting TABs as two characters: "^I".
*/
-int vim_strnsize(s, len)
-char_u *s;
-int len;
+int vim_strnsize(char_u *s, int len)
{
int size = 0;
@@ -655,18 +645,13 @@ int len;
#if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \
|| defined(FEAT_VIRTUALEDIT) || defined(PROTO)
-int chartabsize(p, col)
-char_u *p;
-colnr_T col;
+int chartabsize(char_u *p, colnr_T col)
{
RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col)
}
#endif
-static int win_chartabsize(wp, p, col)
-win_T *wp;
-char_u *p;
-colnr_T col;
+static int win_chartabsize(win_T *wp, char_u *p, colnr_T col)
{
RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col)
}
@@ -675,8 +660,7 @@ colnr_T col;
* Return the number of characters the string 's' will take on the screen,
* taking into account the size of a tab.
*/
-int linetabsize(s)
-char_u *s;
+int linetabsize(char_u *s)
{
return linetabsize_col(0, s);
}
@@ -684,9 +668,7 @@ char_u *s;
/*
* Like linetabsize(), but starting at column "startcol".
*/
-int linetabsize_col(startcol, s)
-int startcol;
-char_u *s;
+int linetabsize_col(int startcol, char_u *s)
{
colnr_T col = startcol;
@@ -698,10 +680,7 @@ char_u *s;
/*
* Like linetabsize(), but for a given window instead of the current one.
*/
-int win_linetabsize(wp, p, len)
-win_T *wp;
-char_u *p;
-colnr_T len;
+int win_linetabsize(win_T *wp, char_u *p, colnr_T len)
{
colnr_T col = 0;
char_u *s;
@@ -715,8 +694,7 @@ colnr_T len;
* Return TRUE if 'c' is a normal identifier character:
* Letters and characters from the 'isident' option.
*/
-int vim_isIDc(c)
-int c;
+int vim_isIDc(int c)
{
return c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR);
}
@@ -726,15 +704,12 @@ int c;
* 'iskeyword' option for current buffer.
* For multi-byte characters mb_get_class() is used (builtin rules).
*/
-int vim_iswordc(c)
-int c;
+int vim_iswordc(int c)
{
return vim_iswordc_buf(c, curbuf);
}
-int vim_iswordc_buf(c, buf)
-int c;
-buf_T *buf;
+int vim_iswordc_buf(int c, buf_T *buf)
{
if (c >= 0x100) {
if (enc_dbcs != 0)
@@ -748,17 +723,14 @@ buf_T *buf;
/*
* Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
*/
-int vim_iswordp(p)
-char_u *p;
+int vim_iswordp(char_u *p)
{
if (has_mbyte && MB_BYTE2LEN(*p) > 1)
return mb_get_class(p) >= 2;
return GET_CHARTAB(curbuf, *p) != 0;
}
-int vim_iswordp_buf(p, buf)
-char_u *p;
-buf_T *buf;
+int vim_iswordp_buf(char_u *p, buf_T *buf)
{
if (has_mbyte && MB_BYTE2LEN(*p) > 1)
return mb_get_class(p) >= 2;
@@ -769,8 +741,7 @@ buf_T *buf;
* return TRUE if 'c' is a valid file-name character
* Assume characters above 0x100 are valid (multi-byte).
*/
-int vim_isfilec(c)
-int c;
+int vim_isfilec(int c)
{
return c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR));
}
@@ -781,8 +752,7 @@ int c;
* Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
* returns false.
*/
-int vim_isfilec_or_wc(c)
-int c;
+int vim_isfilec_or_wc(int c)
{
char_u buf[2];
@@ -796,8 +766,7 @@ int c;
* Assume characters above 0x100 are printable (multi-byte), except for
* Unicode.
*/
-int vim_isprintc(c)
-int c;
+int vim_isprintc(int c)
{
if (enc_utf8 && c >= 0x100)
return utf_printable(c);
@@ -808,8 +777,7 @@ int c;
* Strict version of vim_isprintc(c), don't return TRUE if "c" is the head
* byte of a double-byte character.
*/
-int vim_isprintc_strict(c)
-int c;
+int vim_isprintc_strict(int c)
{
if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1)
return FALSE;
@@ -821,9 +789,7 @@ int c;
/*
* like chartabsize(), but also check for line breaks on the screen
*/
-int lbr_chartabsize(s, col)
-unsigned char *s;
-colnr_T col;
+int lbr_chartabsize(unsigned char *s, colnr_T col)
{
if (!curwin->w_p_lbr && *p_sbr == NUL) {
if (curwin->w_p_wrap)
@@ -836,9 +802,7 @@ colnr_T col;
/*
* Call lbr_chartabsize() and advance the pointer.
*/
-int lbr_chartabsize_adv(s, col)
-char_u **s;
-colnr_T col;
+int lbr_chartabsize_adv(char_u **s, colnr_T col)
{
int retval;
@@ -854,11 +818,7 @@ colnr_T col;
* string at start of line. Warning: *headp is only set if it's a non-zero
* value, init to 0 before calling.
*/
-int win_lbr_chartabsize(wp, s, col, headp)
-win_T *wp;
-char_u *s;
-colnr_T col;
-int *headp UNUSED;
+int win_lbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
{
int c;
int size;
@@ -967,11 +927,7 @@ int *headp UNUSED;
* 'wrap' is on. This means we need to check for a double-byte character that
* doesn't fit at the end of the screen line.
*/
-static int win_nolbr_chartabsize(wp, s, col, headp)
-win_T *wp;
-char_u *s;
-colnr_T col;
-int *headp;
+static int win_nolbr_chartabsize(win_T *wp, char_u *s, colnr_T col, int *headp)
{
int n;
@@ -994,9 +950,7 @@ int *headp;
* Return TRUE if virtual column "vcol" is in the rightmost column of window
* "wp".
*/
-int in_win_border(wp, vcol)
-win_T *wp;
-colnr_T vcol;
+int in_win_border(win_T *wp, colnr_T vcol)
{
int width1; /* width of first line (after line number) */
int width2; /* width of further lines */
@@ -1022,12 +976,7 @@ colnr_T vcol;
*
* This is used very often, keep it fast!
*/
-void getvcol(wp, pos, start, cursor, end)
-win_T *wp;
-pos_T *pos;
-colnr_T *start;
-colnr_T *cursor;
-colnr_T *end;
+void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
{
colnr_T vcol;
char_u *ptr; /* points to current char */
@@ -1129,8 +1078,7 @@ colnr_T *end;
/*
* Get virtual cursor column in the current window, pretending 'list' is off.
*/
-colnr_T getvcol_nolist(posp)
-pos_T *posp;
+colnr_T getvcol_nolist(pos_T *posp)
{
int list_save = curwin->w_p_list;
colnr_T vcol;
@@ -1144,12 +1092,7 @@ pos_T *posp;
/*
* Get virtual column in virtual mode.
*/
-void getvvcol(wp, pos, start, cursor, end)
-win_T *wp;
-pos_T *pos;
-colnr_T *start;
-colnr_T *cursor;
-colnr_T *end;
+void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *end)
{
colnr_T col;
colnr_T coladd;
@@ -1190,10 +1133,7 @@ colnr_T *end;
* Get the leftmost and rightmost virtual column of pos1 and pos2.
* Used for Visual block mode.
*/
-void getvcols(wp, pos1, pos2, left, right)
-win_T *wp;
-pos_T *pos1, *pos2;
-colnr_T *left, *right;
+void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, colnr_T *right)
{
colnr_T from1, from2, to1, to2;
@@ -1220,8 +1160,7 @@ colnr_T *left, *right;
/*
* skipwhite: skip over ' ' and '\t'.
*/
-char_u * skipwhite(q)
-char_u *q;
+char_u *skipwhite(char_u *q)
{
char_u *p = q;
@@ -1233,8 +1172,7 @@ char_u *q;
/*
* skip over digits
*/
-char_u * skipdigits(q)
-char_u *q;
+char_u *skipdigits(char_u *q)
{
char_u *p = q;
@@ -1246,8 +1184,7 @@ char_u *q;
/*
* skip over digits and hex characters
*/
-char_u * skiphex(q)
-char_u *q;
+char_u *skiphex(char_u *q)
{
char_u *p = q;
@@ -1259,8 +1196,7 @@ char_u *q;
/*
* skip to digit (or NUL after the string)
*/
-char_u * skiptodigit(q)
-char_u *q;
+char_u *skiptodigit(char_u *q)
{
char_u *p = q;
@@ -1272,8 +1208,7 @@ char_u *q;
/*
* skip to hex character (or NUL after the string)
*/
-char_u * skiptohex(q)
-char_u *q;
+char_u *skiptohex(char_u *q)
{
char_u *p = q;
@@ -1288,8 +1223,7 @@ char_u *q;
* superscript 1 to be a digit.
* Use the VIM_ISDIGIT() macro for simple arguments.
*/
-int vim_isdigit(c)
-int c;
+int vim_isdigit(int c)
{
return c >= '0' && c <= '9';
}
@@ -1299,8 +1233,7 @@ int c;
* We don't use isxdigit() here, because on some systems it also considers
* superscript 1 to be a digit.
*/
-int vim_isxdigit(c)
-int c;
+int vim_isxdigit(int c)
{
return (c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'f')
@@ -1323,8 +1256,7 @@ static char_u latin1upper[257] =
static char_u latin1lower[257] =
" !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
-int vim_islower(c)
-int c;
+int vim_islower(int c)
{
if (c <= '@')
return FALSE;
@@ -1345,8 +1277,7 @@ int c;
return islower(c);
}
-int vim_isupper(c)
-int c;
+int vim_isupper(int c)
{
if (c <= '@')
return FALSE;
@@ -1367,8 +1298,7 @@ int c;
return isupper(c);
}
-int vim_toupper(c)
-int c;
+int vim_toupper(int c)
{
if (c <= '@')
return c;
@@ -1389,8 +1319,7 @@ int c;
return TOUPPER_LOC(c);
}
-int vim_tolower(c)
-int c;
+int vim_tolower(int c)
{
if (c <= '@')
return c;
@@ -1414,8 +1343,7 @@ int c;
/*
* skiptowhite: skip over text until ' ' or '\t' or NUL.
*/
-char_u * skiptowhite(p)
-char_u *p;
+char_u *skiptowhite(char_u *p)
{
while (*p != ' ' && *p != '\t' && *p != NUL)
++p;
@@ -1427,8 +1355,7 @@ char_u *p;
/*
* skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
*/
-char_u * skiptowhite_esc(p)
-char_u *p;
+char_u *skiptowhite_esc(char_u *p)
{
while (*p != ' ' && *p != '\t' && *p != NUL) {
if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL)
@@ -1443,8 +1370,7 @@ char_u *p;
* Getdigits: Get a number from a string and skip over it.
* Note: the argument is a pointer to a char_u pointer!
*/
-long getdigits(pp)
-char_u **pp;
+long getdigits(char_u **pp)
{
char_u *p;
long retval;
@@ -1461,8 +1387,7 @@ char_u **pp;
/*
* Return TRUE if "lbuf" is empty or only contains blanks.
*/
-int vim_isblankline(lbuf)
-char_u *lbuf;
+int vim_isblankline(char_u *lbuf)
{
char_u *p;
@@ -1486,15 +1411,17 @@ char_u *lbuf;
* If "dohex" is non-zero recognize hex numbers, when > 1 always assume
* hex number.
*/
-void vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr)
-char_u *start;
-int *hexp; /* return: type of number 0 = decimal, 'x'
+void
+vim_str2nr (
+ char_u *start,
+ int *hexp, /* return: type of number 0 = decimal, 'x'
or 'X' is hex, '0' = octal */
-int *len; /* return: detected length of number */
-int dooct; /* recognize octal number */
-int dohex; /* recognize hex number */
-long *nptr; /* return: signed result */
-unsigned long *unptr; /* return: unsigned result */
+ int *len, /* return: detected length of number */
+ int dooct, /* recognize octal number */
+ int dohex, /* recognize hex number */
+ long *nptr, /* return: signed result */
+ unsigned long *unptr /* return: unsigned result */
+)
{
char_u *ptr = start;
int hex = 0; /* default is decimal */
@@ -1569,8 +1496,7 @@ unsigned long *unptr; /* return: unsigned result */
* Return the value of a single hex character.
* Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'.
*/
-int hex2nr(c)
-int c;
+int hex2nr(int c)
{
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
@@ -1585,8 +1511,7 @@ int c;
* Convert two hex characters to a byte.
* Return -1 if one of the characters is not hex.
*/
-int hexhex2nr(p)
-char_u *p;
+int hexhex2nr(char_u *p)
{
if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1]))
return -1;
@@ -1607,8 +1532,7 @@ char_u *p;
* character, assume that all multi-byte characters are valid file name
* characters.
*/
-int rem_backslash(str)
-char_u *str;
+int rem_backslash(char_u *str)
{
#ifdef BACKSLASH_IN_FILENAME
return str[0] == '\\'
@@ -1628,8 +1552,7 @@ char_u *str;
* For MS-DOS we only do this if the character after the backslash
* is not a normal file character.
*/
-void backslash_halve(p)
-char_u *p;
+void backslash_halve(char_u *p)
{
for (; *p; ++p)
if (rem_backslash(p))
@@ -1639,8 +1562,7 @@ char_u *p;
/*
* backslash_halve() plus save the result in allocated memory.
*/
-char_u * backslash_halve_save(p)
-char_u *p;
+char_u *backslash_halve_save(char_u *p)
{
char_u *res;
diff --git a/src/proto/charset.pro b/src/charset.h
index d0223f1e9c..d680522880 100644
--- a/src/proto/charset.pro
+++ b/src/charset.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_CHARSET_H
+#define NEOVIM_CHARSET_H
/* charset.c */
int init_chartab __ARGS((void));
int buf_init_chartab __ARGS((buf_T *buf, int global));
@@ -62,3 +64,4 @@ void backslash_halve __ARGS((char_u *p));
char_u *backslash_halve_save __ARGS((char_u *p));
void ebcdic2ascii __ARGS((char_u *buffer, int len));
/* vim: set ft=c : */
+#endif /* NEOVIM_CHARSET_H */
diff --git a/src/diff.c b/src/diff.c
index ad31128575..626271a7b5 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -12,7 +12,27 @@
*/
#include "vim.h"
-
+#include "diff.h"
+#include "buffer.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_docmd.h"
+#include "fileio.h"
+#include "fold.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "screen.h"
+#include "undo.h"
+#include "window.h"
+#include "os/os.h"
static int diff_busy = FALSE; /* ex_diffgetput() is busy */
@@ -55,8 +75,7 @@ static diff_T *diff_alloc_new __ARGS((tabpage_T *tp, diff_T *dprev, diff_T *dp))
/*
* Called when deleting or unloading a buffer: No longer make a diff with it.
*/
-void diff_buf_delete(buf)
-buf_T *buf;
+void diff_buf_delete(buf_T *buf)
{
int i;
tabpage_T *tp;
@@ -76,8 +95,7 @@ buf_T *buf;
* Check if the current buffer should be added to or removed from the list of
* diff buffers.
*/
-void diff_buf_adjust(win)
-win_T *win;
+void diff_buf_adjust(win_T *win)
{
win_T *wp;
int i;
@@ -108,8 +126,7 @@ win_T *win;
* This must be done before any autocmd, because a command may use info
* about the screen contents.
*/
-void diff_buf_add(buf)
-buf_T *buf;
+void diff_buf_add(buf_T *buf)
{
int i;
@@ -131,8 +148,7 @@ buf_T *buf;
* Find buffer "buf" in the list of diff buffers for the current tab page.
* Return its index or DB_COUNT if not found.
*/
-static int diff_buf_idx(buf)
-buf_T *buf;
+static int diff_buf_idx(buf_T *buf)
{
int idx;
@@ -146,9 +162,7 @@ buf_T *buf;
* Find buffer "buf" in the list of diff buffers for tab page "tp".
* Return its index or DB_COUNT if not found.
*/
-static int diff_buf_idx_tp(buf, tp)
-buf_T *buf;
-tabpage_T *tp;
+static int diff_buf_idx_tp(buf_T *buf, tabpage_T *tp)
{
int idx;
@@ -162,8 +176,7 @@ tabpage_T *tp;
* Mark the diff info involving buffer "buf" as invalid, it will be updated
* when info is requested.
*/
-void diff_invalidate(buf)
-buf_T *buf;
+void diff_invalidate(buf_T *buf)
{
tabpage_T *tp;
int i;
@@ -181,11 +194,7 @@ buf_T *buf;
/*
* Called by mark_adjust(): update line numbers in "curbuf".
*/
-void diff_mark_adjust(line1, line2, amount, amount_after)
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
int idx;
tabpage_T *tp;
@@ -205,13 +214,7 @@ long amount_after;
* new change block and update the line numbers in following blocks.
* When inserting/deleting lines in existing change blocks, update them.
*/
-static void diff_mark_adjust_tp(tp, idx, line1, line2, amount, amount_after)
-tabpage_T *tp;
-int idx;
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
diff_T *dp;
diff_T *dprev;
@@ -417,10 +420,7 @@ long amount_after;
/*
* Allocate a new diff block and link it between "dprev" and "dp".
*/
-static diff_T * diff_alloc_new(tp, dprev, dp)
-tabpage_T *tp;
-diff_T *dprev;
-diff_T *dp;
+static diff_T *diff_alloc_new(tabpage_T *tp, diff_T *dprev, diff_T *dp)
{
diff_T *dnew;
@@ -441,9 +441,7 @@ diff_T *dp;
* This may result in a change where all buffers have zero lines, the caller
* must take care of removing it.
*/
-static void diff_check_unchanged(tp, dp)
-tabpage_T *tp;
-diff_T *dp;
+static void diff_check_unchanged(tabpage_T *tp, diff_T *dp)
{
int i_org;
int i_new;
@@ -512,9 +510,7 @@ diff_T *dp;
* Check if a diff block doesn't contain invalid line numbers.
* This can happen when the diff program returns invalid results.
*/
-static int diff_check_sanity(tp, dp)
-tabpage_T *tp;
-diff_T *dp;
+static int diff_check_sanity(tabpage_T *tp, diff_T *dp)
{
int i;
@@ -529,8 +525,10 @@ diff_T *dp;
/*
* Mark all diff buffers in the current tab page for redraw.
*/
-static void diff_redraw(dofold)
-int dofold; /* also recompute the folds */
+static void
+diff_redraw (
+ int dofold /* also recompute the folds */
+)
{
win_T *wp;
int n;
@@ -557,9 +555,7 @@ int dofold; /* also recompute the folds */
* Always use 'fileformat' set to "unix".
* Return FAIL for failure
*/
-static int diff_write(buf, fname)
-buf_T *buf;
-char_u *fname;
+static int diff_write(buf_T *buf, char_u *fname)
{
int r;
char_u *save_ff;
@@ -579,8 +575,10 @@ char_u *fname;
* The buffers are written to a file, also for unmodified buffers (the file
* could have been produced by autocommands, e.g. the netrw plugin).
*/
-void ex_diffupdate(eap)
-exarg_T *eap UNUSED; /* can be NULL */
+void
+ex_diffupdate (
+ exarg_T *eap /* can be NULL */
+)
{
buf_T *buf;
int idx_orig;
@@ -726,10 +724,7 @@ theend:
/*
* Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
*/
-static void diff_file(tmp_orig, tmp_new, tmp_diff)
-char_u *tmp_orig;
-char_u *tmp_new;
-char_u *tmp_diff;
+static void diff_file(char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff)
{
char_u *cmd;
size_t len;
@@ -769,8 +764,7 @@ char_u *tmp_diff;
* The buffer is written to a file, also for unmodified buffers (the file
* could have been produced by autocommands, e.g. the netrw plugin).
*/
-void ex_diffpatch(eap)
-exarg_T *eap;
+void ex_diffpatch(exarg_T *eap)
{
char_u *tmp_orig; /* name of original temp file */
char_u *tmp_new; /* name of patched temp file */
@@ -925,8 +919,7 @@ theend:
/*
* Split the window and edit another file, setting options to show the diffs.
*/
-void ex_diffsplit(eap)
-exarg_T *eap;
+void ex_diffsplit(exarg_T *eap)
{
win_T *old_curwin = curwin;
@@ -950,8 +943,7 @@ exarg_T *eap;
/*
* Set options to show diffs for the current window.
*/
-void ex_diffthis(eap)
-exarg_T *eap UNUSED;
+void ex_diffthis(exarg_T *eap)
{
/* Set 'diff', 'scrollbind' on and 'wrap' off. */
diff_win_options(curwin, TRUE);
@@ -960,9 +952,11 @@ exarg_T *eap UNUSED;
/*
* Set options in window "wp" for diff mode.
*/
-void diff_win_options(wp, addbuf)
-win_T *wp;
-int addbuf; /* Add buffer to diff. */
+void
+diff_win_options (
+ win_T *wp,
+ int addbuf /* Add buffer to diff. */
+)
{
win_T *old_curwin = curwin;
@@ -1016,8 +1010,7 @@ int addbuf; /* Add buffer to diff. */
* Set options not to show diffs. For the current window or all windows.
* Only in the current tab page.
*/
-void ex_diffoff(eap)
-exarg_T *eap;
+void ex_diffoff(exarg_T *eap)
{
win_T *wp;
win_T *old_curwin = curwin;
@@ -1079,10 +1072,12 @@ exarg_T *eap;
/*
* Read the diff output and add each entry to the diff list.
*/
-static void diff_read(idx_orig, idx_new, fname)
-int idx_orig; /* idx of original file */
-int idx_new; /* idx of new file */
-char_u *fname; /* name of diff output file */
+static void
+diff_read (
+ int idx_orig, /* idx of original file */
+ int idx_new, /* idx of new file */
+ char_u *fname /* name of diff output file */
+)
{
FILE *fd;
diff_T *dprev = NULL;
@@ -1251,11 +1246,7 @@ done:
/*
* Copy an entry at "dp" from "idx_orig" to "idx_new".
*/
-static void diff_copy_entry(dprev, dp, idx_orig, idx_new)
-diff_T *dprev;
-diff_T *dp;
-int idx_orig;
-int idx_new;
+static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig, int idx_new)
{
long off;
@@ -1271,8 +1262,7 @@ int idx_new;
/*
* Clear the list of diffblocks for tab page "tp".
*/
-void diff_clear(tp)
-tabpage_T *tp;
+void diff_clear(tabpage_T *tp)
{
diff_T *p, *next_p;
@@ -1292,9 +1282,7 @@ tabpage_T *tp;
* when 'diffopt' doesn't contain "filler").
* This should only be used for windows where 'diff' is set.
*/
-int diff_check(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+int diff_check(win_T *wp, linenr_T lnum)
{
int idx; /* index in tp_diffbuf[] for this buffer */
diff_T *dp;
@@ -1379,10 +1367,7 @@ linenr_T lnum;
/*
* Compare two entries in diff "*dp" and return TRUE if they are equal.
*/
-static int diff_equal_entry(dp, idx1, idx2)
-diff_T *dp;
-int idx1;
-int idx2;
+static int diff_equal_entry(diff_T *dp, int idx1, int idx2)
{
int i;
char_u *line;
@@ -1410,9 +1395,7 @@ int idx2;
* Compare strings "s1" and "s2" according to 'diffopt'.
* Return non-zero when they are different.
*/
-static int diff_cmp(s1, s2)
-char_u *s1;
-char_u *s2;
+static int diff_cmp(char_u *s1, char_u *s2)
{
char_u *p1, *p2;
int l;
@@ -1463,9 +1446,7 @@ char_u *s2;
/*
* Return the number of filler lines above "lnum".
*/
-int diff_check_fill(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+int diff_check_fill(win_T *wp, linenr_T lnum)
{
int n;
@@ -1482,9 +1463,7 @@ linenr_T lnum;
* Set the topline of "towin" to match the position in "fromwin", so that they
* show the same diff'ed lines.
*/
-void diff_set_topline(fromwin, towin)
-win_T *fromwin;
-win_T *towin;
+void diff_set_topline(win_T *fromwin, win_T *towin)
{
buf_T *frombuf = fromwin->w_buffer;
linenr_T lnum = fromwin->w_topline;
@@ -1586,7 +1565,7 @@ win_T *towin;
/*
* This is called when 'diffopt' is changed.
*/
-int diffopt_changed() {
+int diffopt_changed(void) {
char_u *p;
int diff_context_new = 6;
int diff_flags_new = 0;
@@ -1648,7 +1627,7 @@ int diffopt_changed() {
/*
* Return TRUE if 'diffopt' contains "horizontal".
*/
-int diffopt_horizontal() {
+int diffopt_horizontal(void) {
return (diff_flags & DIFF_HORIZONTAL) != 0;
}
@@ -1656,11 +1635,13 @@ int diffopt_horizontal() {
* Find the difference within a changed line.
* Returns TRUE if the line was added, no other buffer has it.
*/
-int diff_find_change(wp, lnum, startp, endp)
-win_T *wp;
-linenr_T lnum;
-int *startp; /* first char of the change */
-int *endp; /* last char of the change */
+int
+diff_find_change (
+ win_T *wp,
+ linenr_T lnum,
+ int *startp, /* first char of the change */
+ int *endp /* last char of the change */
+)
{
char_u *line_org;
char_u *line_new;
@@ -1763,9 +1744,7 @@ int *endp; /* last char of the change */
* be in a fold.
* Return FALSE if there are no diff blocks at all in this window.
*/
-int diff_infold(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+int diff_infold(win_T *wp, linenr_T lnum)
{
int i;
int idx = -1;
@@ -1808,8 +1787,7 @@ linenr_T lnum;
/*
* "dp" and "do" commands.
*/
-void nv_diffgetput(put)
-int put;
+void nv_diffgetput(int put)
{
exarg_T ea;
@@ -1828,8 +1806,7 @@ int put;
* ":diffget"
* ":diffput"
*/
-void ex_diffgetput(eap)
-exarg_T *eap;
+void ex_diffgetput(exarg_T *eap)
{
linenr_T lnum;
int count;
@@ -2107,9 +2084,7 @@ exarg_T *eap;
* Skip buffer with index "skip_idx".
* When there are no diffs, all folds are removed.
*/
-static void diff_fold_update(dp, skip_idx)
-diff_T *dp;
-int skip_idx;
+static void diff_fold_update(diff_T *dp, int skip_idx)
{
int i;
win_T *wp;
@@ -2124,8 +2099,7 @@ int skip_idx;
/*
* Return TRUE if buffer "buf" is in diff-mode.
*/
-int diff_mode_buf(buf)
-buf_T *buf;
+int diff_mode_buf(buf_T *buf)
{
tabpage_T *tp;
@@ -2139,9 +2113,7 @@ buf_T *buf;
* Move "count" times in direction "dir" to the next diff block.
* Return FAIL if there isn't such a diff block.
*/
-int diff_move_to(dir, count)
-int dir;
-long count;
+int diff_move_to(int dir, long count)
{
int idx;
linenr_T lnum = curwin->w_cursor.lnum;
@@ -2190,11 +2162,7 @@ long count;
return OK;
}
-linenr_T diff_get_corresponding_line(buf1, lnum1, buf2, lnum3)
-buf_T *buf1;
-linenr_T lnum1;
-buf_T *buf2;
-linenr_T lnum3;
+linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2, linenr_T lnum3)
{
int idx1;
int idx2;
@@ -2257,9 +2225,7 @@ linenr_T lnum3;
* For line "lnum" in the current window find the equivalent lnum in window
* "wp", compensating for inserted/deleted lines.
*/
-linenr_T diff_lnum_win(lnum, wp)
-linenr_T lnum;
-win_T *wp;
+linenr_T diff_lnum_win(linenr_T lnum, win_T *wp)
{
diff_T *dp;
int idx;
diff --git a/src/proto/diff.pro b/src/diff.h
index 0093629033..5a2d32204e 100644
--- a/src/proto/diff.pro
+++ b/src/diff.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_DIFF_H
+#define NEOVIM_DIFF_H
/* diff.c */
void diff_buf_delete __ARGS((buf_T *buf));
void diff_buf_adjust __ARGS((win_T *win));
@@ -28,3 +30,4 @@ linenr_T diff_get_corresponding_line __ARGS((buf_T *buf1, linenr_T lnum1,
linenr_T lnum3));
linenr_T diff_lnum_win __ARGS((linenr_T lnum, win_T *wp));
/* vim: set ft=c : */
+#endif /* NEOVIM_DIFF_H */
diff --git a/src/digraph.c b/src/digraph.c
index 4584973526..9a58058fde 100644
--- a/src/digraph.c
+++ b/src/digraph.c
@@ -12,7 +12,18 @@
*/
#include "vim.h"
-
+#include "digraph.h"
+#include "charset.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "getchar.h"
+#include "mbyte.h"
+#include "message.h"
+#include "misc2.h"
+#include "normal.h"
+#include "screen.h"
+#include "ui.h"
typedef int result_T;
@@ -1623,8 +1634,7 @@ static digr_T digraphdefault[] =
/*
* handle digraphs after typing a character
*/
-int do_digraph(c)
-int c;
+int do_digraph(int c)
{
static int backspaced; /* character before K_BS */
static int lastchar; /* last typed character */
@@ -1647,8 +1657,10 @@ int c;
* mode.
* Returns composed character, or NUL when ESC was used.
*/
-int get_digraph(cmdline)
-int cmdline; /* TRUE when called from the cmdline */
+int
+get_digraph (
+ int cmdline /* TRUE when called from the cmdline */
+)
{
int c, cc;
@@ -1683,10 +1695,7 @@ int cmdline; /* TRUE when called from the cmdline */
* If no match, return "char2".
* If "meta_char" is TRUE and "char1" is a space, return "char2" | 0x80.
*/
-static int getexactdigraph(char1, char2, meta_char)
-int char1;
-int char2;
-int meta_char;
+static int getexactdigraph(int char1, int char2, int meta_char)
{
int i;
int retval = 0;
@@ -1759,10 +1768,7 @@ int meta_char;
* Get digraph.
* Allow for both char1-char2 and char2-char1
*/
-int getdigraph(char1, char2, meta_char)
-int char1;
-int char2;
-int meta_char;
+int getdigraph(int char1, int char2, int meta_char)
{
int retval;
@@ -1777,8 +1783,7 @@ int meta_char;
* Add the digraphs in the argument to the digraph table.
* format: {c1}{c2} char {c1}{c2} char ...
*/
-void putdigraph(str)
-char_u *str;
+void putdigraph(char_u *str)
{
int char1, char2, n;
int i;
@@ -1828,7 +1833,7 @@ char_u *str;
}
}
-void listdigraphs() {
+void listdigraphs(void) {
int i;
digr_T *dp;
@@ -1867,8 +1872,7 @@ void listdigraphs() {
wrong, in which case we messed up ScreenLines */
}
-static void printdigraph(dp)
-digr_T *dp;
+static void printdigraph(digr_T *dp)
{
char_u buf[30];
char_u *p;
@@ -1925,7 +1929,7 @@ static void keymap_unload __ARGS((void));
* used when setting the option, not later when the value has already been
* checked.
*/
-char_u * keymap_init() {
+char_u *keymap_init(void) {
curbuf->b_kmap_state &= ~KEYMAP_INIT;
if (*curbuf->b_p_keymap == NUL) {
@@ -1967,8 +1971,7 @@ char_u * keymap_init() {
/*
* ":loadkeymap" command: load the following lines as the keymap.
*/
-void ex_loadkeymap(eap)
-exarg_T *eap;
+void ex_loadkeymap(exarg_T *eap)
{
char_u *line;
char_u *p;
@@ -2044,7 +2047,7 @@ exarg_T *eap;
/*
* Stop using 'keymap'.
*/
-static void keymap_unload() {
+static void keymap_unload(void) {
char_u buf[KMAP_MAXLEN + 10];
int i;
char_u *save_cpo = p_cpo;
diff --git a/src/proto/digraph.pro b/src/digraph.h
index 5573b8c36d..c74e428979 100644
--- a/src/proto/digraph.pro
+++ b/src/digraph.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_DIGRAPH_H
+#define NEOVIM_DIGRAPH_H
/* digraph.c */
int do_digraph __ARGS((int c));
int get_digraph __ARGS((int cmdline));
@@ -7,3 +9,4 @@ void listdigraphs __ARGS((void));
char_u *keymap_init __ARGS((void));
void ex_loadkeymap __ARGS((exarg_T *eap));
/* vim: set ft=c : */
+#endif /* NEOVIM_DIGRAPH_H */
diff --git a/src/edit.c b/src/edit.c
index 4d245fbfaf..6ac6565d40 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -12,6 +12,38 @@
*/
#include "vim.h"
+#include "edit.h"
+#include "buffer.h"
+#include "charset.h"
+#include "digraph.h"
+#include "eval.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "popupmnu.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "spell.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
/*
* definitions used for CTRL-X submode
@@ -284,10 +316,12 @@ static int did_add_space = FALSE; /* auto_format() added an extra space
*
* Return TRUE if a CTRL-O command caused the return (insert mode pending).
*/
-int edit(cmdchar, startln, count)
-int cmdchar;
-int startln; /* if set, insert at start of line */
-long count;
+int
+edit (
+ int cmdchar,
+ int startln, /* if set, insert at start of line */
+ long count
+)
{
int c = 0;
char_u *ptr;
@@ -1264,8 +1298,10 @@ force_cindent:
* Only redraw when there are no characters available. This speeds up
* inserting sequences of characters (e.g., for CTRL-R).
*/
-static void ins_redraw(ready)
-int ready UNUSED; /* not busy with something */
+static void
+ins_redraw (
+ int ready /* not busy with something */
+)
{
linenr_T conceal_old_cursor_line = 0;
linenr_T conceal_new_cursor_line = 0;
@@ -1333,7 +1369,7 @@ int ready UNUSED; /* not busy with something */
/*
* Handle a CTRL-V or CTRL-Q typed in Insert mode.
*/
-static void ins_ctrl_v() {
+static void ins_ctrl_v(void) {
int c;
int did_putchar = FALSE;
@@ -1373,9 +1409,7 @@ static int pc_attr;
static int pc_row;
static int pc_col;
-void edit_putchar(c, highlight)
-int c;
-int highlight;
+void edit_putchar(int c, int highlight)
{
int attr;
@@ -1418,7 +1452,7 @@ int highlight;
/*
* Undo the previous edit_putchar().
*/
-void edit_unputchar() {
+void edit_unputchar(void) {
if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) {
if (pc_status == PC_STATUS_RIGHT)
++curwin->w_wcol;
@@ -1433,8 +1467,7 @@ void edit_unputchar() {
* Called when p_dollar is set: display a '$' at the end of the changed text
* Only works when cursor is in the line that changes.
*/
-void display_dollar(col)
-colnr_T col;
+void display_dollar(colnr_T col)
{
colnr_T save_col;
@@ -1463,7 +1496,7 @@ colnr_T col;
* Call this function before moving the cursor from the normal insert position
* in insert mode.
*/
-static void undisplay_dollar() {
+static void undisplay_dollar(void) {
if (dollar_vcol >= 0) {
dollar_vcol = -1;
redrawWinline(curwin->w_cursor.lnum, FALSE);
@@ -1478,12 +1511,14 @@ static void undisplay_dollar() {
* type == INDENT_SET set indent to "amount"
* if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec).
*/
-void change_indent(type, amount, round, replaced, call_changed_bytes)
-int type;
-int amount;
-int round;
-int replaced; /* replaced character, put on replace stack */
-int call_changed_bytes; /* call changed_bytes() */
+void
+change_indent (
+ int type,
+ int amount,
+ int round,
+ int replaced, /* replaced character, put on replace stack */
+ int call_changed_bytes /* call changed_bytes() */
+)
{
int vcol;
int last_vcol;
@@ -1701,8 +1736,7 @@ int call_changed_bytes; /* call changed_bytes() */
* insert mode. It handles fixing the replace stack for REPLACE and VREPLACE
* modes.
*/
-void truncate_spaces(line)
-char_u *line;
+void truncate_spaces(char_u *line)
{
int i;
@@ -1722,8 +1756,7 @@ char_u *line;
* Will attempt not to go before "col" even when there is a composing
* character.
*/
-void backspace_until_column(col)
-int col;
+void backspace_until_column(int col)
{
while ((int)curwin->w_cursor.col > col) {
curwin->w_cursor.col--;
@@ -1740,8 +1773,7 @@ int col;
* Only matters when there are composing characters.
* Return TRUE when something was deleted.
*/
-static int del_char_after_col(limit_col)
-int limit_col UNUSED;
+static int del_char_after_col(int limit_col)
{
if (enc_utf8 && limit_col >= 0) {
colnr_T ecol = curwin->w_cursor.col + 1;
@@ -1768,7 +1800,7 @@ int limit_col UNUSED;
/*
* CTRL-X pressed in Insert mode.
*/
-static void ins_ctrl_x() {
+static void ins_ctrl_x(void) {
/* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X
* CTRL-V works like CTRL-N */
if (ctrl_x_mode != CTRL_X_CMDLINE) {
@@ -1789,8 +1821,7 @@ static void ins_ctrl_x() {
/*
* Return TRUE if the 'dict' or 'tsr' option can be used.
*/
-static int has_compl_option(dict_opt)
-int dict_opt;
+static int has_compl_option(int dict_opt)
{
if (dict_opt ? (*curbuf->b_p_dict == NUL && *p_dict == NUL
&& !curwin->w_p_spell
@@ -1816,8 +1847,7 @@ int dict_opt;
* Is the character 'c' a valid key to go to or keep us in CTRL-X mode?
* This depends on the current mode.
*/
-int vim_is_ctrl_x_key(c)
-int c;
+int vim_is_ctrl_x_key(int c)
{
/* Always allow ^R - let it's results then be checked */
if (c == Ctrl_R)
@@ -1872,8 +1902,7 @@ int c;
* completed. Used to decide whether to abandon complete mode when the menu
* is visible.
*/
-static int ins_compl_accept_char(c)
-int c;
+static int ins_compl_accept_char(int c)
{
if (ctrl_x_mode & CTRL_X_WANT_IDENT)
/* When expanding an identifier only accept identifier chars. */
@@ -1905,13 +1934,7 @@ int c;
* text is inferred, ie this tries to work out what case you probably wanted
* the rest of the word to be in -- webb
*/
-int ins_compl_add_infercase(str, len, icase, fname, dir, flags)
-char_u *str;
-int len;
-int icase;
-char_u *fname;
-int dir;
-int flags;
+int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
{
char_u *p;
int i, c;
@@ -2044,15 +2067,17 @@ int flags;
* NOTDONE, otherwise add it to the list and return OK. If there is an error,
* maybe because alloc() returns NULL, then FAIL is returned.
*/
-static int ins_compl_add(str, len, icase, fname, cptext, cdir, flags, adup)
-char_u *str;
-int len;
-int icase;
-char_u *fname;
-char_u **cptext; /* extra text for popup menu or NULL */
-int cdir;
-int flags;
-int adup; /* accept duplicate match */
+static int
+ins_compl_add (
+ char_u *str,
+ int len,
+ int icase,
+ char_u *fname,
+ char_u **cptext, /* extra text for popup menu or NULL */
+ int cdir,
+ int flags,
+ int adup /* accept duplicate match */
+)
{
compl_T *match;
int dir = (cdir == 0 ? compl_direction : cdir);
@@ -2153,10 +2178,7 @@ int adup; /* accept duplicate match */
* Return TRUE if "str[len]" matches with match->cp_str, considering
* match->cp_icase.
*/
-static int ins_compl_equal(match, str, len)
-compl_T *match;
-char_u *str;
-int len;
+static int ins_compl_equal(compl_T *match, char_u *str, int len)
{
if (match->cp_icase)
return STRNICMP(match->cp_str, str, (size_t)len) == 0;
@@ -2166,8 +2188,7 @@ int len;
/*
* Reduce the longest common string for match "match".
*/
-static void ins_compl_longest_match(match)
-compl_T *match;
+static void ins_compl_longest_match(compl_T *match)
{
char_u *p, *s;
int c1, c2;
@@ -2234,10 +2255,7 @@ compl_T *match;
* Add an array of matches to the list of matches.
* Frees matches[].
*/
-static void ins_compl_add_matches(num_matches, matches, icase)
-int num_matches;
-char_u **matches;
-int icase;
+static void ins_compl_add_matches(int num_matches, char_u **matches, int icase)
{
int i;
int add_r = OK;
@@ -2254,7 +2272,7 @@ int icase;
/* Make the completion list cyclic.
* Return the number of matches (excluding the original).
*/
-static int ins_compl_make_cyclic() {
+static int ins_compl_make_cyclic(void) {
compl_T *match;
int count = 0;
@@ -2279,9 +2297,7 @@ static int ins_compl_make_cyclic() {
* "startcol" is where the matched text starts (1 is first column).
* "list" is the list of matches.
*/
-void set_completion(startcol, list)
-colnr_T startcol;
-list_T *list;
+void set_completion(colnr_T startcol, list_T *list)
{
/* If already doing completions stop it. */
if (ctrl_x_mode != 0)
@@ -2325,7 +2341,7 @@ static int compl_match_arraysize;
/*
* Update the screen and when there is any scrolling remove the popup menu.
*/
-static void ins_compl_upd_pum() {
+static void ins_compl_upd_pum(void) {
int h;
if (compl_match_array != NULL) {
@@ -2339,7 +2355,7 @@ static void ins_compl_upd_pum() {
/*
* Remove any popup menu.
*/
-static void ins_compl_del_pum() {
+static void ins_compl_del_pum(void) {
if (compl_match_array != NULL) {
pum_undisplay();
vim_free(compl_match_array);
@@ -2350,7 +2366,7 @@ static void ins_compl_del_pum() {
/*
* Return TRUE if the popup menu should be displayed.
*/
-static int pum_wanted() {
+static int pum_wanted(void) {
/* 'completeopt' must contain "menu" or "menuone" */
if (vim_strchr(p_cot, 'm') == NULL)
return FALSE;
@@ -2366,7 +2382,7 @@ static int pum_wanted() {
* Return TRUE if there are two or more matches to be shown in the popup menu.
* One if 'completopt' contains "menuone".
*/
-static int pum_enough_matches() {
+static int pum_enough_matches(void) {
compl_T *compl;
int i;
@@ -2390,7 +2406,7 @@ static int pum_enough_matches() {
* Show the popup menu for the list of matches.
* Also adjusts "compl_shown_match" to an entry that is actually displayed.
*/
-void ins_compl_show_pum() {
+void ins_compl_show_pum(void) {
compl_T *compl;
compl_T *shown_compl = NULL;
int did_find_shown_match = FALSE;
@@ -2516,11 +2532,13 @@ void ins_compl_show_pum() {
* Add any identifiers that match the given pattern in the list of dictionary
* files "dict_start" to the list of completions.
*/
-static void ins_compl_dictionaries(dict_start, pat, flags, thesaurus)
-char_u *dict_start;
-char_u *pat;
-int flags; /* DICT_FIRST and/or DICT_EXACT */
-int thesaurus; /* Thesaurus completion */
+static void
+ins_compl_dictionaries (
+ char_u *dict_start,
+ char_u *pat,
+ int flags, /* DICT_FIRST and/or DICT_EXACT */
+ int thesaurus /* Thesaurus completion */
+)
{
char_u *dict = dict_start;
char_u *ptr;
@@ -2619,14 +2637,7 @@ theend:
vim_free(buf);
}
-static void ins_compl_files(count, files, thesaurus, flags, regmatch, buf, dir)
-int count;
-char_u **files;
-int thesaurus;
-int flags;
-regmatch_T *regmatch;
-char_u *buf;
-int *dir;
+static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir)
{
char_u *ptr;
int i;
@@ -2717,8 +2728,7 @@ int *dir;
* Find the start of the next word.
* Returns a pointer to the first char of the word. Also stops at a NUL.
*/
-char_u * find_word_start(ptr)
-char_u *ptr;
+char_u *find_word_start(char_u *ptr)
{
if (has_mbyte)
while (*ptr != NUL && *ptr != '\n' && mb_get_class(ptr) <= 1)
@@ -2733,8 +2743,7 @@ char_u *ptr;
* Find the end of the word. Assumes it starts inside a word.
* Returns a pointer to just after the word.
*/
-char_u * find_word_end(ptr)
-char_u *ptr;
+char_u *find_word_end(char_u *ptr)
{
int start_class;
@@ -2756,8 +2765,7 @@ char_u *ptr;
* Find the end of the line, omitting CR and NL at the end.
* Returns a pointer to just after the line.
*/
-static char_u * find_line_end(ptr)
-char_u *ptr;
+static char_u *find_line_end(char_u *ptr)
{
char_u *s;
@@ -2770,7 +2778,7 @@ char_u *ptr;
/*
* Free the list of completions
*/
-static void ins_compl_free() {
+static void ins_compl_free(void) {
compl_T *match;
int i;
@@ -2801,7 +2809,7 @@ static void ins_compl_free() {
compl_shown_match = NULL;
}
-static void ins_compl_clear() {
+static void ins_compl_clear(void) {
compl_cont_status = 0;
compl_started = FALSE;
compl_matches = 0;
@@ -2818,7 +2826,7 @@ static void ins_compl_clear() {
/*
* Return TRUE when Insert completion is active.
*/
-int ins_compl_active() {
+int ins_compl_active(void) {
return compl_started;
}
@@ -2828,7 +2836,7 @@ int ins_compl_active() {
* Returns the character to be used, NUL if the work is done and another char
* to be got from the user.
*/
-static int ins_compl_bs() {
+static int ins_compl_bs(void) {
char_u *line;
char_u *p;
@@ -2865,7 +2873,7 @@ static int ins_compl_bs() {
* Return TRUE when we need to find matches again, ins_compl_restart() is to
* be called.
*/
-static int ins_compl_need_restart() {
+static int ins_compl_need_restart(void) {
/* Return TRUE if we didn't complete finding matches or when the
* 'completefunc' returned "always" in the "refresh" dictionary item. */
return compl_was_interrupted
@@ -2878,7 +2886,7 @@ static int ins_compl_need_restart() {
* Show the popup menu with a different set of matches.
* May also search for matches again if the previous search was interrupted.
*/
-static void ins_compl_new_leader() {
+static void ins_compl_new_leader(void) {
ins_compl_del_pum();
ins_compl_delete();
ins_bytes(compl_leader + ins_compl_len());
@@ -2914,7 +2922,7 @@ static void ins_compl_new_leader() {
* Return the length of the completion, from the completion start column to
* the cursor column. Making sure it never goes below zero.
*/
-static int ins_compl_len() {
+static int ins_compl_len(void) {
int off = (int)curwin->w_cursor.col - (int)compl_col;
if (off < 0)
@@ -2926,8 +2934,7 @@ static int ins_compl_len() {
* Append one character to the match leader. May reduce the number of
* matches.
*/
-static void ins_compl_addleader(c)
-int c;
+static void ins_compl_addleader(int c)
{
int cc;
@@ -2965,7 +2972,7 @@ int c;
* Setup for finding completions again without leaving CTRL-X mode. Used when
* BS or a key was typed while still searching for matches.
*/
-static void ins_compl_restart() {
+static void ins_compl_restart(void) {
ins_compl_free();
compl_started = FALSE;
compl_matches = 0;
@@ -2976,8 +2983,7 @@ static void ins_compl_restart() {
/*
* Set the first match, the original text.
*/
-static void ins_compl_set_original_text(str)
-char_u *str;
+static void ins_compl_set_original_text(char_u *str)
{
char_u *p;
@@ -2995,7 +3001,7 @@ char_u *str;
* Append one character to the match leader. May reduce the number of
* matches.
*/
-static void ins_compl_addfrommatch() {
+static void ins_compl_addfrommatch(void) {
char_u *p;
int len = (int)curwin->w_cursor.col - (int)compl_col;
int c;
@@ -3031,8 +3037,7 @@ static void ins_compl_addfrommatch() {
* Called just after typing a character in Insert mode.
* Returns TRUE when the character is not to be inserted;
*/
-static int ins_compl_prep(c)
-int c;
+static int ins_compl_prep(int c)
{
char_u *ptr;
int want_cindent;
@@ -3273,8 +3278,7 @@ int c;
* text. This inserts backspaces and appends the changed text.
* "ptr" is the known leader text or NUL.
*/
-static void ins_compl_fixRedoBufForLeader(ptr_arg)
-char_u *ptr_arg;
+static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
{
int len;
char_u *p;
@@ -3308,9 +3312,7 @@ char_u *ptr_arg;
*
* Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo
*/
-static buf_T * ins_compl_next_buf(buf, flag)
-buf_T *buf;
-int flag;
+static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
{
static win_T *wp;
@@ -3341,9 +3343,11 @@ static void expand_by_function __ARGS((int type, char_u *base));
* Execute user defined complete function 'completefunc' or 'omnifunc', and
* get matches in "matches".
*/
-static void expand_by_function(type, base)
-int type; /* CTRL_X_OMNI or CTRL_X_FUNCTION */
-char_u *base;
+static void
+expand_by_function (
+ int type, /* CTRL_X_OMNI or CTRL_X_FUNCTION */
+ char_u *base
+)
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
@@ -3408,8 +3412,7 @@ theend:
/*
* Add completions from a list.
*/
-static void ins_compl_add_list(list)
-list_T *list;
+static void ins_compl_add_list(list_T *list)
{
listitem_T *li;
int dir = compl_direction;
@@ -3427,8 +3430,7 @@ list_T *list;
/*
* Add completions from a dict.
*/
-static void ins_compl_add_dict(dict)
-dict_T *dict;
+static void ins_compl_add_dict(dict_T *dict)
{
dictitem_T *di_refresh;
dictitem_T *di_words;
@@ -3455,9 +3457,7 @@ dict_T *dict;
* NOTDONE, otherwise add it to the list and return OK. If there is an error,
* maybe because alloc() returns NULL, then FAIL is returned.
*/
-int ins_compl_add_tv(tv, dir)
-typval_T *tv;
-int dir;
+int ins_compl_add_tv(typval_T *tv, int dir)
{
char_u *word;
int icase = FALSE;
@@ -3499,8 +3499,7 @@ int dir;
* This may return before finding all the matches.
* Return the total number of matches or -1 if still unknown -- Acevedo
*/
-static int ins_compl_get_exp(ini)
-pos_T *ini;
+static int ins_compl_get_exp(pos_T *ini)
{
static pos_T first_match_pos;
static pos_T last_match_pos;
@@ -3877,7 +3876,7 @@ pos_T *ini;
}
/* Delete the old text being completed. */
-static void ins_compl_delete() {
+static void ins_compl_delete(void) {
int i;
/*
@@ -3890,7 +3889,7 @@ static void ins_compl_delete() {
}
/* Insert the new text being completed. */
-static void ins_compl_insert() {
+static void ins_compl_insert(void) {
ins_bytes(compl_shown_match->cp_str + ins_compl_len());
if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
compl_used_match = FALSE;
@@ -3914,11 +3913,13 @@ static void ins_compl_insert() {
* "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn
* calls this function with "allow_get_expansion" FALSE.
*/
-static int ins_compl_next(allow_get_expansion, count, insert_match)
-int allow_get_expansion;
-int count; /* repeat completion this many times; should
+static int
+ins_compl_next (
+ int allow_get_expansion,
+ int count, /* repeat completion this many times; should
be at least 1 */
-int insert_match; /* Insert the newly selected match */
+ int insert_match /* Insert the newly selected match */
+)
{
int num_matches = -1;
int i;
@@ -4094,8 +4095,7 @@ int insert_match; /* Insert the newly selected match */
* possible. -- webb
* "frequency" specifies out of how many calls we actually check.
*/
-void ins_compl_check_keys(frequency)
-int frequency;
+void ins_compl_check_keys(int frequency)
{
static int count = 0;
@@ -4146,8 +4146,7 @@ int frequency;
* Decide the direction of Insert mode complete from the key typed.
* Returns BACKWARD or FORWARD.
*/
-static int ins_compl_key2dir(c)
-int c;
+static int ins_compl_key2dir(int c)
{
if (c == Ctrl_P || c == Ctrl_L
|| (pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP
@@ -4160,8 +4159,7 @@ int c;
* Return TRUE for keys that are used for completion only when the popup menu
* is visible.
*/
-static int ins_compl_pum_key(c)
-int c;
+static int ins_compl_pum_key(int c)
{
return pum_visible() && (c == K_PAGEUP || c == K_KPAGEUP || c == K_S_UP
|| c == K_PAGEDOWN || c == K_KPAGEDOWN || c ==
@@ -4173,8 +4171,7 @@ int c;
* Decide the number of completions to move forward.
* Returns 1 for most keys, height of the popup menu for page-up/down keys.
*/
-static int ins_compl_key2count(c)
-int c;
+static int ins_compl_key2count(int c)
{
int h;
@@ -4191,8 +4188,7 @@ int c;
* Return TRUE if completion with "c" should insert the match, FALSE if only
* to change the currently selected completion.
*/
-static int ins_compl_use_match(c)
-int c;
+static int ins_compl_use_match(int c)
{
switch (c) {
case K_UP:
@@ -4213,8 +4209,7 @@ int c;
* Called when character "c" was typed, which has a meaning for completion.
* Returns OK if completion was done, FAIL if something failed (out of mem).
*/
-static int ins_complete(c)
-int c;
+static int ins_complete(int c)
{
char_u *line;
int startcol = 0; /* column where searched text starts */
@@ -4740,10 +4735,7 @@ int c;
* a backslash) the metachars, and dest would be NUL terminated.
* Returns the length (needed) of dest
*/
-static unsigned quote_meta(dest, src, len)
-char_u *dest;
-char_u *src;
-int len;
+static unsigned quote_meta(char_u *dest, char_u *src, int len)
{
unsigned m = (unsigned)len + 1; /* one extra for the NUL */
@@ -4797,7 +4789,7 @@ int len;
* If one or two digits are entered, the next character is given to vungetc().
* For Unicode a character > 255 may be returned.
*/
-int get_literal() {
+int get_literal(void) {
int cc;
int nc;
int i;
@@ -4887,10 +4879,12 @@ int get_literal() {
/*
* Insert character, taking care of special keys and mod_mask
*/
-static void insert_special(c, allow_modmask, ctrlv)
-int c;
-int allow_modmask;
-int ctrlv; /* c was typed after CTRL-V */
+static void
+insert_special (
+ int c,
+ int allow_modmask,
+ int ctrlv /* c was typed after CTRL-V */
+)
{
char_u *p;
int len;
@@ -4944,10 +4938,12 @@ int ctrlv; /* c was typed after CTRL-V */
* INSCHAR_DO_COM - format comments
* INSCHAR_COM_LIST - format comments with num list or 2nd line indent
*/
-void insertchar(c, flags, second_indent)
-int c; /* character to insert or NUL */
-int flags; /* INSCHAR_FORMAT, etc. */
-int second_indent; /* indent for second line if >= 0 */
+void
+insertchar (
+ int c, /* character to insert or NUL */
+ int flags, /* INSCHAR_FORMAT, etc. */
+ int second_indent /* indent for second line if >= 0 */
+)
{
int textwidth;
char_u *p;
@@ -5145,12 +5141,14 @@ int second_indent; /* indent for second line if >= 0 */
* If the INSCHAR_COM_LIST flag is present, then the value of second_indent
* will be the comment leader length sent to open_line().
*/
-static void internal_format(textwidth, second_indent, flags, format_only, c)
-int textwidth;
-int second_indent;
-int flags;
-int format_only;
-int c; /* character to be inserted (can be NUL) */
+static void
+internal_format (
+ int textwidth,
+ int second_indent,
+ int flags,
+ int format_only,
+ int c /* character to be inserted (can be NUL) */
+)
{
int cc;
int save_char = NUL;
@@ -5466,9 +5464,11 @@ int c; /* character to be inserted (can be NUL) */
* The caller must have saved the cursor line for undo, following ones will be
* saved here.
*/
-void auto_format(trailblank, prev_line)
-int trailblank; /* when TRUE also format with trailing blank */
-int prev_line; /* may start in previous line */
+void
+auto_format (
+ int trailblank, /* when TRUE also format with trailing blank */
+ int prev_line /* may start in previous line */
+)
{
pos_T pos;
colnr_T len;
@@ -5566,8 +5566,10 @@ int prev_line; /* may start in previous line */
* delete it now. The space must be under the cursor, just after the insert
* position.
*/
-static void check_auto_format(end_insert)
-int end_insert; /* TRUE when ending Insert mode */
+static void
+check_auto_format (
+ int end_insert /* TRUE when ending Insert mode */
+)
{
int c = ' ';
int cc;
@@ -5599,8 +5601,10 @@ int end_insert; /* TRUE when ending Insert mode */
* if invalid value, use 0.
* Set default to window width (maximum 79) for "gq" operator.
*/
-int comp_textwidth(ff)
-int ff; /* force formatting (for "gq" command) */
+int
+comp_textwidth (
+ int ff /* force formatting (for "gq" command) */
+)
{
int textwidth;
@@ -5628,8 +5632,7 @@ int ff; /* force formatting (for "gq" command) */
/*
* Put a character in the redo buffer, for when just after a CTRL-V.
*/
-static void redo_literal(c)
-int c;
+static void redo_literal(int c)
{
char_u buf[10];
@@ -5646,8 +5649,10 @@ int c;
* start_arrow() is called when an arrow key is used in insert mode.
* For undo/redo it resembles hitting the <ESC> key.
*/
-static void start_arrow(end_insert_pos)
-pos_T *end_insert_pos; /* can be NULL */
+static void
+start_arrow (
+ pos_T *end_insert_pos /* can be NULL */
+)
{
if (!arrow_used) { /* something has been inserted */
AppendToRedobuff(ESC_STR);
@@ -5661,7 +5666,7 @@ pos_T *end_insert_pos; /* can be NULL */
* If we skipped highlighting word at cursor, do it now.
* It may be skipped again, thus reset spell_redraw_lnum first.
*/
-static void check_spell_redraw() {
+static void check_spell_redraw(void) {
if (spell_redraw_lnum != 0) {
linenr_T lnum = spell_redraw_lnum;
@@ -5674,7 +5679,7 @@ static void check_spell_redraw() {
* Called when starting CTRL_X_SPELL mode: Move backwards to a previous badly
* spelled word, if there is one.
*/
-static void spell_back_to_badword() {
+static void spell_back_to_badword(void) {
pos_T tpos = curwin->w_cursor;
spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
@@ -5687,7 +5692,7 @@ static void spell_back_to_badword() {
* If an arrow key has been used, start a new insertion.
* Returns FAIL if undo is impossible, shouldn't insert then.
*/
-int stop_arrow() {
+int stop_arrow(void) {
if (arrow_used) {
if (u_save_cursor() == OK) {
arrow_used = FALSE;
@@ -5719,10 +5724,12 @@ int stop_arrow() {
* "end_insert_pos" is where insert ended. It is NULL when we already jumped
* to another window/buffer.
*/
-static void stop_insert(end_insert_pos, esc, nomove)
-pos_T *end_insert_pos;
-int esc; /* called by ins_esc() */
-int nomove; /* <c-\><c-o>, don't move cursor */
+static void
+stop_insert (
+ pos_T *end_insert_pos,
+ int esc, /* called by ins_esc() */
+ int nomove /* <c-\><c-o>, don't move cursor */
+)
{
int cc;
char_u *ptr;
@@ -5836,8 +5843,7 @@ int nomove; /* <c-\><c-o>, don't move cursor */
* Set the last inserted text to a single character.
* Used for the replace command.
*/
-void set_last_insert(c)
-int c;
+void set_last_insert(int c)
{
char_u *s;
@@ -5856,7 +5862,7 @@ int c;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_last_insert() {
+void free_last_insert(void) {
vim_free(last_insert);
last_insert = NULL;
vim_free(compl_orig_text);
@@ -5870,9 +5876,7 @@ void free_last_insert() {
* and CSI. Handle multi-byte characters.
* Returns a pointer to after the added bytes.
*/
-char_u * add_char2buf(c, s)
-int c;
-char_u *s;
+char_u *add_char2buf(int c, char_u *s)
{
char_u temp[MB_MAXBYTES + 1];
int i;
@@ -5899,8 +5903,7 @@ char_u *s;
* otherwise keep "curswant" column
* if flags & BL_FIX don't leave the cursor on a NUL.
*/
-void beginline(flags)
-int flags;
+void beginline(int flags)
{
if ((flags & BL_SOL) && !p_sol)
coladvance(curwin->w_curswant);
@@ -5927,7 +5930,7 @@ int flags;
* Return OK when successful, FAIL when we hit a line of file boundary.
*/
-int oneright() {
+int oneright(void) {
char_u *ptr;
int l;
@@ -5967,7 +5970,7 @@ int oneright() {
return OK;
}
-int oneleft() {
+int oneleft(void) {
if (virtual_active()) {
int width;
int v = getviscol();
@@ -6016,9 +6019,11 @@ int oneleft() {
return OK;
}
-int cursor_up(n, upd_topline)
-long n;
-int upd_topline; /* When TRUE: update topline */
+int
+cursor_up (
+ long n,
+ int upd_topline /* When TRUE: update topline */
+)
{
linenr_T lnum;
@@ -6067,9 +6072,11 @@ int upd_topline; /* When TRUE: update topline */
/*
* Cursor down a number of logical lines.
*/
-int cursor_down(n, upd_topline)
-long n;
-int upd_topline; /* When TRUE: update topline */
+int
+cursor_down (
+ long n,
+ int upd_topline /* When TRUE: update topline */
+)
{
linenr_T lnum;
@@ -6118,10 +6125,12 @@ int upd_topline; /* When TRUE: update topline */
* Last_insert actually is a copy of the redo buffer, so we
* first have to remove the command.
*/
-int stuff_inserted(c, count, no_esc)
-int c; /* Command character to be inserted */
-long count; /* Repeat this many times */
-int no_esc; /* Don't add an ESC at the end */
+int
+stuff_inserted (
+ int c, /* Command character to be inserted */
+ long count, /* Repeat this many times */
+ int no_esc /* Don't add an ESC at the end */
+)
{
char_u *esc_ptr;
char_u *ptr;
@@ -6173,7 +6182,7 @@ int no_esc; /* Don't add an ESC at the end */
return OK;
}
-char_u * get_last_insert() {
+char_u *get_last_insert(void) {
if (last_insert == NULL)
return NULL;
return last_insert + last_insert_skip;
@@ -6183,7 +6192,7 @@ char_u * get_last_insert() {
* Get last inserted string, and remove trailing <Esc>.
* Returns pointer to allocated memory (must be freed) or NULL.
*/
-char_u * get_last_insert_save() {
+char_u *get_last_insert_save(void) {
char_u *s;
int len;
@@ -6204,8 +6213,7 @@ char_u * get_last_insert_save() {
* When an abbreviation is recognized it is removed from the text and
* the replacement string is inserted in typebuf.tb_buf[], followed by "c".
*/
-static int echeck_abbr(c)
-int c;
+static int echeck_abbr(int c)
{
/* Don't check for abbreviation in paste mode, when disabled and just
* after moving around with cursor keys. */
@@ -6239,8 +6247,10 @@ static char_u *replace_stack = NULL;
static long replace_stack_nr = 0; /* next entry in replace stack */
static long replace_stack_len = 0; /* max. number of entries */
-void replace_push(c)
-int c; /* character that is replaced (NUL is none) */
+void
+replace_push (
+ int c /* character that is replaced (NUL is none) */
+)
{
char_u *p;
@@ -6272,8 +6282,7 @@ int c; /* character that is replaced (NUL is none) */
* reverse byte order, so that the first byte is popped off first.
* Return the number of bytes done (includes composing characters).
*/
-int replace_push_mb(p)
-char_u *p;
+int replace_push_mb(char_u *p)
{
int l = (*mb_ptr2len)(p);
int j;
@@ -6288,7 +6297,7 @@ char_u *p;
* return -1 if stack empty
* return replaced character or NUL otherwise
*/
-static int replace_pop() {
+static int replace_pop(void) {
if (replace_stack_nr == 0)
return -1;
return (int)replace_stack[--replace_stack_nr];
@@ -6298,8 +6307,10 @@ static int replace_pop() {
* Join the top two items on the replace stack. This removes to "off"'th NUL
* encountered.
*/
-static void replace_join(off)
-int off; /* offset for which NUL to remove */
+static void
+replace_join (
+ int off /* offset for which NUL to remove */
+)
{
int i;
@@ -6316,7 +6327,7 @@ int off; /* offset for which NUL to remove */
* Pop bytes from the replace stack until a NUL is found, and insert them
* before the cursor. Can only be used in REPLACE or VREPLACE mode.
*/
-static void replace_pop_ins() {
+static void replace_pop_ins(void) {
int cc;
int oldState = State;
@@ -6332,8 +6343,7 @@ static void replace_pop_ins() {
* Insert bytes popped from the replace stack. "cc" is the first byte. If it
* indicates a multi-byte char, pop the other bytes too.
*/
-static void mb_replace_pop_ins(cc)
-int cc;
+static void mb_replace_pop_ins(int cc)
{
int n;
char_u buf[MB_MAXBYTES + 1];
@@ -6378,7 +6388,7 @@ int cc;
* make the replace stack empty
* (called when exiting replace mode)
*/
-static void replace_flush() {
+static void replace_flush(void) {
vim_free(replace_stack);
replace_stack = NULL;
replace_stack_len = 0;
@@ -6394,8 +6404,7 @@ static void replace_flush() {
* When "limit_col" is >= 0, don't delete before this column. Matters when
* using composing characters, use del_char_after_col() instead of del_char().
*/
-static void replace_do_bs(limit_col)
-int limit_col;
+static void replace_do_bs(int limit_col)
{
int cc;
int orig_len = 0;
@@ -6456,7 +6465,7 @@ int limit_col;
/*
* Return TRUE if C-indenting is on.
*/
-static int cindent_on() {
+static int cindent_on(void) {
return !p_paste && (curbuf->b_p_cin
|| *curbuf->b_p_inde != NUL
);
@@ -6477,7 +6486,7 @@ int (*get_the_indent)__ARGS((void));
did_ai = TRUE; /* delete the indent if the line stays empty */
}
-void fix_indent() {
+void fix_indent(void) {
if (p_paste)
return;
if (curbuf->b_p_lisp && curbuf->b_p_ai)
@@ -6499,10 +6508,7 @@ void fix_indent() {
*
* If line_is_empty is TRUE accept keys with '0' before them.
*/
-int in_cinkeys(keytyped, when, line_is_empty)
-int keytyped;
-int when;
-int line_is_empty;
+int in_cinkeys(int keytyped, int when, int line_is_empty)
{
char_u *look;
int try_match;
@@ -6716,8 +6722,7 @@ int line_is_empty;
/*
* Map Hebrew keyboard when in hkmap mode.
*/
-int hkmap(c)
-int c;
+int hkmap(int c)
{
if (p_hkmapp) { /* phonetic mapping, by Ilya Dogolazky */
enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
@@ -6782,7 +6787,7 @@ int c;
}
}
-static void ins_reg() {
+static void ins_reg(void) {
int need_redraw = FALSE;
int regname;
int literally = 0;
@@ -6878,7 +6883,7 @@ static void ins_reg() {
/*
* CTRL-G commands in Insert mode.
*/
-static void ins_ctrl_g() {
+static void ins_ctrl_g(void) {
int c;
/* Right after CTRL-X the cursor will be after the ruler. */
@@ -6921,7 +6926,7 @@ static void ins_ctrl_g() {
/*
* CTRL-^ in Insert mode.
*/
-static void ins_ctrl_hat() {
+static void ins_ctrl_hat(void) {
if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) {
/* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
if (State & LANGMAP) {
@@ -6959,10 +6964,12 @@ static void ins_ctrl_hat() {
* Returns TRUE when leaving insert mode, FALSE when going to repeat the
* insert.
*/
-static int ins_esc(count, cmdchar, nomove)
-long *count;
-int cmdchar;
-int nomove; /* don't move cursor */
+static int
+ins_esc (
+ long *count,
+ int cmdchar,
+ int nomove /* don't move cursor */
+)
{
int temp;
static int disabled_redraw = FALSE;
@@ -7085,7 +7092,7 @@ int nomove; /* don't move cursor */
* Toggle language: hkmap and revins_on.
* Move to end of reverse inserted text.
*/
-static void ins_ctrl_() {
+static void ins_ctrl_(void) {
if (revins_on && revins_chars && revins_scol >= 0) {
while (gchar_cursor() != NUL && revins_chars--)
++curwin->w_cursor.col;
@@ -7119,8 +7126,7 @@ static void ins_ctrl_() {
* If 'keymodel' contains "startsel", may start selection.
* Returns TRUE when a CTRL-O and other keys stuffed.
*/
-static int ins_start_select(c)
-int c;
+static int ins_start_select(int c)
{
if (km_startsel)
switch (c) {
@@ -7163,8 +7169,7 @@ int c;
/*
* <Insert> key in Insert mode: toggle insert/replace mode.
*/
-static void ins_insert(replaceState)
-int replaceState;
+static void ins_insert(int replaceState)
{
if (p_fkmap && p_ri) {
beep_flush();
@@ -7191,7 +7196,7 @@ int replaceState;
/*
* Pressed CTRL-O in Insert mode.
*/
-static void ins_ctrl_o() {
+static void ins_ctrl_o(void) {
if (State & VREPLACE_FLAG)
restart_edit = 'V';
else if (State & REPLACE_FLAG)
@@ -7211,9 +7216,7 @@ static void ins_ctrl_o() {
* with vi. But vi only supports ^T and ^D after an
* autoindent, we support it everywhere.
*/
-static void ins_shift(c, lastc)
-int c;
-int lastc;
+static void ins_shift(int c, int lastc)
{
if (stop_arrow() == FAIL)
return;
@@ -7243,7 +7246,7 @@ int lastc;
can_cindent = FALSE; /* no cindenting after ^D or ^T */
}
-static void ins_del() {
+static void ins_del(void) {
int temp;
if (stop_arrow() == FAIL)
@@ -7269,8 +7272,7 @@ static void ins_bs_one __ARGS((colnr_T *vcolp));
/*
* Delete one character for ins_bs().
*/
-static void ins_bs_one(vcolp)
-colnr_T *vcolp;
+static void ins_bs_one(colnr_T *vcolp)
{
dec_cursor();
getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL);
@@ -7288,10 +7290,7 @@ colnr_T *vcolp;
* Handle Backspace, delete-word and delete-line in Insert mode.
* Return TRUE when backspace was actually used.
*/
-static int ins_bs(c, mode, inserted_space_p)
-int c;
-int mode;
-int *inserted_space_p;
+static int ins_bs(int c, int mode, int *inserted_space_p)
{
linenr_T lnum;
int cc;
@@ -7600,8 +7599,7 @@ int *inserted_space_p;
return did_backspace;
}
-static void ins_mouse(c)
-int c;
+static void ins_mouse(int c)
{
pos_T tpos;
win_T *old_curwin = curwin;
@@ -7632,8 +7630,7 @@ int c;
redraw_statuslines();
}
-static void ins_mousescroll(dir)
-int dir;
+static void ins_mousescroll(int dir)
{
pos_T tpos;
win_T *old_curwin = curwin;
@@ -7689,7 +7686,7 @@ int dir;
-static void ins_left() {
+static void ins_left(void) {
pos_T tpos;
if ((fdo_flags & FDO_HOR) && KeyTyped)
@@ -7716,8 +7713,7 @@ static void ins_left() {
vim_beep();
}
-static void ins_home(c)
-int c;
+static void ins_home(int c)
{
pos_T tpos;
@@ -7733,8 +7729,7 @@ int c;
start_arrow(&tpos);
}
-static void ins_end(c)
-int c;
+static void ins_end(int c)
{
pos_T tpos;
@@ -7750,7 +7745,7 @@ int c;
start_arrow(&tpos);
}
-static void ins_s_left() {
+static void ins_s_left(void) {
if ((fdo_flags & FDO_HOR) && KeyTyped)
foldOpenCursor();
undisplay_dollar();
@@ -7762,7 +7757,7 @@ static void ins_s_left() {
vim_beep();
}
-static void ins_right() {
+static void ins_right(void) {
if ((fdo_flags & FDO_HOR) && KeyTyped)
foldOpenCursor();
undisplay_dollar();
@@ -7796,7 +7791,7 @@ static void ins_right() {
vim_beep();
}
-static void ins_s_right() {
+static void ins_s_right(void) {
if ((fdo_flags & FDO_HOR) && KeyTyped)
foldOpenCursor();
undisplay_dollar();
@@ -7809,8 +7804,10 @@ static void ins_s_right() {
vim_beep();
}
-static void ins_up(startcol)
-int startcol; /* when TRUE move to Insstart.col */
+static void
+ins_up (
+ int startcol /* when TRUE move to Insstart.col */
+)
{
pos_T tpos;
linenr_T old_topline = curwin->w_topline;
@@ -7831,7 +7828,7 @@ int startcol; /* when TRUE move to Insstart.col */
vim_beep();
}
-static void ins_pageup() {
+static void ins_pageup(void) {
pos_T tpos;
undisplay_dollar();
@@ -7853,8 +7850,10 @@ static void ins_pageup() {
vim_beep();
}
-static void ins_down(startcol)
-int startcol; /* when TRUE move to Insstart.col */
+static void
+ins_down (
+ int startcol /* when TRUE move to Insstart.col */
+)
{
pos_T tpos;
linenr_T old_topline = curwin->w_topline;
@@ -7875,7 +7874,7 @@ int startcol; /* when TRUE move to Insstart.col */
vim_beep();
}
-static void ins_pagedown() {
+static void ins_pagedown(void) {
pos_T tpos;
undisplay_dollar();
@@ -7901,7 +7900,7 @@ static void ins_pagedown() {
* Handle TAB in Insert or Replace mode.
* Return TRUE when the TAB needs to be inserted like a normal character.
*/
-static int ins_tab() {
+static int ins_tab(void) {
int ind;
int i;
int temp;
@@ -8085,8 +8084,7 @@ static int ins_tab() {
* Handle CR or NL in insert mode.
* Return TRUE when out of memory or can't undo.
*/
-static int ins_eol(c)
-int c;
+static int ins_eol(int c)
{
int i;
@@ -8142,7 +8140,7 @@ int c;
* Returns character still to be inserted, or NUL when nothing remaining to be
* done.
*/
-static int ins_digraph() {
+static int ins_digraph(void) {
int c;
int cc;
int did_putchar = FALSE;
@@ -8215,8 +8213,7 @@ static int ins_digraph() {
* Handle CTRL-E and CTRL-Y in Insert mode: copy char from other line.
* Returns the char to be inserted, or NUL if none found.
*/
-int ins_copychar(lnum)
-linenr_T lnum;
+int ins_copychar(linenr_T lnum)
{
int c;
int temp;
@@ -8248,8 +8245,7 @@ linenr_T lnum;
/*
* CTRL-Y or CTRL-E typed in Insert mode.
*/
-static int ins_ctrl_ey(tc)
-int tc;
+static int ins_ctrl_ey(int tc)
{
int c = tc;
@@ -8287,8 +8283,7 @@ int tc;
* Try to do some very smart auto-indenting.
* Used when inserting a "normal" character.
*/
-static void ins_try_si(c)
-int c;
+static void ins_try_si(int c)
{
pos_T *pos, old_pos;
char_u *ptr;
@@ -8369,7 +8364,7 @@ int c;
* Get the value that w_virtcol would have when 'list' is off.
* Unless 'cpo' contains the 'L' flag.
*/
-static colnr_T get_nolist_virtcol() {
+static colnr_T get_nolist_virtcol(void) {
if (curwin->w_p_list && vim_strchr(p_cpo, CPO_LISTWM) == NULL)
return getvcol_nolist(&curwin->w_cursor);
validate_virtcol();
@@ -8382,8 +8377,7 @@ static colnr_T get_nolist_virtcol() {
* Return a pointer to allocated memory with the replacement string.
* Return NULL to continue inserting "c".
*/
-static char_u * do_insert_char_pre(c)
-int c;
+static char_u *do_insert_char_pre(int c)
{
char_u *res;
char_u buf[MB_MAXBYTES + 1];
diff --git a/src/proto/edit.pro b/src/edit.h
index 0284101df4..aa2b72d93b 100644
--- a/src/proto/edit.pro
+++ b/src/edit.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EDIT_H
+#define NEOVIM_EDIT_H
/* edit.c */
int edit __ARGS((int cmdchar, int startln, long count));
void edit_putchar __ARGS((int c, int highlight));
@@ -44,3 +46,4 @@ void ins_scroll __ARGS((void));
void ins_horscroll __ARGS((void));
int ins_copychar __ARGS((linenr_T lnum));
/* vim: set ft=c : */
+#endif /* NEOVIM_EDIT_H */
diff --git a/src/eval.c b/src/eval.c
index bcf9c75730..4d120c82ce 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -12,10 +12,47 @@
*/
#include "vim.h"
-
-
-
-
+#include "eval.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "edit.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "if_cscope.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "os_unix.h"
+#include "popupmnu.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "sha256.h"
+#include "spell.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "version.h"
+#include "window.h"
+#include "os/os.h"
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
# include <math.h>
@@ -263,7 +300,7 @@ typedef struct {
* The reason to use this table anyway is for very quick access to the
* variables with the VV_ defines.
*/
-#include "version.h"
+#include "version_defs.h"
/* values for vv_flags: */
#define VV_COMPAT 1 /* compatible, also used without "v:" */
@@ -816,7 +853,7 @@ static void setwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
/*
* Initialize the global and v: variables.
*/
-void eval_init() {
+void eval_init(void) {
int i;
struct vimvar *p;
@@ -850,7 +887,7 @@ void eval_init() {
}
#if defined(EXITFREE) || defined(PROTO)
-void eval_clear() {
+void eval_clear(void) {
int i;
struct vimvar *p;
@@ -899,8 +936,7 @@ void eval_clear() {
/*
* Return the name of the executed function.
*/
-char_u * func_name(cookie)
-void *cookie;
+char_u *func_name(void *cookie)
{
return ((funccall_T *)cookie)->func->uf_name;
}
@@ -908,8 +944,7 @@ void *cookie;
/*
* Return the address holding the next breakpoint line for a funccall cookie.
*/
-linenr_T * func_breakpoint(cookie)
-void *cookie;
+linenr_T *func_breakpoint(void *cookie)
{
return &((funccall_T *)cookie)->breakpoint;
}
@@ -917,8 +952,7 @@ void *cookie;
/*
* Return the address holding the debug tick for a funccall cookie.
*/
-int * func_dbg_tick(cookie)
-void *cookie;
+int *func_dbg_tick(void *cookie)
{
return &((funccall_T *)cookie)->dbg_tick;
}
@@ -926,8 +960,7 @@ void *cookie;
/*
* Return the nesting level for a funccall cookie.
*/
-int func_level(cookie)
-void *cookie;
+int func_level(void *cookie)
{
return ((funccall_T *)cookie)->level;
}
@@ -942,7 +975,7 @@ funccall_T *previous_funccal = NULL;
/*
* Return TRUE when a function was ended by a ":return" command.
*/
-int current_func_returned() {
+int current_func_returned(void) {
return current_funccal->returned;
}
@@ -950,9 +983,7 @@ int current_func_returned() {
* Set an internal variable to a string value. Creates the variable if it does
* not already exist.
*/
-void set_internal_string_var(name, value)
-char_u *name;
-char_u *value;
+void set_internal_string_var(char_u *name, char_u *value)
{
char_u *val;
typval_T *tvp;
@@ -976,9 +1007,11 @@ static char_u *redir_varname = NULL;
* Start recording command output to a variable
* Returns OK if successfully completed the setup. FAIL otherwise.
*/
-int var_redir_start(name, append)
-char_u *name;
-int append; /* append to an existing variable */
+int
+var_redir_start (
+ char_u *name,
+ int append /* append to an existing variable */
+)
{
int save_emsg;
int err;
@@ -1051,9 +1084,7 @@ int append; /* append to an existing variable */
* :let foo
* :redir END
*/
-void var_redir_str(value, value_len)
-char_u *value;
-int value_len;
+void var_redir_str(char_u *value, int value_len)
{
int len;
@@ -1076,7 +1107,7 @@ int value_len;
* Stop redirecting command output to a variable.
* Frees the allocated memory.
*/
-void var_redir_stop() {
+void var_redir_stop(void) {
typval_T tv;
if (redir_lval != NULL) {
@@ -1105,11 +1136,7 @@ void var_redir_stop() {
redir_varname = NULL;
}
-int eval_charconvert(enc_from, enc_to, fname_from, fname_to)
-char_u *enc_from;
-char_u *enc_to;
-char_u *fname_from;
-char_u *fname_to;
+int eval_charconvert(char_u *enc_from, char_u *enc_to, char_u *fname_from, char_u *fname_to)
{
int err = FALSE;
@@ -1129,9 +1156,7 @@ char_u *fname_to;
return OK;
}
-int eval_printexpr(fname, args)
-char_u *fname;
-char_u *args;
+int eval_printexpr(char_u *fname, char_u *args)
{
int err = FALSE;
@@ -1149,10 +1174,7 @@ char_u *args;
return OK;
}
-void eval_diff(origfile, newfile, outfile)
-char_u *origfile;
-char_u *newfile;
-char_u *outfile;
+void eval_diff(char_u *origfile, char_u *newfile, char_u *outfile)
{
int err = FALSE;
@@ -1165,10 +1187,7 @@ char_u *outfile;
set_vim_var_string(VV_FNAME_OUT, NULL, -1);
}
-void eval_patch(origfile, difffile, outfile)
-char_u *origfile;
-char_u *difffile;
-char_u *outfile;
+void eval_patch(char_u *origfile, char_u *difffile, char_u *outfile)
{
int err;
@@ -1186,11 +1205,13 @@ char_u *outfile;
* Sets "error" to TRUE if there was an error.
* Return TRUE or FALSE.
*/
-int eval_to_bool(arg, error, nextcmd, skip)
-char_u *arg;
-int *error;
-char_u **nextcmd;
-int skip; /* only parse, don't execute */
+int
+eval_to_bool (
+ char_u *arg,
+ int *error,
+ char_u **nextcmd,
+ int skip /* only parse, don't execute */
+)
{
typval_T tv;
int retval = FALSE;
@@ -1217,10 +1238,12 @@ int skip; /* only parse, don't execute */
* only parsing to "nextcmd" is done, without reporting errors. Return
* pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
*/
-char_u * eval_to_string_skip(arg, nextcmd, skip)
-char_u *arg;
-char_u **nextcmd;
-int skip; /* only parse, don't execute */
+char_u *
+eval_to_string_skip (
+ char_u *arg,
+ char_u **nextcmd,
+ int skip /* only parse, don't execute */
+)
{
typval_T tv;
char_u *retval;
@@ -1243,8 +1266,7 @@ int skip; /* only parse, don't execute */
* Skip over an expression at "*pp".
* Return FAIL for an error, OK otherwise.
*/
-int skip_expr(pp)
-char_u **pp;
+int skip_expr(char_u **pp)
{
typval_T rettv;
@@ -1258,10 +1280,7 @@ char_u **pp;
* a Float to a String.
* Return pointer to allocated memory, or NULL for failure.
*/
-char_u * eval_to_string(arg, nextcmd, convert)
-char_u *arg;
-char_u **nextcmd;
-int convert;
+char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert)
{
typval_T tv;
char_u *retval;
@@ -1295,10 +1314,7 @@ int convert;
* Call eval_to_string() without using current local variables and using
* textlock. When "use_sandbox" is TRUE use the sandbox.
*/
-char_u * eval_to_string_safe(arg, nextcmd, use_sandbox)
-char_u *arg;
-char_u **nextcmd;
-int use_sandbox;
+char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox)
{
char_u *retval;
void *save_funccalp;
@@ -1320,8 +1336,7 @@ int use_sandbox;
* Evaluates "expr" silently.
* Returns -1 for an error.
*/
-int eval_to_number(expr)
-char_u *expr;
+int eval_to_number(char_u *expr)
{
typval_T rettv;
int retval;
@@ -1345,9 +1360,7 @@ char_u *expr;
* Save the current typeval in "save_tv".
* When not used yet add the variable to the v: hashtable.
*/
-static void prepare_vimvar(idx, save_tv)
-int idx;
-typval_T *save_tv;
+static void prepare_vimvar(int idx, typval_T *save_tv)
{
*save_tv = vimvars[idx].vv_tv;
if (vimvars[idx].vv_type == VAR_UNKNOWN)
@@ -1358,9 +1371,7 @@ typval_T *save_tv;
* Restore v: variable "idx" to typeval "save_tv".
* When no longer defined, remove the variable from the v: hashtable.
*/
-static void restore_vimvar(idx, save_tv)
-int idx;
-typval_T *save_tv;
+static void restore_vimvar(int idx, typval_T *save_tv)
{
hashitem_T *hi;
@@ -1379,9 +1390,7 @@ typval_T *save_tv;
* For the "expr:" part of 'spellsuggest'.
* Returns NULL when there is an error.
*/
-list_T * eval_spell_expr(badword, expr)
-char_u *badword;
-char_u *expr;
+list_T *eval_spell_expr(char_u *badword, char_u *expr)
{
typval_T save_val;
typval_T rettv;
@@ -1415,9 +1424,7 @@ char_u *expr;
* Return -1 if anything isn't right.
* Used to get the good word and score from the eval_spell_expr() result.
*/
-int get_spellword(list, pp)
-list_T *list;
-char_u **pp;
+int get_spellword(list_T *list, char_u **pp)
{
listitem_T *li;
@@ -1437,9 +1444,7 @@ char_u **pp;
* Returns an allocated typval_T with the result.
* Returns NULL when there is an error.
*/
-typval_T * eval_expr(arg, nextcmd)
-char_u *arg;
-char_u **nextcmd;
+typval_T *eval_expr(char_u *arg, char_u **nextcmd)
{
typval_T *tv;
@@ -1459,13 +1464,15 @@ char_u **nextcmd;
* arguments are currently supported.
* Returns OK or FAIL.
*/
-int call_vim_function(func, argc, argv, safe, str_arg_only, rettv)
-char_u *func;
-int argc;
-char_u **argv;
-int safe; /* use the sandbox */
-int str_arg_only; /* all arguments are strings */
-typval_T *rettv;
+int
+call_vim_function (
+ char_u *func,
+ int argc,
+ char_u **argv,
+ int safe, /* use the sandbox */
+ int str_arg_only, /* all arguments are strings */
+ typval_T *rettv
+)
{
typval_T *argvars;
long n;
@@ -1527,11 +1534,13 @@ typval_T *rettv;
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
-long call_func_retnr(func, argc, argv, safe)
-char_u *func;
-int argc;
-char_u **argv;
-int safe; /* use the sandbox */
+long
+call_func_retnr (
+ char_u *func,
+ int argc,
+ char_u **argv,
+ int safe /* use the sandbox */
+)
{
typval_T rettv;
long retval;
@@ -1553,11 +1562,13 @@ int safe; /* use the sandbox */
* Returns NULL when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
-void * call_func_retstr(func, argc, argv, safe)
-char_u *func;
-int argc;
-char_u **argv;
-int safe; /* use the sandbox */
+void *
+call_func_retstr (
+ char_u *func,
+ int argc,
+ char_u **argv,
+ int safe /* use the sandbox */
+)
{
typval_T rettv;
char_u *retval;
@@ -1576,11 +1587,13 @@ int safe; /* use the sandbox */
* Uses argv[argc] for the function arguments.
* Returns NULL when there is something wrong.
*/
-void * call_func_retlist(func, argc, argv, safe)
-char_u *func;
-int argc;
-char_u **argv;
-int safe; /* use the sandbox */
+void *
+call_func_retlist (
+ char_u *func,
+ int argc,
+ char_u **argv,
+ int safe /* use the sandbox */
+)
{
typval_T rettv;
@@ -1601,15 +1614,14 @@ int safe; /* use the sandbox */
* Save the current function call pointer, and set it to NULL.
* Used when executing autocommands and for ":source".
*/
-void * save_funccal() {
+void *save_funccal(void) {
funccall_T *fc = current_funccal;
current_funccal = NULL;
return (void *)fc;
}
-void restore_funccal(vfc)
-void *vfc;
+void restore_funccal(void *vfc)
{
funccall_T *fc = (funccall_T *)vfc;
@@ -1654,9 +1666,7 @@ proftime_T *tm; /* where waittime was stored */
* Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding
* it in "*cp". Doesn't give error messages.
*/
-int eval_foldexpr(arg, cp)
-char_u *arg;
-int *cp;
+int eval_foldexpr(char_u *arg, int *cp)
{
typval_T tv;
int retval;
@@ -1704,8 +1714,7 @@ int *cp;
* ":let var .= expr" assignment command.
* ":let [var1, var2] = expr" unpack list.
*/
-void ex_let(eap)
-exarg_T *eap;
+void ex_let(exarg_T *eap)
{
char_u *arg = eap->arg;
char_u *expr = NULL;
@@ -1775,13 +1784,15 @@ exarg_T *eap;
* or concatenate.
* Returns OK or FAIL;
*/
-static int ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars)
-char_u *arg_start;
-typval_T *tv;
-int copy; /* copy values from "tv", don't move */
-int semicolon; /* from skip_var_list() */
-int var_count; /* from skip_var_list() */
-char_u *nextchars;
+static int
+ex_let_vars (
+ char_u *arg_start,
+ typval_T *tv,
+ int copy, /* copy values from "tv", don't move */
+ int semicolon, /* from skip_var_list() */
+ int var_count, /* from skip_var_list() */
+ char_u *nextchars
+)
{
char_u *arg = arg_start;
list_T *l;
@@ -1863,10 +1874,7 @@ char_u *nextchars;
* for "[var, var; var]" set "semicolon".
* Return NULL for an error.
*/
-static char_u * skip_var_list(arg, var_count, semicolon)
-char_u *arg;
-int *var_count;
-int *semicolon;
+static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon)
{
char_u *p, *s;
@@ -1905,8 +1913,7 @@ int *semicolon;
* Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
* l[idx].
*/
-static char_u * skip_var_one(arg)
-char_u *arg;
+static char_u *skip_var_one(char_u *arg)
{
if (*arg == '@' && arg[1] != NUL)
return arg + 2;
@@ -1918,11 +1925,7 @@ char_u *arg;
* List variables for hashtab "ht" with prefix "prefix".
* If "empty" is TRUE also list NULL strings as empty strings.
*/
-static void list_hashtable_vars(ht, prefix, empty, first)
-hashtab_T *ht;
-char_u *prefix;
-int empty;
-int *first;
+static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first)
{
hashitem_T *hi;
dictitem_T *di;
@@ -1943,8 +1946,7 @@ int *first;
/*
* List global variables.
*/
-static void list_glob_vars(first)
-int *first;
+static void list_glob_vars(int *first)
{
list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
}
@@ -1952,8 +1954,7 @@ int *first;
/*
* List buffer variables.
*/
-static void list_buf_vars(first)
-int *first;
+static void list_buf_vars(int *first)
{
char_u numbuf[NUMBUFLEN];
@@ -1968,8 +1969,7 @@ int *first;
/*
* List window variables.
*/
-static void list_win_vars(first)
-int *first;
+static void list_win_vars(int *first)
{
list_hashtable_vars(&curwin->w_vars->dv_hashtab,
(char_u *)"w:", TRUE, first);
@@ -1978,8 +1978,7 @@ int *first;
/*
* List tab page variables.
*/
-static void list_tab_vars(first)
-int *first;
+static void list_tab_vars(int *first)
{
list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
(char_u *)"t:", TRUE, first);
@@ -1988,8 +1987,7 @@ int *first;
/*
* List Vim variables.
*/
-static void list_vim_vars(first)
-int *first;
+static void list_vim_vars(int *first)
{
list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
}
@@ -1997,8 +1995,7 @@ int *first;
/*
* List script-local variables, if there is a script.
*/
-static void list_script_vars(first)
-int *first;
+static void list_script_vars(int *first)
{
if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
list_hashtable_vars(&SCRIPT_VARS(current_SID),
@@ -2008,8 +2005,7 @@ int *first;
/*
* List function variables, if there is a function.
*/
-static void list_func_vars(first)
-int *first;
+static void list_func_vars(int *first)
{
if (current_funccal != NULL)
list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
@@ -2019,10 +2015,7 @@ int *first;
/*
* List variables in "arg".
*/
-static char_u * list_arg_vars(eap, arg, first)
-exarg_T *eap;
-char_u *arg;
-int *first;
+static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
{
int error = FALSE;
int len;
@@ -2112,12 +2105,14 @@ int *first;
* Returns a pointer to the char just after the var name.
* Returns NULL if there is an error.
*/
-static char_u * ex_let_one(arg, tv, copy, endchars, op)
-char_u *arg; /* points to variable name */
-typval_T *tv; /* value to assign to variable */
-int copy; /* copy value from "tv" */
-char_u *endchars; /* valid chars after variable name or NULL */
-char_u *op; /* "+", "-", "." or NULL*/
+static char_u *
+ex_let_one (
+ char_u *arg, /* points to variable name */
+ typval_T *tv, /* value to assign to variable */
+ int copy, /* copy value from "tv" */
+ char_u *endchars, /* valid chars after variable name or NULL */
+ char_u *op /* "+", "-", "." or NULL*/
+)
{
int c1;
char_u *name;
@@ -2278,8 +2273,7 @@ char_u *op; /* "+", "-", "." or NULL*/
/*
* If "arg" is equal to "b:changedtick" give an error and return TRUE.
*/
-static int check_changedtick(arg)
-char_u *arg;
+static int check_changedtick(char_u *arg)
{
if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) {
EMSG2(_(e_readonlyvar), arg);
@@ -2306,14 +2300,16 @@ char_u *arg;
* When an evaluation error occurs "lp->ll_name" is NULL;
* Returns NULL for a parsing error. Still need to free items in "lp"!
*/
-static char_u * get_lval(name, rettv, lp, unlet, skip, flags, fne_flags)
-char_u *name;
-typval_T *rettv;
-lval_T *lp;
-int unlet;
-int skip;
-int flags; /* GLV_ values */
-int fne_flags; /* flags for find_name_end() */
+static char_u *
+get_lval (
+ char_u *name,
+ typval_T *rettv,
+ lval_T *lp,
+ int unlet,
+ int skip,
+ int flags, /* GLV_ values */
+ int fne_flags /* flags for find_name_end() */
+)
{
char_u *p;
char_u *expr_start, *expr_end;
@@ -2608,8 +2604,7 @@ int fne_flags; /* flags for find_name_end() */
/*
* Clear lval "lp" that was filled by get_lval().
*/
-static void clear_lval(lp)
-lval_T *lp;
+static void clear_lval(lval_T *lp)
{
vim_free(lp->ll_exp_name);
vim_free(lp->ll_newkey);
@@ -2620,12 +2615,7 @@ lval_T *lp;
* "endp" points to just after the parsed name.
* "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
*/
-static void set_var_lval(lp, endp, rettv, copy, op)
-lval_T *lp;
-char_u *endp;
-typval_T *rettv;
-int copy;
-char_u *op;
+static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)
{
int cc;
listitem_T *ri;
@@ -2725,10 +2715,7 @@ char_u *op;
* Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
* Returns OK or FAIL.
*/
-static int tv_op(tv1, tv2, op)
-typval_T *tv1;
-typval_T *tv2;
-char_u *op;
+static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
{
long n;
char_u numbuf[NUMBUFLEN];
@@ -2816,9 +2803,7 @@ char_u *op;
/*
* Add a watcher to a list.
*/
-void list_add_watch(l, lw)
-list_T *l;
-listwatch_T *lw;
+void list_add_watch(list_T *l, listwatch_T *lw)
{
lw->lw_next = l->lv_watch;
l->lv_watch = lw;
@@ -2828,9 +2813,7 @@ listwatch_T *lw;
* Remove a watcher from a list.
* No warning when it isn't found...
*/
-void list_rem_watch(l, lwrem)
-list_T *l;
-listwatch_T *lwrem;
+void list_rem_watch(list_T *l, listwatch_T *lwrem)
{
listwatch_T *lw, **lwp;
@@ -2848,9 +2831,7 @@ listwatch_T *lwrem;
* Just before removing an item from a list: advance watchers to the next
* item.
*/
-static void list_fix_watch(l, item)
-list_T *l;
-listitem_T *item;
+static void list_fix_watch(list_T *l, listitem_T *item)
{
listwatch_T *lw;
@@ -2865,11 +2846,7 @@ listitem_T *item;
* Set "*errp" to TRUE for an error, FALSE otherwise;
* Return a pointer that holds the info. Null when there is an error.
*/
-void * eval_for_line(arg, errp, nextcmdp, skip)
-char_u *arg;
-int *errp;
-char_u **nextcmdp;
-int skip;
+void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
{
forinfo_T *fi;
char_u *expr;
@@ -2922,9 +2899,7 @@ int skip;
* Return TRUE when a valid item was found, FALSE when at end of list or
* something wrong.
*/
-int next_for_item(fi_void, arg)
-void *fi_void;
-char_u *arg;
+int next_for_item(void *fi_void, char_u *arg)
{
forinfo_T *fi = (forinfo_T *)fi_void;
int result;
@@ -2944,8 +2919,7 @@ char_u *arg;
/*
* Free the structure used to store info used by ":for".
*/
-void free_for_info(fi_void)
-void *fi_void;
+void free_for_info(void *fi_void)
{
forinfo_T *fi = (forinfo_T *)fi_void;
@@ -2957,10 +2931,7 @@ void *fi_void;
}
-void set_context_for_expression(xp, arg, cmdidx)
-expand_T *xp;
-char_u *arg;
-cmdidx_T cmdidx;
+void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
{
int got_eq = FALSE;
int c;
@@ -3042,8 +3013,7 @@ cmdidx_T cmdidx;
/*
* ":1,25call func(arg1, arg2)" function call.
*/
-void ex_call(eap)
-exarg_T *eap;
+void ex_call(exarg_T *eap)
{
char_u *arg = eap->arg;
char_u *startarg;
@@ -3157,8 +3127,7 @@ end:
/*
* ":unlet[!] var1 ... " command.
*/
-void ex_unlet(eap)
-exarg_T *eap;
+void ex_unlet(exarg_T *eap)
{
ex_unletlock(eap, eap->arg, 0);
}
@@ -3166,8 +3135,7 @@ exarg_T *eap;
/*
* ":lockvar" and ":unlockvar" commands
*/
-void ex_lockvar(eap)
-exarg_T *eap;
+void ex_lockvar(exarg_T *eap)
{
char_u *arg = eap->arg;
int deep = 2;
@@ -3185,10 +3153,7 @@ exarg_T *eap;
/*
* ":unlet", ":lockvar" and ":unlockvar" are quite similar.
*/
-static void ex_unletlock(eap, argstart, deep)
-exarg_T *eap;
-char_u *argstart;
-int deep;
+static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
{
char_u *arg = argstart;
char_u *name_end;
@@ -3232,10 +3197,7 @@ int deep;
eap->nextcmd = check_nextcmd(arg);
}
-static int do_unlet_var(lp, name_end, forceit)
-lval_T *lp;
-char_u *name_end;
-int forceit;
+static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
{
int ret = OK;
int cc;
@@ -3278,9 +3240,7 @@ int forceit;
* "unlet" a variable. Return OK if it existed, FAIL if not.
* When "forceit" is TRUE don't complain if the variable doesn't exist.
*/
-int do_unlet(name, forceit)
-char_u *name;
-int forceit;
+int do_unlet(char_u *name, int forceit)
{
hashtab_T *ht;
hashitem_T *hi;
@@ -3310,11 +3270,7 @@ int forceit;
* "deep" is the levels to go (-1 for unlimited);
* "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
*/
-static int do_lock_var(lp, name_end, deep, lock)
-lval_T *lp;
-char_u *name_end;
-int deep;
-int lock;
+static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock)
{
int ret = OK;
int cc;
@@ -3365,10 +3321,7 @@ int lock;
/*
* Lock or unlock an item. "deep" is nr of levels to go.
*/
-static void item_lock(tv, deep, lock)
-typval_T *tv;
-int deep;
-int lock;
+static void item_lock(typval_T *tv, int deep, int lock)
{
static int recurse = 0;
list_T *l;
@@ -3429,8 +3382,7 @@ int lock;
* Return TRUE if typeval "tv" is locked: Either that value is locked itself
* or it refers to a List or Dictionary that is locked.
*/
-static int tv_islocked(tv)
-typval_T *tv;
+static int tv_islocked(typval_T *tv)
{
return (tv->v_lock & VAR_LOCKED)
|| (tv->v_type == VAR_LIST
@@ -3444,7 +3396,7 @@ typval_T *tv;
/*
* Delete all "menutrans_" variables.
*/
-void del_menutrans_vars() {
+void del_menutrans_vars(void) {
hashitem_T *hi;
int todo;
@@ -3474,9 +3426,7 @@ static int varnamebuflen = 0;
/*
* Function to concatenate a prefix and a variable name.
*/
-static char_u * cat_prefix_varname(prefix, name)
-int prefix;
-char_u *name;
+static char_u *cat_prefix_varname(int prefix, char_u *name)
{
int len;
@@ -3501,9 +3451,7 @@ char_u *name;
* Function given to ExpandGeneric() to obtain the list of user defined
* (global/buffer/window/built-in) variable names.
*/
-char_u * get_user_var_name(xp, idx)
-expand_T *xp;
-int idx;
+char_u *get_user_var_name(expand_T *xp, int idx)
{
static long_u gdone;
static long_u bdone;
@@ -3610,11 +3558,7 @@ typedef enum {
* Note: "rettv.v_lock" is not set.
* Return OK or FAIL.
*/
-static int eval0(arg, rettv, nextcmd, evaluate)
-char_u *arg;
-typval_T *rettv;
-char_u **nextcmd;
-int evaluate;
+static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
{
int ret;
char_u *p;
@@ -3650,10 +3594,7 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval1(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int eval1(char_u **arg, typval_T *rettv, int evaluate)
{
int result;
typval_T var2;
@@ -3718,10 +3659,7 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval2(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int eval2(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
long result;
@@ -3784,10 +3722,7 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval3(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int eval3(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
long result;
@@ -3859,10 +3794,7 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval4(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int eval4(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
char_u *p;
@@ -4121,10 +4053,7 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval5(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int eval5(char_u **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
typval_T var3;
@@ -4268,11 +4197,13 @@ int evaluate;
*
* Return OK or FAIL.
*/
-static int eval6(arg, rettv, evaluate, want_string)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
-int want_string; /* after "." operator */
+static int
+eval6 (
+ char_u **arg,
+ typval_T *rettv,
+ int evaluate,
+ int want_string /* after "." operator */
+)
{
typval_T var2;
int op;
@@ -4403,11 +4334,13 @@ int want_string; /* after "." operator */
*
* Return OK or FAIL.
*/
-static int eval7(arg, rettv, evaluate, want_string)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
-int want_string UNUSED; /* after "." operator */
+static int
+eval7 (
+ char_u **arg,
+ typval_T *rettv,
+ int evaluate,
+ int want_string /* after "." operator */
+)
{
long n;
int len;
@@ -4656,11 +4589,13 @@ int want_string UNUSED; /* after "." operator */
* "*arg" points to the '[' or '.'.
* Returns FAIL or OK. "*arg" is advanced to after the ']'.
*/
-static int eval_index(arg, rettv, evaluate, verbose)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
-int verbose; /* give error messages */
+static int
+eval_index (
+ char_u **arg,
+ typval_T *rettv,
+ int evaluate,
+ int verbose /* give error messages */
+)
{
int empty1 = FALSE, empty2 = FALSE;
typval_T var1, var2;
@@ -4883,10 +4818,12 @@ int verbose; /* give error messages */
* "arg" is advanced to character after the option name.
* Return OK or FAIL.
*/
-static int get_option_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv; /* when NULL, only check if option exists */
-int evaluate;
+static int
+get_option_tv (
+ char_u **arg,
+ typval_T *rettv, /* when NULL, only check if option exists */
+ int evaluate
+)
{
char_u *option_end;
long numval;
@@ -4948,10 +4885,7 @@ int evaluate;
* Allocate a variable for a string constant.
* Return OK or FAIL.
*/
-static int get_string_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
char_u *p;
char_u *name;
@@ -5070,10 +5004,7 @@ int evaluate;
* Allocate a variable for a 'str''ing' constant.
* Return OK or FAIL.
*/
-static int get_lit_string_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
{
char_u *p;
char_u *str;
@@ -5129,10 +5060,7 @@ int evaluate;
* Allocate a variable for a List and fill it from "*arg".
* Return OK or FAIL.
*/
-static int get_list_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
{
list_T *l = NULL;
typval_T tv;
@@ -5189,7 +5117,7 @@ failret:
* Allocate an empty header for a list.
* Caller should take care of the reference count.
*/
-list_T * list_alloc() {
+list_T *list_alloc(void) {
list_T *l;
l = (list_T *)alloc_clear(sizeof(list_T));
@@ -5208,8 +5136,7 @@ list_T * list_alloc() {
* Allocate an empty list for a return value.
* Returns OK or FAIL.
*/
-static int rettv_list_alloc(rettv)
-typval_T *rettv;
+static int rettv_list_alloc(typval_T *rettv)
{
list_T *l = list_alloc();
@@ -5226,8 +5153,7 @@ typval_T *rettv;
* Unreference a list: decrement the reference count and free it when it
* becomes zero.
*/
-void list_unref(l)
-list_T *l;
+void list_unref(list_T *l)
{
if (l != NULL && --l->lv_refcount <= 0)
list_free(l, TRUE);
@@ -5237,9 +5163,11 @@ list_T *l;
* Free a list, including all items it points to.
* Ignores the reference count.
*/
-void list_free(l, recurse)
-list_T *l;
-int recurse; /* Free Lists and Dictionaries recursively. */
+void
+list_free (
+ list_T *l,
+ int recurse /* Free Lists and Dictionaries recursively. */
+)
{
listitem_T *item;
@@ -5265,15 +5193,14 @@ int recurse; /* Free Lists and Dictionaries recursively. */
/*
* Allocate a list item.
*/
-listitem_T * listitem_alloc() {
+listitem_T *listitem_alloc(void) {
return (listitem_T *)alloc(sizeof(listitem_T));
}
/*
* Free a list item. Also clears the value. Does not notify watchers.
*/
-void listitem_free(item)
-listitem_T *item;
+void listitem_free(listitem_T *item)
{
clear_tv(&item->li_tv);
vim_free(item);
@@ -5282,9 +5209,7 @@ listitem_T *item;
/*
* Remove a list item from a List and free it. Also clears the value.
*/
-void listitem_remove(l, item)
-list_T *l;
-listitem_T *item;
+void listitem_remove(list_T *l, listitem_T *item)
{
list_remove(l, item, item);
listitem_free(item);
@@ -5293,8 +5218,7 @@ listitem_T *item;
/*
* Get the number of items in a list.
*/
-static long list_len(l)
-list_T *l;
+static long list_len(list_T *l)
{
if (l == NULL)
return 0L;
@@ -5304,11 +5228,13 @@ list_T *l;
/*
* Return TRUE when two lists have exactly the same values.
*/
-static int list_equal(l1, l2, ic, recursive)
-list_T *l1;
-list_T *l2;
-int ic; /* ignore case for strings */
-int recursive; /* TRUE when used recursively */
+static int
+list_equal (
+ list_T *l1,
+ list_T *l2,
+ int ic, /* ignore case for strings */
+ int recursive /* TRUE when used recursively */
+)
{
listitem_T *item1, *item2;
@@ -5332,8 +5258,7 @@ int recursive; /* TRUE when used recursively */
/*
* Return the dictitem that an entry in a hashtable points to.
*/
-dictitem_T * dict_lookup(hi)
-hashitem_T *hi;
+dictitem_T *dict_lookup(hashitem_T *hi)
{
return HI2DI(hi);
}
@@ -5342,11 +5267,13 @@ hashitem_T *hi;
/*
* Return TRUE when two dictionaries have exactly the same key/values.
*/
-static int dict_equal(d1, d2, ic, recursive)
-dict_T *d1;
-dict_T *d2;
-int ic; /* ignore case for strings */
-int recursive; /* TRUE when used recursively */
+static int
+dict_equal (
+ dict_T *d1,
+ dict_T *d2,
+ int ic, /* ignore case for strings */
+ int recursive /* TRUE when used recursively */
+)
{
hashitem_T *hi;
dictitem_T *item2;
@@ -5380,11 +5307,13 @@ static int tv_equal_recurse_limit;
* Compares the items just like "==" would compare them, but strings and
* numbers are different. Floats and numbers are also different.
*/
-static int tv_equal(tv1, tv2, ic, recursive)
-typval_T *tv1;
-typval_T *tv2;
-int ic; /* ignore case */
-int recursive; /* TRUE when used recursively */
+static int
+tv_equal (
+ typval_T *tv1,
+ typval_T *tv2,
+ int ic, /* ignore case */
+ int recursive /* TRUE when used recursively */
+)
{
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *s1, *s2;
@@ -5446,9 +5375,7 @@ int recursive; /* TRUE when used recursively */
* A negative index is counted from the end; -1 is the last item.
* Returns NULL when "n" is out of range.
*/
-listitem_T * list_find(l, n)
-list_T *l;
-long n;
+listitem_T *list_find(list_T *l, long n)
{
listitem_T *item;
long idx;
@@ -5512,10 +5439,12 @@ long n;
/*
* Get list item "l[idx]" as a number.
*/
-static long list_find_nr(l, idx, errorp)
-list_T *l;
-long idx;
-int *errorp; /* set to TRUE when something wrong */
+static long
+list_find_nr (
+ list_T *l,
+ long idx,
+ int *errorp /* set to TRUE when something wrong */
+)
{
listitem_T *li;
@@ -5531,9 +5460,7 @@ int *errorp; /* set to TRUE when something wrong */
/*
* Get list item "l[idx - 1]" as a string. Returns NULL for failure.
*/
-char_u * list_find_str(l, idx)
-list_T *l;
-long idx;
+char_u *list_find_str(list_T *l, long idx)
{
listitem_T *li;
@@ -5549,9 +5476,7 @@ long idx;
* Locate "item" list "l" and return its index.
* Returns -1 when "item" is not in the list.
*/
-static long list_idx_of_item(l, item)
-list_T *l;
-listitem_T *item;
+static long list_idx_of_item(list_T *l, listitem_T *item)
{
long idx = 0;
listitem_T *li;
@@ -5569,9 +5494,7 @@ listitem_T *item;
/*
* Append item "item" to the end of list "l".
*/
-void list_append(l, item)
-list_T *l;
-listitem_T *item;
+void list_append(list_T *l, listitem_T *item)
{
if (l->lv_last == NULL) {
/* empty list */
@@ -5591,9 +5514,7 @@ listitem_T *item;
* Append typval_T "tv" to the end of list "l".
* Return FAIL when out of memory.
*/
-int list_append_tv(l, tv)
-list_T *l;
-typval_T *tv;
+int list_append_tv(list_T *l, typval_T *tv)
{
listitem_T *li = listitem_alloc();
@@ -5608,9 +5529,7 @@ typval_T *tv;
* Add a dictionary to a list. Used by getqflist().
* Return FAIL when out of memory.
*/
-int list_append_dict(list, dict)
-list_T *list;
-dict_T *dict;
+int list_append_dict(list_T *list, dict_T *dict)
{
listitem_T *li = listitem_alloc();
@@ -5629,10 +5548,7 @@ dict_T *dict;
* When "len" >= 0 use "str[len]".
* Returns FAIL when out of memory.
*/
-int list_append_string(l, str, len)
-list_T *l;
-char_u *str;
-int len;
+int list_append_string(list_T *l, char_u *str, int len)
{
listitem_T *li = listitem_alloc();
@@ -5653,9 +5569,7 @@ int len;
* Append "n" to list "l".
* Returns FAIL when out of memory.
*/
-static int list_append_number(l, n)
-list_T *l;
-varnumber_T n;
+static int list_append_number(list_T *l, varnumber_T n)
{
listitem_T *li;
@@ -5674,10 +5588,7 @@ varnumber_T n;
* If "item" is NULL append at the end.
* Return FAIL when out of memory.
*/
-int list_insert_tv(l, tv, item)
-list_T *l;
-typval_T *tv;
-listitem_T *item;
+int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
{
listitem_T *ni = listitem_alloc();
@@ -5688,10 +5599,7 @@ listitem_T *item;
return OK;
}
-void list_insert(l, ni, item)
-list_T *l;
-listitem_T *ni;
-listitem_T *item;
+void list_insert(list_T *l, listitem_T *ni, listitem_T *item)
{
if (item == NULL)
/* Append new item at end of list. */
@@ -5717,10 +5625,7 @@ listitem_T *item;
* If "bef" is NULL append at the end, otherwise insert before this item.
* Returns FAIL when out of memory.
*/
-static int list_extend(l1, l2, bef)
-list_T *l1;
-list_T *l2;
-listitem_T *bef;
+static int list_extend(list_T *l1, list_T *l2, listitem_T *bef)
{
listitem_T *item;
int todo = l2->lv_len;
@@ -5737,10 +5642,7 @@ listitem_T *bef;
* Concatenate lists "l1" and "l2" into a new list, stored in "tv".
* Return FAIL when out of memory.
*/
-static int list_concat(l1, l2, tv)
-list_T *l1;
-list_T *l2;
-typval_T *tv;
+static int list_concat(list_T *l1, list_T *l2, typval_T *tv)
{
list_T *l;
@@ -5764,10 +5666,7 @@ typval_T *tv;
* See item_copy() for "copyID".
* Returns NULL when out of memory.
*/
-static list_T * list_copy(orig, deep, copyID)
-list_T *orig;
-int deep;
-int copyID;
+static list_T *list_copy(list_T *orig, int deep, int copyID)
{
list_T *copy;
listitem_T *item;
@@ -5812,10 +5711,7 @@ int copyID;
* Remove items "item" to "item2" from list "l".
* Does not free the listitem or the value!
*/
-void list_remove(l, item, item2)
-list_T *l;
-listitem_T *item;
-listitem_T *item2;
+void list_remove(list_T *l, listitem_T *item, listitem_T *item2)
{
listitem_T *ip;
@@ -5842,9 +5738,7 @@ listitem_T *item2;
* Return an allocated string with the string representation of a list.
* May return NULL.
*/
-static char_u * list2string(tv, copyID)
-typval_T *tv;
-int copyID;
+static char_u *list2string(typval_T *tv, int copyID)
{
garray_T ga;
@@ -5866,13 +5760,15 @@ typedef struct join_S {
char_u *tofree;
} join_T;
-static int list_join_inner(gap, l, sep, echo_style, copyID, join_gap)
-garray_T *gap; /* to store the result in */
-list_T *l;
-char_u *sep;
-int echo_style;
-int copyID;
-garray_T *join_gap; /* to keep each list item string */
+static int
+list_join_inner (
+ garray_T *gap, /* to store the result in */
+ list_T *l,
+ char_u *sep,
+ int echo_style,
+ int copyID,
+ garray_T *join_gap /* to keep each list item string */
+)
{
int i;
join_T *p;
@@ -5936,12 +5832,7 @@ garray_T *join_gap; /* to keep each list item string */
* When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
* Return FAIL or OK.
*/
-static int list_join(gap, l, sep, echo_style, copyID)
-garray_T *gap;
-list_T *l;
-char_u *sep;
-int echo_style;
-int copyID;
+static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID)
{
garray_T join_ga;
int retval;
@@ -5988,7 +5879,7 @@ int copyID;
* Do garbage collection for lists and dicts.
* Return TRUE if some memory was freed.
*/
-int garbage_collect() {
+int garbage_collect(void) {
int copyID;
buf_T *buf;
win_T *wp;
@@ -6083,8 +5974,7 @@ int garbage_collect() {
/*
* Free lists and dictionaries that are no longer referenced.
*/
-static int free_unref_items(copyID)
-int copyID;
+static int free_unref_items(int copyID)
{
dict_T *dd;
list_T *ll;
@@ -6131,9 +6021,7 @@ int copyID;
/*
* Mark all lists and dicts referenced through hashtab "ht" with "copyID".
*/
-void set_ref_in_ht(ht, copyID)
-hashtab_T *ht;
-int copyID;
+void set_ref_in_ht(hashtab_T *ht, int copyID)
{
int todo;
hashitem_T *hi;
@@ -6149,9 +6037,7 @@ int copyID;
/*
* Mark all lists and dicts referenced through list "l" with "copyID".
*/
-void set_ref_in_list(l, copyID)
-list_T *l;
-int copyID;
+void set_ref_in_list(list_T *l, int copyID)
{
listitem_T *li;
@@ -6162,9 +6048,7 @@ int copyID;
/*
* Mark all lists and dicts referenced through typval "tv" with "copyID".
*/
-void set_ref_in_item(tv, copyID)
-typval_T *tv;
-int copyID;
+void set_ref_in_item(typval_T *tv, int copyID)
{
dict_T *dd;
list_T *ll;
@@ -6194,7 +6078,7 @@ int copyID;
/*
* Allocate an empty header for a dictionary.
*/
-dict_T * dict_alloc() {
+dict_T *dict_alloc(void) {
dict_T *d;
d = (dict_T *)alloc(sizeof(dict_T));
@@ -6219,8 +6103,7 @@ dict_T * dict_alloc() {
* Allocate an empty dict for a return value.
* Returns OK or FAIL.
*/
-static int rettv_dict_alloc(rettv)
-typval_T *rettv;
+static int rettv_dict_alloc(typval_T *rettv)
{
dict_T *d = dict_alloc();
@@ -6238,8 +6121,7 @@ typval_T *rettv;
* Unreference a Dictionary: decrement the reference count and free it when it
* becomes zero.
*/
-void dict_unref(d)
-dict_T *d;
+void dict_unref(dict_T *d)
{
if (d != NULL && --d->dv_refcount <= 0)
dict_free(d, TRUE);
@@ -6249,9 +6131,11 @@ dict_T *d;
* Free a Dictionary, including all items it contains.
* Ignores the reference count.
*/
-void dict_free(d, recurse)
-dict_T *d;
-int recurse; /* Free Lists and Dictionaries recursively. */
+void
+dict_free (
+ dict_T *d,
+ int recurse /* Free Lists and Dictionaries recursively. */
+)
{
int todo;
hashitem_T *hi;
@@ -6291,8 +6175,7 @@ int recurse; /* Free Lists and Dictionaries recursively. */
* Note that the value of the item "di_tv" still needs to be initialized!
* Returns NULL when out of memory.
*/
-dictitem_T * dictitem_alloc(key)
-char_u *key;
+dictitem_T *dictitem_alloc(char_u *key)
{
dictitem_T *di;
@@ -6307,8 +6190,7 @@ char_u *key;
/*
* Make a copy of a Dictionary item.
*/
-static dictitem_T * dictitem_copy(org)
-dictitem_T *org;
+static dictitem_T *dictitem_copy(dictitem_T *org)
{
dictitem_T *di;
@@ -6325,9 +6207,7 @@ dictitem_T *org;
/*
* Remove item "item" from Dictionary "dict" and free it.
*/
-static void dictitem_remove(dict, item)
-dict_T *dict;
-dictitem_T *item;
+static void dictitem_remove(dict_T *dict, dictitem_T *item)
{
hashitem_T *hi;
@@ -6342,8 +6222,7 @@ dictitem_T *item;
/*
* Free a dict item. Also clears the value.
*/
-void dictitem_free(item)
-dictitem_T *item;
+void dictitem_free(dictitem_T *item)
{
clear_tv(&item->di_tv);
vim_free(item);
@@ -6355,10 +6234,7 @@ dictitem_T *item;
* See item_copy() for "copyID".
* Returns NULL when out of memory.
*/
-static dict_T * dict_copy(orig, deep, copyID)
-dict_T *orig;
-int deep;
-int copyID;
+static dict_T *dict_copy(dict_T *orig, int deep, int copyID)
{
dict_T *copy;
dictitem_T *di;
@@ -6411,9 +6287,7 @@ int copyID;
* Add item "item" to Dictionary "d".
* Returns FAIL when out of memory and when key already exists.
*/
-int dict_add(d, item)
-dict_T *d;
-dictitem_T *item;
+int dict_add(dict_T *d, dictitem_T *item)
{
return hash_add(&d->dv_hashtab, item->di_key);
}
@@ -6423,11 +6297,7 @@ dictitem_T *item;
* When "str" is NULL use number "nr", otherwise use "str".
* Returns FAIL when out of memory and when key already exists.
*/
-int dict_add_nr_str(d, key, nr, str)
-dict_T *d;
-char *key;
-long nr;
-char_u *str;
+int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str)
{
dictitem_T *item;
@@ -6453,10 +6323,7 @@ char_u *str;
* Add a list entry to dictionary "d".
* Returns FAIL when out of memory and when key already exists.
*/
-int dict_add_list(d, key, list)
-dict_T *d;
-char *key;
-list_T *list;
+int dict_add_list(dict_T *d, char *key, list_T *list)
{
dictitem_T *item;
@@ -6477,8 +6344,7 @@ list_T *list;
/*
* Get the number of items in a Dictionary.
*/
-static long dict_len(d)
-dict_T *d;
+static long dict_len(dict_T *d)
{
if (d == NULL)
return 0L;
@@ -6490,10 +6356,7 @@ dict_T *d;
* If "len" is negative use strlen(key).
* Returns NULL when not found.
*/
-dictitem_T * dict_find(d, key, len)
-dict_T *d;
-char_u *key;
-int len;
+dictitem_T *dict_find(dict_T *d, char_u *key, int len)
{
#define AKEYLEN 200
char_u buf[AKEYLEN];
@@ -6525,10 +6388,7 @@ int len;
* When "save" is TRUE allocate memory for it.
* Returns NULL if the entry doesn't exist or out of memory.
*/
-char_u * get_dict_string(d, key, save)
-dict_T *d;
-char_u *key;
-int save;
+char_u *get_dict_string(dict_T *d, char_u *key, int save)
{
dictitem_T *di;
char_u *s;
@@ -6546,9 +6406,7 @@ int save;
* Get a number item from a dictionary.
* Returns 0 if the entry doesn't exist or out of memory.
*/
-long get_dict_number(d, key)
-dict_T *d;
-char_u *key;
+long get_dict_number(dict_T *d, char_u *key)
{
dictitem_T *di;
@@ -6562,9 +6420,7 @@ char_u *key;
* Return an allocated string with the string representation of a Dictionary.
* May return NULL.
*/
-static char_u * dict2string(tv, copyID)
-typval_T *tv;
-int copyID;
+static char_u *dict2string(typval_T *tv, int copyID)
{
garray_T ga;
int first = TRUE;
@@ -6618,10 +6474,7 @@ int copyID;
* Allocate a variable for a Dictionary and fill it from "*arg".
* Return OK or FAIL. Returns NOTDONE for {expr}.
*/
-static int get_dict_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
{
dict_T *d = NULL;
typval_T tvkey;
@@ -6732,11 +6585,7 @@ failret:
* When "copyID" is not NULL replace recursive lists and dicts with "...".
* May return NULL.
*/
-static char_u * echo_string(tv, tofree, numbuf, copyID)
-typval_T *tv;
-char_u **tofree;
-char_u *numbuf;
-int copyID;
+static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)
{
static int recurse = 0;
char_u *r = NULL;
@@ -6810,11 +6659,7 @@ int copyID;
* Puts quotes around strings, so that they can be parsed back by eval().
* May return NULL.
*/
-static char_u * tv2string(tv, tofree, numbuf, copyID)
-typval_T *tv;
-char_u **tofree;
-char_u *numbuf;
-int copyID;
+static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID)
{
switch (tv->v_type) {
case VAR_FUNC:
@@ -6842,9 +6687,7 @@ int copyID;
* If "str" is NULL an empty string is assumed.
* If "function" is TRUE make it function('string').
*/
-static char_u * string_quote(str, function)
-char_u *str;
-int function;
+static char_u *string_quote(char_u *str, int function)
{
unsigned len;
char_u *p, *r, *s;
@@ -6883,9 +6726,11 @@ int function;
* this always uses a decimal point.
* Returns the length of the text that was consumed.
*/
-static int string2float(text, value)
-char_u *text;
-float_T *value; /* result stored here */
+static int
+string2float (
+ char_u *text,
+ float_T *value /* result stored here */
+)
{
char *s = (char *)text;
float_T f;
@@ -6901,10 +6746,7 @@ float_T *value; /* result stored here */
* If the environment variable was not set, silently assume it is empty.
* Always return OK.
*/
-static int get_env_tv(arg, rettv, evaluate)
-char_u **arg;
-typval_T *rettv;
-int evaluate;
+static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
{
char_u *string = NULL;
int len;
@@ -7233,9 +7075,7 @@ static struct fst {
* Function given to ExpandGeneric() to obtain the list of internal
* or user defined function names.
*/
-char_u * get_function_name(xp, idx)
-expand_T *xp;
-int idx;
+char_u *get_function_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -7262,9 +7102,7 @@ int idx;
* Function given to ExpandGeneric() to obtain the list of internal or
* user defined variable or function names.
*/
-char_u * get_expr_name(xp, idx)
-expand_T *xp;
-int idx;
+char_u *get_expr_name(expand_T *xp, int idx)
{
static int intidx = -1;
char_u *name;
@@ -7286,8 +7124,10 @@ int idx;
* Find internal function in table above.
* Return index, or -1 if not found
*/
-static int find_internal_func(name)
-char_u *name; /* name of the function */
+static int
+find_internal_func (
+ char_u *name /* name of the function */
+)
{
int first = 0;
int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1;
@@ -7314,10 +7154,7 @@ char_u *name; /* name of the function */
* Check if "name" is a variable of type VAR_FUNC. If so, return the function
* name it contains, otherwise return "name".
*/
-static char_u * deref_func_name(name, lenp, no_autoload)
-char_u *name;
-int *lenp;
-int no_autoload;
+static char_u *deref_func_name(char_u *name, int *lenp, int no_autoload)
{
dictitem_T *v;
int cc;
@@ -7342,17 +7179,18 @@ int no_autoload;
* Allocate a variable for the result of a function.
* Return OK or FAIL.
*/
-static int get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange,
- evaluate, selfdict)
-char_u *name; /* name of the function */
-int len; /* length of "name" */
-typval_T *rettv;
-char_u **arg; /* argument, pointing to the '(' */
-linenr_T firstline; /* first line of range */
-linenr_T lastline; /* last line of range */
-int *doesrange; /* return: function handled range */
-int evaluate;
-dict_T *selfdict; /* Dictionary for "self" */
+static int
+get_func_tv (
+ char_u *name, /* name of the function */
+ int len, /* length of "name" */
+ typval_T *rettv,
+ char_u **arg, /* argument, pointing to the '(' */
+ linenr_T firstline, /* first line of range */
+ linenr_T lastline, /* last line of range */
+ int *doesrange, /* return: function handled range */
+ int evaluate,
+ dict_T *selfdict /* Dictionary for "self" */
+)
{
char_u *argp;
int ret = OK;
@@ -7403,21 +7241,20 @@ dict_T *selfdict; /* Dictionary for "self" */
* Return FAIL when the function can't be called, OK otherwise.
* Also returns OK when an error was encountered while executing the function.
*/
-static int call_func(funcname, len, rettv, argcount, argvars, firstline,
- lastline,
- doesrange, evaluate,
- selfdict)
-char_u *funcname; /* name of the function */
-int len; /* length of "name" */
-typval_T *rettv; /* return value goes here */
-int argcount; /* number of "argvars" */
-typval_T *argvars; /* vars for arguments, must have "argcount"
+static int
+call_func (
+ char_u *funcname, /* name of the function */
+ int len, /* length of "name" */
+ typval_T *rettv, /* return value goes here */
+ int argcount, /* number of "argvars" */
+ typval_T *argvars, /* vars for arguments, must have "argcount"
PLUS ONE elements! */
-linenr_T firstline; /* first line of range */
-linenr_T lastline; /* last line of range */
-int *doesrange; /* return: function handled range */
-int evaluate;
-dict_T *selfdict; /* Dictionary for "self" */
+ linenr_T firstline, /* first line of range */
+ linenr_T lastline, /* last line of range */
+ int *doesrange, /* return: function handled range */
+ int evaluate,
+ dict_T *selfdict /* Dictionary for "self" */
+)
{
int ret = FAIL;
#define ERROR_UNKNOWN 0
@@ -7606,9 +7443,7 @@ dict_T *selfdict; /* Dictionary for "self" */
* Give an error message with a function name. Handle <SNR> things.
* "ermsg" is to be passed without translation, use N_() instead of _().
*/
-static void emsg_funcname(ermsg, name)
-char *ermsg;
-char_u *name;
+static void emsg_funcname(char *ermsg, char_u *name)
{
char_u *p;
@@ -7624,8 +7459,7 @@ char_u *name;
/*
* Return TRUE for a non-zero Number and a non-empty String.
*/
-static int non_zero_arg(argvars)
-typval_T *argvars;
+static int non_zero_arg(typval_T *argvars)
{
return (argvars[0].v_type == VAR_NUMBER
&& argvars[0].vval.v_number != 0)
@@ -7644,9 +7478,7 @@ static int get_float_arg __ARGS((typval_T *argvars, float_T *f));
* Get the float value of "argvars[0]" into "f".
* Returns FAIL when the argument is not a Number or Float.
*/
-static int get_float_arg(argvars, f)
-typval_T *argvars;
-float_T *f;
+static int get_float_arg(typval_T *argvars, float_T *f)
{
if (argvars[0].v_type == VAR_FLOAT) {
*f = argvars[0].vval.v_float;
@@ -7663,9 +7495,7 @@ float_T *f;
/*
* "abs(expr)" function
*/
-static void f_abs(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_abs(typval_T *argvars, typval_T *rettv)
{
if (argvars[0].v_type == VAR_FLOAT) {
rettv->v_type = VAR_FLOAT;
@@ -7687,9 +7517,7 @@ typval_T *rettv;
/*
* "acos()" function
*/
-static void f_acos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_acos(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -7703,9 +7531,7 @@ typval_T *rettv;
/*
* "add(list, item)" function
*/
-static void f_add(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_add(typval_T *argvars, typval_T *rettv)
{
list_T *l;
@@ -7722,9 +7548,7 @@ typval_T *rettv;
/*
* "and(expr, expr)" function
*/
-static void f_and(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_and(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
& get_tv_number_chk(&argvars[1], NULL);
@@ -7733,9 +7557,7 @@ typval_T *rettv;
/*
* "append(lnum, string/list)" function
*/
-static void f_append(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_append(typval_T *argvars, typval_T *rettv)
{
long lnum;
char_u *line;
@@ -7790,9 +7612,7 @@ typval_T *rettv;
/*
* "argc()" function
*/
-static void f_argc(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_argc(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = ARGCOUNT;
}
@@ -7800,9 +7620,7 @@ typval_T *rettv;
/*
* "argidx()" function
*/
-static void f_argidx(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_argidx(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = curwin->w_arg_idx;
}
@@ -7810,9 +7628,7 @@ typval_T *rettv;
/*
* "argv(nr)" function
*/
-static void f_argv(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_argv(typval_T *argvars, typval_T *rettv)
{
int idx;
@@ -7832,9 +7648,7 @@ typval_T *rettv;
/*
* "asin()" function
*/
-static void f_asin(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_asin(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -7848,9 +7662,7 @@ typval_T *rettv;
/*
* "atan()" function
*/
-static void f_atan(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_atan(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -7864,9 +7676,7 @@ typval_T *rettv;
/*
* "atan2()" function
*/
-static void f_atan2(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_atan2(typval_T *argvars, typval_T *rettv)
{
float_T fx, fy;
@@ -7881,9 +7691,7 @@ typval_T *rettv;
/*
* "browse(save, title, initdir, default)" function
*/
-static void f_browse(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_browse(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
@@ -7892,9 +7700,7 @@ typval_T *rettv;
/*
* "browsedir(title, initdir)" function
*/
-static void f_browsedir(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_browsedir(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
@@ -7905,8 +7711,7 @@ static buf_T *find_buffer __ARGS((typval_T *avar));
/*
* Find a buffer by number or exact name.
*/
-static buf_T * find_buffer(avar)
-typval_T *avar;
+static buf_T *find_buffer(typval_T *avar)
{
buf_T *buf = NULL;
@@ -7932,9 +7737,7 @@ typval_T *avar;
/*
* "bufexists(expr)" function
*/
-static void f_bufexists(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_bufexists(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
}
@@ -7942,9 +7745,7 @@ typval_T *rettv;
/*
* "buflisted(expr)" function
*/
-static void f_buflisted(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_buflisted(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
@@ -7955,9 +7756,7 @@ typval_T *rettv;
/*
* "bufloaded(expr)" function
*/
-static void f_bufloaded(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_bufloaded(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
@@ -7970,9 +7769,7 @@ static buf_T *get_buf_tv __ARGS((typval_T *tv, int curtab_only));
/*
* Get buffer by number or pattern.
*/
-static buf_T * get_buf_tv(tv, curtab_only)
-typval_T *tv;
-int curtab_only;
+static buf_T *get_buf_tv(typval_T *tv, int curtab_only)
{
char_u *name = tv->vval.v_string;
int save_magic;
@@ -8010,9 +7807,7 @@ int curtab_only;
/*
* "bufname(expr)" function
*/
-static void f_bufname(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_bufname(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
@@ -8030,9 +7825,7 @@ typval_T *rettv;
/*
* "bufnr(expr)" function
*/
-static void f_bufnr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_bufnr(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
int error = FALSE;
@@ -8062,9 +7855,7 @@ typval_T *rettv;
/*
* "bufwinnr(nr)" function
*/
-static void f_bufwinnr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_bufwinnr(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
int winnr = 0;
@@ -8085,9 +7876,7 @@ typval_T *rettv;
/*
* "byte2line(byte)" function
*/
-static void f_byte2line(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_byte2line(typval_T *argvars, typval_T *rettv)
{
long boff = 0;
@@ -8099,10 +7888,7 @@ typval_T *rettv;
(linenr_T)0, &boff);
}
-static void byteidx(argvars, rettv, comp)
-typval_T *argvars;
-typval_T *rettv;
-int comp;
+static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
{
char_u *t;
char_u *str;
@@ -8129,9 +7915,7 @@ int comp;
/*
* "byteidx()" function
*/
-static void f_byteidx(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_byteidx(typval_T *argvars, typval_T *rettv)
{
byteidx(argvars, rettv, FALSE);
}
@@ -8139,18 +7923,12 @@ typval_T *rettv;
/*
* "byteidxcomp()" function
*/
-static void f_byteidxcomp(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_byteidxcomp(typval_T *argvars, typval_T *rettv)
{
byteidx(argvars, rettv, TRUE);
}
-int func_call(name, args, selfdict, rettv)
-char_u *name;
-typval_T *args;
-dict_T *selfdict;
-typval_T *rettv;
+int func_call(char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv)
{
listitem_T *item;
typval_T argv[MAX_FUNC_ARGS + 1];
@@ -8185,9 +7963,7 @@ typval_T *rettv;
/*
* "call(func, arglist)" function
*/
-static void f_call(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_call(typval_T *argvars, typval_T *rettv)
{
char_u *func;
dict_T *selfdict = NULL;
@@ -8220,9 +7996,7 @@ typval_T *rettv;
/*
* "ceil({float})" function
*/
-static void f_ceil(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_ceil(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -8236,9 +8010,7 @@ typval_T *rettv;
/*
* "changenr()" function
*/
-static void f_changenr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_changenr(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = curbuf->b_u_seq_cur;
}
@@ -8246,9 +8018,7 @@ typval_T *rettv;
/*
* "char2nr(string)" function
*/
-static void f_char2nr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_char2nr(typval_T *argvars, typval_T *rettv)
{
if (has_mbyte) {
int utf8 = 0;
@@ -8267,9 +8037,7 @@ typval_T *rettv;
/*
* "cindent(lnum)" function
*/
-static void f_cindent(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_cindent(typval_T *argvars, typval_T *rettv)
{
pos_T pos;
linenr_T lnum;
@@ -8287,9 +8055,7 @@ typval_T *rettv;
/*
* "clearmatches()" function
*/
-static void f_clearmatches(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_clearmatches(typval_T *argvars, typval_T *rettv)
{
clear_matches(curwin);
}
@@ -8297,9 +8063,7 @@ typval_T *rettv UNUSED;
/*
* "col(string)" function
*/
-static void f_col(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_col(typval_T *argvars, typval_T *rettv)
{
colnr_T col = 0;
pos_T *fp;
@@ -8336,9 +8100,7 @@ typval_T *rettv;
/*
* "complete()" function
*/
-static void f_complete(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv UNUSED;
+static void f_complete(typval_T *argvars, typval_T *rettv)
{
int startcol;
@@ -8367,9 +8129,7 @@ typval_T *rettv UNUSED;
/*
* "complete_add()" function
*/
-static void f_complete_add(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_complete_add(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
}
@@ -8377,9 +8137,7 @@ typval_T *rettv;
/*
* "complete_check()" function
*/
-static void f_complete_check(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_complete_check(typval_T *argvars, typval_T *rettv)
{
int saved = RedrawingDisabled;
@@ -8392,9 +8150,7 @@ typval_T *rettv;
/*
* "confirm(message, buttons[, default [, type]])" function
*/
-static void f_confirm(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_confirm(typval_T *argvars, typval_T *rettv)
{
char_u *message;
char_u *buttons = NULL;
@@ -8442,9 +8198,7 @@ typval_T *rettv UNUSED;
/*
* "copy()" function
*/
-static void f_copy(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_copy(typval_T *argvars, typval_T *rettv)
{
item_copy(&argvars[0], rettv, FALSE, 0);
}
@@ -8452,9 +8206,7 @@ typval_T *rettv;
/*
* "cos()" function
*/
-static void f_cos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_cos(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -8468,9 +8220,7 @@ typval_T *rettv;
/*
* "cosh()" function
*/
-static void f_cosh(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_cosh(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -8484,9 +8234,7 @@ typval_T *rettv;
/*
* "count()" function
*/
-static void f_count(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_count(typval_T *argvars, typval_T *rettv)
{
long n = 0;
int ic = FALSE;
@@ -8551,9 +8299,7 @@ typval_T *rettv;
*
* Checks the existence of a cscope connection.
*/
-static void f_cscope_connection(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_cscope_connection(typval_T *argvars, typval_T *rettv)
{
int num = 0;
char_u *dbpath = NULL;
@@ -8577,9 +8323,7 @@ typval_T *rettv UNUSED;
* Moves the cursor to the specified line and column.
* Returns 0 when the position could be set, -1 otherwise.
*/
-static void f_cursor(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_cursor(typval_T *argvars, typval_T *rettv)
{
long line, col;
long coladd = 0;
@@ -8622,9 +8366,7 @@ typval_T *rettv;
/*
* "deepcopy()" function
*/
-static void f_deepcopy(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_deepcopy(typval_T *argvars, typval_T *rettv)
{
int noref = 0;
@@ -8641,9 +8383,7 @@ typval_T *rettv;
/*
* "delete()" function
*/
-static void f_delete(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_delete(typval_T *argvars, typval_T *rettv)
{
if (check_restricted() || check_secure())
rettv->vval.v_number = -1;
@@ -8654,9 +8394,7 @@ typval_T *rettv;
/*
* "did_filetype()" function
*/
-static void f_did_filetype(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_did_filetype(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = did_filetype;
}
@@ -8664,9 +8402,7 @@ typval_T *rettv UNUSED;
/*
* "diff_filler()" function
*/
-static void f_diff_filler(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_diff_filler(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
}
@@ -8674,9 +8410,7 @@ typval_T *rettv UNUSED;
/*
* "diff_hlID()" function
*/
-static void f_diff_hlID(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_diff_hlID(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum = get_tv_lnum(argvars);
static linenr_T prev_lnum = 0;
@@ -8725,9 +8459,7 @@ typval_T *rettv UNUSED;
/*
* "empty({expr})" function
*/
-static void f_empty(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_empty(typval_T *argvars, typval_T *rettv)
{
int n;
@@ -8762,9 +8494,7 @@ typval_T *rettv;
/*
* "escape({string}, {chars})" function
*/
-static void f_escape(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_escape(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
@@ -8776,9 +8506,7 @@ typval_T *rettv;
/*
* "eval()" function
*/
-static void f_eval(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_eval(typval_T *argvars, typval_T *rettv)
{
char_u *s;
@@ -8796,9 +8524,7 @@ typval_T *rettv;
/*
* "eventhandler()" function
*/
-static void f_eventhandler(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_eventhandler(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = vgetc_busy;
}
@@ -8806,9 +8532,7 @@ typval_T *rettv;
/*
* "executable()" function
*/
-static void f_executable(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_executable(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0]));
}
@@ -8816,9 +8540,7 @@ typval_T *rettv;
/*
* "exists()" function
*/
-static void f_exists(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_exists(typval_T *argvars, typval_T *rettv)
{
char_u *p;
char_u *name;
@@ -8880,9 +8602,7 @@ typval_T *rettv;
/*
* "exp()" function
*/
-static void f_exp(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_exp(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -8896,9 +8616,7 @@ typval_T *rettv;
/*
* "expand()" function
*/
-static void f_expand(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_expand(typval_T *argvars, typval_T *rettv)
{
char_u *s;
int len;
@@ -8962,10 +8680,7 @@ typval_T *rettv;
* When "action" is "force" then a duplicate key is overwritten.
* Otherwise duplicate keys are ignored ("action" is "keep").
*/
-void dict_extend(d1, d2, action)
-dict_T *d1;
-dict_T *d2;
-char_u *action;
+void dict_extend(dict_T *d1, dict_T *d2, char_u *action)
{
dictitem_T *di1;
hashitem_T *hi2;
@@ -9007,9 +8722,7 @@ char_u *action;
* "extend(list, list [, idx])" function
* "extend(dict, dict [, action])" function
*/
-static void f_extend(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_extend(typval_T *argvars, typval_T *rettv)
{
char *arg_errmsg = N_("extend() argument");
@@ -9081,9 +8794,7 @@ typval_T *rettv;
/*
* "feedkeys()" function
*/
-static void f_feedkeys(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv UNUSED;
+static void f_feedkeys(typval_T *argvars, typval_T *rettv)
{
int remap = TRUE;
char_u *keys, *flags;
@@ -9126,9 +8837,7 @@ typval_T *rettv UNUSED;
/*
* "filereadable()" function
*/
-static void f_filereadable(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_filereadable(typval_T *argvars, typval_T *rettv)
{
int fd;
char_u *p;
@@ -9152,9 +8861,7 @@ typval_T *rettv;
* Return 0 for not writable, 1 for writable file, 2 for a dir which we have
* rights to write into.
*/
-static void f_filewritable(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_filewritable(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
}
@@ -9162,10 +8869,7 @@ typval_T *rettv;
static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv,
int find_what));
-static void findfilendir(argvars, rettv, find_what)
-typval_T *argvars UNUSED;
-typval_T *rettv;
-int find_what UNUSED;
+static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
{
char_u *fname;
char_u *fresult = NULL;
@@ -9227,10 +8931,7 @@ static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map,
/*
* Implementation of map() and filter().
*/
-static void filter_map(argvars, rettv, map)
-typval_T *argvars;
-typval_T *rettv;
-int map;
+static void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
char_u buf[NUMBUFLEN];
char_u *expr;
@@ -9326,11 +9027,7 @@ int map;
copy_tv(&argvars[0], rettv);
}
-static int filter_map_one(tv, expr, map, remp)
-typval_T *tv;
-char_u *expr;
-int map;
-int *remp;
+static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp)
{
typval_T rettv;
char_u *s;
@@ -9369,9 +9066,7 @@ theend:
/*
* "filter()" function
*/
-static void f_filter(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_filter(typval_T *argvars, typval_T *rettv)
{
filter_map(argvars, rettv, FALSE);
}
@@ -9379,9 +9074,7 @@ typval_T *rettv;
/*
* "finddir({fname}[, {path}[, {count}]])" function
*/
-static void f_finddir(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_finddir(typval_T *argvars, typval_T *rettv)
{
findfilendir(argvars, rettv, FINDFILE_DIR);
}
@@ -9389,9 +9082,7 @@ typval_T *rettv;
/*
* "findfile({fname}[, {path}[, {count}]])" function
*/
-static void f_findfile(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_findfile(typval_T *argvars, typval_T *rettv)
{
findfilendir(argvars, rettv, FINDFILE_FILE);
}
@@ -9399,9 +9090,7 @@ typval_T *rettv;
/*
* "float2nr({float})" function
*/
-static void f_float2nr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_float2nr(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -9418,9 +9107,7 @@ typval_T *rettv;
/*
* "floor({float})" function
*/
-static void f_floor(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_floor(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -9434,9 +9121,7 @@ typval_T *rettv;
/*
* "fmod()" function
*/
-static void f_fmod(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_fmod(typval_T *argvars, typval_T *rettv)
{
float_T fx, fy;
@@ -9451,9 +9136,7 @@ typval_T *rettv;
/*
* "fnameescape({string})" function
*/
-static void f_fnameescape(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_fnameescape(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_string = vim_strsave_fnameescape(
get_tv_string(&argvars[0]), FALSE);
@@ -9463,9 +9146,7 @@ typval_T *rettv;
/*
* "fnamemodify({fname}, {mods})" function
*/
-static void f_fnamemodify(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_fnamemodify(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
char_u *mods;
@@ -9496,10 +9177,7 @@ static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)
/*
* "foldclosed()" function
*/
-static void foldclosed_both(argvars, rettv, end)
-typval_T *argvars UNUSED;
-typval_T *rettv;
-int end UNUSED;
+static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
linenr_T lnum;
linenr_T first, last;
@@ -9520,9 +9198,7 @@ int end UNUSED;
/*
* "foldclosed()" function
*/
-static void f_foldclosed(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_foldclosed(typval_T *argvars, typval_T *rettv)
{
foldclosed_both(argvars, rettv, FALSE);
}
@@ -9530,9 +9206,7 @@ typval_T *rettv;
/*
* "foldclosedend()" function
*/
-static void f_foldclosedend(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_foldclosedend(typval_T *argvars, typval_T *rettv)
{
foldclosed_both(argvars, rettv, TRUE);
}
@@ -9540,9 +9214,7 @@ typval_T *rettv;
/*
* "foldlevel()" function
*/
-static void f_foldlevel(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_foldlevel(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
@@ -9554,9 +9226,7 @@ typval_T *rettv UNUSED;
/*
* "foldtext()" function
*/
-static void f_foldtext(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_foldtext(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
char_u *s;
@@ -9611,9 +9281,7 @@ typval_T *rettv;
/*
* "foldtextresult(lnum)" function
*/
-static void f_foldtextresult(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_foldtextresult(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
char_u *text;
@@ -9640,18 +9308,14 @@ typval_T *rettv;
/*
* "foreground()" function
*/
-static void f_foreground(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_foreground(typval_T *argvars, typval_T *rettv)
{
}
/*
* "function()" function
*/
-static void f_function(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_function(typval_T *argvars, typval_T *rettv)
{
char_u *s;
@@ -9686,9 +9350,7 @@ typval_T *rettv;
/*
* "garbagecollect()" function
*/
-static void f_garbagecollect(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv UNUSED;
+static void f_garbagecollect(typval_T *argvars, typval_T *rettv)
{
/* This is postponed until we are back at the toplevel, because we may be
* using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
@@ -9701,9 +9363,7 @@ typval_T *rettv UNUSED;
/*
* "get()" function
*/
-static void f_get(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_get(typval_T *argvars, typval_T *rettv)
{
listitem_T *li;
list_T *l;
@@ -9745,12 +9405,7 @@ static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end,
* buffer.
* If 'retlist' is TRUE, then the lines are returned as a Vim List.
*/
-static void get_buffer_lines(buf, start, end, retlist, rettv)
-buf_T *buf;
-linenr_T start;
-linenr_T end;
-int retlist;
-typval_T *rettv;
+static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
char_u *p;
@@ -9786,9 +9441,7 @@ typval_T *rettv;
/*
* "getbufline()" function
*/
-static void f_getbufline(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getbufline(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
linenr_T end;
@@ -9811,9 +9464,7 @@ typval_T *rettv;
/*
* "getbufvar()" function
*/
-static void f_getbufvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getbufvar(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
buf_T *save_curbuf;
@@ -9866,9 +9517,7 @@ typval_T *rettv;
/*
* "getchar()" function
*/
-static void f_getchar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getchar(typval_T *argvars, typval_T *rettv)
{
varnumber_T n;
int error = FALSE;
@@ -9951,9 +9600,7 @@ typval_T *rettv;
/*
* "getcharmod()" function
*/
-static void f_getcharmod(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getcharmod(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = mod_mask;
}
@@ -9961,9 +9608,7 @@ typval_T *rettv;
/*
* "getcmdline()" function
*/
-static void f_getcmdline(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getcmdline(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_cmdline_str();
@@ -9972,9 +9617,7 @@ typval_T *rettv;
/*
* "getcmdpos()" function
*/
-static void f_getcmdpos(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getcmdpos(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = get_cmdline_pos() + 1;
}
@@ -9982,9 +9625,7 @@ typval_T *rettv;
/*
* "getcmdtype()" function
*/
-static void f_getcmdtype(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getcmdtype(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = alloc(2);
@@ -9997,9 +9638,7 @@ typval_T *rettv;
/*
* "getcwd()" function
*/
-static void f_getcwd(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getcwd(typval_T *argvars, typval_T *rettv)
{
char_u *cwd;
@@ -10021,9 +9660,7 @@ typval_T *rettv;
/*
* "getfontname()" function
*/
-static void f_getfontname(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getfontname(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -10032,9 +9669,7 @@ typval_T *rettv;
/*
* "getfperm({fname})" function
*/
-static void f_getfperm(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getfperm(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
struct stat st;
@@ -10060,9 +9695,7 @@ typval_T *rettv;
/*
* "getfsize({fname})" function
*/
-static void f_getfsize(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getfsize(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
struct stat st;
@@ -10088,9 +9721,7 @@ typval_T *rettv;
/*
* "getftime({fname})" function
*/
-static void f_getftime(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getftime(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
struct stat st;
@@ -10106,9 +9737,7 @@ typval_T *rettv;
/*
* "getftype({fname})" function
*/
-static void f_getftype(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getftype(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
struct stat st;
@@ -10183,9 +9812,7 @@ typval_T *rettv;
/*
* "getline(lnum, [end])" function
*/
-static void f_getline(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getline(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
linenr_T end;
@@ -10206,9 +9833,7 @@ typval_T *rettv;
/*
* "getmatches()" function
*/
-static void f_getmatches(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_getmatches(typval_T *argvars, typval_T *rettv)
{
dict_T *dict;
matchitem_T *cur = curwin->w_match_head;
@@ -10231,9 +9856,7 @@ typval_T *rettv UNUSED;
/*
* "getpid()" function
*/
-static void f_getpid(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getpid(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = mch_get_pid();
}
@@ -10241,9 +9864,7 @@ typval_T *rettv;
/*
* "getpos(string)" function
*/
-static void f_getpos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getpos(typval_T *argvars, typval_T *rettv)
{
pos_T *fp;
list_T *l;
@@ -10271,9 +9892,7 @@ typval_T *rettv;
/*
* "getqflist()" and "getloclist()" functions
*/
-static void f_getqflist(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_getqflist(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
@@ -10292,9 +9911,7 @@ typval_T *rettv UNUSED;
/*
* "getreg()" function
*/
-static void f_getreg(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getreg(typval_T *argvars, typval_T *rettv)
{
char_u *strregname;
int regname;
@@ -10320,9 +9937,7 @@ typval_T *rettv;
/*
* "getregtype()" function
*/
-static void f_getregtype(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getregtype(typval_T *argvars, typval_T *rettv)
{
char_u *strregname;
int regname;
@@ -10361,9 +9976,7 @@ typval_T *rettv;
/*
* "gettabvar()" function
*/
-static void f_gettabvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_gettabvar(typval_T *argvars, typval_T *rettv)
{
tabpage_T *tp;
dictitem_T *v;
@@ -10391,9 +10004,7 @@ typval_T *rettv;
/*
* "gettabwinvar()" function
*/
-static void f_gettabwinvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_gettabwinvar(typval_T *argvars, typval_T *rettv)
{
getwinvar(argvars, rettv, 1);
}
@@ -10401,9 +10012,7 @@ typval_T *rettv;
/*
* "getwinposx()" function
*/
-static void f_getwinposx(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getwinposx(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = -1;
}
@@ -10411,9 +10020,7 @@ typval_T *rettv;
/*
* "getwinposy()" function
*/
-static void f_getwinposy(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_getwinposy(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = -1;
}
@@ -10421,9 +10028,11 @@ typval_T *rettv;
/*
* Find window specified by "vp" in tabpage "tp".
*/
-static win_T * find_win_by_nr(vp, tp)
-typval_T *vp;
-tabpage_T *tp UNUSED; /* NULL for current tab page */
+static win_T *
+find_win_by_nr (
+ typval_T *vp,
+ tabpage_T *tp /* NULL for current tab page */
+)
{
win_T *wp;
int nr;
@@ -10445,9 +10054,7 @@ tabpage_T *tp UNUSED; /* NULL for current tab page */
/*
* "getwinvar()" function
*/
-static void f_getwinvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_getwinvar(typval_T *argvars, typval_T *rettv)
{
getwinvar(argvars, rettv, 0);
}
@@ -10455,10 +10062,12 @@ typval_T *rettv;
/*
* getwinvar() and gettabwinvar()
*/
-static void getwinvar(argvars, rettv, off)
-typval_T *argvars;
-typval_T *rettv;
-int off; /* 1 for gettabwinvar() */
+static void
+getwinvar (
+ typval_T *argvars,
+ typval_T *rettv,
+ int off /* 1 for gettabwinvar() */
+)
{
win_T *win, *oldcurwin;
char_u *varname;
@@ -10510,9 +10119,7 @@ int off; /* 1 for gettabwinvar() */
/*
* "glob()" function
*/
-static void f_glob(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_glob(typval_T *argvars, typval_T *rettv)
{
int options = WILD_SILENT|WILD_USE_NL;
expand_T xpc;
@@ -10555,9 +10162,7 @@ typval_T *rettv;
/*
* "globpath()" function
*/
-static void f_globpath(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_globpath(typval_T *argvars, typval_T *rettv)
{
int flags = 0;
char_u buf1[NUMBUFLEN];
@@ -10580,9 +10185,7 @@ typval_T *rettv;
/*
* "has()" function
*/
-static void f_has(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_has(typval_T *argvars, typval_T *rettv)
{
int i;
char_u *name;
@@ -10734,6 +10337,7 @@ typval_T *rettv;
#ifdef FEAT_XTERM_SAVE
"xterm_save",
#endif
+ "neovim",
NULL
};
@@ -10773,9 +10377,7 @@ typval_T *rettv;
/*
* "has_key()" function
*/
-static void f_has_key(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_has_key(typval_T *argvars, typval_T *rettv)
{
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -10791,9 +10393,7 @@ typval_T *rettv;
/*
* "haslocaldir()" function
*/
-static void f_haslocaldir(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_haslocaldir(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = (curwin->w_localdir != NULL);
}
@@ -10801,9 +10401,7 @@ typval_T *rettv;
/*
* "hasmapto()" function
*/
-static void f_hasmapto(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_hasmapto(typval_T *argvars, typval_T *rettv)
{
char_u *name;
char_u *mode;
@@ -10828,9 +10426,7 @@ typval_T *rettv;
/*
* "histadd()" function
*/
-static void f_histadd(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_histadd(typval_T *argvars, typval_T *rettv)
{
int histype;
char_u *str;
@@ -10855,9 +10451,7 @@ typval_T *rettv;
/*
* "histdel()" function
*/
-static void f_histdel(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_histdel(typval_T *argvars, typval_T *rettv)
{
int n;
char_u buf[NUMBUFLEN];
@@ -10883,9 +10477,7 @@ typval_T *rettv UNUSED;
/*
* "histget()" function
*/
-static void f_histget(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_histget(typval_T *argvars, typval_T *rettv)
{
int type;
int idx;
@@ -10909,9 +10501,7 @@ typval_T *rettv;
/*
* "histnr()" function
*/
-static void f_histnr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_histnr(typval_T *argvars, typval_T *rettv)
{
int i;
@@ -10928,9 +10518,7 @@ typval_T *rettv;
/*
* "highlightID(name)" function
*/
-static void f_hlID(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_hlID(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
}
@@ -10938,9 +10526,7 @@ typval_T *rettv;
/*
* "highlight_exists()" function
*/
-static void f_hlexists(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_hlexists(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
}
@@ -10948,9 +10534,7 @@ typval_T *rettv;
/*
* "hostname()" function
*/
-static void f_hostname(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_hostname(typval_T *argvars, typval_T *rettv)
{
char_u hostname[256];
@@ -10962,9 +10546,7 @@ typval_T *rettv;
/*
* iconv() function
*/
-static void f_iconv(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_iconv(typval_T *argvars, typval_T *rettv)
{
char_u buf1[NUMBUFLEN];
char_u buf2[NUMBUFLEN];
@@ -10994,9 +10576,7 @@ typval_T *rettv;
/*
* "indent()" function
*/
-static void f_indent(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_indent(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
@@ -11010,9 +10590,7 @@ typval_T *rettv;
/*
* "index()" function
*/
-static void f_index(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_index(typval_T *argvars, typval_T *rettv)
{
list_T *l;
listitem_T *item;
@@ -11059,10 +10637,7 @@ static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv,
* prompt. The third argument to f_inputdialog() specifies the value to return
* when the user cancels the prompt.
*/
-static void get_user_input(argvars, rettv, inputdialog)
-typval_T *argvars;
-typval_T *rettv;
-int inputdialog;
+static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
{
char_u *prompt = get_tv_string_chk(&argvars[0]);
char_u *p = NULL;
@@ -11154,9 +10729,7 @@ int inputdialog;
* "input()" function
* Also handles inputsecret() when inputsecret is set.
*/
-static void f_input(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_input(typval_T *argvars, typval_T *rettv)
{
get_user_input(argvars, rettv, FALSE);
}
@@ -11164,9 +10737,7 @@ typval_T *rettv;
/*
* "inputdialog()" function
*/
-static void f_inputdialog(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_inputdialog(typval_T *argvars, typval_T *rettv)
{
get_user_input(argvars, rettv, TRUE);
}
@@ -11174,9 +10745,7 @@ typval_T *rettv;
/*
* "inputlist()" function
*/
-static void f_inputlist(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_inputlist(typval_T *argvars, typval_T *rettv)
{
listitem_T *li;
int selected;
@@ -11217,9 +10786,7 @@ static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
/*
* "inputrestore()" function
*/
-static void f_inputrestore(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_inputrestore(typval_T *argvars, typval_T *rettv)
{
if (ga_userinput.ga_len > 0) {
--ga_userinput.ga_len;
@@ -11235,9 +10802,7 @@ typval_T *rettv;
/*
* "inputsave()" function
*/
-static void f_inputsave(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_inputsave(typval_T *argvars, typval_T *rettv)
{
/* Add an entry to the stack of typeahead storage. */
if (ga_grow(&ga_userinput, 1) == OK) {
@@ -11252,9 +10817,7 @@ typval_T *rettv;
/*
* "inputsecret()" function
*/
-static void f_inputsecret(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_inputsecret(typval_T *argvars, typval_T *rettv)
{
++cmdline_star;
++inputsecret_flag;
@@ -11266,9 +10829,7 @@ typval_T *rettv;
/*
* "insert()" function
*/
-static void f_insert(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_insert(typval_T *argvars, typval_T *rettv)
{
long before = 0;
listitem_T *item;
@@ -11303,9 +10864,7 @@ typval_T *rettv;
/*
* "invert(expr)" function
*/
-static void f_invert(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_invert(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
}
@@ -11313,9 +10872,7 @@ typval_T *rettv;
/*
* "isdirectory()" function
*/
-static void f_isdirectory(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_isdirectory(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
}
@@ -11323,9 +10880,7 @@ typval_T *rettv;
/*
* "islocked()" function
*/
-static void f_islocked(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_islocked(typval_T *argvars, typval_T *rettv)
{
lval_T lv;
char_u *end;
@@ -11377,10 +10932,7 @@ static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what));
* "what" == 1: list of values
* "what" == 2: list of items
*/
-static void dict_list(argvars, rettv, what)
-typval_T *argvars;
-typval_T *rettv;
-int what;
+static void dict_list(typval_T *argvars, typval_T *rettv, int what)
{
list_T *l2;
dictitem_T *di;
@@ -11450,9 +11002,7 @@ int what;
/*
* "items(dict)" function
*/
-static void f_items(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_items(typval_T *argvars, typval_T *rettv)
{
dict_list(argvars, rettv, 2);
}
@@ -11460,9 +11010,7 @@ typval_T *rettv;
/*
* "join()" function
*/
-static void f_join(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_join(typval_T *argvars, typval_T *rettv)
{
garray_T ga;
char_u *sep;
@@ -11492,9 +11040,7 @@ typval_T *rettv;
/*
* "keys()" function
*/
-static void f_keys(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_keys(typval_T *argvars, typval_T *rettv)
{
dict_list(argvars, rettv, 0);
}
@@ -11502,9 +11048,7 @@ typval_T *rettv;
/*
* "last_buffer_nr()" function.
*/
-static void f_last_buffer_nr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv)
{
int n = 0;
buf_T *buf;
@@ -11519,9 +11063,7 @@ typval_T *rettv;
/*
* "len()" function
*/
-static void f_len(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_len(typval_T *argvars, typval_T *rettv)
{
switch (argvars[0].v_type) {
case VAR_STRING:
@@ -11543,10 +11085,7 @@ typval_T *rettv;
static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type));
-static void libcall_common(argvars, rettv, type)
-typval_T *argvars;
-typval_T *rettv;
-int type;
+static void libcall_common(typval_T *argvars, typval_T *rettv, int type)
{
#ifdef FEAT_LIBCALL
char_u *string_in;
@@ -11586,9 +11125,7 @@ int type;
/*
* "libcall()" function
*/
-static void f_libcall(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_libcall(typval_T *argvars, typval_T *rettv)
{
libcall_common(argvars, rettv, VAR_STRING);
}
@@ -11596,9 +11133,7 @@ typval_T *rettv;
/*
* "libcallnr()" function
*/
-static void f_libcallnr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_libcallnr(typval_T *argvars, typval_T *rettv)
{
libcall_common(argvars, rettv, VAR_NUMBER);
}
@@ -11606,9 +11141,7 @@ typval_T *rettv;
/*
* "line(string)" function
*/
-static void f_line(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_line(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum = 0;
pos_T *fp;
@@ -11623,9 +11156,7 @@ typval_T *rettv;
/*
* "line2byte(lnum)" function
*/
-static void f_line2byte(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_line2byte(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
@@ -11641,9 +11172,7 @@ typval_T *rettv;
/*
* "lispindent(lnum)" function
*/
-static void f_lispindent(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_lispindent(typval_T *argvars, typval_T *rettv)
{
pos_T pos;
linenr_T lnum;
@@ -11661,19 +11190,14 @@ typval_T *rettv;
/*
* "localtime()" function
*/
-static void f_localtime(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_localtime(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = (varnumber_T)time(NULL);
}
static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact));
-static void get_maparg(argvars, rettv, exact)
-typval_T *argvars;
-typval_T *rettv;
-int exact;
+static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
{
char_u *keys;
char_u *which;
@@ -11741,9 +11265,7 @@ int exact;
/*
* "log()" function
*/
-static void f_log(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_log(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -11757,9 +11279,7 @@ typval_T *rettv;
/*
* "log10()" function
*/
-static void f_log10(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_log10(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -11774,9 +11294,7 @@ typval_T *rettv;
/*
* "map()" function
*/
-static void f_map(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_map(typval_T *argvars, typval_T *rettv)
{
filter_map(argvars, rettv, TRUE);
}
@@ -11784,9 +11302,7 @@ typval_T *rettv;
/*
* "maparg()" function
*/
-static void f_maparg(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_maparg(typval_T *argvars, typval_T *rettv)
{
get_maparg(argvars, rettv, TRUE);
}
@@ -11794,9 +11310,7 @@ typval_T *rettv;
/*
* "mapcheck()" function
*/
-static void f_mapcheck(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_mapcheck(typval_T *argvars, typval_T *rettv)
{
get_maparg(argvars, rettv, FALSE);
}
@@ -11804,10 +11318,7 @@ typval_T *rettv;
static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv,
int start));
-static void find_some_match(argvars, rettv, type)
-typval_T *argvars;
-typval_T *rettv;
-int type;
+static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
{
char_u *str = NULL;
char_u *expr = NULL;
@@ -11960,9 +11471,7 @@ theend:
/*
* "match()" function
*/
-static void f_match(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_match(typval_T *argvars, typval_T *rettv)
{
find_some_match(argvars, rettv, 1);
}
@@ -11970,9 +11479,7 @@ typval_T *rettv;
/*
* "matchadd()" function
*/
-static void f_matchadd(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_matchadd(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
@@ -12003,9 +11510,7 @@ typval_T *rettv UNUSED;
/*
* "matcharg()" function
*/
-static void f_matcharg(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_matcharg(typval_T *argvars, typval_T *rettv)
{
if (rettv_list_alloc(rettv) == OK) {
int id = get_tv_number(&argvars[0]);
@@ -12027,9 +11532,7 @@ typval_T *rettv;
/*
* "matchdelete()" function
*/
-static void f_matchdelete(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_matchdelete(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = match_delete(curwin,
(int)get_tv_number(&argvars[0]), TRUE);
@@ -12038,9 +11541,7 @@ typval_T *rettv UNUSED;
/*
* "matchend()" function
*/
-static void f_matchend(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_matchend(typval_T *argvars, typval_T *rettv)
{
find_some_match(argvars, rettv, 0);
}
@@ -12048,9 +11549,7 @@ typval_T *rettv;
/*
* "matchlist()" function
*/
-static void f_matchlist(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_matchlist(typval_T *argvars, typval_T *rettv)
{
find_some_match(argvars, rettv, 3);
}
@@ -12058,19 +11557,14 @@ typval_T *rettv;
/*
* "matchstr()" function
*/
-static void f_matchstr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_matchstr(typval_T *argvars, typval_T *rettv)
{
find_some_match(argvars, rettv, 2);
}
static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax));
-static void max_min(argvars, rettv, domax)
-typval_T *argvars;
-typval_T *rettv;
-int domax;
+static void max_min(typval_T *argvars, typval_T *rettv, int domax)
{
long n = 0;
long i;
@@ -12124,9 +11618,7 @@ int domax;
/*
* "max()" function
*/
-static void f_max(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_max(typval_T *argvars, typval_T *rettv)
{
max_min(argvars, rettv, TRUE);
}
@@ -12134,9 +11626,7 @@ typval_T *rettv;
/*
* "min()" function
*/
-static void f_min(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_min(typval_T *argvars, typval_T *rettv)
{
max_min(argvars, rettv, FALSE);
}
@@ -12147,9 +11637,7 @@ static int mkdir_recurse __ARGS((char_u *dir, int prot));
* Create the directory in which "dir" is located, and higher levels when
* needed.
*/
-static int mkdir_recurse(dir, prot)
-char_u *dir;
-int prot;
+static int mkdir_recurse(char_u *dir, int prot)
{
char_u *p;
char_u *updir;
@@ -12177,9 +11665,7 @@ int prot;
/*
* "mkdir()" function
*/
-static void f_mkdir(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_mkdir(typval_T *argvars, typval_T *rettv)
{
char_u *dir;
char_u buf[NUMBUFLEN];
@@ -12211,9 +11697,7 @@ typval_T *rettv;
/*
* "mode()" function
*/
-static void f_mode(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_mode(typval_T *argvars, typval_T *rettv)
{
char_u buf[3];
@@ -12268,9 +11752,7 @@ typval_T *rettv;
/*
* "nextnonblank()" function
*/
-static void f_nextnonblank(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_nextnonblank(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
@@ -12288,9 +11770,7 @@ typval_T *rettv;
/*
* "nr2char()" function
*/
-static void f_nr2char(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_nr2char(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
@@ -12314,9 +11794,7 @@ typval_T *rettv;
/*
* "or(expr, expr)" function
*/
-static void f_or(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_or(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
| get_tv_number_chk(&argvars[1], NULL);
@@ -12325,9 +11803,7 @@ typval_T *rettv;
/*
* "pathshorten()" function
*/
-static void f_pathshorten(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_pathshorten(typval_T *argvars, typval_T *rettv)
{
char_u *p;
@@ -12346,9 +11822,7 @@ typval_T *rettv;
/*
* "pow()" function
*/
-static void f_pow(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_pow(typval_T *argvars, typval_T *rettv)
{
float_T fx, fy;
@@ -12363,9 +11837,7 @@ typval_T *rettv;
/*
* "prevnonblank()" function
*/
-static void f_prevnonblank(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_prevnonblank(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
@@ -12389,9 +11861,7 @@ static va_list ap;
/*
* "printf()" function
*/
-static void f_printf(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_printf(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -12422,9 +11892,7 @@ typval_T *rettv;
/*
* "pumvisible()" function
*/
-static void f_pumvisible(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_pumvisible(typval_T *argvars, typval_T *rettv)
{
if (pum_visible())
rettv->vval.v_number = 1;
@@ -12435,9 +11903,7 @@ typval_T *rettv UNUSED;
/*
* "range()" function
*/
-static void f_range(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_range(typval_T *argvars, typval_T *rettv)
{
long start;
long end;
@@ -12473,9 +11939,7 @@ typval_T *rettv;
/*
* "readfile()" function
*/
-static void f_readfile(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_readfile(typval_T *argvars, typval_T *rettv)
{
int binary = FALSE;
int failed = FALSE;
@@ -12686,9 +12150,7 @@ proftime_T *tm;
/*
* "reltime()" function
*/
-static void f_reltime(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_reltime(typval_T *argvars, typval_T *rettv)
{
proftime_T res;
proftime_T start;
@@ -12721,9 +12183,7 @@ typval_T *rettv UNUSED;
/*
* "reltimestr()" function
*/
-static void f_reltimestr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_reltimestr(typval_T *argvars, typval_T *rettv)
{
proftime_T tm;
@@ -12738,9 +12198,7 @@ typval_T *rettv;
/*
* "remote_expr()" function
*/
-static void f_remote_expr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_remote_expr(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -12749,22 +12207,16 @@ typval_T *rettv;
/*
* "remote_foreground()" function
*/
-static void f_remote_foreground(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_remote_foreground(typval_T *argvars, typval_T *rettv)
{
}
-static void f_remote_peek(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_remote_peek(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = -1;
}
-static void f_remote_read(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_remote_read(typval_T *argvars, typval_T *rettv)
{
char_u *r = NULL;
@@ -12775,9 +12227,7 @@ typval_T *rettv;
/*
* "remote_send()" function
*/
-static void f_remote_send(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_remote_send(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -12786,9 +12236,7 @@ typval_T *rettv;
/*
* "remove()" function
*/
-static void f_remove(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_remove(typval_T *argvars, typval_T *rettv)
{
list_T *l;
listitem_T *item, *item2;
@@ -12871,9 +12319,7 @@ typval_T *rettv;
/*
* "rename({from}, {to})" function
*/
-static void f_rename(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_rename(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
@@ -12887,9 +12333,7 @@ typval_T *rettv;
/*
* "repeat()" function
*/
-static void f_repeat(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_repeat(typval_T *argvars, typval_T *rettv)
{
char_u *p;
int n;
@@ -12929,9 +12373,7 @@ typval_T *rettv;
/*
* "resolve()" function
*/
-static void f_resolve(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_resolve(typval_T *argvars, typval_T *rettv)
{
char_u *p;
#ifdef HAVE_READLINK
@@ -13116,9 +12558,7 @@ fail:
/*
* "reverse({list})" function
*/
-static void f_reverse(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_reverse(typval_T *argvars, typval_T *rettv)
{
list_T *l;
listitem_T *li, *ni;
@@ -13157,9 +12597,7 @@ static int get_search_arg __ARGS((typval_T *varp, int *flagsp));
* Possibly sets "p_ws".
* Returns BACKWARD, FORWARD or zero (for an error).
*/
-static int get_search_arg(varp, flagsp)
-typval_T *varp;
-int *flagsp;
+static int get_search_arg(typval_T *varp, int *flagsp)
{
int dir = FORWARD;
char_u *flags;
@@ -13203,10 +12641,7 @@ int *flagsp;
/*
* Shared by search() and searchpos() functions
*/
-static int search_cmn(argvars, match_pos, flagsp)
-typval_T *argvars;
-pos_T *match_pos;
-int *flagsp;
+static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
char_u *pat;
@@ -13294,8 +12729,7 @@ theend:
/*
* round() is not in C90, use ceil() or floor() instead.
*/
-float_T vim_round(f)
-float_T f;
+float_T vim_round(float_T f)
{
return f > 0 ? floor(f + 0.5) : ceil(f - 0.5);
}
@@ -13303,9 +12737,7 @@ float_T f;
/*
* "round({float})" function
*/
-static void f_round(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_round(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -13319,9 +12751,7 @@ typval_T *rettv;
/*
* "screenattr()" function
*/
-static void f_screenattr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_screenattr(typval_T *argvars, typval_T *rettv)
{
int row;
int col;
@@ -13340,9 +12770,7 @@ typval_T *rettv;
/*
* "screenchar()" function
*/
-static void f_screenchar(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_screenchar(typval_T *argvars, typval_T *rettv)
{
int row;
int col;
@@ -13369,9 +12797,7 @@ typval_T *rettv;
*
* First column is 1 to be consistent with virtcol().
*/
-static void f_screencol(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_screencol(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = screen_screencol() + 1;
}
@@ -13379,9 +12805,7 @@ typval_T *rettv;
/*
* "screenrow()" function
*/
-static void f_screenrow(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_screenrow(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = screen_screenrow() + 1;
}
@@ -13389,9 +12813,7 @@ typval_T *rettv;
/*
* "search()" function
*/
-static void f_search(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_search(typval_T *argvars, typval_T *rettv)
{
int flags = 0;
@@ -13401,9 +12823,7 @@ typval_T *rettv;
/*
* "searchdecl()" function
*/
-static void f_searchdecl(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_searchdecl(typval_T *argvars, typval_T *rettv)
{
int locally = 1;
int thisblock = 0;
@@ -13426,9 +12846,7 @@ typval_T *rettv;
/*
* Used by searchpair() and searchpairpos()
*/
-static int searchpair_cmn(argvars, match_pos)
-typval_T *argvars;
-pos_T *match_pos;
+static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
char_u *spat, *mpat, *epat;
char_u *skip;
@@ -13499,9 +12917,7 @@ theend:
/*
* "searchpair()" function
*/
-static void f_searchpair(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_searchpair(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = searchpair_cmn(argvars, NULL);
}
@@ -13509,9 +12925,7 @@ typval_T *rettv;
/*
* "searchpairpos()" function
*/
-static void f_searchpairpos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_searchpairpos(typval_T *argvars, typval_T *rettv)
{
pos_T match_pos;
int lnum = 0;
@@ -13534,17 +12948,18 @@ typval_T *rettv;
* Used by searchpair(), see its documentation for the details.
* Returns 0 or -1 for no match,
*/
-long do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos,
- lnum_stop, time_limit)
-char_u *spat; /* start pattern */
-char_u *mpat; /* middle pattern */
-char_u *epat; /* end pattern */
-int dir; /* BACKWARD or FORWARD */
-char_u *skip; /* skip expression */
-int flags; /* SP_SETPCMARK and other SP_ values */
-pos_T *match_pos;
-linenr_T lnum_stop; /* stop at this line if not zero */
-long time_limit UNUSED; /* stop after this many msec */
+long
+do_searchpair (
+ char_u *spat, /* start pattern */
+ char_u *mpat, /* middle pattern */
+ char_u *epat, /* end pattern */
+ int dir, /* BACKWARD or FORWARD */
+ char_u *skip, /* skip expression */
+ int flags, /* SP_SETPCMARK and other SP_ values */
+ pos_T *match_pos,
+ linenr_T lnum_stop, /* stop at this line if not zero */
+ long time_limit /* stop after this many msec */
+)
{
char_u *save_cpo;
char_u *pat, *pat2 = NULL, *pat3 = NULL;
@@ -13679,9 +13094,7 @@ theend:
/*
* "searchpos()" function
*/
-static void f_searchpos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_searchpos(typval_T *argvars, typval_T *rettv)
{
pos_T match_pos;
int lnum = 0;
@@ -13705,16 +13118,12 @@ typval_T *rettv;
}
-static void f_server2client(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_server2client(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = -1;
}
-static void f_serverlist(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_serverlist(typval_T *argvars, typval_T *rettv)
{
char_u *r = NULL;
@@ -13725,9 +13134,7 @@ typval_T *rettv;
/*
* "setbufvar()" function
*/
-static void f_setbufvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv UNUSED;
+static void f_setbufvar(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
aco_save_T aco;
@@ -13774,9 +13181,7 @@ typval_T *rettv UNUSED;
/*
* "setcmdpos()" function
*/
-static void f_setcmdpos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setcmdpos(typval_T *argvars, typval_T *rettv)
{
int pos = (int)get_tv_number(&argvars[0]) - 1;
@@ -13787,9 +13192,7 @@ typval_T *rettv;
/*
* "setline()" function
*/
-static void f_setline(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setline(typval_T *argvars, typval_T *rettv)
{
linenr_T lnum;
char_u *line = NULL;
@@ -13857,11 +13260,7 @@ static void set_qf_ll_list __ARGS((win_T *wp, typval_T *list_arg, typval_T *
/*
* Used by "setqflist()" and "setloclist()" functions
*/
-static void set_qf_ll_list(wp, list_arg, action_arg, rettv)
-win_T *wp UNUSED;
-typval_T *list_arg UNUSED;
-typval_T *action_arg UNUSED;
-typval_T *rettv;
+static void set_qf_ll_list(win_T *wp, typval_T *list_arg, typval_T *action_arg, typval_T *rettv)
{
char_u *act;
int action = ' ';
@@ -13890,9 +13289,7 @@ typval_T *rettv;
/*
* "setloclist()" function
*/
-static void f_setloclist(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setloclist(typval_T *argvars, typval_T *rettv)
{
win_T *win;
@@ -13906,9 +13303,7 @@ typval_T *rettv;
/*
* "setmatches()" function
*/
-static void f_setmatches(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_setmatches(typval_T *argvars, typval_T *rettv)
{
list_T *l;
listitem_T *li;
@@ -13957,9 +13352,7 @@ typval_T *rettv UNUSED;
/*
* "setpos()" function
*/
-static void f_setpos(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setpos(typval_T *argvars, typval_T *rettv)
{
pos_T pos;
int fnum;
@@ -13992,9 +13385,7 @@ typval_T *rettv;
/*
* "setqflist()" function
*/
-static void f_setqflist(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setqflist(typval_T *argvars, typval_T *rettv)
{
set_qf_ll_list(NULL, &argvars[0], &argvars[1], rettv);
}
@@ -14002,9 +13393,7 @@ typval_T *rettv;
/*
* "setreg()" function
*/
-static void f_setreg(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setreg(typval_T *argvars, typval_T *rettv)
{
int regname;
char_u *strregname;
@@ -14065,9 +13454,7 @@ typval_T *rettv;
/*
* "settabvar()" function
*/
-static void f_settabvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_settabvar(typval_T *argvars, typval_T *rettv)
{
tabpage_T *save_curtab;
tabpage_T *tp;
@@ -14106,9 +13493,7 @@ typval_T *rettv;
/*
* "settabwinvar()" function
*/
-static void f_settabwinvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_settabwinvar(typval_T *argvars, typval_T *rettv)
{
setwinvar(argvars, rettv, 1);
}
@@ -14116,9 +13501,7 @@ typval_T *rettv;
/*
* "setwinvar()" function
*/
-static void f_setwinvar(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_setwinvar(typval_T *argvars, typval_T *rettv)
{
setwinvar(argvars, rettv, 0);
}
@@ -14127,10 +13510,7 @@ typval_T *rettv;
* "setwinvar()" and "settabwinvar()" functions
*/
-static void setwinvar(argvars, rettv, off)
-typval_T *argvars;
-typval_T *rettv UNUSED;
-int off;
+static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
{
win_T *win;
win_T *save_curwin;
@@ -14182,9 +13562,7 @@ int off;
/*
* "sha256({string})" function
*/
-static void f_sha256(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_sha256(typval_T *argvars, typval_T *rettv)
{
char_u *p;
@@ -14197,9 +13575,7 @@ typval_T *rettv;
/*
* "shellescape({string})" function
*/
-static void f_shellescape(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_shellescape(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_string = vim_strsave_shellescape(
get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]));
@@ -14209,9 +13585,7 @@ typval_T *rettv;
/*
* shiftwidth() function
*/
-static void f_shiftwidth(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_shiftwidth(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = get_sw_value(curbuf);
}
@@ -14219,9 +13593,7 @@ typval_T *rettv;
/*
* "simplify()" function
*/
-static void f_simplify(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_simplify(typval_T *argvars, typval_T *rettv)
{
char_u *p;
@@ -14234,9 +13606,7 @@ typval_T *rettv;
/*
* "sin()" function
*/
-static void f_sin(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_sin(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -14250,9 +13620,7 @@ typval_T *rettv;
/*
* "sinh()" function
*/
-static void f_sinh(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_sinh(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -14277,9 +13645,7 @@ static int item_compare_func_err;
/*
* Compare functions for f_sort() below.
*/
-static int item_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int item_compare(const void *s1, const void *s2)
{
char_u *p1, *p2;
char_u *tofree1, *tofree2;
@@ -14302,9 +13668,7 @@ const void *s2;
return res;
}
-static int item_compare2(s1, s2)
-const void *s1;
-const void *s2;
+static int item_compare2(const void *s1, const void *s2)
{
int res;
typval_T rettv;
@@ -14340,9 +13704,7 @@ const void *s2;
/*
* "sort({list})" function
*/
-static void f_sort(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_sort(typval_T *argvars, typval_T *rettv)
{
list_T *l;
listitem_T *li;
@@ -14429,9 +13791,7 @@ typval_T *rettv;
/*
* "soundfold({word})" function
*/
-static void f_soundfold(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_soundfold(typval_T *argvars, typval_T *rettv)
{
char_u *s;
@@ -14443,9 +13803,7 @@ typval_T *rettv;
/*
* "spellbadword()" function
*/
-static void f_spellbadword(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_spellbadword(typval_T *argvars, typval_T *rettv)
{
char_u *word = (char_u *)"";
hlf_T attr = HLF_COUNT;
@@ -14488,9 +13846,7 @@ typval_T *rettv;
/*
* "spellsuggest()" function
*/
-static void f_spellsuggest(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_spellsuggest(typval_T *argvars, typval_T *rettv)
{
char_u *str;
int typeerr = FALSE;
@@ -14536,9 +13892,7 @@ typval_T *rettv;
}
}
-static void f_split(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_split(typval_T *argvars, typval_T *rettv)
{
char_u *str;
char_u *end;
@@ -14611,9 +13965,7 @@ typval_T *rettv;
/*
* "sqrt()" function
*/
-static void f_sqrt(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_sqrt(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -14627,9 +13979,7 @@ typval_T *rettv;
/*
* "str2float()" function
*/
-static void f_str2float(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_str2float(typval_T *argvars, typval_T *rettv)
{
char_u *p = skipwhite(get_tv_string(&argvars[0]));
@@ -14642,9 +13992,7 @@ typval_T *rettv;
/*
* "str2nr()" function
*/
-static void f_str2nr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_str2nr(typval_T *argvars, typval_T *rettv)
{
int base = 10;
char_u *p;
@@ -14669,9 +14017,7 @@ typval_T *rettv;
/*
* "strftime({format}[, {time}])" function
*/
-static void f_strftime(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strftime(typval_T *argvars, typval_T *rettv)
{
char_u result_buf[256];
struct tm *curtime;
@@ -14722,9 +14068,7 @@ typval_T *rettv;
/*
* "stridx()" function
*/
-static void f_stridx(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_stridx(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
char_u *needle;
@@ -14757,9 +14101,7 @@ typval_T *rettv;
/*
* "string()" function
*/
-static void f_string(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_string(typval_T *argvars, typval_T *rettv)
{
char_u *tofree;
char_u numbuf[NUMBUFLEN];
@@ -14774,9 +14116,7 @@ typval_T *rettv;
/*
* "strlen()" function
*/
-static void f_strlen(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strlen(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = (varnumber_T)(STRLEN(
get_tv_string(&argvars[0])));
@@ -14785,9 +14125,7 @@ typval_T *rettv;
/*
* "strchars()" function
*/
-static void f_strchars(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strchars(typval_T *argvars, typval_T *rettv)
{
char_u *s = get_tv_string(&argvars[0]);
varnumber_T len = 0;
@@ -14802,9 +14140,7 @@ typval_T *rettv;
/*
* "strdisplaywidth()" function
*/
-static void f_strdisplaywidth(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv)
{
char_u *s = get_tv_string(&argvars[0]);
int col = 0;
@@ -14818,9 +14154,7 @@ typval_T *rettv;
/*
* "strwidth()" function
*/
-static void f_strwidth(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strwidth(typval_T *argvars, typval_T *rettv)
{
char_u *s = get_tv_string(&argvars[0]);
@@ -14832,9 +14166,7 @@ typval_T *rettv;
/*
* "strpart()" function
*/
-static void f_strpart(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strpart(typval_T *argvars, typval_T *rettv)
{
char_u *p;
int n;
@@ -14874,9 +14206,7 @@ typval_T *rettv;
/*
* "strridx()" function
*/
-static void f_strridx(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strridx(typval_T *argvars, typval_T *rettv)
{
char_u buf[NUMBUFLEN];
char_u *needle;
@@ -14922,9 +14252,7 @@ typval_T *rettv;
/*
* "strtrans()" function
*/
-static void f_strtrans(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_strtrans(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
@@ -14933,9 +14261,7 @@ typval_T *rettv;
/*
* "submatch()" function
*/
-static void f_submatch(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_submatch(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string =
@@ -14945,9 +14271,7 @@ typval_T *rettv;
/*
* "substitute()" function
*/
-static void f_substitute(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_substitute(typval_T *argvars, typval_T *rettv)
{
char_u patbuf[NUMBUFLEN];
char_u subbuf[NUMBUFLEN];
@@ -14968,9 +14292,7 @@ typval_T *rettv;
/*
* "synID(lnum, col, trans)" function
*/
-static void f_synID(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_synID(typval_T *argvars, typval_T *rettv)
{
int id = 0;
long lnum;
@@ -14992,9 +14314,7 @@ typval_T *rettv;
/*
* "synIDattr(id, what [, mode])" function
*/
-static void f_synIDattr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_synIDattr(typval_T *argvars, typval_T *rettv)
{
char_u *p = NULL;
int id;
@@ -15071,9 +14391,7 @@ typval_T *rettv;
/*
* "synIDtrans(id)" function
*/
-static void f_synIDtrans(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_synIDtrans(typval_T *argvars, typval_T *rettv)
{
int id;
@@ -15090,9 +14408,7 @@ typval_T *rettv;
/*
* "synconcealed(lnum, col)" function
*/
-static void f_synconcealed(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_synconcealed(typval_T *argvars, typval_T *rettv)
{
long lnum;
long col;
@@ -15141,9 +14457,7 @@ typval_T *rettv;
/*
* "synstack(lnum, col)" function
*/
-static void f_synstack(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_synstack(typval_T *argvars, typval_T *rettv)
{
long lnum;
long col;
@@ -15173,9 +14487,7 @@ typval_T *rettv;
/*
* "system()" function
*/
-static void f_system(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_system(typval_T *argvars, typval_T *rettv)
{
char_u *res = NULL;
char_u *p;
@@ -15259,9 +14571,7 @@ done:
/*
* "tabpagebuflist()" function
*/
-static void f_tabpagebuflist(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv)
{
tabpage_T *tp;
win_T *wp = NULL;
@@ -15285,9 +14595,7 @@ typval_T *rettv UNUSED;
/*
* "tabpagenr()" function
*/
-static void f_tabpagenr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_tabpagenr(typval_T *argvars, typval_T *rettv)
{
int nr = 1;
char_u *arg;
@@ -15312,9 +14620,7 @@ static int get_winnr __ARGS((tabpage_T *tp, typval_T *argvar));
/*
* Common code for tabpagewinnr() and winnr().
*/
-static int get_winnr(tp, argvar)
-tabpage_T *tp;
-typval_T *argvar;
+static int get_winnr(tabpage_T *tp, typval_T *argvar)
{
win_T *twin;
int nr = 1;
@@ -15354,9 +14660,7 @@ typval_T *argvar;
/*
* "tabpagewinnr()" function
*/
-static void f_tabpagewinnr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv)
{
int nr = 1;
tabpage_T *tp;
@@ -15373,9 +14677,7 @@ typval_T *rettv;
/*
* "tagfiles()" function
*/
-static void f_tagfiles(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_tagfiles(typval_T *argvars, typval_T *rettv)
{
char_u *fname;
tagname_T tn;
@@ -15398,9 +14700,7 @@ typval_T *rettv;
/*
* "taglist()" function
*/
-static void f_taglist(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_taglist(typval_T *argvars, typval_T *rettv)
{
char_u *tag_pattern;
@@ -15417,9 +14717,7 @@ typval_T *rettv;
/*
* "tempname()" function
*/
-static void f_tempname(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_tempname(typval_T *argvars, typval_T *rettv)
{
static int x = 'A';
@@ -15442,9 +14740,7 @@ typval_T *rettv;
/*
* "test(list)" function: Just checking the walls...
*/
-static void f_test(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_test(typval_T *argvars, typval_T *rettv)
{
/* Used for unit testing. Change the code below to your liking. */
}
@@ -15452,9 +14748,7 @@ typval_T *rettv UNUSED;
/*
* "tan()" function
*/
-static void f_tan(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_tan(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -15468,9 +14762,7 @@ typval_T *rettv;
/*
* "tanh()" function
*/
-static void f_tanh(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_tanh(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -15484,9 +14776,7 @@ typval_T *rettv;
/*
* "tolower(string)" function
*/
-static void f_tolower(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_tolower(typval_T *argvars, typval_T *rettv)
{
char_u *p;
@@ -15520,9 +14810,7 @@ typval_T *rettv;
/*
* "toupper(string)" function
*/
-static void f_toupper(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_toupper(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
@@ -15531,9 +14819,7 @@ typval_T *rettv;
/*
* "tr(string, fromstr, tostr)" function
*/
-static void f_tr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_tr(typval_T *argvars, typval_T *rettv)
{
char_u *in_str;
char_u *fromstr;
@@ -15634,9 +14920,7 @@ error:
/*
* "trunc({float})" function
*/
-static void f_trunc(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_trunc(typval_T *argvars, typval_T *rettv)
{
float_T f;
@@ -15651,9 +14935,7 @@ typval_T *rettv;
/*
* "type(expr)" function
*/
-static void f_type(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_type(typval_T *argvars, typval_T *rettv)
{
int n;
@@ -15672,9 +14954,7 @@ typval_T *rettv;
/*
* "undofile(name)" function
*/
-static void f_undofile(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_undofile(typval_T *argvars, typval_T *rettv)
{
rettv->v_type = VAR_STRING;
{
@@ -15696,9 +14976,7 @@ typval_T *rettv;
/*
* "undotree()" function
*/
-static void f_undotree(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_undotree(typval_T *argvars, typval_T *rettv)
{
if (rettv_dict_alloc(rettv) == OK) {
dict_T *dict = rettv->vval.v_dict;
@@ -15723,9 +15001,7 @@ typval_T *rettv;
/*
* "values(dict)" function
*/
-static void f_values(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_values(typval_T *argvars, typval_T *rettv)
{
dict_list(argvars, rettv, 1);
}
@@ -15733,9 +15009,7 @@ typval_T *rettv;
/*
* "virtcol(string)" function
*/
-static void f_virtcol(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_virtcol(typval_T *argvars, typval_T *rettv)
{
colnr_T vcol = 0;
pos_T *fp;
@@ -15754,9 +15028,7 @@ typval_T *rettv;
/*
* "visualmode()" function
*/
-static void f_visualmode(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_visualmode(typval_T *argvars, typval_T *rettv)
{
char_u str[2];
@@ -15773,9 +15045,7 @@ typval_T *rettv UNUSED;
/*
* "wildmenumode()" function
*/
-static void f_wildmenumode(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv UNUSED;
+static void f_wildmenumode(typval_T *argvars, typval_T *rettv)
{
if (wild_menu_showing)
rettv->vval.v_number = 1;
@@ -15784,9 +15054,7 @@ typval_T *rettv UNUSED;
/*
* "winbufnr(nr)" function
*/
-static void f_winbufnr(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_winbufnr(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
@@ -15800,9 +15068,7 @@ typval_T *rettv;
/*
* "wincol()" function
*/
-static void f_wincol(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_wincol(typval_T *argvars, typval_T *rettv)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wcol + 1;
@@ -15811,9 +15077,7 @@ typval_T *rettv;
/*
* "winheight(nr)" function
*/
-static void f_winheight(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_winheight(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
@@ -15827,9 +15091,7 @@ typval_T *rettv;
/*
* "winline()" function
*/
-static void f_winline(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_winline(typval_T *argvars, typval_T *rettv)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wrow + 1;
@@ -15838,9 +15100,7 @@ typval_T *rettv;
/*
* "winnr()" function
*/
-static void f_winnr(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_winnr(typval_T *argvars, typval_T *rettv)
{
int nr = 1;
@@ -15851,9 +15111,7 @@ typval_T *rettv;
/*
* "winrestcmd()" function
*/
-static void f_winrestcmd(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_winrestcmd(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
int winnr = 1;
@@ -15877,9 +15135,7 @@ typval_T *rettv;
/*
* "winrestview()" function
*/
-static void f_winrestview(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv UNUSED;
+static void f_winrestview(typval_T *argvars, typval_T *rettv)
{
dict_T *dict;
@@ -15914,9 +15170,7 @@ typval_T *rettv UNUSED;
/*
* "winsaveview()" function
*/
-static void f_winsaveview(argvars, rettv)
-typval_T *argvars UNUSED;
-typval_T *rettv;
+static void f_winsaveview(typval_T *argvars, typval_T *rettv)
{
dict_T *dict;
@@ -15939,9 +15193,7 @@ typval_T *rettv;
/*
* "winwidth(nr)" function
*/
-static void f_winwidth(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_winwidth(typval_T *argvars, typval_T *rettv)
{
win_T *wp;
@@ -15955,9 +15207,7 @@ typval_T *rettv;
/*
* "writefile()" function
*/
-static void f_writefile(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_writefile(typval_T *argvars, typval_T *rettv)
{
int binary = FALSE;
char_u *fname;
@@ -16019,9 +15269,7 @@ typval_T *rettv;
/*
* "xor(expr, expr)" function
*/
-static void f_xor(argvars, rettv)
-typval_T *argvars;
-typval_T *rettv;
+static void f_xor(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
^ get_tv_number_chk(&argvars[1], NULL);
@@ -16032,10 +15280,12 @@ typval_T *rettv;
* Translate a String variable into a position.
* Returns NULL when there is an error.
*/
-static pos_T * var2fpos(varp, dollar_lnum, fnum)
-typval_T *varp;
-int dollar_lnum; /* TRUE when $ is last line */
-int *fnum; /* set to fnum for '0, 'A, etc. */
+static pos_T *
+var2fpos (
+ typval_T *varp,
+ int dollar_lnum, /* TRUE when $ is last line */
+ int *fnum /* set to fnum for '0, 'A, etc. */
+)
{
char_u *name;
static pos_T pos;
@@ -16134,10 +15384,7 @@ int *fnum; /* set to fnum for '0, 'A, etc. */
* Return FAIL when conversion is not possible, doesn't check the position for
* validity.
*/
-static int list2fpos(arg, posp, fnump)
-typval_T *arg;
-pos_T *posp;
-int *fnump;
+static int list2fpos(typval_T *arg, pos_T *posp, int *fnump)
{
list_T *l = arg->vval.v_list;
long i = 0;
@@ -16184,8 +15431,7 @@ int *fnump;
* Advance "arg" to the first character after the name.
* Return 0 for error.
*/
-static int get_env_len(arg)
-char_u **arg;
+static int get_env_len(char_u **arg)
{
char_u *p;
int len;
@@ -16205,8 +15451,7 @@ char_u **arg;
* "arg" is advanced to the first non-white character after the name.
* Return 0 if something is wrong.
*/
-static int get_id_len(arg)
-char_u **arg;
+static int get_id_len(char_u **arg)
{
char_u *p;
int len;
@@ -16232,11 +15477,7 @@ char_u **arg;
* If the name contains 'magic' {}'s, expand them and return the
* expanded name in an allocated string via 'alias' - caller must free.
*/
-static int get_name_len(arg, alias, evaluate, verbose)
-char_u **arg;
-char_u **alias;
-int evaluate;
-int verbose;
+static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
{
int len;
char_u *p;
@@ -16298,11 +15539,7 @@ int verbose;
* Return a pointer to just after the name. Equal to "arg" if there is no
* valid name.
*/
-static char_u * find_name_end(arg, expr_start, expr_end, flags)
-char_u *arg;
-char_u **expr_start;
-char_u **expr_end;
-int flags;
+static char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags)
{
int mb_nest = 0;
int br_nest = 0;
@@ -16374,11 +15611,7 @@ int flags;
* Returns a new allocated string, which the caller must free.
* Returns NULL for failure.
*/
-static char_u * make_expanded_name(in_start, expr_start, expr_end, in_end)
-char_u *in_start;
-char_u *expr_start;
-char_u *expr_end;
-char_u *in_end;
+static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)
{
char_u c1;
char_u *retval = NULL;
@@ -16426,8 +15659,7 @@ char_u *in_end;
* Return TRUE if character "c" can be used in a variable or function name.
* Does not include '{' or '}' for magic braces.
*/
-static int eval_isnamec(c)
-int c;
+static int eval_isnamec(int c)
{
return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR;
}
@@ -16436,8 +15668,7 @@ int c;
* Return TRUE if character "c" can be used as the first character in a
* variable or function name (excluding '{' and '}').
*/
-static int eval_isnamec1(c)
-int c;
+static int eval_isnamec1(int c)
{
return ASCII_ISALPHA(c) || c == '_';
}
@@ -16445,9 +15676,7 @@ int c;
/*
* Set number v: variable to "val".
*/
-void set_vim_var_nr(idx, val)
-int idx;
-long val;
+void set_vim_var_nr(int idx, long val)
{
vimvars[idx].vv_nr = val;
}
@@ -16455,8 +15684,7 @@ long val;
/*
* Get number v: variable value.
*/
-long get_vim_var_nr(idx)
-int idx;
+long get_vim_var_nr(int idx)
{
return vimvars[idx].vv_nr;
}
@@ -16464,8 +15692,7 @@ int idx;
/*
* Get string v: variable value. Uses a static buffer, can only be used once.
*/
-char_u * get_vim_var_str(idx)
-int idx;
+char_u *get_vim_var_str(int idx)
{
return get_tv_string(&vimvars[idx].vv_tv);
}
@@ -16474,8 +15701,7 @@ int idx;
* Get List v: variable value. Caller must take care of reference count when
* needed.
*/
-list_T * get_vim_var_list(idx)
-int idx;
+list_T *get_vim_var_list(int idx)
{
return vimvars[idx].vv_list;
}
@@ -16483,8 +15709,7 @@ int idx;
/*
* Set v:char to character "c".
*/
-void set_vim_var_char(c)
-int c;
+void set_vim_var_char(int c)
{
char_u buf[MB_MAXBYTES + 1];
@@ -16501,10 +15726,7 @@ int c;
* Set v:count to "count" and v:count1 to "count1".
* When "set_prevcount" is TRUE first set v:prevcount from v:count.
*/
-void set_vcount(count, count1, set_prevcount)
-long count;
-long count1;
-int set_prevcount;
+void set_vcount(long count, long count1, int set_prevcount)
{
if (set_prevcount)
vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr;
@@ -16515,10 +15737,12 @@ int set_prevcount;
/*
* Set string v: variable to a copy of "val".
*/
-void set_vim_var_string(idx, val, len)
-int idx;
-char_u *val;
-int len; /* length of "val" to use or -1 (whole string) */
+void
+set_vim_var_string (
+ int idx,
+ char_u *val,
+ int len /* length of "val" to use or -1 (whole string) */
+)
{
/* Need to do this (at least) once, since we can't initialize a union.
* Will always be invoked when "v:progname" is set. */
@@ -16536,9 +15760,7 @@ int len; /* length of "val" to use or -1 (whole string) */
/*
* Set List v: variable to "val".
*/
-void set_vim_var_list(idx, val)
-int idx;
-list_T *val;
+void set_vim_var_list(int idx, list_T *val)
{
list_unref(vimvars[idx].vv_list);
vimvars[idx].vv_list = val;
@@ -16549,8 +15771,7 @@ list_T *val;
/*
* Set v:register if needed.
*/
-void set_reg_var(c)
-int c;
+void set_reg_var(int c)
{
char_u regname;
@@ -16569,8 +15790,7 @@ int c;
* Must always be called in pairs to save and restore v:exception! Does not
* take care of memory allocations.
*/
-char_u * v_exception(oldval)
-char_u *oldval;
+char_u *v_exception(char_u *oldval)
{
if (oldval == NULL)
return vimvars[VV_EXCEPTION].vv_str;
@@ -16585,8 +15805,7 @@ char_u *oldval;
* Must always be called in pairs to save and restore v:throwpoint! Does not
* take care of memory allocations.
*/
-char_u * v_throwpoint(oldval)
-char_u *oldval;
+char_u *v_throwpoint(char_u *oldval)
{
if (oldval == NULL)
return vimvars[VV_THROWPOINT].vv_str;
@@ -16601,9 +15820,7 @@ char_u *oldval;
* If "oldarg" != NULL, restore the value to "oldarg" and return NULL.
* Must always be called in pairs!
*/
-char_u * set_cmdarg(eap, oldarg)
-exarg_T *eap;
-char_u *oldarg;
+char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
{
char_u *oldval;
char_u *newval;
@@ -16667,12 +15884,14 @@ char_u *oldarg;
* Get the value of internal variable "name".
* Return OK or FAIL.
*/
-static int get_var_tv(name, len, rettv, verbose, no_autoload)
-char_u *name;
-int len; /* length of "name" */
-typval_T *rettv; /* NULL when only checking existence */
-int verbose; /* may give error message */
-int no_autoload; /* do not use script autoloading */
+static int
+get_var_tv (
+ char_u *name,
+ int len, /* length of "name" */
+ typval_T *rettv, /* NULL when only checking existence */
+ int verbose, /* may give error message */
+ int no_autoload /* do not use script autoloading */
+)
{
int ret = OK;
typval_T *tv = NULL;
@@ -16718,11 +15937,13 @@ int no_autoload; /* do not use script autoloading */
* Also handle function call with Funcref variable: func(expr)
* Can all be combined: dict.func(expr)[idx]['func'](expr)
*/
-static int handle_subscript(arg, rettv, evaluate, verbose)
-char_u **arg;
-typval_T *rettv;
-int evaluate; /* do more than finding the end */
-int verbose; /* give error messages */
+static int
+handle_subscript (
+ char_u **arg,
+ typval_T *rettv,
+ int evaluate, /* do more than finding the end */
+ int verbose /* give error messages */
+)
{
int ret = OK;
dict_T *selfdict = NULL;
@@ -16786,7 +16007,7 @@ int verbose; /* give error messages */
* Allocate memory for a variable type-value, and make it empty (0 or NULL
* value).
*/
-static typval_T * alloc_tv() {
+static typval_T *alloc_tv(void) {
return (typval_T *)alloc_clear((unsigned)sizeof(typval_T));
}
@@ -16795,8 +16016,7 @@ static typval_T * alloc_tv() {
* The string "s" must have been allocated, it is consumed.
* Return NULL for out of memory, the variable otherwise.
*/
-static typval_T * alloc_string_tv(s)
-char_u *s;
+static typval_T *alloc_string_tv(char_u *s)
{
typval_T *rettv;
@@ -16812,8 +16032,7 @@ char_u *s;
/*
* Free the memory for a variable type-value.
*/
-void free_tv(varp)
-typval_T *varp;
+void free_tv(typval_T *varp)
{
if (varp != NULL) {
switch (varp->v_type) {
@@ -16844,8 +16063,7 @@ typval_T *varp;
/*
* Free the memory for a variable value and set the value to NULL or 0.
*/
-void clear_tv(varp)
-typval_T *varp;
+void clear_tv(typval_T *varp)
{
if (varp != NULL) {
switch (varp->v_type) {
@@ -16882,8 +16100,7 @@ typval_T *varp;
/*
* Set the value of a variable to NULL without freeing items.
*/
-static void init_tv(varp)
-typval_T *varp;
+static void init_tv(typval_T *varp)
{
if (varp != NULL)
vim_memset(varp, 0, sizeof(typval_T));
@@ -16897,17 +16114,14 @@ typval_T *varp;
* caller of incompatible types: it sets *denote to TRUE if "denote"
* is not NULL or returns -1 otherwise.
*/
-static long get_tv_number(varp)
-typval_T *varp;
+static long get_tv_number(typval_T *varp)
{
int error = FALSE;
return get_tv_number_chk(varp, &error); /* return 0L on error */
}
-long get_tv_number_chk(varp, denote)
-typval_T *varp;
-int *denote;
+long get_tv_number_chk(typval_T *varp, int *denote)
{
long n = 0L;
@@ -16947,8 +16161,7 @@ int *denote;
* Also accepts ".", "$", etc., but that only works for the current buffer.
* Returns -1 on error.
*/
-static linenr_T get_tv_lnum(argvars)
-typval_T *argvars;
+static linenr_T get_tv_lnum(typval_T *argvars)
{
typval_T rettv;
linenr_T lnum;
@@ -16968,9 +16181,7 @@ typval_T *argvars;
* Also accepts "$", then "buf" is used.
* Returns 0 on error.
*/
-static linenr_T get_tv_lnum_buf(argvars, buf)
-typval_T *argvars;
-buf_T *buf;
+static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
{
if (argvars[0].v_type == VAR_STRING
&& argvars[0].vval.v_string != NULL
@@ -16990,34 +16201,28 @@ buf_T *buf;
* get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
* NULL on error.
*/
-static char_u * get_tv_string(varp)
-typval_T *varp;
+static char_u *get_tv_string(typval_T *varp)
{
static char_u mybuf[NUMBUFLEN];
return get_tv_string_buf(varp, mybuf);
}
-static char_u * get_tv_string_buf(varp, buf)
-typval_T *varp;
-char_u *buf;
+static char_u *get_tv_string_buf(typval_T *varp, char_u *buf)
{
char_u *res = get_tv_string_buf_chk(varp, buf);
return res != NULL ? res : (char_u *)"";
}
-char_u * get_tv_string_chk(varp)
-typval_T *varp;
+char_u *get_tv_string_chk(typval_T *varp)
{
static char_u mybuf[NUMBUFLEN];
return get_tv_string_buf_chk(varp, mybuf);
}
-static char_u * get_tv_string_buf_chk(varp, buf)
-typval_T *varp;
-char_u *buf;
+static char_u *get_tv_string_buf_chk(typval_T *varp, char_u *buf)
{
switch (varp->v_type) {
case VAR_NUMBER:
@@ -17053,10 +16258,7 @@ char_u *buf;
* When "htp" is not NULL we are writing to the variable, set "htp" to the
* hashtab_T used.
*/
-static dictitem_T * find_var(name, htp, no_autoload)
-char_u *name;
-hashtab_T **htp;
-int no_autoload;
+static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload)
{
char_u *varname;
hashtab_T *ht;
@@ -17073,11 +16275,7 @@ int no_autoload;
* Find variable "varname" in hashtab "ht" with name "htname".
* Returns NULL if not found.
*/
-static dictitem_T * find_var_in_ht(ht, htname, varname, no_autoload)
-hashtab_T *ht;
-int htname;
-char_u *varname;
-int no_autoload;
+static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload)
{
hashitem_T *hi;
@@ -17121,9 +16319,7 @@ int no_autoload;
* Find the hashtab used for a variable name.
* Set "varname" to the start of name without ':'.
*/
-static hashtab_T * find_var_ht(name, varname)
-char_u *name;
-char_u **varname;
+static hashtab_T *find_var_ht(char_u *name, char_u **varname)
{
hashitem_T *hi;
@@ -17173,8 +16369,7 @@ char_u **varname;
* Note: see get_tv_string() for how long the pointer remains valid.
* Returns NULL when it doesn't exist.
*/
-char_u * get_var_value(name)
-char_u *name;
+char_u *get_var_value(char_u *name)
{
dictitem_T *v;
@@ -17188,8 +16383,7 @@ char_u *name;
* Allocate a new hashtab for a sourced script. It will be used while
* sourcing this script and when executing functions defined in the script.
*/
-void new_script_vars(id)
-scid_T id;
+void new_script_vars(scid_T id)
{
int i;
hashtab_T *ht;
@@ -17220,10 +16414,7 @@ scid_T id;
* Initialize dictionary "dict" as a scope and set variable "dict_var" to
* point to it.
*/
-void init_var_dict(dict, dict_var, scope)
-dict_T *dict;
-dictitem_T *dict_var;
-int scope;
+void init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
{
hash_init(&dict->dv_hashtab);
dict->dv_lock = 0;
@@ -17240,8 +16431,7 @@ int scope;
/*
* Unreference a dictionary initialized by init_var_dict().
*/
-void unref_var_dict(dict)
-dict_T *dict;
+void unref_var_dict(dict_T *dict)
{
/* Now the dict needs to be freed if no one else is using it, go back to
* normal reference counting. */
@@ -17254,8 +16444,7 @@ dict_T *dict;
* Frees all allocated variables and the value they contain.
* Clears hashtab "ht", does not free it.
*/
-void vars_clear(ht)
-hashtab_T *ht;
+void vars_clear(hashtab_T *ht)
{
vars_clear_ext(ht, TRUE);
}
@@ -17263,9 +16452,7 @@ hashtab_T *ht;
/*
* Like vars_clear(), but only free the value if "free_val" is TRUE.
*/
-static void vars_clear_ext(ht, free_val)
-hashtab_T *ht;
-int free_val;
+static void vars_clear_ext(hashtab_T *ht, int free_val)
{
int todo;
hashitem_T *hi;
@@ -17295,9 +16482,7 @@ int free_val;
* Delete a variable from hashtab "ht" at item "hi".
* Clear the variable value and free the dictitem.
*/
-static void delete_var(ht, hi)
-hashtab_T *ht;
-hashitem_T *hi;
+static void delete_var(hashtab_T *ht, hashitem_T *hi)
{
dictitem_T *di = HI2DI(hi);
@@ -17309,10 +16494,7 @@ hashitem_T *hi;
/*
* List the value of one internal variable.
*/
-static void list_one_var(v, prefix, first)
-dictitem_T *v;
-char_u *prefix;
-int *first;
+static void list_one_var(dictitem_T *v, char_u *prefix, int *first)
{
char_u *tofree;
char_u *s;
@@ -17325,12 +16507,14 @@ int *first;
vim_free(tofree);
}
-static void list_one_var_a(prefix, name, type, string, first)
-char_u *prefix;
-char_u *name;
-int type;
-char_u *string;
-int *first; /* when TRUE clear rest of screen and set to FALSE */
+static void
+list_one_var_a (
+ char_u *prefix,
+ char_u *name,
+ int type,
+ char_u *string,
+ int *first /* when TRUE clear rest of screen and set to FALSE */
+)
{
/* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
msg_start();
@@ -17369,10 +16553,12 @@ int *first; /* when TRUE clear rest of screen and set to FALSE */
* If the variable already exists, the value is updated.
* Otherwise the variable is created.
*/
-static void set_var(name, tv, copy)
-char_u *name;
-typval_T *tv;
-int copy; /* make copy of value in "tv" */
+static void
+set_var (
+ char_u *name,
+ typval_T *tv,
+ int copy /* make copy of value in "tv" */
+)
{
dictitem_T *v;
char_u *varname;
@@ -17472,9 +16658,7 @@ int copy; /* make copy of value in "tv" */
* Return TRUE if di_flags "flags" indicates variable "name" is read-only.
* Also give an error message.
*/
-static int var_check_ro(flags, name)
-int flags;
-char_u *name;
+static int var_check_ro(int flags, char_u *name)
{
if (flags & DI_FLAGS_RO) {
EMSG2(_(e_readonlyvar), name);
@@ -17491,9 +16675,7 @@ char_u *name;
* Return TRUE if di_flags "flags" indicates variable "name" is fixed.
* Also give an error message.
*/
-static int var_check_fixed(flags, name)
-int flags;
-char_u *name;
+static int var_check_fixed(int flags, char_u *name)
{
if (flags & DI_FLAGS_FIX) {
EMSG2(_("E795: Cannot delete variable %s"), name);
@@ -17506,9 +16688,11 @@ char_u *name;
* Check if a funcref is assigned to a valid variable name.
* Return TRUE and give an error if not.
*/
-static int var_check_func_name(name, new_var)
-char_u *name; /* points to start of variable name */
-int new_var; /* TRUE when creating the variable */
+static int
+var_check_func_name (
+ char_u *name, /* points to start of variable name */
+ int new_var /* TRUE when creating the variable */
+)
{
if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':')
&& !ASCII_ISUPPER((name[0] != NUL && name[1] == ':')
@@ -17532,8 +16716,7 @@ int new_var; /* TRUE when creating the variable */
* Check if a variable name is valid.
* Return FALSE and give an error if not.
*/
-static int valid_varname(varname)
-char_u *varname;
+static int valid_varname(char_u *varname)
{
char_u *p;
@@ -17550,9 +16733,7 @@ char_u *varname;
* Return TRUE if typeval "tv" is set to be locked (immutable).
* Also give an error message, using "name".
*/
-static int tv_check_lock(lock, name)
-int lock;
-char_u *name;
+static int tv_check_lock(int lock, char_u *name)
{
if (lock & VAR_LOCKED) {
EMSG2(_("E741: Value is locked: %s"),
@@ -17574,9 +16755,7 @@ char_u *name;
* It is OK for "from" and "to" to point to the same item. This is used to
* make a copy later.
*/
-void copy_tv(from, to)
-typval_T *from;
-typval_T *to;
+void copy_tv(typval_T *from, typval_T *to)
{
to->v_type = from->v_type;
to->v_lock = 0;
@@ -17626,11 +16805,7 @@ typval_T *to;
* reference to an already copied list/dict can be used.
* Returns FAIL or OK.
*/
-static int item_copy(from, to, deep, copyID)
-typval_T *from;
-typval_T *to;
-int deep;
-int copyID;
+static int item_copy(typval_T *from, typval_T *to, int deep, int copyID)
{
static int recurse = 0;
int ret = OK;
@@ -17689,8 +16864,7 @@ int copyID;
* newline at the end.
* ":echon expr1 ..." print each argument plain.
*/
-void ex_echo(eap)
-exarg_T *eap;
+void ex_echo(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
@@ -17777,8 +16951,7 @@ exarg_T *eap;
/*
* ":echohl {name}".
*/
-void ex_echohl(eap)
-exarg_T *eap;
+void ex_echohl(exarg_T *eap)
{
int id;
@@ -17796,8 +16969,7 @@ exarg_T *eap;
* Each gets spaces around each argument and a newline at the end for
* echo commands
*/
-void ex_execute(eap)
-exarg_T *eap;
+void ex_execute(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
@@ -17872,9 +17044,7 @@ exarg_T *eap;
* Returns NULL when no option name found. Otherwise pointer to the char
* after the option name.
*/
-static char_u * find_option_end(arg, opt_flags)
-char_u **arg;
-int *opt_flags;
+static char_u *find_option_end(char_u **arg, int *opt_flags)
{
char_u *p = *arg;
@@ -17903,8 +17073,7 @@ int *opt_flags;
/*
* ":function"
*/
-void ex_function(eap)
-exarg_T *eap;
+void ex_function(exarg_T *eap)
{
char_u *theline;
int i;
@@ -18496,11 +17665,13 @@ ret_free:
* TFN_NO_AUTOLOAD: do not use script autoloading
* Advances "pp" to just after the function name (if no error).
*/
-static char_u * trans_function_name(pp, skip, flags, fdp)
-char_u **pp;
-int skip; /* only find the end, don't evaluate */
-int flags;
-funcdict_T *fdp; /* return: info about dictionary used */
+static char_u *
+trans_function_name (
+ char_u **pp,
+ int skip, /* only find the end, don't evaluate */
+ int flags,
+ funcdict_T *fdp /* return: info about dictionary used */
+)
{
char_u *name = NULL;
char_u *start;
@@ -18662,8 +17833,7 @@ theend:
* Return 2 if "p" starts with "s:".
* Return 0 otherwise.
*/
-static int eval_fname_script(p)
-char_u *p;
+static int eval_fname_script(char_u *p)
{
if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
|| STRNICMP(p + 1, "SNR>", 4) == 0))
@@ -18677,8 +17847,7 @@ char_u *p;
* Return TRUE if "p" starts with "<SID>" or "s:".
* Only works if eval_fname_script() returned non-zero for "p"!
*/
-static int eval_fname_sid(p)
-char_u *p;
+static int eval_fname_sid(char_u *p)
{
return *p == 's' || TOUPPER_ASC(p[2]) == 'I';
}
@@ -18686,9 +17855,7 @@ char_u *p;
/*
* List the head of the function: "name(arg1, arg2)".
*/
-static void list_func_head(fp, indent)
-ufunc_T *fp;
-int indent;
+static void list_func_head(ufunc_T *fp, int indent)
{
int j;
@@ -18728,8 +17895,7 @@ int indent;
* Find a function by name, return pointer to it in ufuncs.
* Return NULL for unknown function.
*/
-static ufunc_T * find_func(name)
-char_u *name;
+static ufunc_T *find_func(char_u *name)
{
hashitem_T *hi;
@@ -18740,7 +17906,7 @@ char_u *name;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_all_functions() {
+void free_all_functions(void) {
hashitem_T *hi;
/* Need to start all over every time, because func_free() may change the
@@ -18755,8 +17921,7 @@ void free_all_functions() {
#endif
-int translated_function_exists(name)
-char_u *name;
+int translated_function_exists(char_u *name)
{
if (builtin_function(name))
return find_internal_func(name) >= 0;
@@ -18766,8 +17931,7 @@ char_u *name;
/*
* Return TRUE if a function "name" exists.
*/
-static int function_exists(name)
-char_u *name;
+static int function_exists(char_u *name)
{
char_u *nm = name;
char_u *p;
@@ -18785,9 +17949,7 @@ char_u *name;
return n;
}
-char_u * get_expanded_name(name, check)
-char_u *name;
-int check;
+char_u *get_expanded_name(char_u *name, int check)
{
char_u *nm = name;
char_u *p;
@@ -18806,8 +17968,7 @@ int check;
* Return TRUE if "name" looks like a builtin function name: starts with a
* lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR.
*/
-static int builtin_function(name)
-char_u *name;
+static int builtin_function(char_u *name)
{
return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL
&& vim_strchr(name, AUTOLOAD_CHAR) == NULL;
@@ -18816,8 +17977,7 @@ char_u *name;
/*
* Start profiling function "fp".
*/
-static void func_do_profile(fp)
-ufunc_T *fp;
+static void func_do_profile(ufunc_T *fp)
{
int len = fp->uf_lines.ga_len;
@@ -18845,8 +18005,7 @@ ufunc_T *fp;
/*
* Dump the profiling results for all functions in file "fd".
*/
-void func_dump_profile(fd)
-FILE *fd;
+void func_dump_profile(FILE *fd)
{
hashitem_T *hi;
int todo;
@@ -18906,12 +18065,14 @@ FILE *fd;
vim_free(sorttab);
}
-static void prof_sort_list(fd, sorttab, st_len, title, prefer_self)
-FILE *fd;
-ufunc_T **sorttab;
-int st_len;
-char *title;
-int prefer_self; /* when equal print only self time */
+static void
+prof_sort_list (
+ FILE *fd,
+ ufunc_T **sorttab,
+ int st_len,
+ char *title,
+ int prefer_self /* when equal print only self time */
+)
{
int i;
ufunc_T *fp;
@@ -18957,9 +18118,7 @@ int prefer_self; /* when equal print only self time */
/*
* Compare function for total time sorting.
*/
-static int prof_total_cmp(s1, s2)
-const void *s1;
-const void *s2;
+static int prof_total_cmp(const void *s1, const void *s2)
{
ufunc_T *p1, *p2;
@@ -18971,9 +18130,7 @@ const void *s2;
/*
* Compare function for self time sorting.
*/
-static int prof_self_cmp(s1, s2)
-const void *s1;
-const void *s2;
+static int prof_self_cmp(const void *s1, const void *s2)
{
ufunc_T *p1, *p2;
@@ -18987,9 +18144,11 @@ const void *s2;
* If "name" has a package name try autoloading the script for it.
* Return TRUE if a package was loaded.
*/
-static int script_autoload(name, reload)
-char_u *name;
-int reload; /* load script again when already loaded */
+static int
+script_autoload (
+ char_u *name,
+ int reload /* load script again when already loaded */
+)
{
char_u *p;
char_u *scriptname, *tofree;
@@ -19030,8 +18189,7 @@ int reload; /* load script again when already loaded */
* Return the autoload script name for a function or variable name.
* Returns NULL when out of memory.
*/
-static char_u * autoload_name(name)
-char_u *name;
+static char_u *autoload_name(char_u *name)
{
char_u *p;
char_u *scriptname;
@@ -19054,9 +18212,7 @@ char_u *name;
* Function given to ExpandGeneric() to obtain the list of user defined
* function names.
*/
-char_u * get_user_func_name(xp, idx)
-expand_T *xp;
-int idx;
+char_u *get_user_func_name(expand_T *xp, int idx)
{
static long_u done;
static hashitem_T *hi;
@@ -19096,9 +18252,7 @@ int idx;
* "buf" must be able to hold the function name plus three bytes.
* Takes care of script-local function names.
*/
-static void cat_func_name(buf, fp)
-char_u *buf;
-ufunc_T *fp;
+static void cat_func_name(char_u *buf, ufunc_T *fp)
{
if (fp->uf_name[0] == K_SPECIAL) {
STRCPY(buf, "<SNR>");
@@ -19110,8 +18264,7 @@ ufunc_T *fp;
/*
* ":delfunction {name}"
*/
-void ex_delfunction(eap)
-exarg_T *eap;
+void ex_delfunction(exarg_T *eap)
{
ufunc_T *fp = NULL;
char_u *p;
@@ -19161,8 +18314,7 @@ exarg_T *eap;
/*
* Free a function and remove it from the list of functions.
*/
-static void func_free(fp)
-ufunc_T *fp;
+static void func_free(ufunc_T *fp)
{
hashitem_T *hi;
@@ -19187,8 +18339,7 @@ ufunc_T *fp;
* Unreference a Function: decrement the reference count and free it when it
* becomes zero. Only for numbered functions.
*/
-void func_unref(name)
-char_u *name;
+void func_unref(char_u *name)
{
ufunc_T *fp;
@@ -19208,8 +18359,7 @@ char_u *name;
/*
* Count a reference to a Function.
*/
-void func_ref(name)
-char_u *name;
+void func_ref(char_u *name)
{
ufunc_T *fp;
@@ -19225,15 +18375,16 @@ char_u *name;
/*
* Call a user function.
*/
-static void call_user_func(fp, argcount, argvars, rettv, firstline, lastline,
- selfdict)
-ufunc_T *fp; /* pointer to function */
-int argcount; /* nr of args */
-typval_T *argvars; /* arguments */
-typval_T *rettv; /* return value */
-linenr_T firstline; /* first line of range */
-linenr_T lastline; /* last line of range */
-dict_T *selfdict; /* Dictionary for "self" */
+static void
+call_user_func (
+ ufunc_T *fp, /* pointer to function */
+ int argcount, /* nr of args */
+ typval_T *argvars, /* arguments */
+ typval_T *rettv, /* return value */
+ linenr_T firstline, /* first line of range */
+ linenr_T lastline, /* last line of range */
+ dict_T *selfdict /* Dictionary for "self" */
+)
{
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
@@ -19554,9 +18705,7 @@ dict_T *selfdict; /* Dictionary for "self" */
* Return TRUE if items in "fc" do not have "copyID". That means they are not
* referenced from anywhere that is in use.
*/
-static int can_free_funccal(fc, copyID)
-funccall_T *fc;
-int copyID;
+static int can_free_funccal(funccall_T *fc, int copyID)
{
return fc->l_varlist.lv_copyID != copyID
&& fc->l_vars.dv_copyID != copyID
@@ -19566,9 +18715,11 @@ int copyID;
/*
* Free "fc" and what it contains.
*/
-static void free_funccal(fc, free_val)
-funccall_T *fc;
-int free_val; /* a: vars were allocated */
+static void
+free_funccal (
+ funccall_T *fc,
+ int free_val /* a: vars were allocated */
+)
{
listitem_T *li;
@@ -19590,11 +18741,7 @@ int free_val; /* a: vars were allocated */
/*
* Add a number variable "name" to dict "dp" with value "nr".
*/
-static void add_nr_var(dp, v, name, nr)
-dict_T *dp;
-dictitem_T *v;
-char *name;
-varnumber_T nr;
+static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
{
STRCPY(v->di_key, name);
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
@@ -19607,8 +18754,7 @@ varnumber_T nr;
/*
* ":return [expr]"
*/
-void ex_return(eap)
-exarg_T *eap;
+void ex_return(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
@@ -19660,11 +18806,7 @@ exarg_T *eap;
* with the return rettv. Returns TRUE when the return can be carried out,
* FALSE when the return gets pending.
*/
-int do_return(eap, reanimate, is_cmd, rettv)
-exarg_T *eap;
-int reanimate;
-int is_cmd;
-void *rettv;
+int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
{
int idx;
struct condstack *cstack = eap->cstack;
@@ -19732,8 +18874,7 @@ void *rettv;
/*
* Free the variable with a pending return value.
*/
-void discard_pending_return(rettv)
-void *rettv;
+void discard_pending_return(void *rettv)
{
free_tv((typval_T *)rettv);
}
@@ -19742,8 +18883,7 @@ void *rettv;
* Generate a return command for producing the value of "rettv". The result
* is an allocated string. Used by report_pending() for verbose messages.
*/
-char_u * get_return_cmd(rettv)
-void *rettv;
+char_u *get_return_cmd(void *rettv)
{
char_u *s = NULL;
char_u *tofree = NULL;
@@ -19767,10 +18907,7 @@ void *rettv;
* Called by do_cmdline() to get the next line.
* Returns allocated string, or NULL for end of function.
*/
-char_u * get_func_line(c, cookie, indent)
-int c UNUSED;
-void *cookie;
-int indent UNUSED;
+char_u *get_func_line(int c, void *cookie, int indent)
{
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
@@ -19823,8 +18960,7 @@ int indent UNUSED;
* When skipping lines it may not actually be executed, but we won't find out
* until later and we need to store the time now.
*/
-void func_line_start(cookie)
-void *cookie;
+void func_line_start(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
@@ -19845,8 +18981,7 @@ void *cookie;
/*
* Called when actually executing a function line.
*/
-void func_line_exec(cookie)
-void *cookie;
+void func_line_exec(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
@@ -19858,8 +18993,7 @@ void *cookie;
/*
* Called when done with a function line.
*/
-void func_line_end(cookie)
-void *cookie;
+void func_line_end(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
@@ -19881,8 +19015,7 @@ void *cookie;
* Return TRUE if the currently active function should be ended, because a
* return was encountered or an error occurred. Used inside a ":while".
*/
-int func_has_ended(cookie)
-void *cookie;
+int func_has_ended(void *cookie)
{
funccall_T *fcp = (funccall_T *)cookie;
@@ -19895,8 +19028,7 @@ void *cookie;
/*
* return TRUE if cookie indicates a function which "abort"s on errors.
*/
-int func_has_abort(cookie)
-void *cookie;
+int func_has_abort(void *cookie)
{
return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
}
@@ -19909,8 +19041,7 @@ typedef enum {
static var_flavour_T var_flavour __ARGS((char_u *varname));
-static var_flavour_T var_flavour(varname)
-char_u *varname;
+static var_flavour_T var_flavour(char_u *varname)
{
char_u *p = varname;
@@ -19926,9 +19057,7 @@ char_u *varname;
/*
* Restore global vars that start with a capital from the viminfo file
*/
-int read_viminfo_varlist(virp, writing)
-vir_T *virp;
-int writing;
+int read_viminfo_varlist(vir_T *virp, int writing)
{
char_u *tab;
int type = VAR_NUMBER;
@@ -19985,8 +19114,7 @@ int writing;
/*
* Write global vars that start with a capital to the viminfo file
*/
-void write_viminfo_varlist(fp)
-FILE *fp;
+void write_viminfo_varlist(FILE *fp)
{
hashitem_T *hi;
dictitem_T *this_var;
@@ -20025,8 +19153,7 @@ FILE *fp;
}
}
-int store_session_globals(fd)
-FILE *fd;
+int store_session_globals(FILE *fd)
{
hashitem_T *hi;
dictitem_T *this_var;
@@ -20087,8 +19214,7 @@ FILE *fd;
* Display script name where an item was last set.
* Should only be invoked when 'verbose' is non-zero.
*/
-void last_set_msg(scriptID)
-scid_T scriptID;
+void last_set_msg(scid_T scriptID)
{
char_u *p;
@@ -20107,8 +19233,7 @@ scid_T scriptID;
/*
* List v:oldfiles in a nice way.
*/
-void ex_oldfiles(eap)
-exarg_T *eap UNUSED;
+void ex_oldfiles(exarg_T *eap)
{
list_T *l = vimvars[VV_OLDFILES].vv_list;
listitem_T *li;
@@ -20144,12 +19269,14 @@ exarg_T *eap UNUSED;
* Returns VALID_ flags or -1 for failure.
* When there is an error, *fnamep is set to NULL.
*/
-int modify_fname(src, usedlen, fnamep, bufp, fnamelen)
-char_u *src; /* string with modifiers */
-int *usedlen; /* characters after src that are used */
-char_u **fnamep; /* file name so far */
-char_u **bufp; /* buffer for allocated file name or NULL */
-int *fnamelen; /* length of fnamep */
+int
+modify_fname (
+ char_u *src, /* string with modifiers */
+ int *usedlen, /* characters after src that are used */
+ char_u **fnamep, /* file name so far */
+ char_u **bufp, /* buffer for allocated file name or NULL */
+ int *fnamelen /* length of fnamep */
+)
{
int valid = 0;
char_u *tail;
@@ -20395,11 +19522,7 @@ repeat:
* "flags" can be "g" to do a global substitute.
* Returns an allocated string, NULL for error.
*/
-char_u * do_string_sub(str, pat, sub, flags)
-char_u *str;
-char_u *pat;
-char_u *sub;
-char_u *flags;
+char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
{
int sublen;
regmatch_T regmatch;
diff --git a/src/proto/eval.pro b/src/eval.h
index c0f707cab2..d63ea3dd8b 100644
--- a/src/proto/eval.pro
+++ b/src/eval.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EVAL_H
+#define NEOVIM_EVAL_H
/* eval.c */
void eval_init __ARGS((void));
void eval_clear __ARGS((void));
@@ -148,3 +150,4 @@ int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u *
char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub,
char_u *flags));
/* vim: set ft=c : */
+#endif /* NEOVIM_EVAL_H */
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index d791d777dc..5a28167ddb 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -12,7 +12,44 @@
*/
#include "vim.h"
-#include "version.h"
+#include "version_defs.h"
+#include "ex_cmds.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "digraph.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "spell.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
static int linelen __ARGS((int *has_tab));
static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap,
@@ -32,8 +69,7 @@ help_compare __ARGS((const void *s1, const void *s2));
/*
* ":ascii" and "ga".
*/
-void do_ascii(eap)
-exarg_T *eap UNUSED;
+void do_ascii(exarg_T *eap)
{
int c;
int cval;
@@ -113,8 +149,7 @@ exarg_T *eap UNUSED;
/*
* ":left", ":center" and ":right": align text.
*/
-void ex_align(eap)
-exarg_T *eap;
+void ex_align(exarg_T *eap)
{
pos_T save_curpos;
int len;
@@ -204,8 +239,7 @@ exarg_T *eap;
/*
* Get the length of the current line, excluding trailing white space.
*/
-static int linelen(has_tab)
-int *has_tab;
+static int linelen(int *has_tab)
{
char_u *line;
char_u *first;
@@ -252,9 +286,7 @@ typedef struct {
static int
sort_compare __ARGS((const void *s1, const void *s2));
-static int sort_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int sort_compare(const void *s1, const void *s2)
{
sorti_T l1 = *(sorti_T *)s1;
sorti_T l2 = *(sorti_T *)s2;
@@ -298,8 +330,7 @@ const void *s2;
/*
* ":sort".
*/
-void ex_sort(eap)
-exarg_T *eap;
+void ex_sort(exarg_T *eap)
{
regmatch_T regmatch;
int len;
@@ -509,8 +540,7 @@ sortend:
/*
* ":retab".
*/
-void ex_retab(eap)
-exarg_T *eap;
+void ex_retab(exarg_T *eap)
{
linenr_T lnum;
int got_tab = FALSE;
@@ -642,10 +672,7 @@ exarg_T *eap;
*
* return FAIL for failure, OK otherwise
*/
-int do_move(line1, line2, dest)
-linenr_T line1;
-linenr_T line2;
-linenr_T dest;
+int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
{
char_u *str;
linenr_T l;
@@ -747,10 +774,7 @@ linenr_T dest;
/*
* ":copy"
*/
-void ex_copy(line1, line2, n)
-linenr_T line1;
-linenr_T line2;
-linenr_T n;
+void ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
{
linenr_T count;
char_u *p;
@@ -802,7 +826,7 @@ linenr_T n;
static char_u *prevcmd = NULL; /* the previous command */
#if defined(EXITFREE) || defined(PROTO)
-void free_prev_shellcmd() {
+void free_prev_shellcmd(void) {
vim_free(prevcmd);
}
@@ -813,11 +837,7 @@ void free_prev_shellcmd() {
* Bangs in the argument are replaced with the previously entered command.
* Remember the argument.
*/
-void do_bang(addr_count, eap, forceit, do_in, do_out)
-int addr_count;
-exarg_T *eap;
-int forceit;
-int do_in, do_out;
+void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
{
char_u *arg = eap->arg; /* command */
linenr_T line1 = eap->line1; /* start of range */
@@ -952,11 +972,15 @@ int do_in, do_out;
* We use input redirection if do_in is TRUE.
* We use output redirection if do_out is TRUE.
*/
-static void do_filter(line1, line2, eap, cmd, do_in, do_out)
-linenr_T line1, line2;
-exarg_T *eap; /* for forced 'ff' and 'fenc' */
-char_u *cmd;
-int do_in, do_out;
+static void
+do_filter (
+ linenr_T line1,
+ linenr_T line2,
+ exarg_T *eap, /* for forced 'ff' and 'fenc' */
+ char_u *cmd,
+ int do_in,
+ int do_out
+)
{
char_u *itmp = NULL;
char_u *otmp = NULL;
@@ -1164,9 +1188,11 @@ filterend:
* Call a shell to execute a command.
* When "cmd" is NULL start an interactive shell.
*/
-void do_shell(cmd, flags)
-char_u *cmd;
-int flags; /* may be SHELL_DOOUT when output is redirected */
+void
+do_shell (
+ char_u *cmd,
+ int flags /* may be SHELL_DOOUT when output is redirected */
+)
{
buf_T *buf;
int save_nwr;
@@ -1269,10 +1295,12 @@ int flags; /* may be SHELL_DOOUT when output is redirected */
* output redirection file.
* Returns an allocated string with the shell command, or NULL for failure.
*/
-char_u * make_filter_cmd(cmd, itmp, otmp)
-char_u *cmd; /* command */
-char_u *itmp; /* NULL or name of input file */
-char_u *otmp; /* NULL or name of output file */
+char_u *
+make_filter_cmd (
+ char_u *cmd, /* command */
+ char_u *itmp, /* NULL or name of input file */
+ char_u *otmp /* NULL or name of output file */
+)
{
char_u *buf;
long_u len;
@@ -1342,11 +1370,7 @@ char_u *otmp; /* NULL or name of output file */
* The caller should make sure that there is enough room:
* STRLEN(opt) + STRLEN(fname) + 3
*/
-void append_redir(buf, buflen, opt, fname)
-char_u *buf;
-int buflen;
-char_u *opt;
-char_u *fname;
+void append_redir(char_u *buf, int buflen, char_u *opt, char_u *fname)
{
char_u *p;
char_u *end;
@@ -1373,7 +1397,7 @@ char_u *fname;
static int no_viminfo __ARGS((void));
static int viminfo_errcnt;
-static int no_viminfo() {
+static int no_viminfo(void) {
/* "vim -i NONE" does not read or write a viminfo file */
return use_viminfo != NULL && STRCMP(use_viminfo, "NONE") == 0;
}
@@ -1382,10 +1406,7 @@ static int no_viminfo() {
* Report an error for reading a viminfo file.
* Count the number of errors. When there are more than 10, return TRUE.
*/
-int viminfo_error(errnum, message, line)
-char *errnum;
-char *message;
-char_u *line;
+int viminfo_error(char *errnum, char *message, char_u *line)
{
vim_snprintf((char *)IObuff, IOSIZE, _("%sviminfo: %s in line: "),
errnum, message);
@@ -1404,9 +1425,11 @@ char_u *line;
* read_viminfo() -- Read the viminfo file. Registers etc. which are already
* set are not over-written unless "flags" includes VIF_FORCEIT. -- webb
*/
-int read_viminfo(file, flags)
-char_u *file; /* file name or NULL to use default name */
-int flags; /* VIF_WANT_INFO et al. */
+int
+read_viminfo (
+ char_u *file, /* file name or NULL to use default name */
+ int flags /* VIF_WANT_INFO et al. */
+)
{
FILE *fp;
char_u *fname;
@@ -1448,9 +1471,7 @@ int flags; /* VIF_WANT_INFO et al. */
* If "forceit" is TRUE, then the old file is not read in, and only internal
* info is written to the file.
*/
-void write_viminfo(file, forceit)
-char_u *file;
-int forceit;
+void write_viminfo(char_u *file, int forceit)
{
char_u *fname;
FILE *fp_in = NULL; /* input viminfo file, if any */
@@ -1678,8 +1699,7 @@ end:
* expand environment variables.
* Returns an allocated string. NULL when out of memory.
*/
-static char_u * viminfo_filename(file)
-char_u *file;
+static char_u *viminfo_filename(char_u *file)
{
if (file == NULL || *file == NUL) {
if (use_viminfo != NULL)
@@ -1707,10 +1727,7 @@ char_u *file;
/*
* do_viminfo() -- Should only be called from read_viminfo() & write_viminfo().
*/
-static void do_viminfo(fp_in, fp_out, flags)
-FILE *fp_in;
-FILE *fp_out;
-int flags;
+static void do_viminfo(FILE *fp_in, FILE *fp_out, int flags)
{
int count = 0;
int eof = FALSE;
@@ -1763,10 +1780,7 @@ int flags;
* first part of the viminfo file which contains everything but the marks that
* are local to a file. Returns TRUE when end-of-file is reached. -- webb
*/
-static int read_viminfo_up_to_marks(virp, forceit, writing)
-vir_T *virp;
-int forceit;
-int writing;
+static int read_viminfo_up_to_marks(vir_T *virp, int forceit, int writing)
{
int eof;
buf_T *buf;
@@ -1843,8 +1857,7 @@ int writing;
* 'encoding'. If different and the 'c' flag is in 'viminfo', setup for
* conversion of text with iconv() in viminfo_readstring().
*/
-static int viminfo_encoding(virp)
-vir_T *virp;
+static int viminfo_encoding(vir_T *virp)
{
char_u *p;
int i;
@@ -1868,8 +1881,7 @@ vir_T *virp;
* Read a line from the viminfo file.
* Returns TRUE for end-of-file;
*/
-int viminfo_readline(virp)
-vir_T *virp;
+int viminfo_readline(vir_T *virp)
{
return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
}
@@ -1884,10 +1896,12 @@ vir_T *virp;
*
* Return the string in allocated memory (NULL when out of memory).
*/
-char_u * viminfo_readstring(virp, off, convert)
-vir_T *virp;
-int off; /* offset for virp->vir_line */
-int convert UNUSED; /* convert the string */
+char_u *
+viminfo_readstring (
+ vir_T *virp,
+ int off, /* offset for virp->vir_line */
+ int convert /* convert the string */
+)
{
char_u *retval;
char_u *s, *d;
@@ -1945,9 +1959,7 @@ int convert UNUSED; /* convert the string */
* - write " CTRL-V <length> \n " in first line
* - write " < <string> \n " in second line
*/
-void viminfo_writestring(fd, p)
-FILE *fd;
-char_u *p;
+void viminfo_writestring(FILE *fd, char_u *p)
{
int c;
char_u *s;
@@ -1983,8 +1995,7 @@ char_u *p;
* ^? ^H
* not ^? ^?
*/
-void do_fixdel(eap)
-exarg_T *eap UNUSED;
+void do_fixdel(exarg_T *eap)
{
char_u *p;
@@ -1993,10 +2004,7 @@ exarg_T *eap UNUSED;
&& *p == DEL ? (char_u *)CTRL_H_STR : DEL_STR, FALSE);
}
-void print_line_no_prefix(lnum, use_number, list)
-linenr_T lnum;
-int use_number;
-int list;
+void print_line_no_prefix(linenr_T lnum, int use_number, int list)
{
char_u numbuf[30];
@@ -2011,10 +2019,7 @@ int list;
/*
* Print a text line. Also in silent mode ("ex -s").
*/
-void print_line(lnum, use_number, list)
-linenr_T lnum;
-int use_number;
-int list;
+void print_line(linenr_T lnum, int use_number, int list)
{
int save_silent = silent_mode;
@@ -2031,8 +2036,7 @@ int list;
info_message = FALSE;
}
-int rename_buffer(new_fname)
-char_u *new_fname;
+int rename_buffer(char_u *new_fname)
{
char_u *fname, *sfname, *xfname;
buf_T *buf;
@@ -2078,8 +2082,7 @@ char_u *new_fname;
/*
* ":file[!] [fname]".
*/
-void ex_file(eap)
-exarg_T *eap;
+void ex_file(exarg_T *eap)
{
/* ":0file" removes the file name. Check for illegal uses ":3file",
* "0file name", etc. */
@@ -2102,8 +2105,7 @@ exarg_T *eap;
/*
* ":update".
*/
-void ex_update(eap)
-exarg_T *eap;
+void ex_update(exarg_T *eap)
{
if (curbufIsChanged())
(void)do_write(eap);
@@ -2112,8 +2114,7 @@ exarg_T *eap;
/*
* ":write" and ":saveas".
*/
-void ex_write(eap)
-exarg_T *eap;
+void ex_write(exarg_T *eap)
{
if (eap->usefilter) /* input lines to shell command */
do_bang(1, eap, FALSE, TRUE, FALSE);
@@ -2129,8 +2130,7 @@ exarg_T *eap;
*
* return FAIL for failure, OK otherwise
*/
-int do_write(eap)
-exarg_T *eap;
+int do_write(exarg_T *eap)
{
int other;
char_u *fname = NULL; /* init to shut up gcc */
@@ -2287,13 +2287,15 @@ theend:
* May set eap->forceit if a dialog says it's OK to overwrite.
* Return OK if it's OK, FAIL if it is not.
*/
-int check_overwrite(eap, buf, fname, ffname, other)
-exarg_T *eap;
-buf_T *buf;
-char_u *fname; /* file name to be used (can differ from
+int
+check_overwrite (
+ exarg_T *eap,
+ buf_T *buf,
+ char_u *fname, /* file name to be used (can differ from
buf->ffname) */
-char_u *ffname; /* full path version of fname */
-int other; /* writing under other name */
+ char_u *ffname, /* full path version of fname */
+ int other /* writing under other name */
+)
{
/*
* write to other file or b_flags set or not writing the whole file:
@@ -2384,8 +2386,7 @@ int other; /* writing under other name */
/*
* Handle ":wnext", ":wNext" and ":wprevious" commands.
*/
-void ex_wnext(eap)
-exarg_T *eap;
+void ex_wnext(exarg_T *eap)
{
int i;
@@ -2402,8 +2403,7 @@ exarg_T *eap;
/*
* ":wall", ":wqall" and ":xall": Write all changed files (and exit).
*/
-void do_wqall(eap)
-exarg_T *eap;
+void do_wqall(exarg_T *eap)
{
buf_T *buf;
int error = 0;
@@ -2453,7 +2453,7 @@ exarg_T *eap;
* Check the 'write' option.
* Return TRUE and give a message when it's not st.
*/
-int not_writing() {
+int not_writing(void) {
if (p_write)
return FALSE;
EMSG(_("E142: File not written: Writing is disabled by 'write' option"));
@@ -2465,9 +2465,7 @@ int not_writing() {
* read-only). Ask for overruling in a dialog. Return TRUE and give an error
* message when the buffer is readonly.
*/
-static int check_readonly(forceit, buf)
-int *forceit;
-buf_T *buf;
+static int check_readonly(int *forceit, buf_T *buf)
{
struct stat st;
@@ -2517,13 +2515,7 @@ buf_T *buf;
* -1 for successfully opening another file.
* 'lnum' is the line number for the cursor in the new file (if non-zero).
*/
-int getfile(fnum, ffname, sfname, setpm, lnum, forceit)
-int fnum;
-char_u *ffname;
-char_u *sfname;
-int setpm;
-linenr_T lnum;
-int forceit;
+int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum, int forceit)
{
int other;
int retval;
@@ -2607,14 +2599,16 @@ theend:
*
* return FAIL for failure, OK otherwise
*/
-int do_ecmd(fnum, ffname, sfname, eap, newlnum, flags, oldwin)
-int fnum;
-char_u *ffname;
-char_u *sfname;
-exarg_T *eap; /* can be NULL! */
-linenr_T newlnum;
-int flags;
-win_T *oldwin;
+int
+do_ecmd (
+ int fnum,
+ char_u *ffname,
+ char_u *sfname,
+ exarg_T *eap, /* can be NULL! */
+ linenr_T newlnum,
+ int flags,
+ win_T *oldwin
+)
{
int other_file; /* TRUE if editing another file */
int oldbuf; /* TRUE if using existing buffer */
@@ -3173,8 +3167,7 @@ theend:
return retval;
}
-static void delbuf_msg(name)
-char_u *name;
+static void delbuf_msg(char_u *name)
{
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
name == NULL ? (char_u *)"" : name);
@@ -3187,8 +3180,7 @@ static int append_indent = 0; /* autoindent for first line */
/*
* ":insert" and ":append", also used by ":change"
*/
-void ex_append(eap)
-exarg_T *eap;
+void ex_append(exarg_T *eap)
{
char_u *theline;
int did_undo = FALSE;
@@ -3312,8 +3304,7 @@ exarg_T *eap;
/*
* ":change"
*/
-void ex_change(eap)
-exarg_T *eap;
+void ex_change(exarg_T *eap)
{
linenr_T lnum;
@@ -3340,8 +3331,7 @@ exarg_T *eap;
ex_append(eap);
}
-void ex_z(eap)
-exarg_T *eap;
+void ex_z(exarg_T *eap)
{
char_u *x;
int bigness;
@@ -3460,7 +3450,7 @@ exarg_T *eap;
* If so, give an error message and return TRUE.
* Otherwise, return FALSE.
*/
-int check_restricted() {
+int check_restricted(void) {
if (restricted) {
EMSG(_("E145: Shell commands not allowed in rvim"));
return TRUE;
@@ -3473,7 +3463,7 @@ int check_restricted() {
* If so, give an error message and return TRUE.
* Otherwise, return FALSE.
*/
-int check_secure() {
+int check_secure(void) {
if (secure) {
secure = 2;
EMSG(_(e_curdir));
@@ -3504,8 +3494,7 @@ static int global_need_beginline; /* call beginline() after ":g" */
*
* The usual escapes are supported as described in the regexp docs.
*/
-void do_sub(eap)
-exarg_T *eap;
+void do_sub(exarg_T *eap)
{
linenr_T lnum;
long i = 0;
@@ -4416,8 +4405,10 @@ outofmem:
* Can also be used after a ":global" command.
* Return TRUE if a message was given.
*/
-int do_sub_msg(count_only)
-int count_only; /* used 'n' flag for ":s" */
+int
+do_sub_msg (
+ int count_only /* used 'n' flag for ":s" */
+)
{
/*
* Only report substitutions when:
@@ -4473,8 +4464,7 @@ int count_only; /* used 'n' flag for ":s" */
* for each line that has a mark. This is required because after deleting
* lines we do not know where to search for the next match.
*/
-void ex_global(eap)
-exarg_T *eap;
+void ex_global(exarg_T *eap)
{
linenr_T lnum; /* line number according to old situation */
int ndone = 0;
@@ -4571,8 +4561,7 @@ exarg_T *eap;
/*
* Execute "cmd" on lines marked with ml_setmarked().
*/
-void global_exe(cmd)
-char_u *cmd;
+void global_exe(char_u *cmd)
{
linenr_T old_lcount; /* b_ml.ml_line_count before the command */
buf_T *old_buf = curbuf; /* remember what buffer we started in */
@@ -4626,9 +4615,7 @@ char_u *cmd;
msgmore(curbuf->b_ml.ml_line_count - old_lcount);
}
-int read_viminfo_sub_string(virp, force)
-vir_T *virp;
-int force;
+int read_viminfo_sub_string(vir_T *virp, int force)
{
if (force)
vim_free(old_sub);
@@ -4637,8 +4624,7 @@ int force;
return viminfo_readline(virp);
}
-void write_viminfo_sub_string(fp)
-FILE *fp;
+void write_viminfo_sub_string(FILE *fp)
{
if (get_viminfo_parameter('/') != 0 && old_sub != NULL) {
fputs(_("\n# Last Substitute String:\n$"), fp);
@@ -4647,7 +4633,7 @@ FILE *fp;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_old_sub() {
+void free_old_sub(void) {
vim_free(old_sub);
}
@@ -4657,8 +4643,10 @@ void free_old_sub() {
* Set up for a tagpreview.
* Return TRUE when it was created.
*/
-int prepare_tagpreview(undo_sync)
-int undo_sync; /* sync undo when leaving the window */
+int
+prepare_tagpreview (
+ int undo_sync /* sync undo when leaving the window */
+)
{
win_T *wp;
@@ -4696,8 +4684,7 @@ int undo_sync; /* sync undo when leaving the window */
/*
* ":help": open a read-only window on a help file
*/
-void ex_help(eap)
-exarg_T *eap;
+void ex_help(exarg_T *eap)
{
char_u *arg;
char_u *tag;
@@ -4870,8 +4857,7 @@ erret:
* Changes the "@" to NUL if found, and returns a pointer to "xx".
* Returns NULL if not found.
*/
-char_u * check_help_lang(arg)
-char_u *arg;
+char_u *check_help_lang(char_u *arg)
{
int len = (int)STRLEN(arg);
@@ -4894,10 +4880,12 @@ char_u *arg;
* Assumption is made that the matched_string passed has already been found to
* match some string for which help is requested. webb.
*/
-int help_heuristic(matched_string, offset, wrong_case)
-char_u *matched_string;
-int offset; /* offset for match */
-int wrong_case; /* no matching case */
+int
+help_heuristic (
+ char_u *matched_string,
+ int offset, /* offset for match */
+ int wrong_case /* no matching case */
+)
{
int num_letters;
char_u *p;
@@ -4934,9 +4922,7 @@ int wrong_case; /* no matching case */
* Compare functions for qsort() below, that checks the help heuristics number
* that has been put after the tagname by find_tags().
*/
-static int help_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int help_compare(const void *s1, const void *s2)
{
char *p1;
char *p2;
@@ -4952,11 +4938,7 @@ const void *s2;
* The matches will be sorted with a "best" match algorithm.
* When "keep_lang" is TRUE try keeping the language of the current buffer.
*/
-int find_help_tags(arg, num_matches, matches, keep_lang)
-char_u *arg;
-int *num_matches;
-char_u ***matches;
-int keep_lang;
+int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_lang)
{
char_u *s, *d;
int i;
@@ -5135,7 +5117,7 @@ int keep_lang;
* After reading a help file: May cleanup a help buffer when syntax
* highlighting is not used.
*/
-void fix_help_buffer() {
+void fix_help_buffer(void) {
linenr_T lnum;
char_u *line;
int in_example = FALSE;
@@ -5331,8 +5313,7 @@ void fix_help_buffer() {
/*
* ":exusage"
*/
-void ex_exusage(eap)
-exarg_T *eap UNUSED;
+void ex_exusage(exarg_T *eap)
{
do_cmdline_cmd((char_u *)"help ex-cmd-index");
}
@@ -5340,8 +5321,7 @@ exarg_T *eap UNUSED;
/*
* ":viusage"
*/
-void ex_viusage(eap)
-exarg_T *eap UNUSED;
+void ex_viusage(exarg_T *eap)
{
do_cmdline_cmd((char_u *)"help normal-index");
}
@@ -5352,8 +5332,7 @@ static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang,
/*
* ":helptags"
*/
-void ex_helptags(eap)
-exarg_T *eap;
+void ex_helptags(exarg_T *eap)
{
garray_T ga;
int i, j;
@@ -5454,11 +5433,13 @@ exarg_T *eap;
vim_free(dirname);
}
-static void helptags_one(dir, ext, tagfname, add_help_tags)
-char_u *dir; /* doc directory */
-char_u *ext; /* suffix, ".txt", ".itx", ".frx", etc. */
-char_u *tagfname; /* "tags" for English, "tags-fr" for French. */
-int add_help_tags; /* add "help-tags" tag */
+static void
+helptags_one (
+ char_u *dir, /* doc directory */
+ char_u *ext, /* suffix, ".txt", ".itx", ".frx", etc. */
+ char_u *tagfname, /* "tags" for English, "tags-fr" for French. */
+ int add_help_tags /* add "help-tags" tag */
+)
{
FILE *fd_tags;
FILE *fd;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index a560789fef..4bb11ea20c 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1,1191 +1,76 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * This file defines the Ex commands.
- * When DO_DECLARE_EXCMD is defined, the table with ex command names and
- * options results.
- * When DO_DECLARE_EXCMD is NOT defined, the enum with all the Ex commands
- * results.
- * This clever trick was invented by Ron Aaron.
- */
-
-/*
- * When adding an Ex command:
- * 1. Add an entry in the table below. Keep it sorted on the shortest
- * version of the command name that works. If it doesn't start with a
- * lower case letter, add it at the end.
- * 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c.
- * 3. Add an entry in the index for Ex commands at ":help ex-cmd-index".
- * 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and
- * long name of the command.
- */
-
-#ifdef RANGE
-# undef RANGE /* SASC on Amiga defines it */
-#endif
-
-#define RANGE 0x001 /* allow a linespecs */
-#define BANG 0x002 /* allow a ! after the command name */
-#define EXTRA 0x004 /* allow extra args after command name */
-#define XFILE 0x008 /* expand wildcards in extra part */
-#define NOSPC 0x010 /* no spaces allowed in the extra part */
-#define DFLALL 0x020 /* default file range is 1,$ */
-#define WHOLEFOLD 0x040 /* extend range to include whole fold also
- when less than two numbers given */
-#define NEEDARG 0x080 /* argument required */
-#define TRLBAR 0x100 /* check for trailing vertical bar */
-#define REGSTR 0x200 /* allow "x for register designation */
-#define COUNT 0x400 /* allow count in argument, after command */
-#define NOTRLCOM 0x800 /* no trailing comment allowed */
-#define ZEROR 0x1000 /* zero line number allowed */
-#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
-#define NOTADR 0x4000 /* number before command is not an address */
-#define EDITCMD 0x8000 /* allow "+command" argument */
-#define BUFNAME 0x10000L /* accepts buffer name */
-#define BUFUNL 0x20000L /* accepts unlisted buffer too */
-#define ARGOPT 0x40000L /* allow "++opt=val" argument */
-#define SBOXOK 0x80000L /* allowed in the sandbox */
-#define CMDWIN 0x100000L /* allowed in cmdline window */
-#define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */
-#define EXFLAGS 0x400000L /* allow flags after count in argument */
-#define FILES (XFILE | EXTRA) /* multiple extra files allowed */
-#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
-#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
-
-#ifndef DO_DECLARE_EXCMD
-typedef struct exarg exarg_T;
-#endif
-
-/*
- * This array maps ex command names to command codes.
- * The order in which command names are listed below is significant --
- * ambiguous abbreviations are always resolved to be the first possible match
- * (e.g. "r" is taken to mean "read", not "rewind", because "read" comes
- * before "rewind").
- * Not supported commands are included to avoid ambiguities.
- */
-#ifdef EX
-# undef EX /* just in case */
-#endif
-#ifdef DO_DECLARE_EXCMD
-# define EX(a, b, c, d) {(char_u *)b, c, (long_u)(d)}
-
-typedef void (*ex_func_T) __ARGS ((exarg_T *eap));
-
-static struct cmdname {
- char_u *cmd_name; /* name of the command */
- ex_func_T cmd_func; /* function for this command */
- long_u cmd_argt; /* flags declared above */
-}
-cmdnames[] =
-#else
-# define EX(a, b, c, d) a
-enum CMD_index
-#endif
-{
- EX(CMD_append, "append", ex_append,
- BANG|RANGE|ZEROR|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_abbreviate, "abbreviate", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_abclear, "abclear", ex_abclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_aboveleft, "aboveleft", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_all, "all", ex_all,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_amenu, "amenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_anoremenu, "anoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_args, "args", ex_args,
- BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_argadd, "argadd", ex_argadd,
- BANG|NEEDARG|RANGE|NOTADR|ZEROR|FILES|TRLBAR),
- EX(CMD_argdelete, "argdelete", ex_argdelete,
- BANG|RANGE|NOTADR|FILES|TRLBAR),
- EX(CMD_argdo, "argdo", ex_listdo,
- BANG|NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_argedit, "argedit", ex_argedit,
- BANG|NEEDARG|RANGE|NOTADR|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_argglobal, "argglobal", ex_args,
- BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_arglocal, "arglocal", ex_args,
- BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_argument, "argument", ex_argument,
- BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_ascii, "ascii", do_ascii,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_autocmd, "autocmd", ex_autocmd,
- BANG|EXTRA|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_augroup, "augroup", ex_autocmd,
- BANG|WORD1|TRLBAR|CMDWIN),
- EX(CMD_aunmenu, "aunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_buffer, "buffer", ex_buffer,
- BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
- EX(CMD_bNext, "bNext", ex_bprevious,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_ball, "ball", ex_buffer_all,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_badd, "badd", ex_edit,
- NEEDARG|FILE1|EDITCMD|TRLBAR|CMDWIN),
- EX(CMD_bdelete, "bdelete", ex_bunload,
- BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
- EX(CMD_behave, "behave", ex_behave,
- NEEDARG|WORD1|TRLBAR|CMDWIN),
- EX(CMD_belowright, "belowright", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_bfirst, "bfirst", ex_brewind,
- BANG|RANGE|NOTADR|TRLBAR),
- EX(CMD_blast, "blast", ex_blast,
- BANG|RANGE|NOTADR|TRLBAR),
- EX(CMD_bmodified, "bmodified", ex_bmodified,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_bnext, "bnext", ex_bnext,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_botright, "botright", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_bprevious, "bprevious", ex_bprevious,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_brewind, "brewind", ex_brewind,
- BANG|RANGE|NOTADR|TRLBAR),
- EX(CMD_break, "break", ex_break,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_breakadd, "breakadd", ex_breakadd,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_breakdel, "breakdel", ex_breakdel,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_breaklist, "breaklist", ex_breaklist,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_browse, "browse", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
- EX(CMD_buffers, "buffers", buflist_list,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_bufdo, "bufdo", ex_listdo,
- BANG|NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_bunload, "bunload", ex_bunload,
- BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
- EX(CMD_bwipeout, "bwipeout", ex_bunload,
- BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
- EX(CMD_change, "change", ex_change,
- BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_cNext, "cNext", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cNfile, "cNfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cabbrev, "cabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cabclear, "cabclear", ex_abclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer,
- RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_caddexpr, "caddexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR),
- EX(CMD_caddfile, "caddfile", ex_cfile,
- TRLBAR|FILE1),
- EX(CMD_call, "call", ex_call,
- RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_catch, "catch", ex_catch,
- EXTRA|SBOXOK|CMDWIN),
- EX(CMD_cbuffer, "cbuffer", ex_cbuffer,
- BANG|RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_cc, "cc", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cclose, "cclose", ex_cclose,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_cd, "cd", ex_cd,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_center, "center", ex_align,
- TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
- EX(CMD_cexpr, "cexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
- EX(CMD_cfile, "cfile", ex_cfile,
- TRLBAR|FILE1|BANG),
- EX(CMD_cfirst, "cfirst", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cgetfile, "cgetfile", ex_cfile,
- TRLBAR|FILE1),
- EX(CMD_cgetbuffer, "cgetbuffer", ex_cbuffer,
- RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_cgetexpr, "cgetexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR),
- EX(CMD_chdir, "chdir", ex_cd,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_changes, "changes", ex_changes,
- TRLBAR|CMDWIN),
- EX(CMD_checkpath, "checkpath", ex_checkpath,
- TRLBAR|BANG|CMDWIN),
- EX(CMD_checktime, "checktime", ex_checktime,
- RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
- EX(CMD_clist, "clist", qf_list,
- BANG|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_clast, "clast", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_close, "close", ex_close,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_cmap, "cmap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cmapclear, "cmapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_cmenu, "cmenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cnext, "cnext", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cnewer, "cnewer", qf_age,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_cnfile, "cnfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cnoremap, "cnoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cnoreabbrev, "cnoreabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cnoremenu, "cnoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_copy, "copy", ex_copymove,
- RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_colder, "colder", qf_age,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_colorscheme, "colorscheme", ex_colorscheme,
- WORD1|TRLBAR|CMDWIN),
- EX(CMD_command, "command", ex_command,
- EXTRA|BANG|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_comclear, "comclear", ex_comclear,
- TRLBAR|CMDWIN),
- EX(CMD_compiler, "compiler", ex_compiler,
- BANG|TRLBAR|WORD1|CMDWIN),
- EX(CMD_continue, "continue", ex_continue,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_confirm, "confirm", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
- EX(CMD_copen, "copen", ex_copen,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_cprevious, "cprevious", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cpfile, "cpfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cquit, "cquit", ex_cquit,
- TRLBAR|BANG),
- EX(CMD_crewind, "crewind", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_cscope, "cscope", do_cscope,
- EXTRA|NOTRLCOM|XFILE),
- EX(CMD_cstag, "cstag", do_cstag,
- BANG|TRLBAR|WORD1),
- EX(CMD_cunmap, "cunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cunabbrev, "cunabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cunmenu, "cunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_cwindow, "cwindow", ex_cwindow,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_delete, "delete", ex_operators,
- RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_delmarks, "delmarks", ex_delmarks,
- BANG|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_debug, "debug", ex_debug,
- NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_debuggreedy, "debuggreedy", ex_debuggreedy,
- RANGE|NOTADR|ZEROR|TRLBAR|CMDWIN),
- EX(CMD_delcommand, "delcommand", ex_delcommand,
- NEEDARG|WORD1|TRLBAR|CMDWIN),
- EX(CMD_delfunction, "delfunction", ex_delfunction,
- NEEDARG|WORD1|CMDWIN),
- EX(CMD_display, "display", ex_display,
- EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_diffupdate, "diffupdate", ex_diffupdate,
- BANG|TRLBAR),
- EX(CMD_diffget, "diffget", ex_diffgetput,
- RANGE|EXTRA|TRLBAR|MODIFY),
- EX(CMD_diffoff, "diffoff", ex_diffoff,
- BANG|TRLBAR),
- EX(CMD_diffpatch, "diffpatch", ex_diffpatch,
- EXTRA|FILE1|TRLBAR|MODIFY),
- EX(CMD_diffput, "diffput", ex_diffgetput,
- RANGE|EXTRA|TRLBAR),
- EX(CMD_diffsplit, "diffsplit", ex_diffsplit,
- EXTRA|FILE1|TRLBAR),
- EX(CMD_diffthis, "diffthis", ex_diffthis,
- TRLBAR),
- EX(CMD_digraphs, "digraphs", ex_digraphs,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_djump, "djump", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
- EX(CMD_dlist, "dlist", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_doautocmd, "doautocmd", ex_doautocmd,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_doautoall, "doautoall", ex_doautoall,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_drop, "drop", ex_drop,
- FILES|EDITCMD|NEEDARG|ARGOPT|TRLBAR),
- EX(CMD_dsearch, "dsearch", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_dsplit, "dsplit", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
- EX(CMD_edit, "edit", ex_edit,
- BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_earlier, "earlier", ex_later,
- TRLBAR|EXTRA|NOSPC|CMDWIN),
- EX(CMD_echo, "echo", ex_echo,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_echoerr, "echoerr", ex_execute,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_echohl, "echohl", ex_echohl,
- EXTRA|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_echomsg, "echomsg", ex_execute,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_echon, "echon", ex_echo,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_else, "else", ex_else,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_elseif, "elseif", ex_else,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_emenu, "emenu", ex_emenu,
- NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|NOTADR|CMDWIN),
- EX(CMD_endif, "endif", ex_endif,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_endfunction, "endfunction", ex_endfunction,
- TRLBAR|CMDWIN),
- EX(CMD_endfor, "endfor", ex_endwhile,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_endtry, "endtry", ex_endtry,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_endwhile, "endwhile", ex_endwhile,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_enew, "enew", ex_edit,
- BANG|TRLBAR),
- EX(CMD_ex, "ex", ex_edit,
- BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_execute, "execute", ex_execute,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_exit, "exit", ex_exit,
- RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
- EX(CMD_exusage, "exusage", ex_exusage,
- TRLBAR),
- EX(CMD_file, "file", ex_file,
- RANGE|NOTADR|ZEROR|BANG|FILE1|TRLBAR),
- EX(CMD_files, "files", buflist_list,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_filetype, "filetype", ex_filetype,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_find, "find", ex_find,
- RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_finally, "finally", ex_finally,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_finish, "finish", ex_finish,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_first, "first", ex_rewind,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_fixdel, "fixdel", do_fixdel,
- TRLBAR|CMDWIN),
- EX(CMD_fold, "fold", ex_fold,
- RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_foldclose, "foldclose", ex_foldopen,
- RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_folddoopen, "folddoopen", ex_folddo,
- RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_folddoclosed, "folddoclosed", ex_folddo,
- RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_foldopen, "foldopen", ex_foldopen,
- RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_for, "for", ex_while,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_function, "function", ex_function,
- EXTRA|BANG|CMDWIN),
- EX(CMD_global, "global", ex_global,
- RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN),
- EX(CMD_goto, "goto", ex_goto,
- RANGE|NOTADR|COUNT|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_grep, "grep", ex_make,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_grepadd, "grepadd", ex_make,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_gui, "gui", ex_gui,
- BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
- EX(CMD_gvim, "gvim", ex_gui,
- BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
- EX(CMD_help, "help", ex_help,
- BANG|EXTRA|NOTRLCOM),
- EX(CMD_helpfind, "helpfind", ex_helpfind,
- EXTRA|NOTRLCOM),
- EX(CMD_helpgrep, "helpgrep", ex_helpgrep,
- EXTRA|NOTRLCOM|NEEDARG),
- EX(CMD_helptags, "helptags", ex_helptags,
- NEEDARG|FILES|TRLBAR|CMDWIN),
- EX(CMD_hardcopy, "hardcopy", ex_hardcopy,
- RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG),
- EX(CMD_highlight, "highlight", ex_highlight,
- BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_hide, "hide", ex_hide,
- BANG|EXTRA|NOTRLCOM),
- EX(CMD_history, "history", ex_history,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_insert, "insert", ex_append,
- BANG|RANGE|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_iabbrev, "iabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_iabclear, "iabclear", ex_abclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_if, "if", ex_if,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_ijump, "ijump", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
- EX(CMD_ilist, "ilist", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_imap, "imap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_imapclear, "imapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_imenu, "imenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_inoremap, "inoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_inoreabbrev, "inoreabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_inoremenu, "inoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_intro, "intro", ex_intro,
- TRLBAR|CMDWIN),
- EX(CMD_isearch, "isearch", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_isplit, "isplit", ex_findpat,
- BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
- EX(CMD_iunmap, "iunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_iunabbrev, "iunabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_iunmenu, "iunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_join, "join", ex_join,
- BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_jumps, "jumps", ex_jumps,
- TRLBAR|CMDWIN),
- EX(CMD_k, "k", ex_mark,
- RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_keepmarks, "keepmarks", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_keeppatterns, "keeppatterns", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_list, "list", ex_print,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
- EX(CMD_lNext, "lNext", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_lNfile, "lNfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_last, "last", ex_last,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_language, "language", ex_language,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_laddexpr, "laddexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR),
- EX(CMD_laddbuffer, "laddbuffer", ex_cbuffer,
- RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_laddfile, "laddfile", ex_cfile,
- TRLBAR|FILE1),
- EX(CMD_later, "later", ex_later,
- TRLBAR|EXTRA|NOSPC|CMDWIN),
- EX(CMD_lbuffer, "lbuffer", ex_cbuffer,
- BANG|RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_lcd, "lcd", ex_cd,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_lchdir, "lchdir", ex_cd,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_lclose, "lclose", ex_cclose,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_lcscope, "lcscope", do_cscope,
- EXTRA|NOTRLCOM|XFILE),
- EX(CMD_left, "left", ex_align,
- TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
- EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_let, "let", ex_let,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_lexpr, "lexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
- EX(CMD_lfile, "lfile", ex_cfile,
- TRLBAR|FILE1|BANG),
- EX(CMD_lfirst, "lfirst", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_lgetfile, "lgetfile", ex_cfile,
- TRLBAR|FILE1),
- EX(CMD_lgetbuffer, "lgetbuffer", ex_cbuffer,
- RANGE|NOTADR|WORD1|TRLBAR),
- EX(CMD_lgetexpr, "lgetexpr", ex_cexpr,
- NEEDARG|WORD1|NOTRLCOM|TRLBAR),
- EX(CMD_lgrep, "lgrep", ex_make,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_lgrepadd, "lgrepadd", ex_make,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_lhelpgrep, "lhelpgrep", ex_helpgrep,
- EXTRA|NOTRLCOM|NEEDARG),
- EX(CMD_ll, "ll", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_llast, "llast", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_llist, "llist", qf_list,
- BANG|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_lmap, "lmap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_lmapclear, "lmapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_lmake, "lmake", ex_make,
- BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_lnoremap, "lnoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_lnext, "lnext", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_lnewer, "lnewer", qf_age,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_lnfile, "lnfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_loadview, "loadview", ex_loadview,
- FILE1|TRLBAR),
- EX(CMD_loadkeymap, "loadkeymap", ex_loadkeymap,
- CMDWIN),
- EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_lockvar, "lockvar", ex_lockvar,
- BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
- EX(CMD_lolder, "lolder", qf_age,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_lopen, "lopen", ex_copen,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_lprevious, "lprevious", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_lpfile, "lpfile", ex_cnext,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_lrewind, "lrewind", ex_cc,
- RANGE|NOTADR|COUNT|TRLBAR|BANG),
- EX(CMD_ltag, "ltag", ex_tag,
- NOTADR|TRLBAR|BANG|WORD1),
- EX(CMD_lua, "lua", ex_lua,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_luado, "luado", ex_luado,
- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_luafile, "luafile", ex_luafile,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_lunmap, "lunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_lvimgrep, "lvimgrep", ex_vimgrep,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_lvimgrepadd, "lvimgrepadd", ex_vimgrep,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_lwindow, "lwindow", ex_cwindow,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_ls, "ls", buflist_list,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_move, "move", ex_copymove,
- RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_mark, "mark", ex_mark,
- RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_make, "make", ex_make,
- BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_map, "map", ex_map,
- BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_mapclear, "mapclear", ex_mapclear,
- EXTRA|BANG|TRLBAR|CMDWIN),
- EX(CMD_marks, "marks", do_marks,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_match, "match", ex_match,
- RANGE|NOTADR|EXTRA|CMDWIN),
- EX(CMD_menu, "menu", ex_menu,
- RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_menutranslate, "menutranslate", ex_menutranslate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_messages, "messages", ex_messages,
- TRLBAR|CMDWIN),
- EX(CMD_mkexrc, "mkexrc", ex_mkrc,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_mksession, "mksession", ex_mkrc,
- BANG|FILE1|TRLBAR),
- EX(CMD_mkspell, "mkspell", ex_mkspell,
- BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_mkvimrc, "mkvimrc", ex_mkrc,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_mkview, "mkview", ex_mkrc,
- BANG|FILE1|TRLBAR),
- EX(CMD_mode, "mode", ex_mode,
- WORD1|TRLBAR|CMDWIN),
- EX(CMD_mzscheme, "mzscheme", ex_mzscheme,
- RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK),
- EX(CMD_mzfile, "mzfile", ex_mzfile,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_next, "next", ex_next,
- RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_nbkey, "nbkey", ex_nbkey,
- EXTRA|NOTADR|NEEDARG),
- EX(CMD_nbclose, "nbclose", ex_nbclose,
- TRLBAR|CMDWIN),
- EX(CMD_nbstart, "nbstart", ex_nbstart,
- WORD1|TRLBAR|CMDWIN),
- EX(CMD_new, "new", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_nmap, "nmap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_nmapclear, "nmapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_nmenu, "nmenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_nnoremap, "nnoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_nnoremenu, "nnoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_noremap, "noremap", ex_map,
- BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_noautocmd, "noautocmd", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_nohlsearch, "nohlsearch", ex_nohlsearch,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_noreabbrev, "noreabbrev", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_noremenu, "noremenu", ex_menu,
- RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_normal, "normal", ex_normal,
- RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
- EX(CMD_number, "number", ex_print,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
- EX(CMD_nunmap, "nunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_nunmenu, "nunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_open, "open", ex_open,
- RANGE|BANG|EXTRA),
- EX(CMD_oldfiles, "oldfiles", ex_oldfiles,
- BANG|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_omap, "omap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_omapclear, "omapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_omenu, "omenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_only, "only", ex_only,
- BANG|TRLBAR),
- EX(CMD_onoremap, "onoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_onoremenu, "onoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_options, "options", ex_options,
- TRLBAR),
- EX(CMD_ounmap, "ounmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_ounmenu, "ounmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_ownsyntax, "ownsyntax", ex_ownsyntax,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_print, "print", ex_print,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK),
- EX(CMD_pclose, "pclose", ex_pclose,
- BANG|TRLBAR),
- EX(CMD_perl, "perl", ex_perl,
- RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN),
- EX(CMD_perldo, "perldo", ex_perldo,
- RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN),
- EX(CMD_pedit, "pedit", ex_pedit,
- BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_pop, "pop", ex_tag,
- RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
- EX(CMD_popup, "popup", ex_popup,
- NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN),
- EX(CMD_ppop, "ppop", ex_ptag,
- RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
- EX(CMD_preserve, "preserve", ex_preserve,
- TRLBAR),
- EX(CMD_previous, "previous", ex_previous,
- EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_promptfind, "promptfind", gui_mch_find_dialog,
- EXTRA|NOTRLCOM|CMDWIN),
- EX(CMD_promptrepl, "promptrepl", gui_mch_replace_dialog,
- EXTRA|NOTRLCOM|CMDWIN),
- EX(CMD_profile, "profile", ex_profile,
- BANG|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_profdel, "profdel", ex_breakdel,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_psearch, "psearch", ex_psearch,
- BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA),
- EX(CMD_ptag, "ptag", ex_ptag,
- RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
- EX(CMD_ptNext, "ptNext", ex_ptag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_ptfirst, "ptfirst", ex_ptag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_ptjump, "ptjump", ex_ptag,
- BANG|TRLBAR|WORD1),
- EX(CMD_ptlast, "ptlast", ex_ptag,
- BANG|TRLBAR),
- EX(CMD_ptnext, "ptnext", ex_ptag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_ptprevious, "ptprevious", ex_ptag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_ptrewind, "ptrewind", ex_ptag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_ptselect, "ptselect", ex_ptag,
- BANG|TRLBAR|WORD1),
- EX(CMD_put, "put", ex_put,
- RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|MODIFY),
- EX(CMD_pwd, "pwd", ex_pwd,
- TRLBAR|CMDWIN),
- EX(CMD_python, "python", ex_python,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_pydo, "pydo", ex_pydo,
- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_pyfile, "pyfile", ex_pyfile,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_py3, "py3", ex_py3,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_py3do, "py3do", ex_py3do,
- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_python3, "python3", ex_py3,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_py3file, "py3file", ex_py3file,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_quit, "quit", ex_quit,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_quitall, "quitall", ex_quit_all,
- BANG|TRLBAR),
- EX(CMD_qall, "qall", ex_quit_all,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_read, "read", ex_read,
- BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|MODIFY),
- EX(CMD_recover, "recover", ex_recover,
- BANG|FILE1|TRLBAR),
- EX(CMD_redo, "redo", ex_redo,
- TRLBAR|CMDWIN),
- EX(CMD_redir, "redir", ex_redir,
- BANG|FILES|TRLBAR|CMDWIN),
- EX(CMD_redraw, "redraw", ex_redraw,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_redrawstatus, "redrawstatus", ex_redrawstatus,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_registers, "registers", ex_display,
- EXTRA|NOTRLCOM|TRLBAR|CMDWIN),
- EX(CMD_resize, "resize", ex_resize,
- RANGE|NOTADR|TRLBAR|WORD1),
- EX(CMD_retab, "retab", ex_retab,
- TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|MODIFY),
- EX(CMD_return, "return", ex_return,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_rewind, "rewind", ex_rewind,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_right, "right", ex_align,
- TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
- EX(CMD_rightbelow, "rightbelow", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_runtime, "runtime", ex_runtime,
- BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_ruby, "ruby", ex_ruby,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_rubydo, "rubydo", ex_rubydo,
- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_rubyfile, "rubyfile", ex_rubyfile,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_rundo, "rundo", ex_rundo,
- NEEDARG|FILE1),
- EX(CMD_rviminfo, "rviminfo", ex_viminfo,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_substitute, "substitute", do_sub,
- RANGE|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_sNext, "sNext", ex_previous,
- EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_sargument, "sargument", ex_argument,
- BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_sall, "sall", ex_all,
- BANG|RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sandbox, "sandbox", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_saveas, "saveas", ex_write,
- BANG|DFLALL|FILE1|ARGOPT|CMDWIN|TRLBAR),
- EX(CMD_sbuffer, "sbuffer", ex_buffer,
- BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
- EX(CMD_sbNext, "sbNext", ex_bprevious,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sball, "sball", ex_buffer_all,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sbfirst, "sbfirst", ex_brewind,
- TRLBAR),
- EX(CMD_sblast, "sblast", ex_blast,
- TRLBAR),
- EX(CMD_sbmodified, "sbmodified", ex_bmodified,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sbnext, "sbnext", ex_bnext,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sbprevious, "sbprevious", ex_bprevious,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sbrewind, "sbrewind", ex_brewind,
- TRLBAR),
- EX(CMD_scriptnames, "scriptnames", ex_scriptnames,
- TRLBAR|CMDWIN),
- EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
- WORD1|TRLBAR|CMDWIN),
- EX(CMD_scscope, "scscope", do_scscope,
- EXTRA|NOTRLCOM),
- EX(CMD_set, "set", ex_set,
- TRLBAR|EXTRA|CMDWIN|SBOXOK),
- EX(CMD_setfiletype, "setfiletype", ex_setfiletype,
- TRLBAR|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_setglobal, "setglobal", ex_set,
- TRLBAR|EXTRA|CMDWIN|SBOXOK),
- EX(CMD_setlocal, "setlocal", ex_set,
- TRLBAR|EXTRA|CMDWIN|SBOXOK),
- EX(CMD_sfind, "sfind", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_sfirst, "sfirst", ex_rewind,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_shell, "shell", ex_shell,
- TRLBAR|CMDWIN),
- EX(CMD_simalt, "simalt", ex_simalt,
- NEEDARG|WORD1|TRLBAR|CMDWIN),
- EX(CMD_sign, "sign", ex_sign,
- NEEDARG|RANGE|NOTADR|EXTRA|CMDWIN),
- EX(CMD_silent, "silent", ex_wrongmodifier,
- NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_sleep, "sleep", ex_sleep,
- RANGE|NOTADR|COUNT|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_slast, "slast", ex_last,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_smagic, "smagic", ex_submagic,
- RANGE|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_smap, "smap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_smapclear, "smapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_smenu, "smenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_snext, "snext", ex_next,
- RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_sniff, "sniff", ex_sniff,
- EXTRA|TRLBAR),
- EX(CMD_snomagic, "snomagic", ex_submagic,
- RANGE|WHOLEFOLD|EXTRA|CMDWIN),
- EX(CMD_snoremap, "snoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_snoremenu, "snoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_source, "source", ex_source,
- BANG|FILE1|TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_sort, "sort", ex_sort,
- RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY),
- EX(CMD_split, "split", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_spellgood, "spellgood", ex_spell,
- BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
- EX(CMD_spelldump, "spelldump", ex_spelldump,
- BANG|TRLBAR),
- EX(CMD_spellinfo, "spellinfo", ex_spellinfo,
- TRLBAR),
- EX(CMD_spellrepall, "spellrepall", ex_spellrepall,
- TRLBAR),
- EX(CMD_spellundo, "spellundo", ex_spell,
- BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
- EX(CMD_spellwrong, "spellwrong", ex_spell,
- BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
- EX(CMD_sprevious, "sprevious", ex_previous,
- EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_srewind, "srewind", ex_rewind,
- EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_stop, "stop", ex_stop,
- TRLBAR|BANG|CMDWIN),
- EX(CMD_stag, "stag", ex_stag,
- RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
- EX(CMD_startinsert, "startinsert", ex_startinsert,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_startgreplace, "startgreplace", ex_startinsert,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_startreplace, "startreplace", ex_startinsert,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_stopinsert, "stopinsert", ex_stopinsert,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_stjump, "stjump", ex_stag,
- BANG|TRLBAR|WORD1),
- EX(CMD_stselect, "stselect", ex_stag,
- BANG|TRLBAR|WORD1),
- EX(CMD_sunhide, "sunhide", ex_buffer_all,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_sunmap, "sunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_sunmenu, "sunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_suspend, "suspend", ex_stop,
- TRLBAR|BANG|CMDWIN),
- EX(CMD_sview, "sview", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_swapname, "swapname", ex_swapname,
- TRLBAR|CMDWIN),
- EX(CMD_syntax, "syntax", ex_syntax,
- EXTRA|NOTRLCOM|CMDWIN),
- EX(CMD_syntime, "syntime", ex_syntime,
- NEEDARG|WORD1|TRLBAR|CMDWIN),
- EX(CMD_syncbind, "syncbind", ex_syncbind,
- TRLBAR),
- EX(CMD_t, "t", ex_copymove,
- RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_tNext, "tNext", ex_tag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_tag, "tag", ex_tag,
- RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
- EX(CMD_tags, "tags", do_tags,
- TRLBAR|CMDWIN),
- EX(CMD_tab, "tab", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_tabclose, "tabclose", ex_tabclose,
- RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN),
- EX(CMD_tabdo, "tabdo", ex_listdo,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_tabedit, "tabedit", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_tabfind, "tabfind", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
- EX(CMD_tabfirst, "tabfirst", ex_tabnext,
- TRLBAR),
- EX(CMD_tabmove, "tabmove", ex_tabmove,
- RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR),
- EX(CMD_tablast, "tablast", ex_tabnext,
- TRLBAR),
- EX(CMD_tabnext, "tabnext", ex_tabnext,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_tabnew, "tabnew", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_tabonly, "tabonly", ex_tabonly,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_tabprevious, "tabprevious", ex_tabnext,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_tabNext, "tabNext", ex_tabnext,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_tabrewind, "tabrewind", ex_tabnext,
- TRLBAR),
- EX(CMD_tabs, "tabs", ex_tabs,
- TRLBAR|CMDWIN),
- EX(CMD_tcl, "tcl", ex_tcl,
- RANGE|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_tcldo, "tcldo", ex_tcldo,
- RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
- EX(CMD_tclfile, "tclfile", ex_tclfile,
- RANGE|FILE1|NEEDARG|CMDWIN),
- EX(CMD_tearoff, "tearoff", ex_tearoff,
- NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN),
- EX(CMD_tfirst, "tfirst", ex_tag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_throw, "throw", ex_throw,
- EXTRA|NEEDARG|SBOXOK|CMDWIN),
- EX(CMD_tjump, "tjump", ex_tag,
- BANG|TRLBAR|WORD1),
- EX(CMD_tlast, "tlast", ex_tag,
- BANG|TRLBAR),
- EX(CMD_tmenu, "tmenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_tnext, "tnext", ex_tag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_topleft, "topleft", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_tprevious, "tprevious", ex_tag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_trewind, "trewind", ex_tag,
- RANGE|NOTADR|BANG|TRLBAR|ZEROR),
- EX(CMD_try, "try", ex_try,
- TRLBAR|SBOXOK|CMDWIN),
- EX(CMD_tselect, "tselect", ex_tag,
- BANG|TRLBAR|WORD1),
- EX(CMD_tunmenu, "tunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_undo, "undo", ex_undo,
- RANGE|NOTADR|COUNT|ZEROR|TRLBAR|CMDWIN),
- EX(CMD_undojoin, "undojoin", ex_undojoin,
- TRLBAR|CMDWIN),
- EX(CMD_undolist, "undolist", ex_undolist,
- TRLBAR|CMDWIN),
- EX(CMD_unabbreviate, "unabbreviate", ex_abbreviate,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_unhide, "unhide", ex_buffer_all,
- RANGE|NOTADR|COUNT|TRLBAR),
- EX(CMD_unlet, "unlet", ex_unlet,
- BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
- EX(CMD_unlockvar, "unlockvar", ex_lockvar,
- BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
- EX(CMD_unmap, "unmap", ex_unmap,
- BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_unmenu, "unmenu", ex_menu,
- BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_unsilent, "unsilent", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_update, "update", ex_update,
- RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
- EX(CMD_vglobal, "vglobal", ex_global,
- RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN),
- EX(CMD_version, "version", ex_version,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_verbose, "verbose", ex_wrongmodifier,
- NEEDARG|RANGE|NOTADR|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_vertical, "vertical", ex_wrongmodifier,
- NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_visual, "visual", ex_edit,
- BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_view, "view", ex_edit,
- BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_vimgrep, "vimgrep", ex_vimgrep,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_vimgrepadd, "vimgrepadd", ex_vimgrep,
- RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
- EX(CMD_viusage, "viusage", ex_viusage,
- TRLBAR),
- EX(CMD_vmap, "vmap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_vmapclear, "vmapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_vmenu, "vmenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_vnoremap, "vnoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_vnew, "vnew", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_vnoremenu, "vnoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_vsplit, "vsplit", ex_splitview,
- BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_vunmap, "vunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_vunmenu, "vunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_write, "write", ex_write,
- RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
- EX(CMD_wNext, "wNext", ex_wnext,
- RANGE|WHOLEFOLD|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
- EX(CMD_wall, "wall", do_wqall,
- BANG|TRLBAR|CMDWIN),
- EX(CMD_while, "while", ex_while,
- EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
- EX(CMD_winsize, "winsize", ex_winsize,
- EXTRA|NEEDARG|TRLBAR),
- EX(CMD_wincmd, "wincmd", ex_wincmd,
- NEEDARG|WORD1|RANGE|NOTADR),
- EX(CMD_windo, "windo", ex_listdo,
- BANG|NEEDARG|EXTRA|NOTRLCOM),
- EX(CMD_winpos, "winpos", ex_winpos,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_wnext, "wnext", ex_wnext,
- RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
- EX(CMD_wprevious, "wprevious", ex_wnext,
- RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
- EX(CMD_wq, "wq", ex_exit,
- RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
- EX(CMD_wqall, "wqall", do_wqall,
- BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
- EX(CMD_wsverb, "wsverb", ex_wsverb,
- EXTRA|NOTADR|NEEDARG),
- EX(CMD_wundo, "wundo", ex_wundo,
- BANG|NEEDARG|FILE1),
- EX(CMD_wviminfo, "wviminfo", ex_viminfo,
- BANG|FILE1|TRLBAR|CMDWIN),
- EX(CMD_xit, "xit", ex_exit,
- RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
- EX(CMD_xall, "xall", do_wqall,
- BANG|TRLBAR),
- EX(CMD_xmap, "xmap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_xmapclear, "xmapclear", ex_mapclear,
- EXTRA|TRLBAR|CMDWIN),
- EX(CMD_xmenu, "xmenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_xnoremap, "xnoremap", ex_map,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_xnoremenu, "xnoremenu", ex_menu,
- RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_xunmap, "xunmap", ex_unmap,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_xunmenu, "xunmenu", ex_menu,
- EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
- EX(CMD_yank, "yank", ex_operators,
- RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
- EX(CMD_z, "z", ex_z,
- RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN),
-
- /* commands that don't start with a lowercase letter */
- EX(CMD_bang, "!", ex_bang,
- RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
- EX(CMD_pound, "#", ex_print,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
- EX(CMD_and, "&", do_sub,
- RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
- EX(CMD_star, "*", ex_at,
- RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_lshift, "<", ex_operators,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_equal, "=", ex_equal,
- RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
- EX(CMD_rshift, ">", ex_operators,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
- EX(CMD_at, "@", ex_at,
- RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
- EX(CMD_Next, "Next", ex_previous,
- EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
- EX(CMD_Print, "Print", ex_print,
- RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
- EX(CMD_X, "X", ex_X,
- TRLBAR),
- EX(CMD_tilde, "~", do_sub,
- RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
-
-#ifndef DO_DECLARE_EXCMD
- CMD_SIZE, /* MUST be after all real commands! */
- CMD_USER = -1, /* User-defined command */
- CMD_USER_BUF = -2 /* User-defined command local to buffer */
-#endif
-};
-
-#define USER_CMDIDX(idx) ((int)(idx) < 0)
-
-#ifndef DO_DECLARE_EXCMD
-typedef enum CMD_index cmdidx_T;
-
-/*
- * Arguments used for Ex commands.
- */
-struct exarg {
- char_u *arg; /* argument of the command */
- char_u *nextcmd; /* next command (NULL if none) */
- char_u *cmd; /* the name of the command (except for :make) */
- char_u **cmdlinep; /* pointer to pointer of allocated cmdline */
- cmdidx_T cmdidx; /* the index for the command */
- long argt; /* flags for the command */
- int skip; /* don't execute the command, only parse it */
- int forceit; /* TRUE if ! present */
- int addr_count; /* the number of addresses given */
- linenr_T line1; /* the first line number */
- linenr_T line2; /* the second line number or count */
- int flags; /* extra flags after count: EXFLAG_ */
- char_u *do_ecmd_cmd; /* +command arg to be used in edited file */
- linenr_T do_ecmd_lnum; /* the line number in an edited file */
- int append; /* TRUE with ":w >>file" command */
- int usefilter; /* TRUE with ":w !command" and ":r!command" */
- int amount; /* number of '>' or '<' for shift command */
- int regname; /* register name (NUL if none) */
- int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
- int read_edit; /* ++edit argument */
- int force_ff; /* ++ff= argument (index in cmd[]) */
- int force_enc; /* ++enc= argument (index in cmd[]) */
- int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
- int useridx; /* user command index */
- char_u *errmsg; /* returned error message */
- char_u *(*getline)__ARGS((int, void *, int));
- void *cookie; /* argument for getline() */
- struct condstack *cstack; /* condition stack for ":if" etc. */
-};
-
-#define FORCE_BIN 1 /* ":edit ++bin file" */
-#define FORCE_NOBIN 2 /* ":edit ++nobin file" */
-
-/* Values for "flags" */
-#define EXFLAG_LIST 0x01 /* 'l': list */
-#define EXFLAG_NR 0x02 /* '#': number */
-#define EXFLAG_PRINT 0x04 /* 'p': print */
-
-#endif
+#ifndef NEOVIM_EX_CMDS_H
+#define NEOVIM_EX_CMDS_H
+/* ex_cmds.c */
+
+void do_ascii __ARGS((exarg_T *eap));
+void ex_align __ARGS((exarg_T *eap));
+void ex_sort __ARGS((exarg_T *eap));
+void ex_retab __ARGS((exarg_T *eap));
+int do_move __ARGS((linenr_T line1, linenr_T line2, linenr_T dest));
+void ex_copy __ARGS((linenr_T line1, linenr_T line2, linenr_T n));
+void free_prev_shellcmd __ARGS((void));
+void do_bang __ARGS((int addr_count, exarg_T *eap, int forceit, int do_in,
+ int do_out));
+void do_shell __ARGS((char_u *cmd, int flags));
+char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp));
+void append_redir __ARGS((char_u *buf, int buflen, char_u *opt, char_u *fname));
+int viminfo_error __ARGS((char *errnum, char *message, char_u *line));
+int read_viminfo __ARGS((char_u *file, int flags));
+void write_viminfo __ARGS((char_u *file, int forceit));
+int viminfo_readline __ARGS((vir_T *virp));
+char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
+void viminfo_writestring __ARGS((FILE *fd, char_u *p));
+void do_fixdel __ARGS((exarg_T *eap));
+void print_line_no_prefix __ARGS((linenr_T lnum, int use_number, int list));
+void print_line __ARGS((linenr_T lnum, int use_number, int list));
+int rename_buffer __ARGS((char_u *new_fname));
+void ex_file __ARGS((exarg_T *eap));
+void ex_update __ARGS((exarg_T *eap));
+void ex_write __ARGS((exarg_T *eap));
+int do_write __ARGS((exarg_T *eap));
+int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *
+ ffname,
+ int other));
+void ex_wnext __ARGS((exarg_T *eap));
+void do_wqall __ARGS((exarg_T *eap));
+int not_writing __ARGS((void));
+int getfile __ARGS((int fnum, char_u *ffname, char_u *sfname, int setpm,
+ linenr_T lnum,
+ int forceit));
+int do_ecmd __ARGS((int fnum, char_u *ffname, char_u *sfname, exarg_T *eap,
+ linenr_T newlnum, int flags,
+ win_T *oldwin));
+void ex_append __ARGS((exarg_T *eap));
+void ex_change __ARGS((exarg_T *eap));
+void ex_z __ARGS((exarg_T *eap));
+int check_restricted __ARGS((void));
+int check_secure __ARGS((void));
+void do_sub __ARGS((exarg_T *eap));
+int do_sub_msg __ARGS((int count_only));
+void ex_global __ARGS((exarg_T *eap));
+void global_exe __ARGS((char_u *cmd));
+int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
+void write_viminfo_sub_string __ARGS((FILE *fp));
+void free_old_sub __ARGS((void));
+int prepare_tagpreview __ARGS((int undo_sync));
+void ex_help __ARGS((exarg_T *eap));
+char_u *check_help_lang __ARGS((char_u *arg));
+int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case));
+int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches,
+ int keep_lang));
+void fix_help_buffer __ARGS((void));
+void ex_exusage __ARGS((exarg_T *eap));
+void ex_viusage __ARGS((exarg_T *eap));
+void ex_helptags __ARGS((exarg_T *eap));
+void ex_sign __ARGS((exarg_T *eap));
+void sign_gui_started __ARGS((void));
+int sign_get_attr __ARGS((int typenr, int line));
+char_u *sign_get_text __ARGS((int typenr));
+void *sign_get_image __ARGS((int typenr));
+char_u *sign_typenr2name __ARGS((int typenr));
+void free_signs __ARGS((void));
+char_u *get_sign_name __ARGS((expand_T *xp, int idx));
+void set_context_in_sign_cmd __ARGS((expand_T *xp, char_u *arg));
+void ex_drop __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
+#endif /* NEOVIM_EX_CMDS_H */
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 209fcddd67..dfda02ff19 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -12,7 +12,32 @@
*/
#include "vim.h"
-#include "version.h"
+#include "version_defs.h"
+#include "ex_cmds2.h"
+#include "buffer.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "term.h"
+#include "undo.h"
+#include "window.h"
static void cmd_source __ARGS((char_u *fname, exarg_T *eap));
@@ -64,8 +89,7 @@ static int debug_greedy = FALSE; /* batch mode debugging: don't save
* do_debug(): Debug mode.
* Repeatedly get Ex commands, until told to continue normal execution.
*/
-void do_debug(cmd)
-char_u *cmd;
+void do_debug(char_u *cmd)
{
int save_msg_scroll = msg_scroll;
int save_State = State;
@@ -247,8 +271,7 @@ char_u *cmd;
/*
* ":debug".
*/
-void ex_debug(eap)
-exarg_T *eap;
+void ex_debug(exarg_T *eap)
{
int debug_break_level_save = debug_break_level;
@@ -277,8 +300,7 @@ static char_u *debug_skipped_name;
* decide to execute something themselves.
* Called from do_one_cmd() before executing a command.
*/
-void dbg_check_breakpoint(eap)
-exarg_T *eap;
+void dbg_check_breakpoint(exarg_T *eap)
{
char_u *p;
@@ -317,8 +339,7 @@ exarg_T *eap;
* Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was
* set. Return TRUE when the debug mode is entered this time.
*/
-int dbg_check_skipped(eap)
-exarg_T *eap;
+int dbg_check_skipped(exarg_T *eap)
{
int prev_got_int;
@@ -374,9 +395,11 @@ static linenr_T debuggy_find __ARGS((int file,char_u *fname, linenr_T after,
* is allocated.
* Returns FAIL for failure.
*/
-static int dbg_parsearg(arg, gap)
-char_u *arg;
-garray_T *gap; /* either &dbg_breakp or &prof_ga */
+static int
+dbg_parsearg (
+ char_u *arg,
+ garray_T *gap /* either &dbg_breakp or &prof_ga */
+)
{
char_u *p = arg;
char_u *q;
@@ -456,8 +479,7 @@ garray_T *gap; /* either &dbg_breakp or &prof_ga */
/*
* ":breakadd".
*/
-void ex_breakadd(eap)
-exarg_T *eap;
+void ex_breakadd(exarg_T *eap)
{
struct debuggy *bp;
char_u *pat;
@@ -493,8 +515,7 @@ exarg_T *eap;
/*
* ":debuggreedy".
*/
-void ex_debuggreedy(eap)
-exarg_T *eap;
+void ex_debuggreedy(exarg_T *eap)
{
if (eap->addr_count == 0 || eap->line2 != 0)
debug_greedy = TRUE;
@@ -505,8 +526,7 @@ exarg_T *eap;
/*
* ":breakdel" and ":profdel".
*/
-void ex_breakdel(eap)
-exarg_T *eap;
+void ex_breakdel(exarg_T *eap)
{
struct debuggy *bp, *bpi;
int nr;
@@ -577,8 +597,7 @@ exarg_T *eap;
/*
* ":breaklist".
*/
-void ex_breaklist(eap)
-exarg_T *eap UNUSED;
+void ex_breaklist(exarg_T *eap)
{
struct debuggy *bp;
int i;
@@ -602,10 +621,12 @@ exarg_T *eap UNUSED;
* Find a breakpoint for a function or sourced file.
* Returns line number at which to break; zero when no matching breakpoint.
*/
-linenr_T dbg_find_breakpoint(file, fname, after)
-int file; /* TRUE for a file, FALSE for a function */
-char_u *fname; /* file or function name */
-linenr_T after; /* after this line number */
+linenr_T
+dbg_find_breakpoint (
+ int file, /* TRUE for a file, FALSE for a function */
+ char_u *fname, /* file or function name */
+ linenr_T after /* after this line number */
+)
{
return debuggy_find(file, fname, after, &dbg_breakp, NULL);
}
@@ -613,10 +634,12 @@ linenr_T after; /* after this line number */
/*
* Return TRUE if profiling is on for a function or sourced file.
*/
-int has_profiling(file, fname, fp)
-int file; /* TRUE for a file, FALSE for a function */
-char_u *fname; /* file or function name */
-int *fp; /* return: forceit */
+int
+has_profiling (
+ int file, /* TRUE for a file, FALSE for a function */
+ char_u *fname, /* file or function name */
+ int *fp /* return: forceit */
+)
{
return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
!= (linenr_T)0;
@@ -625,12 +648,14 @@ int *fp; /* return: forceit */
/*
* Common code for dbg_find_breakpoint() and has_profiling().
*/
-static linenr_T debuggy_find(file, fname, after, gap, fp)
-int file; /* TRUE for a file, FALSE for a function */
-char_u *fname; /* file or function name */
-linenr_T after; /* after this line number */
-garray_T *gap; /* either &dbg_breakp or &prof_ga */
-int *fp; /* if not NULL: return forceit */
+static linenr_T
+debuggy_find (
+ int file, /* TRUE for a file, FALSE for a function */
+ char_u *fname, /* file or function name */
+ linenr_T after, /* after this line number */
+ garray_T *gap, /* either &dbg_breakp or &prof_ga */
+ int *fp /* if not NULL: return forceit */
+)
{
struct debuggy *bp;
int i;
@@ -687,9 +712,7 @@ int *fp; /* if not NULL: return forceit */
/*
* Called when a breakpoint was encountered.
*/
-void dbg_breakpoint(name, lnum)
-char_u *name;
-linenr_T lnum;
+void dbg_breakpoint(char_u *name, linenr_T lnum)
{
/* We need to check if this line is actually executed in do_one_cmd() */
debug_breakpoint_name = name;
@@ -901,8 +924,7 @@ static proftime_T pause_time;
/*
* ":profile cmd args"
*/
-void ex_profile(eap)
-exarg_T *eap;
+void ex_profile(exarg_T *eap)
{
char_u *e;
int len;
@@ -960,9 +982,7 @@ static char *pexpand_cmds[] = {
* Function given to ExpandGeneric() to obtain the profile command
* specific expansion.
*/
-char_u * get_profile_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_profile_name(expand_T *xp, int idx)
{
switch (pexpand_what) {
case PEXP_SUBCMD:
@@ -976,9 +996,7 @@ int idx;
/*
* Handle command line completion for :profile command.
*/
-void set_context_in_profile_cmd(xp, arg)
-expand_T *xp;
-char_u *arg;
+void set_context_in_profile_cmd(expand_T *xp, char_u *arg)
{
char_u *end_subcmd;
@@ -1004,7 +1022,7 @@ char_u *arg;
/*
* Dump the profiling info.
*/
-void profile_dump() {
+void profile_dump(void) {
FILE *fd;
if (profile_fname != NULL) {
@@ -1022,8 +1040,7 @@ void profile_dump() {
/*
* Start profiling script "fp".
*/
-static void script_do_profile(si)
-scriptitem_T *si;
+static void script_do_profile(scriptitem_T *si)
{
si->sn_pr_count = 0;
profile_zero(&si->sn_pr_total);
@@ -1075,14 +1092,14 @@ static proftime_T inchar_time;
/*
* Called when starting to wait for the user to type a character.
*/
-void prof_inchar_enter() {
+void prof_inchar_enter(void) {
profile_start(&inchar_time);
}
/*
* Called when finished waiting for the user to type a character.
*/
-void prof_inchar_exit() {
+void prof_inchar_exit(void) {
profile_end(&inchar_time);
profile_add(&prof_wait_time, &inchar_time);
}
@@ -1090,8 +1107,7 @@ void prof_inchar_exit() {
/*
* Dump the profiling results for all scripts in file "fd".
*/
-static void script_dump_profile(fd)
-FILE *fd;
+static void script_dump_profile(FILE *fd)
{
int id;
scriptitem_T *si;
@@ -1142,7 +1158,7 @@ FILE *fd;
* Return TRUE when a function defined in the current script should be
* profiled.
*/
-int prof_def_func() {
+int prof_def_func(void) {
if (current_SID > 0)
return SCRIPT_ITEM(current_SID).sn_pr_force;
return FALSE;
@@ -1154,9 +1170,7 @@ int prof_def_func() {
*
* return FAIL for failure, OK otherwise
*/
-int autowrite(buf, forceit)
-buf_T *buf;
-int forceit;
+int autowrite(buf_T *buf, int forceit)
{
int r;
@@ -1177,7 +1191,7 @@ int forceit;
/*
* flush all buffers, except the ones that are readonly
*/
-void autowrite_all() {
+void autowrite_all(void) {
buf_T *buf;
if (!(p_aw || p_awa) || !p_write)
@@ -1195,9 +1209,7 @@ void autowrite_all() {
* Return TRUE if buffer was changed and cannot be abandoned.
* For flags use the CCGD_ values.
*/
-int check_changed(buf, flags)
-buf_T *buf;
-int flags;
+int check_changed(buf_T *buf, int flags)
{
int forceit = (flags & CCGD_FORCEIT);
@@ -1239,9 +1251,11 @@ int flags;
* Ask the user what to do when abandoning a changed buffer.
* Must check 'write' option first!
*/
-void dialog_changed(buf, checkall)
-buf_T *buf;
-int checkall; /* may abandon all changed buffers */
+void
+dialog_changed (
+ buf_T *buf,
+ int checkall /* may abandon all changed buffers */
+)
{
char_u buff[DIALOG_MSG_SIZE];
int ret;
@@ -1300,9 +1314,7 @@ int checkall; /* may abandon all changed buffers */
* Return TRUE if the buffer "buf" can be abandoned, either by making it
* hidden, autowriting it or unloading it.
*/
-int can_abandon(buf, forceit)
-buf_T *buf;
-int forceit;
+int can_abandon(buf_T *buf, int forceit)
{
return P_HID(buf)
|| !bufIsChanged(buf)
@@ -1316,10 +1328,7 @@ static void add_bufnum __ARGS((int *bufnrs, int *bufnump, int nr));
/*
* Add a buffer number to "bufnrs", unless it's already there.
*/
-static void add_bufnum(bufnrs, bufnump, nr)
-int *bufnrs;
-int *bufnump;
-int nr;
+static void add_bufnum(int *bufnrs, int *bufnump, int nr)
{
int i;
@@ -1334,8 +1343,10 @@ int nr;
* Return TRUE if any buffer was changed and cannot be abandoned.
* That changed buffer becomes the current buffer.
*/
-int check_changed_any(hidden)
-int hidden; /* Only check hidden buffers */
+int
+check_changed_any (
+ int hidden /* Only check hidden buffers */
+)
{
int ret = FALSE;
buf_T *buf;
@@ -1440,7 +1451,7 @@ theend:
* return FAIL if there is no file name, OK if there is one
* give error message for FAIL
*/
-int check_fname() {
+int check_fname(void) {
if (curbuf->b_ffname == NULL) {
EMSG(_(e_noname));
return FAIL;
@@ -1453,9 +1464,7 @@ int check_fname() {
*
* return FAIL for failure, OK otherwise
*/
-int buf_write_all(buf, forceit)
-buf_T *buf;
-int forceit;
+int buf_write_all(buf_T *buf, int forceit)
{
int retval;
buf_T *old_curbuf = curbuf;
@@ -1488,8 +1497,7 @@ static int alist_add_list __ARGS((int count, char_u **files, int after));
* Changes the argument in-place, puts a NUL after it. Backticks remain.
* Return a pointer to the start of the next argument.
*/
-static char_u * do_one_arg(str)
-char_u *str;
+static char_u *do_one_arg(char_u *str)
{
char_u *p;
int inbacktick;
@@ -1520,9 +1528,7 @@ char_u *str;
* Separate the arguments in "str" and return a list of pointers in the
* growarray "gap".
*/
-int get_arglist(gap, str)
-garray_T *gap;
-char_u *str;
+int get_arglist(garray_T *gap, char_u *str)
{
ga_init2(gap, (int)sizeof(char_u *), 20);
while (*str != NUL) {
@@ -1543,11 +1549,7 @@ char_u *str;
* "fnames[fcountp]". When "wig" is TRUE, removes files matching 'wildignore'.
* Return FAIL or OK.
*/
-int get_arglist_exp(str, fcountp, fnamesp, wig)
-char_u *str;
-int *fcountp;
-char_u ***fnamesp;
-int wig;
+int get_arglist_exp(char_u *str, int *fcountp, char_u ***fnamesp, int wig)
{
garray_T ga;
int i;
@@ -1573,10 +1575,12 @@ int wig;
*
* Return FAIL for failure, OK otherwise.
*/
-static int do_arglist(str, what, after)
-char_u *str;
-int what UNUSED;
-int after UNUSED; /* 0 means before first one */
+static int
+do_arglist (
+ char_u *str,
+ int what,
+ int after /* 0 means before first one */
+)
{
garray_T new_ga;
int exp_count;
@@ -1657,7 +1661,7 @@ int after UNUSED; /* 0 means before first one */
/*
* Check the validity of the arg_idx for each other window.
*/
-static void alist_check_arg_idx() {
+static void alist_check_arg_idx(void) {
win_T *win;
tabpage_T *tp;
@@ -1670,8 +1674,7 @@ static void alist_check_arg_idx() {
* Return TRUE if window "win" is editing the file at the current argument
* index.
*/
-static int editing_arg_idx(win)
-win_T *win;
+static int editing_arg_idx(win_T *win)
{
return !(win->w_arg_idx >= WARGCOUNT(win)
|| (win->w_buffer->b_fnum
@@ -1685,8 +1688,7 @@ win_T *win;
/*
* Check if window "win" is editing the w_arg_idx file in its argument list.
*/
-void check_arg_idx(win)
-win_T *win;
+void check_arg_idx(win_T *win)
{
if (WARGCOUNT(win) > 1 && !editing_arg_idx(win)) {
/* We are not editing the current entry in the argument list.
@@ -1716,8 +1718,7 @@ win_T *win;
/*
* ":args", ":argslocal" and ":argsglobal".
*/
-void ex_args(eap)
-exarg_T *eap;
+void ex_args(exarg_T *eap)
{
int i;
@@ -1773,8 +1774,7 @@ exarg_T *eap;
/*
* ":previous", ":sprevious", ":Next" and ":sNext".
*/
-void ex_previous(eap)
-exarg_T *eap;
+void ex_previous(exarg_T *eap)
{
/* If past the last one already, go to the last one. */
if (curwin->w_arg_idx - (int)eap->line2 >= ARGCOUNT)
@@ -1786,8 +1786,7 @@ exarg_T *eap;
/*
* ":rewind", ":first", ":sfirst" and ":srewind".
*/
-void ex_rewind(eap)
-exarg_T *eap;
+void ex_rewind(exarg_T *eap)
{
do_argfile(eap, 0);
}
@@ -1795,8 +1794,7 @@ exarg_T *eap;
/*
* ":last" and ":slast".
*/
-void ex_last(eap)
-exarg_T *eap;
+void ex_last(exarg_T *eap)
{
do_argfile(eap, ARGCOUNT - 1);
}
@@ -1804,8 +1802,7 @@ exarg_T *eap;
/*
* ":argument" and ":sargument".
*/
-void ex_argument(eap)
-exarg_T *eap;
+void ex_argument(exarg_T *eap)
{
int i;
@@ -1819,9 +1816,7 @@ exarg_T *eap;
/*
* Edit file "argn" of the argument lists.
*/
-void do_argfile(eap, argn)
-exarg_T *eap;
-int argn;
+void do_argfile(exarg_T *eap, int argn)
{
int other;
char_u *p;
@@ -1884,8 +1879,7 @@ int argn;
/*
* ":next", and commands that behave like it.
*/
-void ex_next(eap)
-exarg_T *eap;
+void ex_next(exarg_T *eap)
{
int i;
@@ -1911,8 +1905,7 @@ exarg_T *eap;
/*
* ":argedit"
*/
-void ex_argedit(eap)
-exarg_T *eap;
+void ex_argedit(exarg_T *eap)
{
int fnum;
int i;
@@ -1946,8 +1939,7 @@ exarg_T *eap;
/*
* ":argadd"
*/
-void ex_argadd(eap)
-exarg_T *eap;
+void ex_argadd(exarg_T *eap)
{
do_arglist(eap->arg, AL_ADD,
eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1);
@@ -1957,8 +1949,7 @@ exarg_T *eap;
/*
* ":argdelete"
*/
-void ex_argdelete(eap)
-exarg_T *eap;
+void ex_argdelete(exarg_T *eap)
{
int i;
int n;
@@ -1991,8 +1982,7 @@ exarg_T *eap;
/*
* ":argdo", ":windo", ":bufdo", ":tabdo"
*/
-void ex_listdo(eap)
-exarg_T *eap;
+void ex_listdo(exarg_T *eap)
{
int i;
win_T *wp;
@@ -2120,10 +2110,12 @@ exarg_T *eap;
* Files[] itself is not taken over.
* Returns index of first added argument. Returns -1 when failed (out of mem).
*/
-static int alist_add_list(count, files, after)
-int count;
-char_u **files;
-int after; /* where to add: 0 = before first one */
+static int
+alist_add_list (
+ int count,
+ char_u **files,
+ int after /* where to add: 0 = before first one */
+)
{
int i;
@@ -2154,8 +2146,7 @@ int after; /* where to add: 0 = before first one */
/*
* ":compiler[!] {name}"
*/
-void ex_compiler(eap)
-exarg_T *eap;
+void ex_compiler(exarg_T *eap)
{
char_u *buf;
char_u *old_cur_comp = NULL;
@@ -2216,17 +2207,14 @@ exarg_T *eap;
/*
* ":runtime {name}"
*/
-void ex_runtime(eap)
-exarg_T *eap;
+void ex_runtime(exarg_T *eap)
{
source_runtime(eap->arg, eap->forceit);
}
static void source_callback __ARGS((char_u *fname, void *cookie));
-static void source_callback(fname, cookie)
-char_u *fname;
-void *cookie UNUSED;
+static void source_callback(char_u *fname, void *cookie)
{
(void)do_source(fname, FALSE, DOSO_NONE);
}
@@ -2237,9 +2225,7 @@ void *cookie UNUSED;
* When "all" is TRUE, source all files, otherwise only the first one.
* return FAIL when no file could be sourced, OK otherwise.
*/
-int source_runtime(name, all)
-char_u *name;
-int all;
+int source_runtime(char_u *name, int all)
{
return do_in_runtimepath(name, all, source_callback, NULL);
}
@@ -2339,8 +2325,7 @@ void *cookie;
/*
* ":options"
*/
-void ex_options(eap)
-exarg_T *eap UNUSED;
+void ex_options(exarg_T *eap)
{
cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
}
@@ -2348,15 +2333,12 @@ exarg_T *eap UNUSED;
/*
* ":source {fname}"
*/
-void ex_source(eap)
-exarg_T *eap;
+void ex_source(exarg_T *eap)
{
cmd_source(eap->arg, eap);
}
-static void cmd_source(fname, eap)
-char_u *fname;
-exarg_T *eap;
+static void cmd_source(char_u *fname, exarg_T *eap)
{
if (*fname == NUL)
EMSG(_(e_argreq));
@@ -2406,8 +2388,7 @@ struct source_cookie {
/*
* Return the address holding the next breakpoint line for a source cookie.
*/
-linenr_T * source_breakpoint(cookie)
-void *cookie;
+linenr_T *source_breakpoint(void *cookie)
{
return &((struct source_cookie *)cookie)->breakpoint;
}
@@ -2415,8 +2396,7 @@ void *cookie;
/*
* Return the address holding the debug tick for a source cookie.
*/
-int * source_dbg_tick(cookie)
-void *cookie;
+int *source_dbg_tick(void *cookie)
{
return &((struct source_cookie *)cookie)->dbg_tick;
}
@@ -2424,8 +2404,7 @@ void *cookie;
/*
* Return the nesting level for a source cookie.
*/
-int source_level(cookie)
-void *cookie;
+int source_level(void *cookie)
{
return ((struct source_cookie *)cookie)->level;
}
@@ -2440,8 +2419,7 @@ static FILE *fopen_noinh_readbin __ARGS((char *filename));
* Special function to open a file without handle inheritance.
* When possible the handle is closed on exec().
*/
-static FILE * fopen_noinh_readbin(filename)
-char *filename;
+static FILE *fopen_noinh_readbin(char *filename)
{
int fd_tmp = mch_open(filename, O_RDONLY, 0);
@@ -2468,10 +2446,12 @@ char *filename;
*
* return FAIL if file could not be opened, OK otherwise
*/
-int do_source(fname, check_other, is_vimrc)
-char_u *fname;
-int check_other; /* check for .vimrc and _vimrc */
-int is_vimrc; /* DOSO_ value */
+int
+do_source (
+ char_u *fname,
+ int check_other, /* check for .vimrc and _vimrc */
+ int is_vimrc /* DOSO_ value */
+)
{
struct source_cookie cookie;
char_u *save_sourcing_name;
@@ -2773,8 +2753,7 @@ theend:
/*
* ":scriptnames"
*/
-void ex_scriptnames(eap)
-exarg_T *eap UNUSED;
+void ex_scriptnames(exarg_T *eap)
{
int i;
@@ -2790,7 +2769,7 @@ exarg_T *eap UNUSED;
/*
* Fix slashes in the list of script names for 'shellslash'.
*/
-void scriptnames_slash_adjust() {
+void scriptnames_slash_adjust(void) {
int i;
for (i = 1; i <= script_items.ga_len; ++i)
@@ -2803,8 +2782,7 @@ void scriptnames_slash_adjust() {
/*
* Get a pointer to a script name. Used for ":verbose set".
*/
-char_u * get_scriptname(id)
-scid_T id;
+char_u *get_scriptname(scid_T id)
{
if (id == SID_MODELINE)
return (char_u *)_("modeline");
@@ -2820,7 +2798,7 @@ scid_T id;
}
# if defined(EXITFREE) || defined(PROTO)
-void free_scriptnames() {
+void free_scriptnames(void) {
int i;
for (i = script_items.ga_len; i > 0; --i)
@@ -2840,10 +2818,7 @@ void free_scriptnames() {
* Test with earlier versions, MSL 2.2 is the library supplied with
* Codewarrior Pro 2.
*/
-char * fgets_cr(s, n, stream)
-char *s;
-int n;
-FILE *stream;
+char *fgets_cr(char *s, int n, FILE *stream)
{
return fgets(s, n, stream);
}
@@ -2854,10 +2829,7 @@ FILE *stream;
* For older versions of the Metrowerks library.
* At least CodeWarrior 9 needed this code.
*/
-char * fgets_cr(s, n, stream)
-char *s;
-int n;
-FILE *stream;
+char *fgets_cr(char *s, int n, FILE *stream)
{
int c = 0;
int char_read = 0;
@@ -2893,10 +2865,7 @@ FILE *stream;
* Return a pointer to the line in allocated memory.
* Return NULL for end-of-file or some error.
*/
-char_u * getsourceline(c, cookie, indent)
-int c UNUSED;
-void *cookie;
-int indent UNUSED;
+char_u *getsourceline(int c, void *cookie, int indent)
{
struct source_cookie *sp = (struct source_cookie *)cookie;
char_u *line;
@@ -2987,8 +2956,7 @@ int indent UNUSED;
return line;
}
-static char_u * get_one_sourceline(sp)
-struct source_cookie *sp;
+static char_u *get_one_sourceline(struct source_cookie *sp)
{
garray_T ga;
int len;
@@ -3126,7 +3094,7 @@ struct source_cookie *sp;
* When skipping lines it may not actually be executed, but we won't find out
* until later and we need to store the time now.
*/
-void script_line_start() {
+void script_line_start(void) {
scriptitem_T *si;
sn_prl_T *pp;
@@ -3157,7 +3125,7 @@ void script_line_start() {
/*
* Called when actually executing a function line.
*/
-void script_line_exec() {
+void script_line_exec(void) {
scriptitem_T *si;
if (current_SID <= 0 || current_SID > script_items.ga_len)
@@ -3170,7 +3138,7 @@ void script_line_exec() {
/*
* Called when done with a function line.
*/
-void script_line_end() {
+void script_line_end(void) {
scriptitem_T *si;
sn_prl_T *pp;
@@ -3196,8 +3164,7 @@ void script_line_end() {
* ":scriptencoding": Set encoding conversion for a sourced script.
* Without the multi-byte feature it's simply ignored.
*/
-void ex_scriptencoding(eap)
-exarg_T *eap UNUSED;
+void ex_scriptencoding(exarg_T *eap)
{
struct source_cookie *sp;
char_u *name;
@@ -3225,8 +3192,7 @@ exarg_T *eap UNUSED;
/*
* ":finish": Mark a sourced file as finished.
*/
-void ex_finish(eap)
-exarg_T *eap;
+void ex_finish(exarg_T *eap)
{
if (getline_equal(eap->getline, eap->cookie, getsourceline))
do_finish(eap, FALSE);
@@ -3239,9 +3205,7 @@ exarg_T *eap;
* Also called for a pending finish at the ":endtry" or after returning from
* an extra do_cmdline(). "reanimate" is used in the latter case.
*/
-void do_finish(eap, reanimate)
-exarg_T *eap;
-int reanimate;
+void do_finish(exarg_T *eap, int reanimate)
{
int idx;
@@ -3282,8 +3246,7 @@ void *cookie;
/*
* ":checktime [buffer]"
*/
-void ex_checktime(eap)
-exarg_T *eap;
+void ex_checktime(exarg_T *eap)
{
buf_T *buf;
int save_no_check_timestamps = no_check_timestamps;
@@ -3304,8 +3267,7 @@ exarg_T *eap;
# define HAVE_GET_LOCALE_VAL
static char *get_locale_val __ARGS((int what));
-static char * get_locale_val(what)
-int what;
+static char *get_locale_val(int what)
{
char *loc;
@@ -3324,7 +3286,7 @@ int what;
* Obtain the current messages language. Used to set the default for
* 'helplang'. May return NULL or an empty string.
*/
-char_u * get_mess_lang() {
+char_u *get_mess_lang(void) {
char_u *p;
# ifdef HAVE_GET_LOCALE_VAL
@@ -3355,7 +3317,7 @@ static char_u *get_mess_env __ARGS((void));
/*
* Get the language used for messages from the environment.
*/
-static char_u * get_mess_env() {
+static char_u *get_mess_env(void) {
char_u *p;
p = mch_getenv((char_u *)"LC_ALL");
@@ -3381,7 +3343,7 @@ static char_u * get_mess_env() {
* Set the "v:lang" variable according to the current locale setting.
* Also do "v:lc_time"and "v:ctype".
*/
-void set_lang_var() {
+void set_lang_var(void) {
char_u *loc;
# ifdef HAVE_GET_LOCALE_VAL
@@ -3411,8 +3373,7 @@ void set_lang_var() {
/*
* ":language": Set the language (locale).
*/
-void ex_language(eap)
-exarg_T *eap;
+void ex_language(exarg_T *eap)
{
char *loc;
char_u *p;
@@ -3519,7 +3480,7 @@ static char_u **find_locales __ARGS((void));
/*
* Lazy initialization of all available locales.
*/
-static void init_locales() {
+static void init_locales(void) {
if (!did_init_locales) {
did_init_locales = TRUE;
locales = find_locales();
@@ -3528,7 +3489,7 @@ static void init_locales() {
/* Return an array of strings for all available locales + NULL for the
* last element. Return NULL in case of error. */
-static char_u ** find_locales() {
+static char_u **find_locales(void) {
garray_T locales_ga;
char_u *loc;
@@ -3564,7 +3525,7 @@ static char_u ** find_locales() {
}
# if defined(EXITFREE) || defined(PROTO)
-void free_locales() {
+void free_locales(void) {
int i;
if (locales != NULL) {
for (i = 0; locales[i] != NULL; i++)
@@ -3580,9 +3541,7 @@ void free_locales() {
* Function given to ExpandGeneric() to obtain the possible arguments of the
* ":language" command.
*/
-char_u * get_lang_arg(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_lang_arg(expand_T *xp, int idx)
{
if (idx == 0)
return (char_u *)"messages";
@@ -3600,9 +3559,7 @@ int idx;
/*
* Function given to ExpandGeneric() to obtain the available locales.
*/
-char_u * get_locales(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_locales(expand_T *xp, int idx)
{
init_locales();
if (locales == NULL)
diff --git a/src/proto/ex_cmds2.pro b/src/ex_cmds2.h
index 51efb73455..a01096cfd7 100644
--- a/src/proto/ex_cmds2.pro
+++ b/src/ex_cmds2.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EX_CMDS2_H
+#define NEOVIM_EX_CMDS2_H
/* ex_cmds2.c */
void do_debug __ARGS((char_u *cmd));
void ex_debug __ARGS((exarg_T *eap));
@@ -91,3 +93,4 @@ void free_locales __ARGS((void));
char_u *get_lang_arg __ARGS((expand_T *xp, int idx));
char_u *get_locales __ARGS((expand_T *xp, int idx));
/* vim: set ft=c : */
+#endif /* NEOVIM_EX_CMDS2_H */
diff --git a/src/ex_cmds_defs.h b/src/ex_cmds_defs.h
new file mode 100644
index 0000000000..a560789fef
--- /dev/null
+++ b/src/ex_cmds_defs.h
@@ -0,0 +1,1191 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * This file defines the Ex commands.
+ * When DO_DECLARE_EXCMD is defined, the table with ex command names and
+ * options results.
+ * When DO_DECLARE_EXCMD is NOT defined, the enum with all the Ex commands
+ * results.
+ * This clever trick was invented by Ron Aaron.
+ */
+
+/*
+ * When adding an Ex command:
+ * 1. Add an entry in the table below. Keep it sorted on the shortest
+ * version of the command name that works. If it doesn't start with a
+ * lower case letter, add it at the end.
+ * 2. Add a "case: CMD_xxx" in the big switch in ex_docmd.c.
+ * 3. Add an entry in the index for Ex commands at ":help ex-cmd-index".
+ * 4. Add documentation in ../doc/xxx.txt. Add a tag for both the short and
+ * long name of the command.
+ */
+
+#ifdef RANGE
+# undef RANGE /* SASC on Amiga defines it */
+#endif
+
+#define RANGE 0x001 /* allow a linespecs */
+#define BANG 0x002 /* allow a ! after the command name */
+#define EXTRA 0x004 /* allow extra args after command name */
+#define XFILE 0x008 /* expand wildcards in extra part */
+#define NOSPC 0x010 /* no spaces allowed in the extra part */
+#define DFLALL 0x020 /* default file range is 1,$ */
+#define WHOLEFOLD 0x040 /* extend range to include whole fold also
+ when less than two numbers given */
+#define NEEDARG 0x080 /* argument required */
+#define TRLBAR 0x100 /* check for trailing vertical bar */
+#define REGSTR 0x200 /* allow "x for register designation */
+#define COUNT 0x400 /* allow count in argument, after command */
+#define NOTRLCOM 0x800 /* no trailing comment allowed */
+#define ZEROR 0x1000 /* zero line number allowed */
+#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
+#define NOTADR 0x4000 /* number before command is not an address */
+#define EDITCMD 0x8000 /* allow "+command" argument */
+#define BUFNAME 0x10000L /* accepts buffer name */
+#define BUFUNL 0x20000L /* accepts unlisted buffer too */
+#define ARGOPT 0x40000L /* allow "++opt=val" argument */
+#define SBOXOK 0x80000L /* allowed in the sandbox */
+#define CMDWIN 0x100000L /* allowed in cmdline window */
+#define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */
+#define EXFLAGS 0x400000L /* allow flags after count in argument */
+#define FILES (XFILE | EXTRA) /* multiple extra files allowed */
+#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
+#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
+
+#ifndef DO_DECLARE_EXCMD
+typedef struct exarg exarg_T;
+#endif
+
+/*
+ * This array maps ex command names to command codes.
+ * The order in which command names are listed below is significant --
+ * ambiguous abbreviations are always resolved to be the first possible match
+ * (e.g. "r" is taken to mean "read", not "rewind", because "read" comes
+ * before "rewind").
+ * Not supported commands are included to avoid ambiguities.
+ */
+#ifdef EX
+# undef EX /* just in case */
+#endif
+#ifdef DO_DECLARE_EXCMD
+# define EX(a, b, c, d) {(char_u *)b, c, (long_u)(d)}
+
+typedef void (*ex_func_T) __ARGS ((exarg_T *eap));
+
+static struct cmdname {
+ char_u *cmd_name; /* name of the command */
+ ex_func_T cmd_func; /* function for this command */
+ long_u cmd_argt; /* flags declared above */
+}
+cmdnames[] =
+#else
+# define EX(a, b, c, d) a
+enum CMD_index
+#endif
+{
+ EX(CMD_append, "append", ex_append,
+ BANG|RANGE|ZEROR|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_abbreviate, "abbreviate", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_abclear, "abclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_aboveleft, "aboveleft", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_all, "all", ex_all,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_amenu, "amenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_anoremenu, "anoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_args, "args", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argadd, "argadd", ex_argadd,
+ BANG|NEEDARG|RANGE|NOTADR|ZEROR|FILES|TRLBAR),
+ EX(CMD_argdelete, "argdelete", ex_argdelete,
+ BANG|RANGE|NOTADR|FILES|TRLBAR),
+ EX(CMD_argdo, "argdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_argedit, "argedit", ex_argedit,
+ BANG|NEEDARG|RANGE|NOTADR|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argglobal, "argglobal", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_arglocal, "arglocal", ex_args,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_argument, "argument", ex_argument,
+ BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_ascii, "ascii", do_ascii,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_autocmd, "autocmd", ex_autocmd,
+ BANG|EXTRA|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_augroup, "augroup", ex_autocmd,
+ BANG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_aunmenu, "aunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_buffer, "buffer", ex_buffer,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_bNext, "bNext", ex_bprevious,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_ball, "ball", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_badd, "badd", ex_edit,
+ NEEDARG|FILE1|EDITCMD|TRLBAR|CMDWIN),
+ EX(CMD_bdelete, "bdelete", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_behave, "behave", ex_behave,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_belowright, "belowright", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bfirst, "bfirst", ex_brewind,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_blast, "blast", ex_blast,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_bmodified, "bmodified", ex_bmodified,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_bnext, "bnext", ex_bnext,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_botright, "botright", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bprevious, "bprevious", ex_bprevious,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_brewind, "brewind", ex_brewind,
+ BANG|RANGE|NOTADR|TRLBAR),
+ EX(CMD_break, "break", ex_break,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_breakadd, "breakadd", ex_breakadd,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_breakdel, "breakdel", ex_breakdel,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_breaklist, "breaklist", ex_breaklist,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_browse, "browse", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_buffers, "buffers", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_bufdo, "bufdo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_bunload, "bunload", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_bwipeout, "bwipeout", ex_bunload,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_change, "change", ex_change,
+ BANG|WHOLEFOLD|RANGE|COUNT|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_cNext, "cNext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cNfile, "cNfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cabbrev, "cabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cabclear, "cabclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_caddbuffer, "caddbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_caddexpr, "caddexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_caddfile, "caddfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_call, "call", ex_call,
+ RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_catch, "catch", ex_catch,
+ EXTRA|SBOXOK|CMDWIN),
+ EX(CMD_cbuffer, "cbuffer", ex_cbuffer,
+ BANG|RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_cc, "cc", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cclose, "cclose", ex_cclose,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cd, "cd", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_center, "center", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_cexpr, "cexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+ EX(CMD_cfile, "cfile", ex_cfile,
+ TRLBAR|FILE1|BANG),
+ EX(CMD_cfirst, "cfirst", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cgetfile, "cgetfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_cgetbuffer, "cgetbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_cgetexpr, "cgetexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_chdir, "chdir", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_changes, "changes", ex_changes,
+ TRLBAR|CMDWIN),
+ EX(CMD_checkpath, "checkpath", ex_checkpath,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_checktime, "checktime", ex_checktime,
+ RANGE|NOTADR|BUFNAME|COUNT|EXTRA|TRLBAR),
+ EX(CMD_clist, "clist", qf_list,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_clast, "clast", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_close, "close", ex_close,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_cmap, "cmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cmapclear, "cmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_cmenu, "cmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnext, "cnext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cnewer, "cnewer", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cnfile, "cnfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cnoremap, "cnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnoreabbrev, "cnoreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cnoremenu, "cnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_copy, "copy", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_colder, "colder", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_colorscheme, "colorscheme", ex_colorscheme,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_command, "command", ex_command,
+ EXTRA|BANG|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_comclear, "comclear", ex_comclear,
+ TRLBAR|CMDWIN),
+ EX(CMD_compiler, "compiler", ex_compiler,
+ BANG|TRLBAR|WORD1|CMDWIN),
+ EX(CMD_continue, "continue", ex_continue,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_confirm, "confirm", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_copen, "copen", ex_copen,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_cprevious, "cprevious", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cpfile, "cpfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cquit, "cquit", ex_cquit,
+ TRLBAR|BANG),
+ EX(CMD_crewind, "crewind", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_cscope, "cscope", do_cscope,
+ EXTRA|NOTRLCOM|XFILE),
+ EX(CMD_cstag, "cstag", do_cstag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_cunmap, "cunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cunabbrev, "cunabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cunmenu, "cunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_cwindow, "cwindow", ex_cwindow,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_delete, "delete", ex_operators,
+ RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_delmarks, "delmarks", ex_delmarks,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_debug, "debug", ex_debug,
+ NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_debuggreedy, "debuggreedy", ex_debuggreedy,
+ RANGE|NOTADR|ZEROR|TRLBAR|CMDWIN),
+ EX(CMD_delcommand, "delcommand", ex_delcommand,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_delfunction, "delfunction", ex_delfunction,
+ NEEDARG|WORD1|CMDWIN),
+ EX(CMD_display, "display", ex_display,
+ EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_diffupdate, "diffupdate", ex_diffupdate,
+ BANG|TRLBAR),
+ EX(CMD_diffget, "diffget", ex_diffgetput,
+ RANGE|EXTRA|TRLBAR|MODIFY),
+ EX(CMD_diffoff, "diffoff", ex_diffoff,
+ BANG|TRLBAR),
+ EX(CMD_diffpatch, "diffpatch", ex_diffpatch,
+ EXTRA|FILE1|TRLBAR|MODIFY),
+ EX(CMD_diffput, "diffput", ex_diffgetput,
+ RANGE|EXTRA|TRLBAR),
+ EX(CMD_diffsplit, "diffsplit", ex_diffsplit,
+ EXTRA|FILE1|TRLBAR),
+ EX(CMD_diffthis, "diffthis", ex_diffthis,
+ TRLBAR),
+ EX(CMD_digraphs, "digraphs", ex_digraphs,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_djump, "djump", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_dlist, "dlist", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_doautocmd, "doautocmd", ex_doautocmd,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_doautoall, "doautoall", ex_doautoall,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_drop, "drop", ex_drop,
+ FILES|EDITCMD|NEEDARG|ARGOPT|TRLBAR),
+ EX(CMD_dsearch, "dsearch", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_dsplit, "dsplit", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_edit, "edit", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_earlier, "earlier", ex_later,
+ TRLBAR|EXTRA|NOSPC|CMDWIN),
+ EX(CMD_echo, "echo", ex_echo,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echoerr, "echoerr", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echohl, "echohl", ex_echohl,
+ EXTRA|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_echomsg, "echomsg", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_echon, "echon", ex_echo,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_else, "else", ex_else,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_elseif, "elseif", ex_else,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_emenu, "emenu", ex_emenu,
+ NEEDARG|EXTRA|TRLBAR|NOTRLCOM|RANGE|NOTADR|CMDWIN),
+ EX(CMD_endif, "endif", ex_endif,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endfunction, "endfunction", ex_endfunction,
+ TRLBAR|CMDWIN),
+ EX(CMD_endfor, "endfor", ex_endwhile,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endtry, "endtry", ex_endtry,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_endwhile, "endwhile", ex_endwhile,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_enew, "enew", ex_edit,
+ BANG|TRLBAR),
+ EX(CMD_ex, "ex", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_execute, "execute", ex_execute,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_exit, "exit", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_exusage, "exusage", ex_exusage,
+ TRLBAR),
+ EX(CMD_file, "file", ex_file,
+ RANGE|NOTADR|ZEROR|BANG|FILE1|TRLBAR),
+ EX(CMD_files, "files", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_filetype, "filetype", ex_filetype,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_find, "find", ex_find,
+ RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_finally, "finally", ex_finally,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_finish, "finish", ex_finish,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_first, "first", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_fixdel, "fixdel", do_fixdel,
+ TRLBAR|CMDWIN),
+ EX(CMD_fold, "fold", ex_fold,
+ RANGE|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_foldclose, "foldclose", ex_foldopen,
+ RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_folddoopen, "folddoopen", ex_folddo,
+ RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_folddoclosed, "folddoclosed", ex_folddo,
+ RANGE|DFLALL|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_foldopen, "foldopen", ex_foldopen,
+ RANGE|BANG|WHOLEFOLD|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_for, "for", ex_while,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_function, "function", ex_function,
+ EXTRA|BANG|CMDWIN),
+ EX(CMD_global, "global", ex_global,
+ RANGE|WHOLEFOLD|BANG|EXTRA|DFLALL|SBOXOK|CMDWIN),
+ EX(CMD_goto, "goto", ex_goto,
+ RANGE|NOTADR|COUNT|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_grep, "grep", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_grepadd, "grepadd", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_gui, "gui", ex_gui,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+ EX(CMD_gvim, "gvim", ex_gui,
+ BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN),
+ EX(CMD_help, "help", ex_help,
+ BANG|EXTRA|NOTRLCOM),
+ EX(CMD_helpfind, "helpfind", ex_helpfind,
+ EXTRA|NOTRLCOM),
+ EX(CMD_helpgrep, "helpgrep", ex_helpgrep,
+ EXTRA|NOTRLCOM|NEEDARG),
+ EX(CMD_helptags, "helptags", ex_helptags,
+ NEEDARG|FILES|TRLBAR|CMDWIN),
+ EX(CMD_hardcopy, "hardcopy", ex_hardcopy,
+ RANGE|COUNT|EXTRA|TRLBAR|DFLALL|BANG),
+ EX(CMD_highlight, "highlight", ex_highlight,
+ BANG|EXTRA|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_hide, "hide", ex_hide,
+ BANG|EXTRA|NOTRLCOM),
+ EX(CMD_history, "history", ex_history,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_insert, "insert", ex_append,
+ BANG|RANGE|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_iabbrev, "iabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iabclear, "iabclear", ex_abclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_if, "if", ex_if,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_ijump, "ijump", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_ilist, "ilist", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_imap, "imap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_imapclear, "imapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_imenu, "imenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoremap, "inoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoreabbrev, "inoreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_inoremenu, "inoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_intro, "intro", ex_intro,
+ TRLBAR|CMDWIN),
+ EX(CMD_isearch, "isearch", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_isplit, "isplit", ex_findpat,
+ BANG|RANGE|DFLALL|WHOLEFOLD|EXTRA),
+ EX(CMD_iunmap, "iunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iunabbrev, "iunabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_iunmenu, "iunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_join, "join", ex_join,
+ BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_jumps, "jumps", ex_jumps,
+ TRLBAR|CMDWIN),
+ EX(CMD_k, "k", ex_mark,
+ RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_keepmarks, "keepmarks", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keeppatterns, "keeppatterns", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_list, "list", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_lNext, "lNext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lNfile, "lNfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_last, "last", ex_last,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_language, "language", ex_language,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_laddexpr, "laddexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_laddbuffer, "laddbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_laddfile, "laddfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_later, "later", ex_later,
+ TRLBAR|EXTRA|NOSPC|CMDWIN),
+ EX(CMD_lbuffer, "lbuffer", ex_cbuffer,
+ BANG|RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_lcd, "lcd", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_lchdir, "lchdir", ex_cd,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_lclose, "lclose", ex_cclose,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lcscope, "lcscope", do_cscope,
+ EXTRA|NOTRLCOM|XFILE),
+ EX(CMD_left, "left", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_let, "let", ex_let,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_lexpr, "lexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
+ EX(CMD_lfile, "lfile", ex_cfile,
+ TRLBAR|FILE1|BANG),
+ EX(CMD_lfirst, "lfirst", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lgetfile, "lgetfile", ex_cfile,
+ TRLBAR|FILE1),
+ EX(CMD_lgetbuffer, "lgetbuffer", ex_cbuffer,
+ RANGE|NOTADR|WORD1|TRLBAR),
+ EX(CMD_lgetexpr, "lgetexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR),
+ EX(CMD_lgrep, "lgrep", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lgrepadd, "lgrepadd", ex_make,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lhelpgrep, "lhelpgrep", ex_helpgrep,
+ EXTRA|NOTRLCOM|NEEDARG),
+ EX(CMD_ll, "ll", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_llast, "llast", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_llist, "llist", qf_list,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lmap, "lmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lmapclear, "lmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lmake, "lmake", ex_make,
+ BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lnoremap, "lnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lnext, "lnext", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lnewer, "lnewer", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lnfile, "lnfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_loadview, "loadview", ex_loadview,
+ FILE1|TRLBAR),
+ EX(CMD_loadkeymap, "loadkeymap", ex_loadkeymap,
+ CMDWIN),
+ EX(CMD_lockmarks, "lockmarks", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_lockvar, "lockvar", ex_lockvar,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_lolder, "lolder", qf_age,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lopen, "lopen", ex_copen,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_lprevious, "lprevious", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lpfile, "lpfile", ex_cnext,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_lrewind, "lrewind", ex_cc,
+ RANGE|NOTADR|COUNT|TRLBAR|BANG),
+ EX(CMD_ltag, "ltag", ex_tag,
+ NOTADR|TRLBAR|BANG|WORD1),
+ EX(CMD_lua, "lua", ex_lua,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_luado, "luado", ex_luado,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_luafile, "luafile", ex_luafile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_lunmap, "lunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_lvimgrep, "lvimgrep", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lvimgrepadd, "lvimgrepadd", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_lwindow, "lwindow", ex_cwindow,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_ls, "ls", buflist_list,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_move, "move", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_mark, "mark", ex_mark,
+ RANGE|WORD1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_make, "make", ex_make,
+ BANG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_map, "map", ex_map,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_mapclear, "mapclear", ex_mapclear,
+ EXTRA|BANG|TRLBAR|CMDWIN),
+ EX(CMD_marks, "marks", do_marks,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_match, "match", ex_match,
+ RANGE|NOTADR|EXTRA|CMDWIN),
+ EX(CMD_menu, "menu", ex_menu,
+ RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_menutranslate, "menutranslate", ex_menutranslate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_messages, "messages", ex_messages,
+ TRLBAR|CMDWIN),
+ EX(CMD_mkexrc, "mkexrc", ex_mkrc,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_mksession, "mksession", ex_mkrc,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_mkspell, "mkspell", ex_mkspell,
+ BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_mkvimrc, "mkvimrc", ex_mkrc,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_mkview, "mkview", ex_mkrc,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_mode, "mode", ex_mode,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_mzscheme, "mzscheme", ex_mzscheme,
+ RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN|SBOXOK),
+ EX(CMD_mzfile, "mzfile", ex_mzfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_next, "next", ex_next,
+ RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_nbkey, "nbkey", ex_nbkey,
+ EXTRA|NOTADR|NEEDARG),
+ EX(CMD_nbclose, "nbclose", ex_nbclose,
+ TRLBAR|CMDWIN),
+ EX(CMD_nbstart, "nbstart", ex_nbstart,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_new, "new", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_nmap, "nmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nmapclear, "nmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_nmenu, "nmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nnoremap, "nnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nnoremenu, "nnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noremap, "noremap", ex_map,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noautocmd, "noautocmd", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_nohlsearch, "nohlsearch", ex_nohlsearch,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_noreabbrev, "noreabbrev", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_noremenu, "noremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_normal, "normal", ex_normal,
+ RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
+ EX(CMD_number, "number", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_nunmap, "nunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_nunmenu, "nunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_open, "open", ex_open,
+ RANGE|BANG|EXTRA),
+ EX(CMD_oldfiles, "oldfiles", ex_oldfiles,
+ BANG|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_omap, "omap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_omapclear, "omapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_omenu, "omenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_only, "only", ex_only,
+ BANG|TRLBAR),
+ EX(CMD_onoremap, "onoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_onoremenu, "onoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_options, "options", ex_options,
+ TRLBAR),
+ EX(CMD_ounmap, "ounmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_ounmenu, "ounmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_ownsyntax, "ownsyntax", ex_ownsyntax,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_print, "print", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK),
+ EX(CMD_pclose, "pclose", ex_pclose,
+ BANG|TRLBAR),
+ EX(CMD_perl, "perl", ex_perl,
+ RANGE|EXTRA|DFLALL|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_perldo, "perldo", ex_perldo,
+ RANGE|EXTRA|DFLALL|NEEDARG|CMDWIN),
+ EX(CMD_pedit, "pedit", ex_pedit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_pop, "pop", ex_tag,
+ RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+ EX(CMD_popup, "popup", ex_popup,
+ NEEDARG|EXTRA|BANG|TRLBAR|NOTRLCOM|CMDWIN),
+ EX(CMD_ppop, "ppop", ex_ptag,
+ RANGE|NOTADR|BANG|COUNT|TRLBAR|ZEROR),
+ EX(CMD_preserve, "preserve", ex_preserve,
+ TRLBAR),
+ EX(CMD_previous, "previous", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_promptfind, "promptfind", gui_mch_find_dialog,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_promptrepl, "promptrepl", gui_mch_replace_dialog,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_profile, "profile", ex_profile,
+ BANG|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_profdel, "profdel", ex_breakdel,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_psearch, "psearch", ex_psearch,
+ BANG|RANGE|WHOLEFOLD|DFLALL|EXTRA),
+ EX(CMD_ptag, "ptag", ex_ptag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_ptNext, "ptNext", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptfirst, "ptfirst", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptjump, "ptjump", ex_ptag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_ptlast, "ptlast", ex_ptag,
+ BANG|TRLBAR),
+ EX(CMD_ptnext, "ptnext", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptprevious, "ptprevious", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptrewind, "ptrewind", ex_ptag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_ptselect, "ptselect", ex_ptag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_put, "put", ex_put,
+ RANGE|WHOLEFOLD|BANG|REGSTR|TRLBAR|ZEROR|CMDWIN|MODIFY),
+ EX(CMD_pwd, "pwd", ex_pwd,
+ TRLBAR|CMDWIN),
+ EX(CMD_python, "python", ex_python,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_pydo, "pydo", ex_pydo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_pyfile, "pyfile", ex_pyfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_py3, "py3", ex_py3,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_py3do, "py3do", ex_py3do,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_python3, "python3", ex_py3,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_py3file, "py3file", ex_py3file,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_quit, "quit", ex_quit,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_quitall, "quitall", ex_quit_all,
+ BANG|TRLBAR),
+ EX(CMD_qall, "qall", ex_quit_all,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_read, "read", ex_read,
+ BANG|RANGE|WHOLEFOLD|FILE1|ARGOPT|TRLBAR|ZEROR|CMDWIN|MODIFY),
+ EX(CMD_recover, "recover", ex_recover,
+ BANG|FILE1|TRLBAR),
+ EX(CMD_redo, "redo", ex_redo,
+ TRLBAR|CMDWIN),
+ EX(CMD_redir, "redir", ex_redir,
+ BANG|FILES|TRLBAR|CMDWIN),
+ EX(CMD_redraw, "redraw", ex_redraw,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_redrawstatus, "redrawstatus", ex_redrawstatus,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_registers, "registers", ex_display,
+ EXTRA|NOTRLCOM|TRLBAR|CMDWIN),
+ EX(CMD_resize, "resize", ex_resize,
+ RANGE|NOTADR|TRLBAR|WORD1),
+ EX(CMD_retab, "retab", ex_retab,
+ TRLBAR|RANGE|WHOLEFOLD|DFLALL|BANG|WORD1|CMDWIN|MODIFY),
+ EX(CMD_return, "return", ex_return,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_rewind, "rewind", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_right, "right", ex_align,
+ TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_rightbelow, "rightbelow", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_runtime, "runtime", ex_runtime,
+ BANG|NEEDARG|FILES|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_ruby, "ruby", ex_ruby,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_rubydo, "rubydo", ex_rubydo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_rubyfile, "rubyfile", ex_rubyfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_rundo, "rundo", ex_rundo,
+ NEEDARG|FILE1),
+ EX(CMD_rviminfo, "rviminfo", ex_viminfo,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_substitute, "substitute", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_sNext, "sNext", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sargument, "sargument", ex_argument,
+ BANG|RANGE|NOTADR|COUNT|EXTRA|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sall, "sall", ex_all,
+ BANG|RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sandbox, "sandbox", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_saveas, "saveas", ex_write,
+ BANG|DFLALL|FILE1|ARGOPT|CMDWIN|TRLBAR),
+ EX(CMD_sbuffer, "sbuffer", ex_buffer,
+ BANG|RANGE|NOTADR|BUFNAME|BUFUNL|COUNT|EXTRA|TRLBAR),
+ EX(CMD_sbNext, "sbNext", ex_bprevious,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sball, "sball", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbfirst, "sbfirst", ex_brewind,
+ TRLBAR),
+ EX(CMD_sblast, "sblast", ex_blast,
+ TRLBAR),
+ EX(CMD_sbmodified, "sbmodified", ex_bmodified,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbnext, "sbnext", ex_bnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbprevious, "sbprevious", ex_bprevious,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sbrewind, "sbrewind", ex_brewind,
+ TRLBAR),
+ EX(CMD_scriptnames, "scriptnames", ex_scriptnames,
+ TRLBAR|CMDWIN),
+ EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding,
+ WORD1|TRLBAR|CMDWIN),
+ EX(CMD_scscope, "scscope", do_scscope,
+ EXTRA|NOTRLCOM),
+ EX(CMD_set, "set", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_setfiletype, "setfiletype", ex_setfiletype,
+ TRLBAR|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_setglobal, "setglobal", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_setlocal, "setlocal", ex_set,
+ TRLBAR|EXTRA|CMDWIN|SBOXOK),
+ EX(CMD_sfind, "sfind", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sfirst, "sfirst", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_shell, "shell", ex_shell,
+ TRLBAR|CMDWIN),
+ EX(CMD_simalt, "simalt", ex_simalt,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_sign, "sign", ex_sign,
+ NEEDARG|RANGE|NOTADR|EXTRA|CMDWIN),
+ EX(CMD_silent, "silent", ex_wrongmodifier,
+ NEEDARG|EXTRA|BANG|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_sleep, "sleep", ex_sleep,
+ RANGE|NOTADR|COUNT|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_slast, "slast", ex_last,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_smagic, "smagic", ex_submagic,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_smap, "smap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_smapclear, "smapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_smenu, "smenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_snext, "snext", ex_next,
+ RANGE|NOTADR|BANG|FILES|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_sniff, "sniff", ex_sniff,
+ EXTRA|TRLBAR),
+ EX(CMD_snomagic, "snomagic", ex_submagic,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN),
+ EX(CMD_snoremap, "snoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_snoremenu, "snoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_source, "source", ex_source,
+ BANG|FILE1|TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_sort, "sort", ex_sort,
+ RANGE|DFLALL|WHOLEFOLD|BANG|EXTRA|NOTRLCOM|MODIFY),
+ EX(CMD_split, "split", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_spellgood, "spellgood", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_spelldump, "spelldump", ex_spelldump,
+ BANG|TRLBAR),
+ EX(CMD_spellinfo, "spellinfo", ex_spellinfo,
+ TRLBAR),
+ EX(CMD_spellrepall, "spellrepall", ex_spellrepall,
+ TRLBAR),
+ EX(CMD_spellundo, "spellundo", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_spellwrong, "spellwrong", ex_spell,
+ BANG|RANGE|NOTADR|NEEDARG|EXTRA|TRLBAR),
+ EX(CMD_sprevious, "sprevious", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_srewind, "srewind", ex_rewind,
+ EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_stop, "stop", ex_stop,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_stag, "stag", ex_stag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_startinsert, "startinsert", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_startgreplace, "startgreplace", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_startreplace, "startreplace", ex_startinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_stopinsert, "stopinsert", ex_stopinsert,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_stjump, "stjump", ex_stag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_stselect, "stselect", ex_stag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_sunhide, "sunhide", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_sunmap, "sunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_sunmenu, "sunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_suspend, "suspend", ex_stop,
+ TRLBAR|BANG|CMDWIN),
+ EX(CMD_sview, "sview", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_swapname, "swapname", ex_swapname,
+ TRLBAR|CMDWIN),
+ EX(CMD_syntax, "syntax", ex_syntax,
+ EXTRA|NOTRLCOM|CMDWIN),
+ EX(CMD_syntime, "syntime", ex_syntime,
+ NEEDARG|WORD1|TRLBAR|CMDWIN),
+ EX(CMD_syncbind, "syncbind", ex_syncbind,
+ TRLBAR),
+ EX(CMD_t, "t", ex_copymove,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_tNext, "tNext", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_tag, "tag", ex_tag,
+ RANGE|NOTADR|BANG|WORD1|TRLBAR|ZEROR),
+ EX(CMD_tags, "tags", do_tags,
+ TRLBAR|CMDWIN),
+ EX(CMD_tab, "tab", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tabclose, "tabclose", ex_tabclose,
+ RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN),
+ EX(CMD_tabdo, "tabdo", ex_listdo,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tabedit, "tabedit", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_tabfind, "tabfind", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|NEEDARG|TRLBAR),
+ EX(CMD_tabfirst, "tabfirst", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabmove, "tabmove", ex_tabmove,
+ RANGE|NOTADR|ZEROR|EXTRA|NOSPC|TRLBAR),
+ EX(CMD_tablast, "tablast", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabnext, "tabnext", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabnew, "tabnew", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|ZEROR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_tabonly, "tabonly", ex_tabonly,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_tabprevious, "tabprevious", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabNext, "tabNext", ex_tabnext,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_tabrewind, "tabrewind", ex_tabnext,
+ TRLBAR),
+ EX(CMD_tabs, "tabs", ex_tabs,
+ TRLBAR|CMDWIN),
+ EX(CMD_tcl, "tcl", ex_tcl,
+ RANGE|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_tcldo, "tcldo", ex_tcldo,
+ RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
+ EX(CMD_tclfile, "tclfile", ex_tclfile,
+ RANGE|FILE1|NEEDARG|CMDWIN),
+ EX(CMD_tearoff, "tearoff", ex_tearoff,
+ NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN),
+ EX(CMD_tfirst, "tfirst", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_throw, "throw", ex_throw,
+ EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_tjump, "tjump", ex_tag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_tlast, "tlast", ex_tag,
+ BANG|TRLBAR),
+ EX(CMD_tmenu, "tmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_tnext, "tnext", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_topleft, "topleft", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_tprevious, "tprevious", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_trewind, "trewind", ex_tag,
+ RANGE|NOTADR|BANG|TRLBAR|ZEROR),
+ EX(CMD_try, "try", ex_try,
+ TRLBAR|SBOXOK|CMDWIN),
+ EX(CMD_tselect, "tselect", ex_tag,
+ BANG|TRLBAR|WORD1),
+ EX(CMD_tunmenu, "tunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_undo, "undo", ex_undo,
+ RANGE|NOTADR|COUNT|ZEROR|TRLBAR|CMDWIN),
+ EX(CMD_undojoin, "undojoin", ex_undojoin,
+ TRLBAR|CMDWIN),
+ EX(CMD_undolist, "undolist", ex_undolist,
+ TRLBAR|CMDWIN),
+ EX(CMD_unabbreviate, "unabbreviate", ex_abbreviate,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unhide, "unhide", ex_buffer_all,
+ RANGE|NOTADR|COUNT|TRLBAR),
+ EX(CMD_unlet, "unlet", ex_unlet,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_unlockvar, "unlockvar", ex_lockvar,
+ BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN),
+ EX(CMD_unmap, "unmap", ex_unmap,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unmenu, "unmenu", ex_menu,
+ BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_unsilent, "unsilent", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_update, "update", ex_update,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_vglobal, "vglobal", ex_global,
+ RANGE|WHOLEFOLD|EXTRA|DFLALL|CMDWIN),
+ EX(CMD_version, "version", ex_version,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_verbose, "verbose", ex_wrongmodifier,
+ NEEDARG|RANGE|NOTADR|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_vertical, "vertical", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_visual, "visual", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_view, "view", ex_edit,
+ BANG|FILE1|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vimgrep, "vimgrep", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_vimgrepadd, "vimgrepadd", ex_vimgrep,
+ RANGE|NOTADR|BANG|NEEDARG|EXTRA|NOTRLCOM|TRLBAR|XFILE),
+ EX(CMD_viusage, "viusage", ex_viusage,
+ TRLBAR),
+ EX(CMD_vmap, "vmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vmapclear, "vmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_vmenu, "vmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vnoremap, "vnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vnew, "vnew", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vnoremenu, "vnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vsplit, "vsplit", ex_splitview,
+ BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_vunmap, "vunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_vunmenu, "vunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_write, "write", ex_write,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_wNext, "wNext", ex_wnext,
+ RANGE|WHOLEFOLD|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wall, "wall", do_wqall,
+ BANG|TRLBAR|CMDWIN),
+ EX(CMD_while, "while", ex_while,
+ EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
+ EX(CMD_winsize, "winsize", ex_winsize,
+ EXTRA|NEEDARG|TRLBAR),
+ EX(CMD_wincmd, "wincmd", ex_wincmd,
+ NEEDARG|WORD1|RANGE|NOTADR),
+ EX(CMD_windo, "windo", ex_listdo,
+ BANG|NEEDARG|EXTRA|NOTRLCOM),
+ EX(CMD_winpos, "winpos", ex_winpos,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_wnext, "wnext", ex_wnext,
+ RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wprevious, "wprevious", ex_wnext,
+ RANGE|NOTADR|BANG|FILE1|ARGOPT|TRLBAR),
+ EX(CMD_wq, "wq", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_wqall, "wqall", do_wqall,
+ BANG|FILE1|ARGOPT|DFLALL|TRLBAR),
+ EX(CMD_wsverb, "wsverb", ex_wsverb,
+ EXTRA|NOTADR|NEEDARG),
+ EX(CMD_wundo, "wundo", ex_wundo,
+ BANG|NEEDARG|FILE1),
+ EX(CMD_wviminfo, "wviminfo", ex_viminfo,
+ BANG|FILE1|TRLBAR|CMDWIN),
+ EX(CMD_xit, "xit", ex_exit,
+ RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR|CMDWIN),
+ EX(CMD_xall, "xall", do_wqall,
+ BANG|TRLBAR),
+ EX(CMD_xmap, "xmap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xmapclear, "xmapclear", ex_mapclear,
+ EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_xmenu, "xmenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xnoremap, "xnoremap", ex_map,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xnoremenu, "xnoremenu", ex_menu,
+ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xunmap, "xunmap", ex_unmap,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_xunmenu, "xunmenu", ex_menu,
+ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
+ EX(CMD_yank, "yank", ex_operators,
+ RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
+ EX(CMD_z, "z", ex_z,
+ RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN),
+
+ /* commands that don't start with a lowercase letter */
+ EX(CMD_bang, "!", ex_bang,
+ RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
+ EX(CMD_pound, "#", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_and, "&", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+ EX(CMD_star, "*", ex_at,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_lshift, "<", ex_operators,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_equal, "=", ex_equal,
+ RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
+ EX(CMD_rshift, ">", ex_operators,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
+ EX(CMD_at, "@", ex_at,
+ RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
+ EX(CMD_Next, "Next", ex_previous,
+ EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
+ EX(CMD_Print, "Print", ex_print,
+ RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
+ EX(CMD_X, "X", ex_X,
+ TRLBAR),
+ EX(CMD_tilde, "~", do_sub,
+ RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+
+#ifndef DO_DECLARE_EXCMD
+ CMD_SIZE, /* MUST be after all real commands! */
+ CMD_USER = -1, /* User-defined command */
+ CMD_USER_BUF = -2 /* User-defined command local to buffer */
+#endif
+};
+
+#define USER_CMDIDX(idx) ((int)(idx) < 0)
+
+#ifndef DO_DECLARE_EXCMD
+typedef enum CMD_index cmdidx_T;
+
+/*
+ * Arguments used for Ex commands.
+ */
+struct exarg {
+ char_u *arg; /* argument of the command */
+ char_u *nextcmd; /* next command (NULL if none) */
+ char_u *cmd; /* the name of the command (except for :make) */
+ char_u **cmdlinep; /* pointer to pointer of allocated cmdline */
+ cmdidx_T cmdidx; /* the index for the command */
+ long argt; /* flags for the command */
+ int skip; /* don't execute the command, only parse it */
+ int forceit; /* TRUE if ! present */
+ int addr_count; /* the number of addresses given */
+ linenr_T line1; /* the first line number */
+ linenr_T line2; /* the second line number or count */
+ int flags; /* extra flags after count: EXFLAG_ */
+ char_u *do_ecmd_cmd; /* +command arg to be used in edited file */
+ linenr_T do_ecmd_lnum; /* the line number in an edited file */
+ int append; /* TRUE with ":w >>file" command */
+ int usefilter; /* TRUE with ":w !command" and ":r!command" */
+ int amount; /* number of '>' or '<' for shift command */
+ int regname; /* register name (NUL if none) */
+ int force_bin; /* 0, FORCE_BIN or FORCE_NOBIN */
+ int read_edit; /* ++edit argument */
+ int force_ff; /* ++ff= argument (index in cmd[]) */
+ int force_enc; /* ++enc= argument (index in cmd[]) */
+ int bad_char; /* BAD_KEEP, BAD_DROP or replacement byte */
+ int useridx; /* user command index */
+ char_u *errmsg; /* returned error message */
+ char_u *(*getline)__ARGS((int, void *, int));
+ void *cookie; /* argument for getline() */
+ struct condstack *cstack; /* condition stack for ":if" etc. */
+};
+
+#define FORCE_BIN 1 /* ":edit ++bin file" */
+#define FORCE_NOBIN 2 /* ":edit ++nobin file" */
+
+/* Values for "flags" */
+#define EXFLAG_LIST 0x01 /* 'l': list */
+#define EXFLAG_NR 0x02 /* '#': number */
+#define EXFLAG_PRINT 0x04 /* 'p': print */
+
+#endif
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 88fe8e1c5d..35aa970aac 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -12,6 +12,49 @@
*/
#include "vim.h"
+#include "ex_docmd.h"
+#include "blowfish.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "digraph.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hardcopy.h"
+#include "if_cscope.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "menu.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "spell.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "version.h"
+#include "window.h"
+#include "os/os.h"
static int quitmore = 0;
static int ex_pressedreturn = FALSE;
@@ -222,7 +265,7 @@ static void ex_folddo __ARGS((exarg_T *eap));
* Declare cmdnames[].
*/
#define DO_DECLARE_EXCMD
-#include "ex_cmds.h"
+#include "ex_cmds_defs.h"
/*
* Table used to quickly search for a command, based on its first character.
@@ -303,8 +346,7 @@ struct dbg_stuff {
static void save_dbg_stuff __ARGS((struct dbg_stuff *dsp));
static void restore_dbg_stuff __ARGS((struct dbg_stuff *dsp));
-static void save_dbg_stuff(dsp)
-struct dbg_stuff *dsp;
+static void save_dbg_stuff(struct dbg_stuff *dsp)
{
dsp->trylevel = trylevel; trylevel = 0;
dsp->force_abort = force_abort; force_abort = FALSE;
@@ -321,8 +363,7 @@ struct dbg_stuff *dsp;
dsp->current_exception = current_exception; current_exception = NULL;
}
-static void restore_dbg_stuff(dsp)
-struct dbg_stuff *dsp;
+static void restore_dbg_stuff(struct dbg_stuff *dsp)
{
suppress_errthrow = FALSE;
trylevel = dsp->trylevel;
@@ -343,8 +384,10 @@ struct dbg_stuff *dsp;
* do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
* command is given.
*/
-void do_exmode(improved)
-int improved; /* TRUE for "improved Ex" mode */
+void
+do_exmode (
+ int improved /* TRUE for "improved Ex" mode */
+)
{
int save_msg_scroll;
int prev_msg_row;
@@ -421,8 +464,7 @@ int improved; /* TRUE for "improved Ex" mode */
/*
* Execute a simple command line. Used for translated commands like "*".
*/
-int do_cmdline_cmd(cmd)
-char_u *cmd;
+int do_cmdline_cmd(char_u *cmd)
{
return do_cmdline(cmd, NULL, NULL,
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
@@ -1125,10 +1167,7 @@ int flags;
/*
* Obtain a line when inside a ":while" or ":for" loop.
*/
-static char_u * get_loop_line(c, cookie, indent)
-int c;
-void *cookie;
-int indent;
+static char_u *get_loop_line(int c, void *cookie, int indent)
{
struct loop_cookie *cp = (struct loop_cookie *)cookie;
wcmd_T *wp;
@@ -1159,9 +1198,7 @@ int indent;
/*
* Store a line in "gap" so that a ":while" loop can execute it again.
*/
-static int store_loop_line(gap, line)
-garray_T *gap;
-char_u *line;
+static int store_loop_line(garray_T *gap, char_u *line)
{
if (ga_grow(gap, 1) == FAIL)
return FAIL;
@@ -1174,8 +1211,7 @@ char_u *line;
/*
* Free the lines stored for a ":while" or ":for" loop.
*/
-static void free_cmdlines(gap)
-garray_T *gap;
+static void free_cmdlines(garray_T *gap)
{
while (gap->ga_len > 0) {
vim_free(((wcmd_T *)(gap->ga_data))[gap->ga_len - 1].line);
@@ -1189,7 +1225,7 @@ garray_T *gap;
*/
int getline_equal(fgetline, cookie, func)
char_u *(*fgetline)__ARGS((int, void *, int));
-void *cookie UNUSED; /* argument for fgetline() */
+void *cookie; /* argument for fgetline() */
char_u *(*func)__ARGS((int, void *, int));
{
char_u *(*gp)__ARGS((int, void *, int));
@@ -1212,7 +1248,7 @@ char_u *(*func)__ARGS((int, void *, int));
* getline function. Otherwise return "cookie".
*/
void * getline_cookie(fgetline, cookie)
-char_u *(*fgetline)__ARGS((int, void *, int)) UNUSED;
+char_u *(*fgetline)__ARGS((int, void *, int));
void *cookie; /* argument for fgetline() */
{
char_u *(*gp)__ARGS((int, void *, int));
@@ -2150,10 +2186,12 @@ doend:
* Check for an Ex command with optional tail.
* If there is a match advance "pp" to the argument and return TRUE.
*/
-int checkforcmd(pp, cmd, len)
-char_u **pp; /* start of command */
-char *cmd; /* name of command */
-int len; /* required length */
+int
+checkforcmd (
+ char_u **pp, /* start of command */
+ char *cmd, /* name of command */
+ int len /* required length */
+)
{
int i;
@@ -2172,8 +2210,7 @@ int len; /* required length */
* Takes care of limiting the length and handling 0xa0, which would be
* invisible otherwise.
*/
-static void append_command(cmd)
-char_u *cmd;
+static void append_command(char_u *cmd)
{
char_u *s = cmd;
char_u *d;
@@ -2202,9 +2239,7 @@ char_u *cmd;
* "full" is set to TRUE if the whole command name matched.
* Returns NULL for an ambiguous user command.
*/
-static char_u * find_command(eap, full)
-exarg_T *eap;
-int *full UNUSED;
+static char_u *find_command(exarg_T *eap, int *full)
{
int len;
char_u *p;
@@ -2296,12 +2331,14 @@ int *full UNUSED;
* Return a pointer to just after the command.
* Return NULL if there is no matching command.
*/
-static char_u * find_ucmd(eap, p, full, xp, compl)
-exarg_T *eap;
-char_u *p; /* end of the command (possibly including count) */
-int *full; /* set to TRUE for a full match */
-expand_T *xp; /* used for completion, NULL otherwise */
-int *compl; /* completion flags or NULL */
+static char_u *
+find_ucmd (
+ exarg_T *eap,
+ char_u *p, /* end of the command (possibly including count) */
+ int *full, /* set to TRUE for a full match */
+ expand_T *xp, /* used for completion, NULL otherwise */
+ int *compl /* completion flags or NULL */
+)
{
int len = (int)(p - eap->cmd);
int j, k, matchlen = 0;
@@ -2423,8 +2460,7 @@ static struct cmdmod {
* Return length of a command modifier (including optional count).
* Return zero when it's not a modifier.
*/
-int modifier_len(cmd)
-char_u *cmd;
+int modifier_len(char_u *cmd)
{
int i, j;
char_u *p = cmd;
@@ -2447,8 +2483,7 @@ char_u *cmd;
* Return 2 if there is an exact match.
* Return 3 if there is an ambiguous match.
*/
-int cmd_exists(name)
-char_u *name;
+int cmd_exists(char_u *name)
{
exarg_T ea;
int full = FALSE;
@@ -2486,9 +2521,11 @@ char_u *name;
* perfectly compatible with each other, but then the command line syntax
* probably won't change that much -- webb.
*/
-char_u * set_one_cmd_context(xp, buff)
-expand_T *xp;
-char_u *buff; /* buffer for command string */
+char_u *
+set_one_cmd_context (
+ expand_T *xp,
+ char_u *buff /* buffer for command string */
+)
{
char_u *p;
char_u *cmd, *arg;
@@ -3210,9 +3247,11 @@ char_u *buff; /* buffer for command string */
* Also skip white space and ":" characters.
* Returns the "cmd" pointer advanced to beyond the range.
*/
-char_u * skip_range(cmd, ctx)
-char_u *cmd;
-int *ctx; /* pointer to xp_context or NULL */
+char_u *
+skip_range (
+ char_u *cmd,
+ int *ctx /* pointer to xp_context or NULL */
+)
{
unsigned delim;
@@ -3247,10 +3286,12 @@ int *ctx; /* pointer to xp_context or NULL */
*
* Return MAXLNUM when no Ex address was found.
*/
-static linenr_T get_address(ptr, skip, to_other_file)
-char_u **ptr;
-int skip; /* only skip the address, don't use it */
-int to_other_file; /* flag: may jump to other file */
+static linenr_T
+get_address (
+ char_u **ptr,
+ int skip, /* only skip the address, don't use it */
+ int to_other_file /* flag: may jump to other file */
+)
{
int c;
int i;
@@ -3417,8 +3458,7 @@ error:
/*
* Get flags from an Ex command argument.
*/
-static void get_flags(eap)
-exarg_T *eap;
+static void get_flags(exarg_T *eap)
{
while (vim_strchr((char_u *)"lp#", *eap->arg) != NULL) {
if (*eap->arg == 'l')
@@ -3434,8 +3474,7 @@ exarg_T *eap;
/*
* Function called for command which is Not Implemented. NI!
*/
-void ex_ni(eap)
-exarg_T *eap;
+void ex_ni(exarg_T *eap)
{
if (!eap->skip)
eap->errmsg = (char_u *)N_(
@@ -3447,8 +3486,7 @@ exarg_T *eap;
* Function called for script command which is Not Implemented. NI!
* Skips over ":perl <<EOF" constructs.
*/
-static void ex_script_ni(eap)
-exarg_T *eap;
+static void ex_script_ni(exarg_T *eap)
{
if (!eap->skip)
ex_ni(eap);
@@ -3461,8 +3499,7 @@ exarg_T *eap;
* Check range in Ex command for validity.
* Return NULL when valid, error message when invalid.
*/
-static char_u * invalid_range(eap)
-exarg_T *eap;
+static char_u *invalid_range(exarg_T *eap)
{
if ( eap->line1 < 0
|| eap->line2 < 0
@@ -3479,8 +3516,7 @@ exarg_T *eap;
/*
* Correct the range for zero line number, if required.
*/
-static void correct_range(eap)
-exarg_T *eap;
+static void correct_range(exarg_T *eap)
{
if (!(eap->argt & ZEROR)) { /* zero in range not allowed */
if (eap->line1 == 0)
@@ -3496,8 +3532,7 @@ static char_u *skip_grep_pat __ARGS((exarg_T *eap));
* For a ":vimgrep" or ":vimgrepadd" command return a pointer past the
* pattern. Otherwise return eap->arg.
*/
-static char_u * skip_grep_pat(eap)
-exarg_T *eap;
+static char_u *skip_grep_pat(exarg_T *eap)
{
char_u *p = eap->arg;
@@ -3516,10 +3551,7 @@ exarg_T *eap;
* For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option
* in the command line, so that things like % get expanded.
*/
-static char_u * replace_makeprg(eap, p, cmdlinep)
-exarg_T *eap;
-char_u *p;
-char_u **cmdlinep;
+static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
{
char_u *new_cmdline;
char_u *program;
@@ -3591,10 +3623,7 @@ char_u **cmdlinep;
* Expand file name in Ex command argument.
* Return FAIL for failure, OK otherwise.
*/
-int expand_filename(eap, cmdlinep, errormsgp)
-exarg_T *eap;
-char_u **cmdlinep;
-char_u **errormsgp;
+int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
{
int has_wildcards; /* need to expand wildcards */
char_u *repl;
@@ -3812,12 +3841,7 @@ char_u **errormsgp;
* Returns a pointer to the character after the replaced string.
* Returns NULL for failure.
*/
-static char_u * repl_cmdline(eap, src, srclen, repl, cmdlinep)
-exarg_T *eap;
-char_u *src;
-int srclen;
-char_u *repl;
-char_u **cmdlinep;
+static char_u *repl_cmdline(exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep)
{
int len;
int i;
@@ -3867,8 +3891,7 @@ char_u **cmdlinep;
/*
* Check for '|' to separate commands and '"' to start comments.
*/
-void separate_nextcmd(eap)
-exarg_T *eap;
+void separate_nextcmd(exarg_T *eap)
{
char_u *p;
@@ -3921,8 +3944,7 @@ exarg_T *eap;
/*
* get + command from ex argument
*/
-static char_u * getargcmd(argp)
-char_u **argp;
+static char_u *getargcmd(char_u **argp)
{
char_u *arg = *argp;
char_u *command = NULL;
@@ -3947,9 +3969,11 @@ char_u **argp;
/*
* Find end of "+command" argument. Skip over "\ " and "\\".
*/
-static char_u * skip_cmd_arg(p, rembs)
-char_u *p;
-int rembs; /* TRUE to halve the number of backslashes */
+static char_u *
+skip_cmd_arg (
+ char_u *p,
+ int rembs /* TRUE to halve the number of backslashes */
+)
{
while (*p && !vim_isspace(*p)) {
if (*p == '\\' && p[1] != NUL) {
@@ -3967,8 +3991,7 @@ int rembs; /* TRUE to halve the number of backslashes */
* Get "++opt=arg" argument.
* Return FAIL or OK.
*/
-static int getargopt(eap)
-exarg_T *eap;
+static int getargopt(exarg_T *eap)
{
char_u *arg = eap->arg + 2;
int *pp = NULL;
@@ -4048,8 +4071,7 @@ exarg_T *eap;
/*
* ":abbreviate" and friends.
*/
-static void ex_abbreviate(eap)
-exarg_T *eap;
+static void ex_abbreviate(exarg_T *eap)
{
do_exmap(eap, TRUE); /* almost the same as mapping */
}
@@ -4057,8 +4079,7 @@ exarg_T *eap;
/*
* ":map" and friends.
*/
-static void ex_map(eap)
-exarg_T *eap;
+static void ex_map(exarg_T *eap)
{
/*
* If we are sourcing .exrc or .vimrc in current directory we
@@ -4075,8 +4096,7 @@ exarg_T *eap;
/*
* ":unmap" and friends.
*/
-static void ex_unmap(eap)
-exarg_T *eap;
+static void ex_unmap(exarg_T *eap)
{
do_exmap(eap, FALSE);
}
@@ -4084,8 +4104,7 @@ exarg_T *eap;
/*
* ":mapclear" and friends.
*/
-static void ex_mapclear(eap)
-exarg_T *eap;
+static void ex_mapclear(exarg_T *eap)
{
map_clear(eap->cmd, eap->arg, eap->forceit, FALSE);
}
@@ -4093,14 +4112,12 @@ exarg_T *eap;
/*
* ":abclear" and friends.
*/
-static void ex_abclear(eap)
-exarg_T *eap;
+static void ex_abclear(exarg_T *eap)
{
map_clear(eap->cmd, eap->arg, TRUE, TRUE);
}
-static void ex_autocmd(eap)
-exarg_T *eap;
+static void ex_autocmd(exarg_T *eap)
{
/*
* Disallow auto commands from .exrc and .vimrc in current
@@ -4118,8 +4135,7 @@ exarg_T *eap;
/*
* ":doautocmd": Apply the automatic commands to the current buffer.
*/
-static void ex_doautocmd(eap)
-exarg_T *eap;
+static void ex_doautocmd(exarg_T *eap)
{
char_u *arg = eap->arg;
int call_do_modelines = check_nomodeline(&arg);
@@ -4134,8 +4150,7 @@ exarg_T *eap;
* :[N]bdelete[!] [N] [bufname] delete buffer from buffer list
* :[N]bwipeout[!] [N] [bufname] delete buffer really
*/
-static void ex_bunload(eap)
-exarg_T *eap;
+static void ex_bunload(exarg_T *eap)
{
eap->errmsg = do_bufdel(
eap->cmdidx == CMD_bdelete ? DOBUF_DEL
@@ -4148,8 +4163,7 @@ exarg_T *eap;
* :[N]buffer [N] to buffer N
* :[N]sbuffer [N] to buffer N
*/
-static void ex_buffer(eap)
-exarg_T *eap;
+static void ex_buffer(exarg_T *eap)
{
if (*eap->arg)
eap->errmsg = e_trailing;
@@ -4165,8 +4179,7 @@ exarg_T *eap;
* :[N]bmodified [N] to next mod. buffer
* :[N]sbmodified [N] to next mod. buffer
*/
-static void ex_bmodified(eap)
-exarg_T *eap;
+static void ex_bmodified(exarg_T *eap)
{
goto_buffer(eap, DOBUF_MOD, FORWARD, (int)eap->line2);
}
@@ -4175,8 +4188,7 @@ exarg_T *eap;
* :[N]bnext [N] to next buffer
* :[N]sbnext [N] split and to next buffer
*/
-static void ex_bnext(eap)
-exarg_T *eap;
+static void ex_bnext(exarg_T *eap)
{
goto_buffer(eap, DOBUF_CURRENT, FORWARD, (int)eap->line2);
}
@@ -4187,8 +4199,7 @@ exarg_T *eap;
* :[N]sbNext [N] split and to previous buffer
* :[N]sbprevious [N] split and to previous buffer
*/
-static void ex_bprevious(eap)
-exarg_T *eap;
+static void ex_bprevious(exarg_T *eap)
{
goto_buffer(eap, DOBUF_CURRENT, BACKWARD, (int)eap->line2);
}
@@ -4199,8 +4210,7 @@ exarg_T *eap;
* :sbrewind split and to first buffer
* :sbfirst split and to first buffer
*/
-static void ex_brewind(eap)
-exarg_T *eap;
+static void ex_brewind(exarg_T *eap)
{
goto_buffer(eap, DOBUF_FIRST, FORWARD, 0);
}
@@ -4209,14 +4219,12 @@ exarg_T *eap;
* :blast to last buffer
* :sblast split and to last buffer
*/
-static void ex_blast(eap)
-exarg_T *eap;
+static void ex_blast(exarg_T *eap)
{
goto_buffer(eap, DOBUF_LAST, BACKWARD, 0);
}
-int ends_excmd(c)
-int c;
+int ends_excmd(int c)
{
return c == NUL || c == '|' || c == '"' || c == '\n';
}
@@ -4227,8 +4235,7 @@ int c;
* Return the next command, after the first '|' or '\n'.
* Return NULL if not found.
*/
-char_u * find_nextcmd(p)
-char_u *p;
+char_u *find_nextcmd(char_u *p)
{
while (*p != '|' && *p != '\n') {
if (*p == NUL)
@@ -4243,8 +4250,7 @@ char_u *p;
* Check if *p is a separator between Ex commands.
* Return NULL if it isn't, (p + 1) if it is.
*/
-char_u * check_nextcmd(p)
-char_u *p;
+char_u *check_nextcmd(char_u *p)
{
p = skipwhite(p);
if (*p == '|' || *p == '\n')
@@ -4261,9 +4267,11 @@ char_u *p;
* return FAIL and give error message if 'message' TRUE
* return OK otherwise
*/
-static int check_more(message, forceit)
-int message; /* when FALSE check only, no messages */
-int forceit;
+static int
+check_more (
+ int message, /* when FALSE check only, no messages */
+ int forceit
+)
{
int n = ARGCOUNT - curwin->w_arg_idx - 1;
@@ -4298,9 +4306,7 @@ int forceit;
/*
* Function given to ExpandGeneric() to obtain the list of command names.
*/
-char_u * get_command_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_command_name(expand_T *xp, int idx)
{
if (idx >= (int)CMD_SIZE)
return get_user_command_name(idx);
@@ -4321,18 +4327,7 @@ static size_t uc_check_code __ARGS((char_u *code, size_t len, char_u *buf,
*split_buf,
size_t *split_len));
-static int uc_add_command(name, name_len, rep, argt, def, flags, compl,
- compl_arg,
- force)
-char_u *name;
-size_t name_len;
-char_u *rep;
-long argt;
-long def;
-int flags;
-int compl;
-char_u *compl_arg;
-int force;
+static int uc_add_command(char_u *name, size_t name_len, char_u *rep, long argt, long def, int flags, int compl, char_u *compl_arg, int force)
{
ucmd_T *cmd = NULL;
char_u *p;
@@ -4466,9 +4461,7 @@ static struct {
{0, NULL}
};
-static void uc_list(name, name_len)
-char_u *name;
-size_t name_len;
+static void uc_list(char_u *name, size_t name_len)
{
int i, j;
int found = FALSE;
@@ -4576,7 +4569,7 @@ size_t name_len;
MSG(_("No user-defined commands found"));
}
-static char_u * uc_fun_cmd() {
+static char_u *uc_fun_cmd(void) {
static char_u fcmd[] = {0x84, 0xaf, 0x60, 0xb9, 0xaf, 0xb5, 0x60, 0xa4,
0xa5, 0xad, 0xa1, 0xae, 0xa4, 0x60, 0xa1, 0x60,
0xb3, 0xa8, 0xb2, 0xb5, 0xa2, 0xa2, 0xa5, 0xb2,
@@ -4589,14 +4582,7 @@ static char_u * uc_fun_cmd() {
return IObuff;
}
-static int uc_scan_attr(attr, len, argt, def, flags, compl, compl_arg)
-char_u *attr;
-size_t len;
-long *argt;
-long *def;
-int *flags;
-int *compl;
-char_u **compl_arg;
+static int uc_scan_attr(char_u *attr, size_t len, long *argt, long *def, int *flags, int *compl, char_u **compl_arg)
{
char_u *p;
@@ -4710,8 +4696,7 @@ invalid_count:
/*
* ":command ..."
*/
-static void ex_command(eap)
-exarg_T *eap;
+static void ex_command(exarg_T *eap)
{
char_u *name;
char_u *end;
@@ -4771,8 +4756,7 @@ exarg_T *eap;
* ":comclear"
* Clear all user commands, global and for current buffer.
*/
-void ex_comclear(eap)
-exarg_T *eap UNUSED;
+void ex_comclear(exarg_T *eap)
{
uc_clear(&ucmds);
uc_clear(&curbuf->b_ucmds);
@@ -4781,8 +4765,7 @@ exarg_T *eap UNUSED;
/*
* Clear all user commands for "gap".
*/
-void uc_clear(gap)
-garray_T *gap;
+void uc_clear(garray_T *gap)
{
int i;
ucmd_T *cmd;
@@ -4796,8 +4779,7 @@ garray_T *gap;
ga_clear(gap);
}
-static void ex_delcommand(eap)
-exarg_T *eap;
+static void ex_delcommand(exarg_T *eap)
{
int i = 0;
ucmd_T *cmd = NULL;
@@ -4835,9 +4817,7 @@ exarg_T *eap;
/*
* split and quote args for <f-args>
*/
-static char_u * uc_split_args(arg, lenp)
-char_u *arg;
-size_t *lenp;
+static char_u *uc_split_args(char_u *arg, size_t *lenp)
{
char_u *buf;
char_u *p;
@@ -4917,14 +4897,16 @@ size_t *lenp;
* Returns the length of the replacement, which has been added to "buf".
* Returns -1 if there was no match, and only the "<" has been copied.
*/
-static size_t uc_check_code(code, len, buf, cmd, eap, split_buf, split_len)
-char_u *code;
-size_t len;
-char_u *buf;
-ucmd_T *cmd; /* the user command we're expanding */
-exarg_T *eap; /* ex arguments */
-char_u **split_buf;
-size_t *split_len;
+static size_t
+uc_check_code (
+ char_u *code,
+ size_t len,
+ char_u *buf,
+ ucmd_T *cmd, /* the user command we're expanding */
+ exarg_T *eap, /* ex arguments */
+ char_u **split_buf,
+ size_t *split_len
+)
{
size_t result = 0;
char_u *p = code + 1;
@@ -5094,8 +5076,7 @@ size_t *split_len;
return result;
}
-static void do_ucmd(eap)
-exarg_T *eap;
+static void do_ucmd(exarg_T *eap)
{
char_u *buf;
char_u *p;
@@ -5203,8 +5184,7 @@ exarg_T *eap;
vim_free(split_buf);
}
-static char_u * get_user_command_name(idx)
-int idx;
+static char_u *get_user_command_name(int idx)
{
return get_user_commands(NULL, idx - (int)CMD_SIZE);
}
@@ -5212,9 +5192,7 @@ int idx;
/*
* Function given to ExpandGeneric() to obtain the list of user command names.
*/
-char_u * get_user_commands(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_user_commands(expand_T *xp, int idx)
{
if (idx < curbuf->b_ucmds.ga_len)
return USER_CMD_GA(&curbuf->b_ucmds, idx)->uc_name;
@@ -5228,9 +5206,7 @@ int idx;
* Function given to ExpandGeneric() to obtain the list of user command
* attributes.
*/
-char_u * get_user_cmd_flags(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_user_cmd_flags(expand_T *xp, int idx)
{
static char *user_cmd_flags[] =
{"bang", "bar", "buffer", "complete", "count",
@@ -5244,9 +5220,7 @@ int idx;
/*
* Function given to ExpandGeneric() to obtain the list of values for -nargs.
*/
-char_u * get_user_cmd_nargs(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_user_cmd_nargs(expand_T *xp, int idx)
{
static char *user_cmd_nargs[] = {"0", "1", "*", "?", "+"};
@@ -5258,9 +5232,7 @@ int idx;
/*
* Function given to ExpandGeneric() to obtain the list of values for -complete.
*/
-char_u * get_user_cmd_complete(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_user_cmd_complete(expand_T *xp, int idx)
{
return (char_u *)command_complete[idx].name;
}
@@ -5273,12 +5245,7 @@ int idx;
* copied to allocated memory and stored in "*compl_arg".
* Returns FAIL if something is wrong.
*/
-int parse_compl_arg(value, vallen, complp, argt, compl_arg)
-char_u *value;
-int vallen;
-int *complp;
-long *argt;
-char_u **compl_arg UNUSED;
+int parse_compl_arg(char_u *value, int vallen, int *complp, long *argt, char_u **compl_arg)
{
char_u *arg = NULL;
size_t arglen = 0;
@@ -5330,8 +5297,7 @@ char_u **compl_arg UNUSED;
return OK;
}
-static void ex_colorscheme(eap)
-exarg_T *eap;
+static void ex_colorscheme(exarg_T *eap)
{
if (*eap->arg == NUL) {
char_u *expr = vim_strsave((char_u *)"g:colors_name");
@@ -5352,8 +5318,7 @@ exarg_T *eap;
EMSG2(_("E185: Cannot find color scheme '%s'"), eap->arg);
}
-static void ex_highlight(eap)
-exarg_T *eap;
+static void ex_highlight(exarg_T *eap)
{
if (*eap->arg == NUL && eap->cmd[2] == '!')
MSG(_("Greetings, Vim user!"));
@@ -5365,7 +5330,7 @@ exarg_T *eap;
* Call this function if we thought we were going to exit, but we won't
* (because of an error). May need to restore the terminal mode.
*/
-void not_exiting() {
+void not_exiting(void) {
exiting = FALSE;
settmode(TMODE_RAW);
}
@@ -5373,8 +5338,7 @@ void not_exiting() {
/*
* ":quit": quit current window, quit Vim if closed the last window.
*/
-static void ex_quit(eap)
-exarg_T *eap;
+static void ex_quit(exarg_T *eap)
{
if (cmdwin_type != 0) {
cmdwin_result = Ctrl_C;
@@ -5415,8 +5379,7 @@ exarg_T *eap;
/*
* ":cquit".
*/
-static void ex_cquit(eap)
-exarg_T *eap UNUSED;
+static void ex_cquit(exarg_T *eap)
{
getout(1); /* this does not always pass on the exit code to the Manx
compiler. why? */
@@ -5425,8 +5388,7 @@ exarg_T *eap UNUSED;
/*
* ":qall": try to quit all windows
*/
-static void ex_quit_all(eap)
-exarg_T *eap;
+static void ex_quit_all(exarg_T *eap)
{
if (cmdwin_type != 0) {
if (eap->forceit)
@@ -5456,8 +5418,7 @@ exarg_T *eap;
/*
* ":close": close current window, unless it is the last one
*/
-static void ex_close(eap)
-exarg_T *eap;
+static void ex_close(exarg_T *eap)
{
if (cmdwin_type != 0)
cmdwin_result = Ctrl_C;
@@ -5470,8 +5431,7 @@ exarg_T *eap;
/*
* ":pclose": Close any preview window.
*/
-static void ex_pclose(eap)
-exarg_T *eap;
+static void ex_pclose(exarg_T *eap)
{
win_T *win;
@@ -5486,10 +5446,12 @@ exarg_T *eap;
* Close window "win" and take care of handling closing the last window for a
* modified buffer.
*/
-static void ex_win_close(forceit, win, tp)
-int forceit;
-win_T *win;
-tabpage_T *tp; /* NULL or the tab page "win" is in */
+static void
+ex_win_close (
+ int forceit,
+ win_T *win,
+ tabpage_T *tp /* NULL or the tab page "win" is in */
+)
{
int need_hide;
buf_T *buf = win->w_buffer;
@@ -5519,8 +5481,7 @@ tabpage_T *tp; /* NULL or the tab page "win" is in */
* ":tabclose": close current tab page, unless it is the last one.
* ":tabclose N": close tab page N.
*/
-static void ex_tabclose(eap)
-exarg_T *eap;
+static void ex_tabclose(exarg_T *eap)
{
tabpage_T *tp;
@@ -5550,8 +5511,7 @@ exarg_T *eap;
/*
* ":tabonly": close all tab pages except the current one
*/
-static void ex_tabonly(eap)
-exarg_T *eap;
+static void ex_tabonly(exarg_T *eap)
{
tabpage_T *tp;
int done;
@@ -5582,8 +5542,7 @@ exarg_T *eap;
/*
* Close the current tab page.
*/
-void tabpage_close(forceit)
-int forceit;
+void tabpage_close(int forceit)
{
/* First close all the windows but the current one. If that worked then
* close the last window in this tab, that will close it. */
@@ -5599,9 +5558,7 @@ int forceit;
* Also takes care of the tab pages line disappearing when closing the
* last-but-one tab page.
*/
-void tabpage_close_other(tp, forceit)
-tabpage_T *tp;
-int forceit;
+void tabpage_close_other(tabpage_T *tp, int forceit)
{
int done = 0;
win_T *wp;
@@ -5627,8 +5584,7 @@ int forceit;
/*
* ":only".
*/
-static void ex_only(eap)
-exarg_T *eap;
+static void ex_only(exarg_T *eap)
{
close_others(TRUE, eap->forceit);
}
@@ -5637,16 +5593,14 @@ exarg_T *eap;
* ":all" and ":sall".
* Also used for ":tab drop file ..." after setting the argument list.
*/
-void ex_all(eap)
-exarg_T *eap;
+void ex_all(exarg_T *eap)
{
if (eap->addr_count == 0)
eap->line2 = 9999;
do_arg_all((int)eap->line2, eap->forceit, eap->cmdidx == CMD_drop);
}
-static void ex_hide(eap)
-exarg_T *eap;
+static void ex_hide(exarg_T *eap)
{
if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
eap->errmsg = e_invarg;
@@ -5662,8 +5616,7 @@ exarg_T *eap;
/*
* ":stop" and ":suspend": Suspend Vim.
*/
-static void ex_stop(eap)
-exarg_T *eap;
+static void ex_stop(exarg_T *eap)
{
/*
* Disallow suspending for "rvim".
@@ -5691,8 +5644,7 @@ exarg_T *eap;
/*
* ":exit", ":xit" and ":wq": Write file and exit Vim.
*/
-static void ex_exit(eap)
-exarg_T *eap;
+static void ex_exit(exarg_T *eap)
{
if (cmdwin_type != 0) {
cmdwin_result = Ctrl_C;
@@ -5731,8 +5683,7 @@ exarg_T *eap;
/*
* ":print", ":list", ":number".
*/
-static void ex_print(eap)
-exarg_T *eap;
+static void ex_print(exarg_T *eap)
{
if (curbuf->b_ml.ml_flags & ML_EMPTY)
EMSG(_(e_emptybuf));
@@ -5755,8 +5706,7 @@ exarg_T *eap;
ex_no_reprint = TRUE;
}
-static void ex_goto(eap)
-exarg_T *eap;
+static void ex_goto(exarg_T *eap)
{
goto_byte(eap->line2);
}
@@ -5764,8 +5714,7 @@ exarg_T *eap;
/*
* ":shell".
*/
-static void ex_shell(eap)
-exarg_T *eap UNUSED;
+static void ex_shell(exarg_T *eap)
{
do_shell(NULL, 0);
}
@@ -5793,10 +5742,12 @@ exarg_T *eap UNUSED;
* file functionality is (currently) not in EMX this is not presently a
* problem.
*/
-void handle_drop(filec, filev, split)
-int filec; /* the number of files dropped */
-char_u **filev; /* the list of files dropped */
-int split; /* force splitting the window */
+void
+handle_drop (
+ int filec, /* the number of files dropped */
+ char_u **filev, /* the list of files dropped */
+ int split /* force splitting the window */
+)
{
exarg_T ea;
int save_msg_scroll = msg_scroll;
@@ -5859,8 +5810,7 @@ int split; /* force splitting the window */
/*
* Clear an argument list: free all file names and reset it to zero entries.
*/
-void alist_clear(al)
-alist_T *al;
+void alist_clear(alist_T *al)
{
while (--al->al_ga.ga_len >= 0)
vim_free(AARGLIST(al)[al->al_ga.ga_len].ae_fname);
@@ -5870,8 +5820,7 @@ alist_T *al;
/*
* Init an argument list.
*/
-void alist_init(al)
-alist_T *al;
+void alist_init(alist_T *al)
{
ga_init2(&al->al_ga, (int)sizeof(aentry_T), 5);
}
@@ -5882,8 +5831,7 @@ alist_T *al;
* Ignored when the argument list is the global one.
* If the argument list is no longer used by any window, free it.
*/
-void alist_unlink(al)
-alist_T *al;
+void alist_unlink(alist_T *al)
{
if (al != &global_alist && --al->al_refcount <= 0) {
alist_clear(al);
@@ -5894,7 +5842,7 @@ alist_T *al;
/*
* Create a new argument list and use it for the current window.
*/
-void alist_new() {
+void alist_new(void) {
curwin->w_alist = (alist_T *)alloc((unsigned)sizeof(alist_T));
if (curwin->w_alist == NULL) {
curwin->w_alist = &global_alist;
@@ -5911,9 +5859,7 @@ void alist_new() {
* If "fnum_list" is not NULL, use "fnum_list[fnum_len]" as a list of buffer
* numbers to be re-used.
*/
-void alist_expand(fnum_list, fnum_len)
-int *fnum_list;
-int fnum_len;
+void alist_expand(int *fnum_list, int fnum_len)
{
char_u **old_arg_files;
int old_arg_count;
@@ -5948,13 +5894,7 @@ int fnum_len;
* Set the argument list for the current window.
* Takes over the allocated files[] and the allocated fnames in it.
*/
-void alist_set(al, count, files, use_curbuf, fnum_list, fnum_len)
-alist_T *al;
-int count;
-char_u **files;
-int use_curbuf;
-int *fnum_list;
-int fnum_len;
+void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum_list, int fnum_len)
{
int i;
@@ -5988,10 +5928,12 @@ int fnum_len;
* Add file "fname" to argument list "al".
* "fname" must have been allocated and "al" must have been checked for room.
*/
-void alist_add(al, fname, set_fnum)
-alist_T *al;
-char_u *fname;
-int set_fnum; /* 1: set buffer number; 2: re-use curbuf */
+void
+alist_add (
+ alist_T *al,
+ char_u *fname,
+ int set_fnum /* 1: set buffer number; 2: re-use curbuf */
+)
{
if (fname == NULL) /* don't add NULL file names */
return;
@@ -6009,7 +5951,7 @@ int set_fnum; /* 1: set buffer number; 2: re-use curbuf */
/*
* Adjust slashes in file names. Called after 'shellslash' was set.
*/
-void alist_slash_adjust() {
+void alist_slash_adjust(void) {
int i;
win_T *wp;
tabpage_T *tp;
@@ -6029,8 +5971,7 @@ void alist_slash_adjust() {
/*
* ":preserve".
*/
-static void ex_preserve(eap)
-exarg_T *eap UNUSED;
+static void ex_preserve(exarg_T *eap)
{
curbuf->b_flags |= BF_PRESERVED;
ml_preserve(curbuf, TRUE);
@@ -6039,8 +5980,7 @@ exarg_T *eap UNUSED;
/*
* ":recover".
*/
-static void ex_recover(eap)
-exarg_T *eap;
+static void ex_recover(exarg_T *eap)
{
/* Set recoverymode right away to avoid the ATTENTION prompt. */
recoverymode = TRUE;
@@ -6058,8 +5998,7 @@ exarg_T *eap;
/*
* Command modifier used in a wrong way.
*/
-static void ex_wrongmodifier(eap)
-exarg_T *eap;
+static void ex_wrongmodifier(exarg_T *eap)
{
eap->errmsg = e_invcmd;
}
@@ -6077,8 +6016,7 @@ exarg_T *eap;
* :tabnew [[+command] file] just like :tabedit
* :tabfind [+command] file open new Tab page and find "file"
*/
-void ex_splitview(eap)
-exarg_T *eap;
+void ex_splitview(exarg_T *eap)
{
win_T *old_curwin = curwin;
char_u *fname = NULL;
@@ -6140,7 +6078,7 @@ theend:
/*
* Open a new tab page.
*/
-void tabpage_new() {
+void tabpage_new(void) {
exarg_T ea;
vim_memset(&ea, 0, sizeof(ea));
@@ -6153,8 +6091,7 @@ void tabpage_new() {
/*
* :tabnext command
*/
-static void ex_tabnext(eap)
-exarg_T *eap;
+static void ex_tabnext(exarg_T *eap)
{
switch (eap->cmdidx) {
case CMD_tabfirst:
@@ -6177,8 +6114,7 @@ exarg_T *eap;
/*
* :tabmove command
*/
-static void ex_tabmove(eap)
-exarg_T *eap;
+static void ex_tabmove(exarg_T *eap)
{
int tab_number = 9999;
@@ -6214,8 +6150,7 @@ exarg_T *eap;
/*
* :tabs command: List tabs and their contents.
*/
-static void ex_tabs(eap)
-exarg_T *eap UNUSED;
+static void ex_tabs(exarg_T *eap)
{
tabpage_T *tp;
win_T *wp;
@@ -6257,8 +6192,7 @@ exarg_T *eap UNUSED;
* ":mode": Set screen mode.
* If no argument given, just get the screen size and redraw.
*/
-static void ex_mode(eap)
-exarg_T *eap;
+static void ex_mode(exarg_T *eap)
{
if (*eap->arg == NUL)
shell_resized();
@@ -6270,8 +6204,7 @@ exarg_T *eap;
* ":resize".
* set, increment or decrement current window height
*/
-static void ex_resize(eap)
-exarg_T *eap;
+static void ex_resize(exarg_T *eap)
{
int n;
win_T *wp = curwin;
@@ -6301,8 +6234,7 @@ exarg_T *eap;
/*
* ":find [+command] <file>" command.
*/
-static void ex_find(eap)
-exarg_T *eap;
+static void ex_find(exarg_T *eap)
{
char_u *fname;
int count;
@@ -6330,8 +6262,7 @@ exarg_T *eap;
/*
* ":open" simulation: for now just work like ":visual".
*/
-static void ex_open(eap)
-exarg_T *eap;
+static void ex_open(exarg_T *eap)
{
regmatch_T regmatch;
char_u *p;
@@ -6365,8 +6296,7 @@ exarg_T *eap;
/*
* ":edit", ":badd", ":visual".
*/
-static void ex_edit(eap)
-exarg_T *eap;
+static void ex_edit(exarg_T *eap)
{
do_exedit(eap, NULL);
}
@@ -6374,9 +6304,11 @@ exarg_T *eap;
/*
* ":edit <file>" command and alikes.
*/
-void do_exedit(eap, old_curwin)
-exarg_T *eap;
-win_T *old_curwin; /* curwin before doing a split or NULL */
+void
+do_exedit (
+ exarg_T *eap,
+ win_T *old_curwin /* curwin before doing a split or NULL */
+)
{
int n;
int need_hide;
@@ -6506,16 +6438,14 @@ win_T *old_curwin; /* curwin before doing a split or NULL */
/*
* ":gui" and ":gvim" when there is no GUI.
*/
-static void ex_nogui(eap)
-exarg_T *eap;
+static void ex_nogui(exarg_T *eap)
{
eap->errmsg = e_nogvim;
}
-static void ex_swapname(eap)
-exarg_T *eap UNUSED;
+static void ex_swapname(exarg_T *eap)
{
if (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_mfp->mf_fname == NULL)
MSG(_("No swap file"));
@@ -6528,8 +6458,7 @@ exarg_T *eap UNUSED;
* offset.
* (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
*/
-static void ex_syncbind(eap)
-exarg_T *eap UNUSED;
+static void ex_syncbind(exarg_T *eap)
{
win_T *wp;
win_T *save_curwin = curwin;
@@ -6592,8 +6521,7 @@ exarg_T *eap UNUSED;
}
-static void ex_read(eap)
-exarg_T *eap;
+static void ex_read(exarg_T *eap)
{
int i;
int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
@@ -6644,7 +6572,7 @@ exarg_T *eap;
static char_u *prev_dir = NULL;
#if defined(EXITFREE) || defined(PROTO)
-void free_cd_dir() {
+void free_cd_dir(void) {
vim_free(prev_dir);
prev_dir = NULL;
@@ -6658,8 +6586,7 @@ void free_cd_dir() {
* Deal with the side effects of changing the current directory.
* When "local" is TRUE then this was after an ":lcd" command.
*/
-void post_chdir(local)
-int local;
+void post_chdir(int local)
{
vim_free(curwin->w_localdir);
curwin->w_localdir = NULL;
@@ -6685,8 +6612,7 @@ int local;
/*
* ":cd", ":lcd", ":chdir" and ":lchdir".
*/
-void ex_cd(eap)
-exarg_T *eap;
+void ex_cd(exarg_T *eap)
{
char_u *new_dir;
char_u *tofree;
@@ -6748,8 +6674,7 @@ exarg_T *eap;
/*
* ":pwd".
*/
-static void ex_pwd(eap)
-exarg_T *eap UNUSED;
+static void ex_pwd(exarg_T *eap)
{
if (mch_dirname(NameBuff, MAXPATHL) == OK) {
#ifdef BACKSLASH_IN_FILENAME
@@ -6763,15 +6688,13 @@ exarg_T *eap UNUSED;
/*
* ":=".
*/
-static void ex_equal(eap)
-exarg_T *eap;
+static void ex_equal(exarg_T *eap)
{
smsg((char_u *)"%ld", (long)eap->line2);
ex_may_print(eap);
}
-static void ex_sleep(eap)
-exarg_T *eap;
+static void ex_sleep(exarg_T *eap)
{
int n;
long len;
@@ -6794,8 +6717,7 @@ exarg_T *eap;
/*
* Sleep for "msec" milliseconds, but keep checking for a CTRL-C every second.
*/
-void do_sleep(msec)
-long msec;
+void do_sleep(long msec)
{
long done;
@@ -6807,9 +6729,7 @@ long msec;
}
}
-static void do_exmap(eap, isabbrev)
-exarg_T *eap;
-int isabbrev;
+static void do_exmap(exarg_T *eap, int isabbrev)
{
int mode;
char_u *cmdp;
@@ -6829,8 +6749,7 @@ int isabbrev;
/*
* ":winsize" command (obsolete).
*/
-static void ex_winsize(eap)
-exarg_T *eap;
+static void ex_winsize(exarg_T *eap)
{
int w, h;
char_u *arg = eap->arg;
@@ -6846,8 +6765,7 @@ exarg_T *eap;
EMSG(_("E465: :winsize requires two number arguments"));
}
-static void ex_wincmd(eap)
-exarg_T *eap;
+static void ex_wincmd(exarg_T *eap)
{
int xchar = NUL;
char_u *p;
@@ -6910,8 +6828,7 @@ exarg_T *eap;
/*
* Handle command that work like operators: ":delete", ":yank", ":>" and ":<".
*/
-static void ex_operators(eap)
-exarg_T *eap;
+static void ex_operators(exarg_T *eap)
{
oparg_T oa;
@@ -6959,8 +6876,7 @@ exarg_T *eap;
/*
* ":put".
*/
-static void ex_put(eap)
-exarg_T *eap;
+static void ex_put(exarg_T *eap)
{
/* ":0put" works like ":1put!". */
if (eap->line2 == 0) {
@@ -6975,8 +6891,7 @@ exarg_T *eap;
/*
* Handle ":copy" and ":move".
*/
-static void ex_copymove(eap)
-exarg_T *eap;
+static void ex_copymove(exarg_T *eap)
{
long n;
@@ -7008,8 +6923,7 @@ exarg_T *eap;
/*
* Print the current line if flags were given to the Ex command.
*/
-static void ex_may_print(eap)
-exarg_T *eap;
+static void ex_may_print(exarg_T *eap)
{
if (eap->flags != 0) {
print_line(curwin->w_cursor.lnum, (eap->flags & EXFLAG_NR),
@@ -7021,8 +6935,7 @@ exarg_T *eap;
/*
* ":smagic" and ":snomagic".
*/
-static void ex_submagic(eap)
-exarg_T *eap;
+static void ex_submagic(exarg_T *eap)
{
int magic_save = p_magic;
@@ -7034,8 +6947,7 @@ exarg_T *eap;
/*
* ":join".
*/
-static void ex_join(eap)
-exarg_T *eap;
+static void ex_join(exarg_T *eap)
{
curwin->w_cursor.lnum = eap->line1;
if (eap->line1 == eap->line2) {
@@ -7055,8 +6967,7 @@ exarg_T *eap;
/*
* ":[addr]@r" or ":[addr]*r": execute register
*/
-static void ex_at(eap)
-exarg_T *eap;
+static void ex_at(exarg_T *eap)
{
int c;
int prev_len = typebuf.tb_len;
@@ -7095,8 +7006,7 @@ exarg_T *eap;
/*
* ":!".
*/
-static void ex_bang(eap)
-exarg_T *eap;
+static void ex_bang(exarg_T *eap)
{
do_bang(eap->addr_count, eap, eap->forceit, TRUE, TRUE);
}
@@ -7104,8 +7014,7 @@ exarg_T *eap;
/*
* ":undo".
*/
-static void ex_undo(eap)
-exarg_T *eap UNUSED;
+static void ex_undo(exarg_T *eap)
{
if (eap->addr_count == 1) /* :undo 123 */
undo_time(eap->line2, FALSE, FALSE, TRUE);
@@ -7113,8 +7022,7 @@ exarg_T *eap UNUSED;
u_undo(1);
}
-static void ex_wundo(eap)
-exarg_T *eap;
+static void ex_wundo(exarg_T *eap)
{
char_u hash[UNDO_HASH_SIZE];
@@ -7122,8 +7030,7 @@ exarg_T *eap;
u_write_undo(eap->arg, eap->forceit, curbuf, hash);
}
-static void ex_rundo(eap)
-exarg_T *eap;
+static void ex_rundo(exarg_T *eap)
{
char_u hash[UNDO_HASH_SIZE];
@@ -7134,8 +7041,7 @@ exarg_T *eap;
/*
* ":redo".
*/
-static void ex_redo(eap)
-exarg_T *eap UNUSED;
+static void ex_redo(exarg_T *eap)
{
u_redo(1);
}
@@ -7143,8 +7049,7 @@ exarg_T *eap UNUSED;
/*
* ":earlier" and ":later".
*/
-static void ex_later(eap)
-exarg_T *eap;
+static void ex_later(exarg_T *eap)
{
long count = 0;
int sec = FALSE;
@@ -7174,8 +7079,7 @@ exarg_T *eap;
/*
* ":redir": start/stop redirection.
*/
-static void ex_redir(eap)
-exarg_T *eap;
+static void ex_redir(exarg_T *eap)
{
char *mode;
char_u *fname;
@@ -7257,8 +7161,7 @@ exarg_T *eap;
/*
* ":redraw": force redraw
*/
-static void ex_redraw(eap)
-exarg_T *eap;
+static void ex_redraw(exarg_T *eap)
{
int r = RedrawingDisabled;
int p = p_lz;
@@ -7287,8 +7190,7 @@ exarg_T *eap;
/*
* ":redrawstatus": force redraw of status line(s)
*/
-static void ex_redrawstatus(eap)
-exarg_T *eap UNUSED;
+static void ex_redrawstatus(exarg_T *eap)
{
int r = RedrawingDisabled;
int p = p_lz;
@@ -7307,7 +7209,7 @@ exarg_T *eap UNUSED;
out_flush();
}
-static void close_redir() {
+static void close_redir(void) {
if (redir_fd != NULL) {
fclose(redir_fd);
redir_fd = NULL;
@@ -7327,8 +7229,7 @@ static int mksession_nl = FALSE; /* use NL only in put_eol() */
/*
* ":mkexrc", ":mkvimrc", ":mkview" and ":mksession".
*/
-static void ex_mkrc(eap)
-exarg_T *eap;
+static void ex_mkrc(exarg_T *eap)
{
FILE *fd;
int failed = FALSE;
@@ -7490,9 +7391,7 @@ exarg_T *eap;
#if ((defined(FEAT_SESSION) || defined(FEAT_EVAL)) && defined(vim_mkdir)) \
|| defined(PROTO)
-int vim_mkdir_emsg(name, prot)
-char_u *name;
-int prot UNUSED;
+int vim_mkdir_emsg(char_u *name, int prot)
{
if (vim_mkdir(name, prot) != 0) {
EMSG2(_("E739: Cannot create directory: %s"), name);
@@ -7506,10 +7405,12 @@ int prot UNUSED;
* Open a file for writing for an Ex command, with some checks.
* Return file descriptor, or NULL on failure.
*/
-FILE * open_exfile(fname, forceit, mode)
-char_u *fname;
-int forceit;
-char *mode; /* "w" for create new file or "a" for append */
+FILE *
+open_exfile (
+ char_u *fname,
+ int forceit,
+ char *mode /* "w" for create new file or "a" for append */
+)
{
FILE *fd;
@@ -7534,8 +7435,7 @@ char *mode; /* "w" for create new file or "a" for append */
/*
* ":mark" and ":k".
*/
-static void ex_mark(eap)
-exarg_T *eap;
+static void ex_mark(exarg_T *eap)
{
pos_T pos;
@@ -7556,7 +7456,7 @@ exarg_T *eap;
/*
* Update w_topline, w_leftcol and the cursor position.
*/
-void update_topline_cursor() {
+void update_topline_cursor(void) {
check_cursor(); /* put cursor on valid line */
update_topline();
if (!curwin->w_p_wrap)
@@ -7567,8 +7467,7 @@ void update_topline_cursor() {
/*
* ":normal[!] {commands}": Execute normal mode commands.
*/
-static void ex_normal(eap)
-exarg_T *eap;
+static void ex_normal(exarg_T *eap)
{
int save_msg_scroll = msg_scroll;
int save_restart_edit = restart_edit;
@@ -7677,8 +7576,7 @@ exarg_T *eap;
/*
* ":startinsert", ":startreplace" and ":startgreplace"
*/
-static void ex_startinsert(eap)
-exarg_T *eap;
+static void ex_startinsert(exarg_T *eap)
{
if (eap->forceit) {
coladvance((colnr_T)MAXCOL);
@@ -7708,8 +7606,7 @@ exarg_T *eap;
/*
* ":stopinsert"
*/
-static void ex_stopinsert(eap)
-exarg_T *eap UNUSED;
+static void ex_stopinsert(exarg_T *eap)
{
restart_edit = 0;
stop_insert_mode = TRUE;
@@ -7719,10 +7616,7 @@ exarg_T *eap UNUSED;
* Execute normal mode command "cmd".
* "remap" can be REMAP_NONE or REMAP_YES.
*/
-void exec_normal_cmd(cmd, remap, silent)
-char_u *cmd;
-int remap;
-int silent;
+void exec_normal_cmd(char_u *cmd, int remap, int silent)
{
oparg_T oa;
@@ -7740,8 +7634,7 @@ int silent;
}
}
-static void ex_checkpath(eap)
-exarg_T *eap;
+static void ex_checkpath(exarg_T *eap)
{
find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L,
eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW,
@@ -7751,16 +7644,14 @@ exarg_T *eap;
/*
* ":psearch"
*/
-static void ex_psearch(eap)
-exarg_T *eap;
+static void ex_psearch(exarg_T *eap)
{
g_do_tagpreview = p_pvh;
ex_findpat(eap);
g_do_tagpreview = 0;
}
-static void ex_findpat(eap)
-exarg_T *eap;
+static void ex_findpat(exarg_T *eap)
{
int whole = TRUE;
long n;
@@ -7816,8 +7707,7 @@ exarg_T *eap;
/*
* ":ptag", ":ptselect", ":ptjump", ":ptnext", etc.
*/
-static void ex_ptag(eap)
-exarg_T *eap;
+static void ex_ptag(exarg_T *eap)
{
g_do_tagpreview = p_pvh; /* will be reset to 0 in ex_tag_cmd() */
ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name + 1);
@@ -7826,8 +7716,7 @@ exarg_T *eap;
/*
* ":pedit"
*/
-static void ex_pedit(eap)
-exarg_T *eap;
+static void ex_pedit(exarg_T *eap)
{
win_T *curwin_save = curwin;
@@ -7848,8 +7737,7 @@ exarg_T *eap;
/*
* ":stag", ":stselect" and ":stjump".
*/
-static void ex_stag(eap)
-exarg_T *eap;
+static void ex_stag(exarg_T *eap)
{
postponed_split = -1;
postponed_split_flags = cmdmod.split;
@@ -7862,15 +7750,12 @@ exarg_T *eap;
/*
* ":tag", ":tselect", ":tjump", ":tnext", etc.
*/
-static void ex_tag(eap)
-exarg_T *eap;
+static void ex_tag(exarg_T *eap)
{
ex_tag_cmd(eap, cmdnames[eap->cmdidx].cmd_name);
}
-static void ex_tag_cmd(eap, name)
-exarg_T *eap;
-char_u *name;
+static void ex_tag_cmd(exarg_T *eap, char_u *name)
{
int cmd;
@@ -7914,9 +7799,7 @@ char_u *name;
* If found return one of the SPEC_ values and set "*usedlen" to the length of
* the variable. Otherwise return -1 and "*usedlen" is unchanged.
*/
-int find_cmdline_var(src, usedlen)
-char_u *src;
-int *usedlen;
+int find_cmdline_var(char_u *src, int *usedlen)
{
int len;
int i;
@@ -7973,14 +7856,16 @@ int *usedlen;
* Returns NULL if no match was found. "usedlen" then still contains the
* number of characters to skip.
*/
-char_u * eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
-char_u *src; /* pointer into commandline */
-char_u *srcstart; /* beginning of valid memory for src */
-int *usedlen; /* characters after src that are used */
-linenr_T *lnump; /* line number for :e command, or NULL */
-char_u **errormsg; /* pointer to error message */
-int *escaped; /* return value has escaped white space (can
+char_u *
+eval_vars (
+ char_u *src, /* pointer into commandline */
+ char_u *srcstart, /* beginning of valid memory for src */
+ int *usedlen, /* characters after src that are used */
+ linenr_T *lnump, /* line number for :e command, or NULL */
+ char_u **errormsg, /* pointer to error message */
+ int *escaped /* return value has escaped white space (can
* be NULL) */
+)
{
int i;
char_u *s;
@@ -8188,7 +8073,7 @@ int *escaped; /* return value has escaped white space (can
* Spaces and backslashes in the file names are escaped with a backslash.
* Returns NULL when out of memory.
*/
-static char_u * arg_all() {
+static char_u *arg_all(void) {
int len;
int idx;
char_u *retval = NULL;
@@ -8244,8 +8129,7 @@ static char_u * arg_all() {
*
* Returns an allocated string, or NULL for any error.
*/
-char_u * expand_sfile(arg)
-char_u *arg;
+char_u *expand_sfile(char_u *arg)
{
char_u *errormsg;
int len;
@@ -8311,9 +8195,11 @@ static int ses_fname __ARGS((FILE *fd, buf_T *buf, unsigned *flagp));
* Write openfile commands for the current buffers to an .exrc file.
* Return FAIL on error, OK otherwise.
*/
-static int makeopens(fd, dirnow)
-FILE *fd;
-char_u *dirnow; /* Current directory name */
+static int
+makeopens (
+ FILE *fd,
+ char_u *dirnow /* Current directory name */
+)
{
buf_T *buf;
int only_save_windows = TRUE;
@@ -8581,10 +8467,7 @@ char_u *dirnow; /* Current directory name */
return OK;
}
-static int ses_winsizes(fd, restore_size, tab_firstwin)
-FILE *fd;
-int restore_size;
-win_T *tab_firstwin;
+static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
{
int n = 0;
win_T *wp;
@@ -8625,9 +8508,7 @@ win_T *tab_firstwin;
* After the commands the last window in the frame is the current window.
* Returns FAIL when writing the commands to "fd" fails.
*/
-static int ses_win_rec(fd, fr)
-FILE *fd;
-frame_T *fr;
+static int ses_win_rec(FILE *fd, frame_T *fr)
{
frame_T *frc;
int count = 0;
@@ -8671,8 +8552,7 @@ frame_T *fr;
* Skip frames that don't contain windows we want to save in the Session.
* Returns NULL when there none.
*/
-static frame_T * ses_skipframe(fr)
-frame_T *fr;
+static frame_T *ses_skipframe(frame_T *fr)
{
frame_T *frc;
@@ -8686,8 +8566,7 @@ frame_T *fr;
* Return TRUE if frame "fr" has a window somewhere that we want to save in
* the Session.
*/
-static int ses_do_frame(fr)
-frame_T *fr;
+static int ses_do_frame(frame_T *fr)
{
frame_T *frc;
@@ -8702,8 +8581,7 @@ frame_T *fr;
/*
* Return non-zero if window "wp" is to be stored in the Session.
*/
-static int ses_do_win(wp)
-win_T *wp;
+static int ses_do_win(win_T *wp)
{
if (wp->w_buffer->b_fname == NULL
/* When 'buftype' is "nofile" can't restore the window contents. */
@@ -8719,13 +8597,15 @@ win_T *wp;
* Write commands to "fd" to restore the view of a window.
* Caller must make sure 'scrolloff' is zero.
*/
-static int put_view(fd, wp, add_edit, flagp, current_arg_idx)
-FILE *fd;
-win_T *wp;
-int add_edit; /* add ":edit" command to view */
-unsigned *flagp; /* vop_flags or ssop_flags */
-int current_arg_idx; /* current argument index of the window, use
+static int
+put_view (
+ FILE *fd,
+ win_T *wp,
+ int add_edit, /* add ":edit" command to view */
+ unsigned *flagp, /* vop_flags or ssop_flags */
+ int current_arg_idx /* current argument index of the window, use
* -1 if unknown */
+)
{
win_T *save_curwin;
int f;
@@ -8895,12 +8775,14 @@ int current_arg_idx; /* current argument index of the window, use
* Write an argument list to the session file.
* Returns FAIL if writing fails.
*/
-static int ses_arglist(fd, cmd, gap, fullname, flagp)
-FILE *fd;
-char *cmd;
-garray_T *gap;
-int fullname; /* TRUE: use full path name */
-unsigned *flagp;
+static int
+ses_arglist (
+ FILE *fd,
+ char *cmd,
+ garray_T *gap,
+ int fullname, /* TRUE: use full path name */
+ unsigned *flagp
+)
{
int i;
char_u *buf = NULL;
@@ -8936,10 +8818,7 @@ unsigned *flagp;
* Also ends the line.
* Returns FAIL if writing fails.
*/
-static int ses_fname(fd, buf, flagp)
-FILE *fd;
-buf_T *buf;
-unsigned *flagp;
+static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
{
char_u *name;
@@ -8967,10 +8846,7 @@ unsigned *flagp;
* characters.
* Returns FAIL if writing fails or out of memory.
*/
-static int ses_put_fname(fd, name, flagp)
-FILE *fd;
-char_u *name;
-unsigned *flagp;
+static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
{
char_u *sname;
char_u *p;
@@ -9004,8 +8880,7 @@ unsigned *flagp;
/*
* ":loadview [nr]"
*/
-static void ex_loadview(eap)
-exarg_T *eap;
+static void ex_loadview(exarg_T *eap)
{
char_u *fname;
@@ -9019,8 +8894,7 @@ exarg_T *eap;
/*
* Get the name of the view file for the current buffer.
*/
-static char_u * get_view_file(c)
-int c;
+static char_u *get_view_file(int c)
{
int len = 0;
char_u *p, *s;
@@ -9079,8 +8953,7 @@ int c;
* Write end-of-line character(s) for ":mkexrc", ":mkvimrc" and ":mksession".
* Return FAIL for a write error.
*/
-int put_eol(fd)
-FILE *fd;
+int put_eol(FILE *fd)
{
if (
#ifdef USE_CRNL
@@ -9099,9 +8972,7 @@ FILE *fd;
* Write a line to "fd".
* Return FAIL for a write error.
*/
-int put_line(fd, s)
-FILE *fd;
-char *s;
+int put_line(FILE *fd, char *s)
{
if (fputs(s, fd) < 0 || put_eol(fd) == FAIL)
return FAIL;
@@ -9111,8 +8982,7 @@ char *s;
/*
* ":rviminfo" and ":wviminfo".
*/
-static void ex_viminfo(eap)
-exarg_T *eap;
+static void ex_viminfo(exarg_T *eap)
{
char_u *save_viminfo;
@@ -9132,10 +9002,7 @@ exarg_T *eap;
* Make a dialog message in "buff[DIALOG_MSG_SIZE]".
* "format" must contain "%s".
*/
-void dialog_msg(buff, format, fname)
-char_u *buff;
-char *format;
-char_u *fname;
+void dialog_msg(char_u *buff, char *format, char_u *fname)
{
if (fname == NULL)
fname = (char_u *)_("Untitled");
@@ -9145,8 +9012,7 @@ char_u *fname;
/*
* ":behave {mswin,xterm}"
*/
-static void ex_behave(eap)
-exarg_T *eap;
+static void ex_behave(exarg_T *eap)
{
if (STRCMP(eap->arg, "mswin") == 0) {
set_option_value((char_u *)"selection", 0L, (char_u *)"exclusive", 0);
@@ -9167,9 +9033,7 @@ exarg_T *eap;
* Function given to ExpandGeneric() to obtain the possible arguments of the
* ":behave {mswin,xterm}" command.
*/
-char_u * get_behave_arg(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_behave_arg(expand_T *xp, int idx)
{
if (idx == 0)
return (char_u *)"mswin";
@@ -9191,8 +9055,7 @@ static int filetype_indent = FALSE;
* indent on: load filetype.vim and indent.vim
* indent off: load indoff.vim
*/
-static void ex_filetype(eap)
-exarg_T *eap;
+static void ex_filetype(exarg_T *eap)
{
char_u *arg = eap->arg;
int plugin = FALSE;
@@ -9259,15 +9122,13 @@ exarg_T *eap;
/*
* ":setfiletype {name}"
*/
-static void ex_setfiletype(eap)
-exarg_T *eap;
+static void ex_setfiletype(exarg_T *eap)
{
if (!did_filetype)
set_option_value((char_u *)"filetype", 0L, eap->arg, OPT_LOCAL);
}
-static void ex_digraphs(eap)
-exarg_T *eap UNUSED;
+static void ex_digraphs(exarg_T *eap)
{
if (*eap->arg != NUL)
putdigraph(eap->arg);
@@ -9275,8 +9136,7 @@ exarg_T *eap UNUSED;
listdigraphs();
}
-static void ex_set(eap)
-exarg_T *eap;
+static void ex_set(exarg_T *eap)
{
int flags = 0;
@@ -9290,8 +9150,7 @@ exarg_T *eap;
/*
* ":nohlsearch"
*/
-static void ex_nohlsearch(eap)
-exarg_T *eap UNUSED;
+static void ex_nohlsearch(exarg_T *eap)
{
SET_NO_HLSEARCH(TRUE);
redraw_all_later(SOME_VALID);
@@ -9302,8 +9161,7 @@ exarg_T *eap UNUSED;
* Sets nextcmd to the start of the next command, if any. Also called when
* skipping commands to find the next command.
*/
-static void ex_match(eap)
-exarg_T *eap;
+static void ex_match(exarg_T *eap)
{
char_u *p;
char_u *g = NULL;
@@ -9361,29 +9219,25 @@ exarg_T *eap;
/*
* ":X": Get crypt key
*/
-static void ex_X(eap)
-exarg_T *eap UNUSED;
+static void ex_X(exarg_T *eap)
{
if (get_crypt_method(curbuf) == 0 || blowfish_self_test() == OK)
(void)get_crypt_key(TRUE, TRUE);
}
-static void ex_fold(eap)
-exarg_T *eap;
+static void ex_fold(exarg_T *eap)
{
if (foldManualAllowed(TRUE))
foldCreate(eap->line1, eap->line2);
}
-static void ex_foldopen(eap)
-exarg_T *eap;
+static void ex_foldopen(exarg_T *eap)
{
opFoldRange(eap->line1, eap->line2, eap->cmdidx == CMD_foldopen,
eap->forceit, FALSE);
}
-static void ex_folddo(eap)
-exarg_T *eap;
+static void ex_folddo(exarg_T *eap)
{
linenr_T lnum;
diff --git a/src/proto/ex_docmd.pro b/src/ex_docmd.h
index ff83cad83f..f3f9ca16ec 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/ex_docmd.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EX_DOCMD_H
+#define NEOVIM_EX_DOCMD_H
/* ex_docmd.c */
void do_exmode __ARGS((int improved));
int do_cmdline_cmd __ARGS((char_u *cmd));
@@ -67,3 +69,4 @@ int put_line __ARGS((FILE *fd, char *s));
void dialog_msg __ARGS((char_u *buff, char *format, char_u *fname));
char_u *get_behave_arg __ARGS((expand_T *xp, int idx));
/* vim: set ft=c : */
+#endif /* NEOVIM_EX_DOCMD_H */
diff --git a/src/ex_eval.c b/src/ex_eval.c
index 5f845c3f33..e4148068f5 100644
--- a/src/ex_eval.c
+++ b/src/ex_eval.c
@@ -12,6 +12,14 @@
*/
#include "vim.h"
+#include "ex_eval.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "message.h"
+#include "misc2.h"
+#include "regexp.h"
static void free_msglist __ARGS((struct msglist *l));
@@ -84,7 +92,7 @@ static int cause_abort = FALSE;
* cancellation of an expression evaluation after an aborting function call or
* due to a parsing error, aborting() always returns the same value.
*/
-int aborting() {
+int aborting(void) {
return (did_emsg && force_abort) || got_int || did_throw;
}
@@ -94,7 +102,7 @@ int aborting() {
* be necessary to restore "force_abort" even before the throw point for the
* error message has been reached. update_force_abort() should be called then.
*/
-void update_force_abort() {
+void update_force_abort(void) {
if (cause_abort)
force_abort = TRUE;
}
@@ -105,8 +113,7 @@ void update_force_abort() {
* execution of a failing subcommand as long as the error message has not been
* displayed and actually caused the abortion.
*/
-int should_abort(retcode)
-int retcode;
+int should_abort(int retcode)
{
return (retcode == FAIL && trylevel != 0 && !emsg_silent) || aborting();
}
@@ -117,7 +124,7 @@ int retcode;
* to find finally clauses to be executed, and that some errors in skipped
* commands are still reported.
*/
-int aborted_in_try() {
+int aborted_in_try(void) {
/* This function is only called after an error. In this case, "force_abort"
* determines whether searching for finally clauses is necessary. */
return force_abort;
@@ -132,10 +139,7 @@ int aborted_in_try() {
* most specific one and used as the exception value. The "severe" flag can be
* set to TRUE, if a later but severer message should be used instead.
*/
-int cause_errthrow(mesg, severe, ignore)
-char_u *mesg;
-int severe;
-int *ignore;
+int cause_errthrow(char_u *mesg, int severe, int *ignore)
{
struct msglist *elem;
struct msglist **plist;
@@ -275,8 +279,7 @@ int *ignore;
/*
* Free a "msg_list" and the messages it contains.
*/
-static void free_msglist(l)
-struct msglist *l;
+static void free_msglist(struct msglist *l)
{
struct msglist *messages, *next;
@@ -293,7 +296,7 @@ struct msglist *l;
* Free global "*msg_list" and the messages it contains, then set "*msg_list"
* to NULL.
*/
-void free_global_msglist() {
+void free_global_msglist(void) {
free_msglist(*msg_list);
*msg_list = NULL;
}
@@ -303,9 +306,7 @@ void free_global_msglist() {
* error exception. If cstack is NULL, postpone the throw until do_cmdline()
* has returned (see do_one_cmd()).
*/
-void do_errthrow(cstack, cmdname)
-struct condstack *cstack;
-char_u *cmdname;
+void do_errthrow(struct condstack *cstack, char_u *cmdname)
{
/*
* Ensure that all commands in nested function calls and sourced files
@@ -337,8 +338,7 @@ char_u *cmdname;
* exception if appropriate. Return TRUE if the current exception is discarded,
* FALSE otherwise.
*/
-int do_intthrow(cstack)
-struct condstack *cstack;
+int do_intthrow(struct condstack *cstack)
{
/*
* If no interrupt occurred or no try conditional is active and no exception
@@ -384,11 +384,7 @@ struct condstack *cstack;
/*
* Get an exception message that is to be stored in current_exception->value.
*/
-char_u * get_exception_string(value, type, cmdname, should_free)
-void *value;
-int type;
-char_u *cmdname;
-int *should_free;
+char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should_free)
{
char_u *ret, *mesg;
int cmdlen;
@@ -457,10 +453,7 @@ int *should_free;
* user or interrupt exception, or points to a message list in case of an
* error exception.
*/
-static int throw_exception(value, type, cmdname)
-void *value;
-int type;
-char_u *cmdname;
+static int throw_exception(void *value, int type, char_u *cmdname)
{
except_T *excp;
int should_free;
@@ -541,9 +534,7 @@ fail:
* Discard an exception. "was_finished" is set when the exception has been
* caught and the catch clause has been ended normally.
*/
-static void discard_exception(excp, was_finished)
-except_T *excp;
-int was_finished;
+static void discard_exception(except_T *excp, int was_finished)
{
char_u *saved_IObuff;
@@ -589,7 +580,7 @@ int was_finished;
/*
* Discard the exception currently being thrown.
*/
-void discard_current_exception() {
+void discard_current_exception(void) {
discard_exception(current_exception, FALSE);
current_exception = NULL;
did_throw = FALSE;
@@ -599,8 +590,7 @@ void discard_current_exception() {
/*
* Put an exception on the caught stack.
*/
-static void catch_exception(excp)
-except_T *excp;
+static void catch_exception(except_T *excp)
{
excp->caught = caught_stack;
caught_stack = excp;
@@ -643,8 +633,7 @@ except_T *excp;
/*
* Remove an exception from the caught stack.
*/
-static void finish_exception(excp)
-except_T *excp;
+static void finish_exception(except_T *excp)
{
if (excp != caught_stack)
EMSG(_(e_internal));
@@ -687,10 +676,7 @@ except_T *excp;
* what is pending. "value" specifies the return value for a pending ":return"
* or the exception value for a pending exception.
*/
-static void report_pending(action, pending, value)
-int action;
-int pending;
-void *value;
+static void report_pending(int action, int pending, void *value)
{
char_u *mesg;
char *s;
@@ -765,9 +751,7 @@ void *value;
* If something is made pending in a finally clause, report it if required by
* the 'verbose' option or when debugging.
*/
-void report_make_pending(pending, value)
-int pending;
-void *value;
+void report_make_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
if (debug_break_level <= 0)
@@ -782,9 +766,7 @@ void *value;
* If something pending in a finally clause is resumed at the ":endtry", report
* it if required by the 'verbose' option or when debugging.
*/
-void report_resume_pending(pending, value)
-int pending;
-void *value;
+void report_resume_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
if (debug_break_level <= 0)
@@ -799,9 +781,7 @@ void *value;
* If something pending in a finally clause is discarded, report it if required
* by the 'verbose' option or when debugging.
*/
-void report_discard_pending(pending, value)
-int pending;
-void *value;
+void report_discard_pending(int pending, void *value)
{
if (p_verbose >= 14 || debug_break_level > 0) {
if (debug_break_level <= 0)
@@ -816,8 +796,7 @@ void *value;
/*
* ":if".
*/
-void ex_if(eap)
-exarg_T *eap;
+void ex_if(exarg_T *eap)
{
int error;
int skip;
@@ -854,8 +833,7 @@ exarg_T *eap;
/*
* ":endif".
*/
-void ex_endif(eap)
-exarg_T *eap;
+void ex_endif(exarg_T *eap)
{
did_endif = TRUE;
if (eap->cstack->cs_idx < 0
@@ -883,8 +861,7 @@ exarg_T *eap;
/*
* ":else" and ":elseif".
*/
-void ex_else(eap)
-exarg_T *eap;
+void ex_else(exarg_T *eap)
{
int error;
int skip;
@@ -965,8 +942,7 @@ exarg_T *eap;
/*
* Handle ":while" and ":for".
*/
-void ex_while(eap)
-exarg_T *eap;
+void ex_while(exarg_T *eap)
{
int error;
int skip;
@@ -1055,8 +1031,7 @@ exarg_T *eap;
/*
* ":continue"
*/
-void ex_continue(eap)
-exarg_T *eap;
+void ex_continue(exarg_T *eap)
{
int idx;
struct condstack *cstack = eap->cstack;
@@ -1089,8 +1064,7 @@ exarg_T *eap;
/*
* ":break"
*/
-void ex_break(eap)
-exarg_T *eap;
+void ex_break(exarg_T *eap)
{
int idx;
struct condstack *cstack = eap->cstack;
@@ -1113,8 +1087,7 @@ exarg_T *eap;
/*
* ":endwhile" and ":endfor"
*/
-void ex_endwhile(eap)
-exarg_T *eap;
+void ex_endwhile(exarg_T *eap)
{
struct condstack *cstack = eap->cstack;
int idx;
@@ -1190,8 +1163,7 @@ exarg_T *eap;
/*
* ":throw expr"
*/
-void ex_throw(eap)
-exarg_T *eap;
+void ex_throw(exarg_T *eap)
{
char_u *arg = eap->arg;
char_u *value;
@@ -1218,8 +1190,7 @@ exarg_T *eap;
* for ":throw" (user exception) and error and interrupt exceptions. Also
* used for rethrowing an uncaught exception.
*/
-void do_throw(cstack)
-struct condstack *cstack;
+void do_throw(struct condstack *cstack)
{
int idx;
int inactivate_try = FALSE;
@@ -1279,8 +1250,7 @@ struct condstack *cstack;
/*
* ":try"
*/
-void ex_try(eap)
-exarg_T *eap;
+void ex_try(exarg_T *eap)
{
int skip;
struct condstack *cstack = eap->cstack;
@@ -1347,8 +1317,7 @@ exarg_T *eap;
/*
* ":catch /{pattern}/" and ":catch"
*/
-void ex_catch(eap)
-exarg_T *eap;
+void ex_catch(exarg_T *eap)
{
int idx = 0;
int give_up = FALSE;
@@ -1489,8 +1458,7 @@ exarg_T *eap;
/*
* ":finally"
*/
-void ex_finally(eap)
-exarg_T *eap;
+void ex_finally(exarg_T *eap)
{
int idx;
int skip = FALSE;
@@ -1608,8 +1576,7 @@ exarg_T *eap;
/*
* ":endtry"
*/
-void ex_endtry(eap)
-exarg_T *eap;
+void ex_endtry(exarg_T *eap)
{
int idx;
int skip;
@@ -1797,8 +1764,7 @@ exarg_T *eap;
* do_cmdline() that is going to be made for the cleanup autocommand
* execution.
*/
-void enter_cleanup(csp)
-cleanup_T *csp;
+void enter_cleanup(cleanup_T *csp)
{
int pending = CSTP_NONE;
@@ -1854,8 +1820,7 @@ cleanup_T *csp;
* cleanup autocommands. In the latter case, the saved error/interrupt/
* exception state is discarded.
*/
-void leave_cleanup(csp)
-cleanup_T *csp;
+void leave_cleanup(cleanup_T *csp)
{
int pending = csp->pending;
@@ -1935,10 +1900,7 @@ cleanup_T *csp;
* entered, is restored (used by ex_endtry()). This is normally done only
* when such a try conditional is left.
*/
-int cleanup_conditionals(cstack, searched_cond, inclusive)
-struct condstack *cstack;
-int searched_cond;
-int inclusive;
+int cleanup_conditionals(struct condstack *cstack, int searched_cond, int inclusive)
{
int idx;
int stop = FALSE;
@@ -2046,8 +2008,7 @@ int inclusive;
/*
* Return an appropriate error message for a missing endwhile/endfor/endif.
*/
-static char_u * get_end_emsg(cstack)
-struct condstack *cstack;
+static char_u *get_end_emsg(struct condstack *cstack)
{
if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
return e_endwhile;
@@ -2064,11 +2025,7 @@ struct condstack *cstack;
* type.
* Also free "for info" structures where needed.
*/
-void rewind_conditionals(cstack, idx, cond_type, cond_level)
-struct condstack *cstack;
-int idx;
-int cond_type;
-int *cond_level;
+void rewind_conditionals(struct condstack *cstack, int idx, int cond_type, int *cond_level)
{
while (cstack->cs_idx > idx) {
if (cstack->cs_flags[cstack->cs_idx] & cond_type)
@@ -2082,8 +2039,7 @@ int *cond_level;
/*
* ":endfunction" when not after a ":function"
*/
-void ex_endfunction(eap)
-exarg_T *eap UNUSED;
+void ex_endfunction(exarg_T *eap)
{
EMSG(_("E193: :endfunction not inside a function"));
}
@@ -2091,8 +2047,7 @@ exarg_T *eap UNUSED;
/*
* Return TRUE if the string "p" looks like a ":while" or ":for" command.
*/
-int has_loop_cmd(p)
-char_u *p;
+int has_loop_cmd(char_u *p)
{
int len;
diff --git a/src/proto/ex_eval.pro b/src/ex_eval.h
index 7fc87410e0..3685899063 100644
--- a/src/proto/ex_eval.pro
+++ b/src/ex_eval.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EX_EVAL_H
+#define NEOVIM_EX_EVAL_H
/* ex_eval.c */
int aborting __ARGS((void));
void update_force_abort __ARGS((void));
@@ -36,3 +38,4 @@ void rewind_conditionals __ARGS((struct condstack *cstack, int idx,
void ex_endfunction __ARGS((exarg_T *eap));
int has_loop_cmd __ARGS((char_u *p));
/* vim: set ft=c : */
+#endif /* NEOVIM_EX_EVAL_H */
diff --git a/src/ex_getln.c b/src/ex_getln.c
index dbef0a9449..c3f389e279 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -12,6 +12,38 @@
*/
#include "vim.h"
+#include "ex_getln.h"
+#include "buffer.h"
+#include "charset.h"
+#include "digraph.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "if_cscope.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "menu.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "ops.h"
+#include "option.h"
+#include "os_unix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "window.h"
+#include "os/os.h"
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
@@ -125,10 +157,12 @@ sort_func_compare __ARGS((const void *s1, const void *s2));
* Return pointer to allocated string if there is a commandline, NULL
* otherwise.
*/
-char_u * getcmdline(firstc, count, indent)
-int firstc;
-long count UNUSED; /* only used for incremental search */
-int indent; /* indent for inside conditionals */
+char_u *
+getcmdline (
+ int firstc,
+ long count, /* only used for incremental search */
+ int indent /* indent for inside conditionals */
+)
{
int c;
int i;
@@ -1545,12 +1579,14 @@ returncmd:
* f_input() when evaluating an expression from CTRL-R =).
* Returns the command line in allocated memory, or NULL.
*/
-char_u * getcmdline_prompt(firstc, prompt, attr, xp_context, xp_arg)
-int firstc;
-char_u *prompt; /* command line prompt */
-int attr; /* attributes for prompt */
-int xp_context; /* type of expansion */
-char_u *xp_arg; /* user-defined expansion argument */
+char_u *
+getcmdline_prompt (
+ int firstc,
+ char_u *prompt, /* command line prompt */
+ int attr, /* attributes for prompt */
+ int xp_context, /* type of expansion */
+ char_u *xp_arg /* user-defined expansion argument */
+)
{
char_u *s;
struct cmdline_info save_ccline;
@@ -1579,7 +1615,7 @@ char_u *xp_arg; /* user-defined expansion argument */
* another window or buffer. Used when editing the command line, evaluating
* 'balloonexpr', etc.
*/
-int text_locked() {
+int text_locked(void) {
if (cmdwin_type != 0)
return TRUE;
return textlock != 0;
@@ -1589,7 +1625,7 @@ int text_locked() {
* Give an error message for a command that isn't allowed while the cmdline
* window is open or editing the cmdline in another way.
*/
-void text_locked_msg() {
+void text_locked_msg(void) {
if (cmdwin_type != 0)
EMSG(_(e_cmdwin));
else
@@ -1600,7 +1636,7 @@ void text_locked_msg() {
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
* and give an error message.
*/
-int curbuf_locked() {
+int curbuf_locked(void) {
if (curbuf_lock > 0) {
EMSG(_("E788: Not allowed to edit another buffer now"));
return TRUE;
@@ -1612,7 +1648,7 @@ int curbuf_locked() {
* Check if "allbuf_lock" is set and return TRUE when it is and give an error
* message.
*/
-int allbuf_locked() {
+int allbuf_locked(void) {
if (allbuf_lock > 0) {
EMSG(_("E811: Not allowed to change buffer information now"));
return TRUE;
@@ -1620,8 +1656,7 @@ int allbuf_locked() {
return FALSE;
}
-static int cmdline_charsize(idx)
-int idx;
+static int cmdline_charsize(int idx)
{
if (cmdline_star > 0) /* showing '*', always 1 position */
return 1;
@@ -1632,7 +1667,7 @@ int idx;
* Compute the offset of the cursor on the command line for the prompt and
* indent.
*/
-static void set_cmdspos() {
+static void set_cmdspos(void) {
if (ccline.cmdfirstc != NUL)
ccline.cmdspos = 1 + ccline.cmdindent;
else
@@ -1642,7 +1677,7 @@ static void set_cmdspos() {
/*
* Compute the screen position for the cursor on the command line.
*/
-static void set_cmdspos_cursor() {
+static void set_cmdspos_cursor(void) {
int i, m, c;
set_cmdspos();
@@ -1672,9 +1707,7 @@ static void set_cmdspos_cursor() {
* Check if the character at "idx", which is "cells" wide, is a multi-byte
* character that doesn't fit, so that a ">" must be displayed.
*/
-static void correct_cmdspos(idx, cells)
-int idx;
-int cells;
+static void correct_cmdspos(int idx, int cells)
{
if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
&& (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
@@ -1685,10 +1718,12 @@ int cells;
/*
* Get an Ex command line for the ":" command.
*/
-char_u * getexline(c, cookie, indent)
-int c; /* normally ':', NUL for ":append" */
-void *cookie UNUSED;
-int indent; /* indent for inside conditionals */
+char_u *
+getexline (
+ int c, /* normally ':', NUL for ":append" */
+ void *cookie,
+ int indent /* indent for inside conditionals */
+)
{
/* When executing a register, remove ':' that's in front of each line. */
if (exec_from_reg && vpeekc() == ':')
@@ -1702,11 +1737,13 @@ int indent; /* indent for inside conditionals */
* mappings or abbreviations.
* Returns a string in allocated memory or NULL.
*/
-char_u * getexmodeline(promptc, cookie, indent)
-int promptc; /* normally ':', NUL for ":append" and '?' for
+char_u *
+getexmodeline (
+ int promptc, /* normally ':', NUL for ":append" and '?' for
:s prompt */
-void *cookie UNUSED;
-int indent; /* indent for inside conditionals */
+ void *cookie,
+ int indent /* indent for inside conditionals */
+)
{
garray_T line_ga;
char_u *pend;
@@ -1932,14 +1969,14 @@ redraw:
/*
* Return TRUE if ccline.overstrike is on.
*/
-int cmdline_overstrike() {
+int cmdline_overstrike(void) {
return ccline.overstrike;
}
/*
* Return TRUE if the cursor is at the end of the cmdline.
*/
-int cmdline_at_end() {
+int cmdline_at_end(void) {
return ccline.cmdpos >= ccline.cmdlen;
}
@@ -1952,8 +1989,7 @@ int cmdline_at_end() {
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
* Returns the new value of ccline.cmdbuff and ccline.cmdbufflen.
*/
-static void alloc_cmdbuff(len)
-int len;
+static void alloc_cmdbuff(int len)
{
/*
* give some extra space to avoid having to allocate all the time
@@ -1971,8 +2007,7 @@ int len;
* Re-allocate the command line to length len + something extra.
* return FAIL for failure, OK otherwise
*/
-static int realloc_cmdbuff(len)
-int len;
+static int realloc_cmdbuff(int len)
{
char_u *p;
@@ -2009,7 +2044,7 @@ int len;
static char_u *arshape_buf = NULL;
# if defined(EXITFREE) || defined(PROTO)
-void free_cmdline_buf() {
+void free_cmdline_buf(void) {
vim_free(arshape_buf);
}
@@ -2019,9 +2054,7 @@ void free_cmdline_buf() {
* Draw part of the cmdline at the current cursor position. But draw stars
* when cmdline_star is TRUE.
*/
-static void draw_cmdline(start, len)
-int start;
-int len;
+static void draw_cmdline(int start, int len)
{
int i;
@@ -2120,9 +2153,7 @@ int len;
* right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc.
* "c" must be printable (fit in one display cell)!
*/
-void putcmdline(c, shift)
-int c;
-int shift;
+void putcmdline(int c, int shift)
{
if (cmd_silent)
return;
@@ -2137,7 +2168,7 @@ int shift;
/*
* Undo a putcmdline(c, FALSE).
*/
-void unputcmdline() {
+void unputcmdline(void) {
if (cmd_silent)
return;
msg_no_more = TRUE;
@@ -2160,10 +2191,7 @@ void unputcmdline() {
* twice in a row, then 'redraw' should be FALSE and redrawcmd() should be
* called afterwards.
*/
-int put_on_cmdline(str, len, redraw)
-char_u *str;
-int len;
-int redraw;
+int put_on_cmdline(char_u *str, int len, int redraw)
{
int retval;
int i;
@@ -2298,8 +2326,7 @@ static int prev_ccline_used = FALSE;
* and overwrite it. But get_cmdline_str() may need it, thus make it
* available globally in prev_ccline.
*/
-static void save_cmdline(ccp)
-struct cmdline_info *ccp;
+static void save_cmdline(struct cmdline_info *ccp)
{
if (!prev_ccline_used) {
vim_memset(&prev_ccline, 0, sizeof(struct cmdline_info));
@@ -2315,8 +2342,7 @@ struct cmdline_info *ccp;
/*
* Restore ccline after it has been saved with save_cmdline().
*/
-static void restore_cmdline(ccp)
-struct cmdline_info *ccp;
+static void restore_cmdline(struct cmdline_info *ccp)
{
ccline = prev_ccline;
prev_ccline = *ccp;
@@ -2327,7 +2353,7 @@ struct cmdline_info *ccp;
* passed to restore_cmdline_alloc() later.
* Returns NULL when failed.
*/
-char_u * save_cmdline_alloc() {
+char_u *save_cmdline_alloc(void) {
struct cmdline_info *p;
p = (struct cmdline_info *)alloc((unsigned)sizeof(struct cmdline_info));
@@ -2339,8 +2365,7 @@ char_u * save_cmdline_alloc() {
/*
* Restore the command line from the return value of save_cmdline_alloc().
*/
-void restore_cmdline_alloc(p)
-char_u *p;
+void restore_cmdline_alloc(char_u *p)
{
if (p != NULL) {
restore_cmdline((struct cmdline_info *)p);
@@ -2356,10 +2381,12 @@ char_u *p;
*
* return FAIL for failure, OK otherwise
*/
-static int cmdline_paste(regname, literally, remcr)
-int regname;
-int literally; /* Insert text literally instead of "as typed" */
-int remcr; /* remove trailing CR */
+static int
+cmdline_paste (
+ int regname,
+ int literally, /* Insert text literally instead of "as typed" */
+ int remcr /* remove trailing CR */
+)
{
long i;
char_u *arg;
@@ -2433,9 +2460,7 @@ int remcr; /* remove trailing CR */
* When "literally" is FALSE, insert as typed, but don't leave the command
* line.
*/
-void cmdline_paste_str(s, literally)
-char_u *s;
-int literally;
+void cmdline_paste_str(char_u *s, int literally)
{
int c, cv;
@@ -2465,8 +2490,7 @@ int literally;
* Delete characters on the command line, from "from" to the current
* position.
*/
-static void cmdline_del(from)
-int from;
+static void cmdline_del(int from)
{
mch_memmove(ccline.cmdbuff + from, ccline.cmdbuff + ccline.cmdpos,
(size_t)(ccline.cmdlen - ccline.cmdpos + 1));
@@ -2478,7 +2502,7 @@ int from;
* this function is called when the screen size changes and with incremental
* search
*/
-void redrawcmdline() {
+void redrawcmdline(void) {
if (cmd_silent)
return;
need_wait_return = FALSE;
@@ -2487,7 +2511,7 @@ void redrawcmdline() {
cursorcmd();
}
-static void redrawcmdprompt() {
+static void redrawcmdprompt(void) {
int i;
if (cmd_silent)
@@ -2508,7 +2532,7 @@ static void redrawcmdprompt() {
/*
* Redraw what is currently on the command line.
*/
-void redrawcmd() {
+void redrawcmd(void) {
if (cmd_silent)
return;
@@ -2541,7 +2565,7 @@ void redrawcmd() {
skip_redraw = FALSE;
}
-void compute_cmdrow() {
+void compute_cmdrow(void) {
if (exmode_active || msg_scrolled != 0)
cmdline_row = Rows - 1;
else
@@ -2549,7 +2573,7 @@ void compute_cmdrow() {
+ W_STATUS_HEIGHT(lastwin);
}
-static void cursorcmd() {
+static void cursorcmd(void) {
if (cmd_silent)
return;
@@ -2568,8 +2592,7 @@ static void cursorcmd() {
windgoto(msg_row, msg_col);
}
-void gotocmdline(clr)
-int clr;
+void gotocmdline(int clr)
{
msg_start();
if (cmdmsg_rl)
@@ -2587,8 +2610,7 @@ int clr;
* When an abbreviation is recognized it is removed from the text with
* backspaces and the replacement string is inserted, followed by "c".
*/
-static int ccheck_abbr(c)
-int c;
+static int ccheck_abbr(int c)
{
if (p_paste || no_abbr) /* no abbreviations or in paste mode */
return FALSE;
@@ -2596,9 +2618,7 @@ int c;
return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
}
-static int sort_func_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int sort_func_compare(const void *s1, const void *s2)
{
char_u *p1 = *(char_u **)s1;
char_u *p2 = *(char_u **)s2;
@@ -2614,11 +2634,13 @@ const void *s2;
* For the caller, this means that the character is just passed through like a
* normal character (instead of being expanded). This allows :s/^I^D etc.
*/
-static int nextwild(xp, type, options, escape)
-expand_T *xp;
-int type;
-int options; /* extra options for ExpandOne() */
-int escape; /* if TRUE, escape the returned matches */
+static int
+nextwild (
+ expand_T *xp,
+ int type,
+ int options, /* extra options for ExpandOne() */
+ int escape /* if TRUE, escape the returned matches */
+)
{
int i, j;
char_u *p1;
@@ -2753,12 +2775,14 @@ int escape; /* if TRUE, escape the returned matches */
*
* The variables xp->xp_context and xp->xp_backslash must have been set!
*/
-char_u * ExpandOne(xp, str, orig, options, mode)
-expand_T *xp;
-char_u *str;
-char_u *orig; /* allocated copy of original of expanded string */
-int options;
-int mode;
+char_u *
+ExpandOne (
+ expand_T *xp,
+ char_u *str,
+ char_u *orig, /* allocated copy of original of expanded string */
+ int options,
+ int mode
+)
{
char_u *ss = NULL;
static int findex;
@@ -2937,8 +2961,7 @@ int mode;
/*
* Prepare an expand structure for use.
*/
-void ExpandInit(xp)
-expand_T *xp;
+void ExpandInit(expand_T *xp)
{
xp->xp_pattern = NULL;
xp->xp_pattern_len = 0;
@@ -2955,8 +2978,7 @@ expand_T *xp;
/*
* Cleanup an expand structure after use.
*/
-void ExpandCleanup(xp)
-expand_T *xp;
+void ExpandCleanup(expand_T *xp)
{
if (xp->xp_numfiles >= 0) {
FreeWild(xp->xp_numfiles, xp->xp_files);
@@ -2964,12 +2986,7 @@ expand_T *xp;
}
}
-void ExpandEscape(xp, str, numfiles, files, options)
-expand_T *xp;
-char_u *str;
-int numfiles;
-char_u **files;
-int options;
+void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int options)
{
int i;
char_u *p;
@@ -3048,9 +3065,7 @@ int options;
* after a Vim command, or, when "shell" is non-zero, a shell command.
* Returns the result in allocated memory.
*/
-char_u * vim_strsave_fnameescape(fname, shell)
-char_u *fname;
-int shell;
+char_u *vim_strsave_fnameescape(char_u *fname, int shell)
{
char_u *p;
#ifdef BACKSLASH_IN_FILENAME
@@ -3087,8 +3102,7 @@ int shell;
/*
* Put a backslash before the file name in "pp", which is in allocated memory.
*/
-static void escape_fname(pp)
-char_u **pp;
+static void escape_fname(char_u **pp)
{
char_u *p;
@@ -3105,10 +3119,7 @@ char_u **pp;
* For each file name in files[num_files]:
* If 'orig_pat' starts with "~/", replace the home directory with "~".
*/
-void tilde_replace(orig_pat, num_files, files)
-char_u *orig_pat;
-int num_files;
-char_u **files;
+void tilde_replace(char_u *orig_pat, int num_files, char_u **files)
{
int i;
char_u *p;
@@ -3129,9 +3140,7 @@ char_u **files;
* Returns EXPAND_NOTHING when the character that triggered expansion should
* be inserted like a normal character.
*/
-static int showmatches(xp, wildmenu)
-expand_T *xp;
-int wildmenu UNUSED;
+static int showmatches(expand_T *xp, int wildmenu)
{
#define L_SHOWFILE(m) (showtail ? sm_gettail(files_found[m]) : files_found[m])
int num_files;
@@ -3285,8 +3294,7 @@ int wildmenu UNUSED;
* Private gettail for showmatches() (and win_redr_status_matches()):
* Find tail of file name path, but ignore trailing "/".
*/
-char_u * sm_gettail(s)
-char_u *s;
+char_u *sm_gettail(char_u *s)
{
char_u *p;
char_u *t = s;
@@ -3313,8 +3321,7 @@ char_u *s;
* When not completing file names or there is a wildcard in the path FALSE is
* returned.
*/
-static int expand_showtail(xp)
-expand_T *xp;
+static int expand_showtail(expand_T *xp)
{
char_u *s;
char_u *end;
@@ -3347,10 +3354,12 @@ expand_T *xp;
* When expanding other names: The string will be used with regcomp(). Copy
* the name into allocated memory and prepend "^".
*/
-char_u * addstar(fname, len, context)
-char_u *fname;
-int len;
-int context; /* EXPAND_FILES etc. */
+char_u *
+addstar (
+ char_u *fname,
+ int len,
+ int context /* EXPAND_FILES etc. */
+)
{
char_u *retval;
int i, j;
@@ -3505,8 +3514,7 @@ int context; /* EXPAND_FILES etc. */
* EXPAND_ENV_VARS Complete environment variable names
* EXPAND_USER Complete user names
*/
-static void set_expand_context(xp)
-expand_T *xp;
+static void set_expand_context(expand_T *xp)
{
/* only expansion for ':', '>' and '=' command-lines */
if (ccline.cmdfirstc != ':'
@@ -3519,11 +3527,13 @@ expand_T *xp;
set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
}
-void set_cmd_context(xp, str, len, col)
-expand_T *xp;
-char_u *str; /* start of command line */
-int len; /* length of command line (excl. NUL) */
-int col; /* position of cursor */
+void
+set_cmd_context (
+ expand_T *xp,
+ char_u *str, /* start of command line */
+ int len, /* length of command line (excl. NUL) */
+ int col /* position of cursor */
+)
{
int old_char = NUL;
char_u *nextcomm;
@@ -3567,12 +3577,14 @@ int col; /* position of cursor */
* key that triggered expansion literally.
* Returns EXPAND_OK otherwise.
*/
-int expand_cmdline(xp, str, col, matchcount, matches)
-expand_T *xp;
-char_u *str; /* start of command line */
-int col; /* position of cursor */
-int *matchcount; /* return: nr of matches */
-char_u ***matches; /* return: array of pointers to matches */
+int
+expand_cmdline (
+ expand_T *xp,
+ char_u *str, /* start of command line */
+ int col, /* position of cursor */
+ int *matchcount, /* return: nr of matches */
+ char_u ***matches /* return: array of pointers to matches */
+)
{
char_u *file_str = NULL;
int options = WILD_ADD_SLASH|WILD_SILENT;
@@ -3610,9 +3622,7 @@ char_u ***matches; /* return: array of pointers to matches */
*/
static void cleanup_help_tags __ARGS((int num_file, char_u **file));
-static void cleanup_help_tags(num_file, file)
-int num_file;
-char_u **file;
+static void cleanup_help_tags(int num_file, char_u **file)
{
int i, j;
int len;
@@ -3636,12 +3646,14 @@ char_u **file;
/*
* Do the expansion based on xp->xp_context and "pat".
*/
-static int ExpandFromContext(xp, pat, num_file, file, options)
-expand_T *xp;
-char_u *pat;
-int *num_file;
-char_u ***file;
-int options; /* EW_ flags */
+static int
+ExpandFromContext (
+ expand_T *xp,
+ char_u *pat,
+ int *num_file,
+ char_u ***file,
+ int options /* EW_ flags */
+)
{
regmatch_T regmatch;
int ret;
@@ -3900,11 +3912,13 @@ int escaped;
* Complete a shell command.
* Returns FAIL or OK;
*/
-static int expand_shellcmd(filepat, num_file, file, flagsarg)
-char_u *filepat; /* pattern to match with command names */
-int *num_file; /* return: number of matches */
-char_u ***file; /* return: array with matches */
-int flagsarg; /* EW_ flags */
+static int
+expand_shellcmd (
+ char_u *filepat, /* pattern to match with command names */
+ int *num_file, /* return: number of matches */
+ char_u ***file, /* return: array with matches */
+ int flagsarg /* EW_ flags */
+)
{
char_u *pat;
int i;
@@ -4051,11 +4065,7 @@ char_u ***file;
/*
* Expand names with a function defined by the user.
*/
-static int ExpandUserDefined(xp, regmatch, num_file, file)
-expand_T *xp;
-regmatch_T *regmatch;
-int *num_file;
-char_u ***file;
+static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
char_u *retstr;
char_u *s;
@@ -4101,10 +4111,7 @@ char_u ***file;
/*
* Expand names with a list returned by a function defined by the user.
*/
-static int ExpandUserList(xp, num_file, file)
-expand_T *xp;
-int *num_file;
-char_u ***file;
+static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
{
list_T *retlist;
listitem_T *li;
@@ -4139,11 +4146,7 @@ char_u ***file;
* 'runtimepath'/{dirnames}/{pat}.vim
* "dirnames" is an array with one or more directory names.
*/
-static int ExpandRTDir(pat, num_file, file, dirnames)
-char_u *pat;
-int *num_file;
-char_u ***file;
-char *dirnames[];
+static int ExpandRTDir(char_u *pat, int *num_file, char_u ***file, char *dirnames[])
{
char_u *matches;
char_u *s;
@@ -4207,10 +4210,7 @@ char *dirnames[];
* Returns an allocated string with all matches concatenated, separated by
* newlines. Returns NULL for an error or no matches.
*/
-char_u * globpath(path, file, expand_options)
-char_u *path;
-char_u *file;
-int expand_options;
+char_u *globpath(char_u *path, char_u *file, int expand_options)
{
expand_T xpc;
char_u *buf;
@@ -4273,8 +4273,7 @@ int expand_options;
/*
* Translate a history character to the associated type number.
*/
-static int hist_char2type(c)
-int c;
+static int hist_char2type(int c)
{
if (c == ':')
return HIST_CMD;
@@ -4307,9 +4306,7 @@ static char *(history_names[]) =
* Function given to ExpandGeneric() to obtain the possible first
* arguments of the ":history command.
*/
-static char_u * get_history_arg(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+static char_u *get_history_arg(expand_T *xp, int idx)
{
static char_u compl[2] = { NUL, NUL };
char *short_names = ":=@>?/";
@@ -4331,7 +4328,7 @@ int idx;
* init_history() - Initialize the command line history.
* Also used to re-allocate the history when the size changes.
*/
-void init_history() {
+void init_history(void) {
int newlen; /* new length of history table */
histentry_T *temp;
int i;
@@ -4394,8 +4391,7 @@ void init_history() {
}
}
-static void clear_hist_entry(hisptr)
-histentry_T *hisptr;
+static void clear_hist_entry(histentry_T *hisptr)
{
hisptr->hisnum = 0;
hisptr->viminfo = FALSE;
@@ -4406,12 +4402,14 @@ histentry_T *hisptr;
* Check if command line 'str' is already in history.
* If 'move_to_front' is TRUE, matching entry is moved to end of history.
*/
-static int in_history(type, str, move_to_front, sep, writing)
-int type;
-char_u *str;
-int move_to_front; /* Move the entry to the front if it exists */
-int sep;
-int writing; /* ignore entries read from viminfo */
+static int
+in_history (
+ int type,
+ char_u *str,
+ int move_to_front, /* Move the entry to the front if it exists */
+ int sep,
+ int writing /* ignore entries read from viminfo */
+)
{
int i;
int last_i = -1;
@@ -4460,8 +4458,7 @@ int writing; /* ignore entries read from viminfo */
* When "name" is empty, return "cmd" history.
* Returns -1 for unknown history name.
*/
-int get_histtype(name)
-char_u *name;
+int get_histtype(char_u *name)
{
int i;
int len = (int)STRLEN(name);
@@ -4487,11 +4484,13 @@ static int last_maptick = -1; /* last seen maptick */
* history then it is moved to the front. "histype" may be one of he HIST_
* values.
*/
-void add_to_history(histype, new_entry, in_map, sep)
-int histype;
-char_u *new_entry;
-int in_map; /* consider maptick when inside a mapping */
-int sep; /* separator character used (search hist) */
+void
+add_to_history (
+ int histype,
+ char_u *new_entry,
+ int in_map, /* consider maptick when inside a mapping */
+ int sep /* separator character used (search hist) */
+)
{
histentry_T *hisptr;
int len;
@@ -4543,8 +4542,7 @@ int sep; /* separator character used (search hist) */
* Get identifier of newest history entry.
* "histype" may be one of the HIST_ values.
*/
-int get_history_idx(histype)
-int histype;
+int get_history_idx(int histype)
{
if (hislen == 0 || histype < 0 || histype >= HIST_COUNT
|| hisidx[histype] < 0)
@@ -4559,7 +4557,7 @@ static struct cmdline_info *get_ccline_ptr __ARGS((void));
* Get pointer to the command line info to use. cmdline_paste() may clear
* ccline and put the previous value in prev_ccline.
*/
-static struct cmdline_info * get_ccline_ptr()
+static struct cmdline_info *get_ccline_ptr(void)
{
if ((State & CMDLINE) == 0)
return NULL;
@@ -4575,7 +4573,7 @@ static struct cmdline_info * get_ccline_ptr()
* Only works when the command line is being edited.
* Returns NULL when something is wrong.
*/
-char_u * get_cmdline_str() {
+char_u *get_cmdline_str(void) {
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
@@ -4589,7 +4587,7 @@ char_u * get_cmdline_str() {
* Only works when the command line is being edited.
* Returns -1 when something is wrong.
*/
-int get_cmdline_pos() {
+int get_cmdline_pos(void) {
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
@@ -4602,8 +4600,7 @@ int get_cmdline_pos() {
* Only works when the command line is being edited.
* Returns 1 when failed, 0 when OK.
*/
-int set_cmdline_pos(pos)
-int pos;
+int set_cmdline_pos(int pos)
{
struct cmdline_info *p = get_ccline_ptr();
@@ -4625,7 +4622,7 @@ int pos;
* Only works when the command line is being edited.
* Returns NUL when something is wrong.
*/
-int get_cmdline_type() {
+int get_cmdline_type(void) {
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
@@ -4641,9 +4638,7 @@ int get_cmdline_type() {
* num < 0: relative position in history wrt newest entry
* "histype" may be one of the HIST_ values.
*/
-static int calc_hist_idx(histype, num)
-int histype;
-int num;
+static int calc_hist_idx(int histype, int num)
{
int i;
histentry_T *hist;
@@ -4678,9 +4673,7 @@ int num;
* Get a history entry by its index.
* "histype" may be one of the HIST_ values.
*/
-char_u * get_history_entry(histype, idx)
-int histype;
-int idx;
+char_u *get_history_entry(int histype, int idx)
{
idx = calc_hist_idx(histype, idx);
if (idx >= 0)
@@ -4693,8 +4686,7 @@ int idx;
* Clear all entries of a history.
* "histype" may be one of the HIST_ values.
*/
-int clr_history(histype)
-int histype;
+int clr_history(int histype)
{
int i;
histentry_T *hisptr;
@@ -4716,9 +4708,7 @@ int histype;
* Remove all entries matching {str} from a history.
* "histype" may be one of the HIST_ values.
*/
-int del_history_entry(histype, str)
-int histype;
-char_u *str;
+int del_history_entry(int histype, char_u *str)
{
regmatch_T regmatch;
histentry_T *hisptr;
@@ -4767,9 +4757,7 @@ char_u *str;
* Remove an indexed entry from a history.
* "histype" may be one of the HIST_ values.
*/
-int del_history_idx(histype, idx)
-int histype;
-int idx;
+int del_history_idx(int histype, int idx)
{
int i, j;
@@ -4802,7 +4790,7 @@ int idx;
* Very specific function to remove the value in ":set key=val" from the
* history.
*/
-void remove_key_from_history() {
+void remove_key_from_history(void) {
char_u *p;
int i;
@@ -4830,10 +4818,7 @@ void remove_key_from_history() {
* text lines in a buffer!) from a string. Used for ":history" and ":clist".
* Returns OK if parsed successfully, otherwise FAIL.
*/
-int get_list_range(str, num1, num2)
-char_u **str;
-int *num1;
-int *num2;
+int get_list_range(char_u **str, int *num1, int *num2)
{
int len;
int first = FALSE;
@@ -4863,8 +4848,7 @@ int *num2;
/*
* :history command - print a history
*/
-void ex_history(eap)
-exarg_T *eap;
+void ex_history(exarg_T *eap)
{
histentry_T *hist;
int histype1 = HIST_CMD;
@@ -4956,9 +4940,11 @@ static int hist_type2char __ARGS((int type, int use_question));
/*
* Translate a history type number to the associated character.
*/
-static int hist_type2char(type, use_question)
-int type;
-int use_question; /* use '?' instead of '/' */
+static int
+hist_type2char (
+ int type,
+ int use_question /* use '?' instead of '/' */
+)
{
if (type == HIST_CMD)
return ':';
@@ -4977,9 +4963,7 @@ int use_question; /* use '?' instead of '/' */
* Prepare for reading the history from the viminfo file.
* This allocates history arrays to store the read history lines.
*/
-void prepare_viminfo_history(asklen, writing)
-int asklen;
-int writing;
+void prepare_viminfo_history(int asklen, int writing)
{
int i;
int num;
@@ -5017,9 +5001,7 @@ int writing;
* Accept a line from the viminfo, store it in the history array when it's
* new.
*/
-int read_viminfo_history(virp, writing)
-vir_T *virp;
-int writing;
+int read_viminfo_history(vir_T *virp, int writing)
{
int type;
long_u len;
@@ -5061,7 +5043,7 @@ int writing;
/*
* Finish reading history lines from viminfo. Not used when writing viminfo.
*/
-void finish_viminfo_history() {
+void finish_viminfo_history(void) {
int idx;
int i;
int type;
@@ -5114,9 +5096,7 @@ void finish_viminfo_history() {
* file, data is in viminfo_history[].
* When "merge" is FALSE just write all history lines. Used for ":wviminfo!".
*/
-void write_viminfo_history(fp, merge)
-FILE *fp;
-int merge;
+void write_viminfo_history(FILE *fp, int merge)
{
int i;
int type;
@@ -5202,8 +5182,7 @@ int merge;
* Write a character at the current cursor+offset position.
* It is directly written into the command buffer block.
*/
-void cmd_pchar(c, offset)
-int c, offset;
+void cmd_pchar(int c, int offset)
{
if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0) {
EMSG(_("E198: cmd_pchar beyond the command length"));
@@ -5213,8 +5192,7 @@ int c, offset;
ccline.cmdbuff[ccline.cmdlen] = NUL;
}
-int cmd_gchar(offset)
-int offset;
+int cmd_gchar(int offset)
{
if (ccline.cmdpos + offset >= ccline.cmdlen || ccline.cmdpos + offset < 0) {
/* EMSG(_("cmd_gchar beyond the command length")); */
@@ -5231,7 +5209,7 @@ int offset;
* Ctrl_C if it is to be abandoned
* K_IGNORE if editing continues
*/
-static int ex_window() {
+static int ex_window(void) {
struct cmdline_info save_ccline;
buf_T *old_curbuf = curbuf;
win_T *old_curwin = curwin;
@@ -5447,9 +5425,7 @@ static int ex_window() {
* endmarker
* Returns a pointer to allocated memory with {script} or NULL.
*/
-char_u * script_get(eap, cmd)
-exarg_T *eap;
-char_u *cmd;
+char_u *script_get(exarg_T *eap, char_u *cmd)
{
char_u *theline;
char *end_pattern = NULL;
diff --git a/src/proto/ex_getln.pro b/src/ex_getln.h
index e3a642283f..bf04476e2f 100644
--- a/src/proto/ex_getln.pro
+++ b/src/ex_getln.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_EX_GETLN_H
+#define NEOVIM_EX_GETLN_H
/* ex_getln.c */
char_u *getcmdline __ARGS((int firstc, long count, int indent));
char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr,
@@ -64,3 +66,4 @@ void cmd_pchar __ARGS((int c, int offset));
int cmd_gchar __ARGS((int offset));
char_u *script_get __ARGS((exarg_T *eap, char_u *cmd));
/* vim: set ft=c : */
+#endif /* NEOVIM_EX_GETLN_H */
diff --git a/src/farsi.c b/src/farsi.c
index a76f37fd26..f3c55216f2 100644
--- a/src/farsi.c
+++ b/src/farsi.c
@@ -7,6 +7,10 @@
* See README.txt for an overview of the Vim source code.
*/
+#include "farsi.h"
+#include "edit.h"
+#include "ex_getln.h"
+
/*
* farsi.c: functions for Farsi language
*
@@ -37,8 +41,7 @@ static void lrswapbuf __ARGS((char_u *buf, int len));
/*
** Convert the given Farsi character into a _X or _X_ type
*/
-static int toF_Xor_X_(c)
-int c;
+static int toF_Xor_X_(int c)
{
int tempc;
@@ -127,8 +130,7 @@ int c;
/*
** Convert the given Farsi character into Farsi capital character .
*/
-int toF_TyA(c)
-int c;
+int toF_TyA(int c)
{
switch (c) {
case ALEF_:
@@ -205,8 +207,7 @@ int c;
** That is a character that is combined with the others.
** Note: the offset is used only for command line buffer.
*/
-static int F_is_TyB_TyC_TyD(src, offset)
-int src, offset;
+static int F_is_TyB_TyC_TyD(int src, int offset)
{
int c;
@@ -255,8 +256,7 @@ int src, offset;
/*
** Is the Farsi character one of the terminating only type.
*/
-static int F_is_TyE(c)
-int c;
+static int F_is_TyE(int c)
{
switch (c) {
case ALEF_A:
@@ -277,8 +277,7 @@ int c;
/*
** Is the Farsi character one of the none leading type.
*/
-static int F_is_TyC_TyD(c)
-int c;
+static int F_is_TyC_TyD(int c)
{
switch (c) {
case ALEF_:
@@ -300,8 +299,7 @@ int c;
/*
** Convert a none leading Farsi char into a leading type.
*/
-static int toF_TyB(c)
-int c;
+static int toF_TyB(int c)
{
switch (c) {
case ALEF_: return ALEF;
@@ -322,8 +320,7 @@ int c;
/*
** Overwrite the current redo and cursor characters + left adjust
*/
-static void put_curr_and_l_to_X(c)
-int c;
+static void put_curr_and_l_to_X(int c)
{
int tempc;
@@ -353,8 +350,7 @@ int c;
put_and_redo(c);
}
-static void put_and_redo(c)
-int c;
+static void put_and_redo(int c)
{
pchar_cursor(c);
AppendCharToRedobuff(K_BS);
@@ -364,7 +360,7 @@ int c;
/*
** Change the char. under the cursor to a X_ or X type
*/
-static void chg_c_toX_orX() {
+static void chg_c_toX_orX(void) {
int tempc, curc;
switch ((curc = gchar_cursor())) {
@@ -481,7 +477,7 @@ static void chg_c_toX_orX() {
** Change the char. under the cursor to a _X_ or X_ type
*/
-static void chg_c_to_X_orX_() {
+static void chg_c_to_X_orX_(void) {
int tempc;
switch (gchar_cursor()) {
@@ -529,7 +525,7 @@ static void chg_c_to_X_orX_() {
/*
** Change the char. under the cursor to a _X_ or _X type
*/
-static void chg_c_to_X_or_X () {
+static void chg_c_to_X_or_X(void) {
int tempc;
tempc = gchar_cursor();
@@ -556,7 +552,7 @@ static void chg_c_to_X_or_X () {
/*
** Change the character left to the cursor to a _X_ or X_ type
*/
-static void chg_l_to_X_orX_ () {
+static void chg_l_to_X_orX_(void) {
int tempc;
if (curwin->w_cursor.col != 0 &&
@@ -622,7 +618,7 @@ static void chg_l_to_X_orX_ () {
** Change the character left to the cursor to a X or _X type
*/
-static void chg_l_toXor_X () {
+static void chg_l_toXor_X(void) {
int tempc;
if (curwin->w_cursor.col != 0 &&
@@ -688,7 +684,7 @@ static void chg_l_toXor_X () {
** Change the character right to the cursor to a _X or _X_ type
*/
-static void chg_r_to_Xor_X_() {
+static void chg_r_to_Xor_X_(void) {
int tempc, c;
if (curwin->w_cursor.col) {
@@ -710,8 +706,7 @@ static void chg_r_to_Xor_X_() {
** Map Farsi keyboard when in fkmap mode.
*/
-int fkmap(c)
-int c;
+int fkmap(int c)
{
int tempc;
static int revins;
@@ -1387,8 +1382,7 @@ int c;
/*
** Convert a none leading Farsi char into a leading type.
*/
-static int toF_leading(c)
-int c;
+static int toF_leading(int c)
{
switch (c) {
case ALEF_: return ALEF;
@@ -1440,8 +1434,7 @@ int c;
/*
** Convert a given Farsi char into right joining type.
*/
-static int toF_Rjoin(c)
-int c;
+static int toF_Rjoin(int c)
{
switch (c) {
case ALEF: return ALEF_;
@@ -1495,8 +1488,7 @@ int c;
/*
** Can a given Farsi character join via its left edj.
*/
-static int canF_Ljoin(c)
-int c;
+static int canF_Ljoin(int c)
{
switch (c) {
case _BE:
@@ -1568,8 +1560,7 @@ int c;
/*
** Can a given Farsi character join via its right edj.
*/
-static int canF_Rjoin(c)
-int c;
+static int canF_Rjoin(int c)
{
switch (c) {
case ALEF:
@@ -1595,8 +1586,7 @@ int c;
/*
** is a given Farsi character a terminating type.
*/
-static int F_isterm(c)
-int c;
+static int F_isterm(int c)
{
switch (c) {
case ALEF:
@@ -1621,8 +1611,7 @@ int c;
/*
** Convert the given Farsi character into a ending type .
*/
-static int toF_ending(c)
-int c;
+static int toF_ending(int c)
{
switch (c) {
@@ -1697,7 +1686,7 @@ int c;
/*
** Convert the Farsi 3342 standard into Farsi VIM.
*/
-void conv_to_pvim() {
+void conv_to_pvim(void) {
char_u *ptr;
int lnum, llen, i;
@@ -1739,7 +1728,7 @@ void conv_to_pvim() {
/*
* Convert the Farsi VIM into Farsi 3342 standard.
*/
-void conv_to_pstd() {
+void conv_to_pstd(void) {
char_u *ptr;
int lnum, llen, i;
@@ -1768,9 +1757,7 @@ void conv_to_pstd() {
/*
* left-right swap the characters in buf[len].
*/
-static void lrswapbuf(buf, len)
-char_u *buf;
-int len;
+static void lrswapbuf(char_u *buf, int len)
{
char_u *s, *e;
int c;
@@ -1790,8 +1777,7 @@ int len;
/*
* swap all the characters in reverse direction
*/
-char_u * lrswap(ibuf)
-char_u *ibuf;
+char_u *lrswap(char_u *ibuf)
{
if (ibuf != NULL && *ibuf != NUL)
lrswapbuf(ibuf, (int)STRLEN(ibuf));
@@ -1801,9 +1787,7 @@ char_u *ibuf;
/*
* swap all the Farsi characters in reverse direction
*/
-char_u * lrFswap(cmdbuf, len)
-char_u *cmdbuf;
-int len;
+char_u *lrFswap(char_u *cmdbuf, int len)
{
int i, cnt;
@@ -1831,8 +1815,7 @@ int len;
* accordingly.
* TODO: handle different separator characters. Use skip_regexp().
*/
-char_u * lrF_sub(ibuf)
-char_u *ibuf;
+char_u *lrF_sub(char_u *ibuf)
{
char_u *p, *ep;
int i, cnt;
@@ -1870,8 +1853,7 @@ char_u *ibuf;
/*
* Map Farsi keyboard when in cmd_fkmap mode.
*/
-int cmdl_fkmap(c)
-int c;
+int cmdl_fkmap(int c)
{
int tempc;
@@ -2124,8 +2106,7 @@ int c;
/*
* F_isalpha returns TRUE if 'c' is a Farsi alphabet
*/
-int F_isalpha(c)
-int c;
+int F_isalpha(int c)
{
return ( c >= TEE_ && c <= _YE)
|| (c >= ALEF_A && c <= YE)
@@ -2135,8 +2116,7 @@ int c;
/*
* F_isdigit returns TRUE if 'c' is a Farsi digit
*/
-int F_isdigit(c)
-int c;
+int F_isdigit(int c)
{
return c >= FARSI_0 && c <= FARSI_9;
}
@@ -2144,14 +2124,12 @@ int c;
/*
* F_ischar returns TRUE if 'c' is a Farsi character.
*/
-int F_ischar(c)
-int c;
+int F_ischar(int c)
{
return c >= TEE_ && c <= YE_;
}
-void farsi_fkey(cap)
-cmdarg_T *cap;
+void farsi_fkey(cmdarg_T *cap)
{
int c = cap->cmdchar;
diff --git a/src/farsi.h b/src/farsi.h
index a9dd2fb79f..84c3402431 100644
--- a/src/farsi.h
+++ b/src/farsi.h
@@ -6,6 +6,9 @@
* Do ":help credits" in Vim to see a list of people who contributed.
*/
+#ifndef NEOVIM_FARSI_H
+#define NEOVIM_FARSI_H
+
/*
* Farsi characters are categorized into following types:
*
@@ -224,3 +227,5 @@ EXTERN char_u farsi_text_5[]
= { ' ', YE_, _SIN, RE, ALEF_, _FE, '\0'}
#endif
;
+
+#endif /* NEOVIM_FARSI_H */
diff --git a/src/fileio.c b/src/fileio.c
index d05181e654..482c47e17d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -12,6 +12,38 @@
*/
#include "vim.h"
+#include "fileio.h"
+#include "blowfish.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "mbyte.h"
+#include "memfile.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "sha256.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
+#include "os/os.h"
#if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
@@ -121,11 +153,7 @@ static void vim_settempdir __ARGS((char_u *tempdir));
static char *e_auchangedbuf = N_(
"E812: Autocommands changed buffer or buffer name");
-void filemess(buf, name, s, attr)
-buf_T *buf;
-char_u *name;
-char_u *s;
-int attr;
+void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
{
int msg_scroll_save;
@@ -180,14 +208,16 @@ int attr;
*
* return FAIL for failure, OK otherwise
*/
-int readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
-char_u *fname;
-char_u *sfname;
-linenr_T from;
-linenr_T lines_to_skip;
-linenr_T lines_to_read;
-exarg_T *eap; /* can be NULL! */
-int flags;
+int
+readfile (
+ char_u *fname,
+ char_u *sfname,
+ linenr_T from,
+ linenr_T lines_to_skip,
+ linenr_T lines_to_read,
+ exarg_T *eap, /* can be NULL! */
+ int flags
+)
{
int fd = 0;
int newfile = (flags & READ_NEW);
@@ -2020,8 +2050,7 @@ failed:
* some shells on some operating systems, e.g., bash on SunOS.
* Do not accept "/dev/fd/[012]", opening these may hang Vim.
*/
-static int is_dev_fd_file(fname)
-char_u *fname;
+static int is_dev_fd_file(char_u *fname)
{
return STRNCMP(fname, "/dev/fd/", 8) == 0
&& VIM_ISDIGIT(fname[8])
@@ -2037,10 +2066,12 @@ char_u *fname;
* line number where we are now.
* Used for error messages that include a line number.
*/
-static linenr_T readfile_linenr(linecnt, p, endp)
-linenr_T linecnt; /* line count before reading more bytes */
-char_u *p; /* start of more bytes read */
-char_u *endp; /* end of more bytes read */
+static linenr_T
+readfile_linenr (
+ linenr_T linecnt, /* line count before reading more bytes */
+ char_u *p, /* start of more bytes read */
+ char_u *endp /* end of more bytes read */
+)
{
char_u *s;
linenr_T lnum;
@@ -2057,9 +2088,7 @@ char_u *endp; /* end of more bytes read */
* equal to the buffer "buf". Used for calling readfile().
* Returns OK or FAIL.
*/
-int prep_exarg(eap, buf)
-exarg_T *eap;
-buf_T *buf;
+int prep_exarg(exarg_T *eap, buf_T *buf)
{
eap->cmd = alloc((unsigned)(STRLEN(buf->b_p_ff)
+ STRLEN(buf->b_p_fenc)
@@ -2081,9 +2110,7 @@ buf_T *buf;
/*
* Set default or forced 'fileformat' and 'binary'.
*/
-void set_file_options(set_options, eap)
-int set_options;
-exarg_T *eap;
+void set_file_options(int set_options, exarg_T *eap)
{
/* set default 'fileformat' */
if (set_options) {
@@ -2105,8 +2132,7 @@ exarg_T *eap;
/*
* Set forced 'fileencoding'.
*/
-void set_forced_fenc(eap)
-exarg_T *eap;
+void set_forced_fenc(exarg_T *eap)
{
if (eap->force_enc != 0) {
char_u *fenc = enc_canonize(eap->cmd + eap->force_enc);
@@ -2125,8 +2151,7 @@ exarg_T *eap;
* NULL.
* When *pp is not set to NULL, the result is in allocated memory.
*/
-static char_u * next_fenc(pp)
-char_u **pp;
+static char_u *next_fenc(char_u **pp)
{
char_u *p;
char_u *r;
@@ -2163,10 +2188,12 @@ char_u **pp;
* after reading it).
* Returns NULL if the conversion failed ("*fdp" is not set) .
*/
-static char_u * readfile_charconvert(fname, fenc, fdp)
-char_u *fname; /* name of input file */
-char_u *fenc; /* converted from */
-int *fdp; /* in/out: file descriptor of file */
+static char_u *
+readfile_charconvert (
+ char_u *fname, /* name of input file */
+ char_u *fenc, /* converted from */
+ int *fdp /* in/out: file descriptor of file */
+)
{
char_u *tmpname;
char_u *errmsg = NULL;
@@ -2208,7 +2235,7 @@ int *fdp; /* in/out: file descriptor of file */
* Read marks for the current buffer from the viminfo file, when we support
* buffer marks and the buffer has a name.
*/
-static void check_marks_read() {
+static void check_marks_read(void) {
if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0
&& curbuf->b_ffname != NULL)
read_viminfo(NULL, VIF_WANT_MARKS);
@@ -2223,9 +2250,7 @@ static void check_marks_read() {
* start of the file.
* Returns -1 when no encryption used.
*/
-static int crypt_method_from_magic(ptr, len)
-char *ptr;
-int len;
+static int crypt_method_from_magic(char *ptr, int len)
{
int i;
@@ -2249,16 +2274,16 @@ int len;
* *filesizep are updated.
* Return the (new) encryption key, NULL for no encryption.
*/
-static char_u * check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile,
- fname,
- did_ask)
-char_u *cryptkey; /* previous encryption key or NULL */
-char_u *ptr; /* pointer to read bytes */
-long *sizep; /* length of read bytes */
-off_t *filesizep; /* nr of bytes used from file */
-int newfile; /* editing a new buffer */
-char_u *fname; /* file name to display */
-int *did_ask; /* flag: whether already asked for key */
+static char_u *
+check_for_cryptkey (
+ char_u *cryptkey, /* previous encryption key or NULL */
+ char_u *ptr, /* pointer to read bytes */
+ long *sizep, /* length of read bytes */
+ off_t *filesizep, /* nr of bytes used from file */
+ int newfile, /* editing a new buffer */
+ char_u *fname, /* file name to display */
+ int *did_ask /* flag: whether already asked for key */
+)
{
int method = crypt_method_from_magic((char *)ptr, *sizep);
int b_p_ro = curbuf->b_p_ro;
@@ -2327,8 +2352,7 @@ int *did_ask; /* flag: whether already asked for key */
* Check for magic number used for encryption. Applies to the current buffer.
* If found and decryption is possible returns OK;
*/
-int prepare_crypt_read(fp)
-FILE *fp;
+int prepare_crypt_read(FILE *fp)
{
int method;
char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
@@ -2364,9 +2388,7 @@ FILE *fp;
* When out of memory returns NULL.
* Otherwise calls crypt_push_state(), call crypt_pop_state() later.
*/
-char_u * prepare_crypt_write(buf, lenp)
-buf_T *buf;
-int *lenp;
+char_u *prepare_crypt_write(buf_T *buf, int *lenp)
{
char_u *header;
int seed_len = crypt_seed_len[get_crypt_method(buf)];
@@ -2398,10 +2420,12 @@ int *lenp;
#ifdef UNIX
-static void set_file_time(fname, atime, mtime)
-char_u *fname;
-time_t atime; /* access time */
-time_t mtime; /* modification time */
+static void
+set_file_time (
+ char_u *fname,
+ time_t atime, /* access time */
+ time_t mtime /* modification time */
+)
{
# if defined(HAVE_UTIME) && defined(HAVE_UTIME_H)
struct utimbuf buf;
@@ -2427,9 +2451,11 @@ time_t mtime; /* modification time */
/*
* Return TRUE if a file appears to be read-only from the file permissions.
*/
-int check_file_readonly(fname, perm)
-char_u *fname; /* full path to file */
-int perm; /* known permissions on file */
+int
+check_file_readonly (
+ char_u *fname, /* full path to file */
+ int perm /* known permissions on file */
+)
{
#ifndef USE_MCH_ACCESS
int fd = 0;
@@ -2465,18 +2491,20 @@ int perm; /* known permissions on file */
*
* return FAIL for failure, OK otherwise
*/
-int buf_write(buf, fname, sfname, start, end, eap, append, forceit,
- reset_changed, filtering)
-buf_T *buf;
-char_u *fname;
-char_u *sfname;
-linenr_T start, end;
-exarg_T *eap; /* for forced 'ff' and 'fenc', can be
+int
+buf_write (
+ buf_T *buf,
+ char_u *fname,
+ char_u *sfname,
+ linenr_T start,
+ linenr_T end,
+ exarg_T *eap, /* for forced 'ff' and 'fenc', can be
NULL! */
-int append; /* append to the file */
-int forceit;
-int reset_changed;
-int filtering;
+ int append, /* append to the file */
+ int forceit,
+ int reset_changed,
+ int filtering
+)
{
int fd;
char_u *backup = NULL;
@@ -4094,9 +4122,7 @@ nofail:
* Set the name of the current buffer. Use when the buffer doesn't have a
* name and a ":r" or ":w" command with a file name is used.
*/
-static int set_rw_fname(fname, sfname)
-char_u *fname;
-char_u *sfname;
+static int set_rw_fname(char_u *fname, char_u *sfname)
{
buf_T *buf = curbuf;
@@ -4135,9 +4161,7 @@ char_u *sfname;
/*
* Put file name into IObuff with quotes.
*/
-void msg_add_fname(buf, fname)
-buf_T *buf;
-char_u *fname;
+void msg_add_fname(buf_T *buf, char_u *fname)
{
if (fname == NULL)
fname = (char_u *)"-stdin-";
@@ -4150,8 +4174,7 @@ char_u *fname;
* Append message for text mode to IObuff.
* Return TRUE if something appended.
*/
-static int msg_add_fileformat(eol_type)
-int eol_type;
+static int msg_add_fileformat(int eol_type)
{
#ifndef USE_CRNL
if (eol_type == EOL_DOS) {
@@ -4177,10 +4200,7 @@ int eol_type;
/*
* Append line and character count to IObuff.
*/
-void msg_add_lines(insert_space, lnum, nchars)
-int insert_space;
-long lnum;
-off_t nchars;
+void msg_add_lines(int insert_space, long lnum, off_t nchars)
{
char_u *p;
@@ -4220,7 +4240,7 @@ off_t nchars;
/*
* Append message for missing line separator to IObuff.
*/
-static void msg_add_eol() {
+static void msg_add_eol(void) {
STRCAT(IObuff,
shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
}
@@ -4230,9 +4250,7 @@ static void msg_add_eol() {
* The size isn't checked, because using a tool like "gzip" takes care of
* using the same timestamp but can't set the size.
*/
-static int check_mtime(buf, st)
-buf_T *buf;
-struct stat *st;
+static int check_mtime(buf_T *buf, struct stat *st)
{
if (buf->b_mtime_read != 0
&& time_differs((long)st->st_mtime, buf->b_mtime_read)) {
@@ -4249,8 +4267,7 @@ struct stat *st;
return OK;
}
-static int time_differs(t1, t2)
-long t1, t2;
+static int time_differs(long t1, long t2)
{
#if defined(__linux__) || defined(MSDOS) || defined(MSWIN)
/* On a FAT filesystem, esp. under Linux, there are only 5 bits to store
@@ -4268,8 +4285,7 @@ long t1, t2;
*
* Return FAIL for failure, OK otherwise.
*/
-static int buf_write_bytes(ip)
-struct bw_info *ip;
+static int buf_write_bytes(struct bw_info *ip)
{
int wlen;
char_u *buf = ip->bw_buf; /* data to write */
@@ -4479,10 +4495,12 @@ struct bw_info *ip;
* Convert a Unicode character to bytes.
* Return TRUE for an error, FALSE when it's OK.
*/
-static int ucs2bytes(c, pp, flags)
-unsigned c; /* in: character */
-char_u **pp; /* in/out: pointer to result */
-int flags; /* FIO_ flags */
+static int
+ucs2bytes (
+ unsigned c, /* in: character */
+ char_u **pp, /* in/out: pointer to result */
+ int flags /* FIO_ flags */
+)
{
char_u *p = *pp;
int error = FALSE;
@@ -4544,8 +4562,7 @@ int flags; /* FIO_ flags */
* Return TRUE if file encoding "fenc" requires conversion from or to
* 'encoding'.
*/
-static int need_conversion(fenc)
-char_u *fenc;
+static int need_conversion(char_u *fenc)
{
int same_encoding;
int enc_flags;
@@ -4577,8 +4594,7 @@ char_u *fenc;
* internal conversion.
* if "ptr" is an empty string, use 'encoding'.
*/
-static int get_fio_flags(ptr)
-char_u *ptr;
+static int get_fio_flags(char_u *ptr)
{
int prop;
@@ -4618,11 +4634,7 @@ char_u *ptr;
* Return the name of the encoding and set "*lenp" to the length.
* Returns NULL when no BOM found.
*/
-static char_u * check_for_bom(p, size, lenp, flags)
-char_u *p;
-long size;
-int *lenp;
-int flags;
+static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags)
{
char *name = NULL;
int len = 2;
@@ -4663,9 +4675,7 @@ int flags;
* Generate a BOM in "buf[4]" for encoding "name".
* Return the length of the BOM (zero when no BOM).
*/
-static int make_bom(buf, name)
-char_u *buf;
-char_u *name;
+static int make_bom(char_u *buf, char_u *name)
{
int flags;
char_u *p;
@@ -4694,8 +4704,7 @@ char_u *name;
* directory.
* Returns "full_path" or pointer into "full_path" if shortened.
*/
-char_u * shorten_fname1(full_path)
-char_u *full_path;
+char_u *shorten_fname1(char_u *full_path)
{
char_u *dirname;
char_u *p = full_path;
@@ -4719,9 +4728,7 @@ char_u *full_path;
* Returns NULL if not shorter name possible, pointer into "full_path"
* otherwise.
*/
-char_u * shorten_fname(full_path, dir_name)
-char_u *full_path;
-char_u *dir_name;
+char_u *shorten_fname(char_u *full_path, char_u *dir_name)
{
int len;
char_u *p;
@@ -4751,8 +4758,7 @@ char_u *dir_name;
* For buffers that have buftype "nofile" or "scratch": never change the file
* name.
*/
-void shorten_fnames(force)
-int force;
+void shorten_fnames(int force)
{
char_u dirname[MAXPATHL];
buf_T *buf;
@@ -4792,9 +4798,7 @@ int force;
/*
* Shorten all filenames in "fnames[count]" by current directory.
*/
-void shorten_filenames(fnames, count)
-char_u **fnames;
-int count;
+void shorten_filenames(char_u **fnames, int count)
{
int i;
char_u dirname[MAXPATHL];
@@ -4827,9 +4831,12 @@ int count;
* Space for the returned name is allocated, must be freed later.
* Returns NULL when out of memory.
*/
-char_u * modname(fname, ext, prepend_dot)
-char_u *fname, *ext;
-int prepend_dot; /* may prepend a '.' to file name */
+char_u *
+modname (
+ char_u *fname,
+ char_u *ext,
+ int prepend_dot /* may prepend a '.' to file name */
+)
{
return buf_modname(
#ifdef SHORT_FNAME
@@ -4840,10 +4847,13 @@ int prepend_dot; /* may prepend a '.' to file name */
fname, ext, prepend_dot);
}
-char_u * buf_modname(shortname, fname, ext, prepend_dot)
-int shortname; /* use 8.3 file name */
-char_u *fname, *ext;
-int prepend_dot; /* may prepend a '.' to file name */
+char_u *
+buf_modname (
+ int shortname, /* use 8.3 file name */
+ char_u *fname,
+ char_u *ext,
+ int prepend_dot /* may prepend a '.' to file name */
+)
{
char_u *retval;
char_u *s;
@@ -5009,10 +5019,7 @@ int prepend_dot; /* may prepend a '.' to file name */
* Like fgets(), but if the file line is too long, it is truncated and the
* rest of the line is thrown away. Returns TRUE for end-of-file.
*/
-int vim_fgets(buf, size, fp)
-char_u *buf;
-int size;
-FILE *fp;
+int vim_fgets(char_u *buf, int size, FILE *fp)
{
char *eof;
#define FGETS_SIZE 200
@@ -5046,10 +5053,7 @@ FILE *fp;
* Returns TRUE for end-of-file.
* Only used for the Mac, because it's much slower than vim_fgets().
*/
-int tag_fgets(buf, size, fp)
-char_u *buf;
-int size;
-FILE *fp;
+int tag_fgets(char_u *buf, int size, FILE *fp)
{
int i = 0;
int c;
@@ -5085,9 +5089,7 @@ FILE *fp;
* function will (attempts to?) copy the file across if rename fails -- webb
* Return -1 for failure, 0 for success.
*/
-int vim_rename(from, to)
-char_u *from;
-char_u *to;
+int vim_rename(char_u *from, char_u *to)
{
int fd_in;
int fd_out;
@@ -5255,8 +5257,10 @@ static int already_warned = FALSE;
* Returns TRUE if some message was written (screen should be redrawn and
* cursor positioned).
*/
-int check_timestamps(focus)
-int focus; /* called for GUI focus event */
+int
+check_timestamps (
+ int focus /* called for GUI focus event */
+)
{
buf_T *buf;
int didit = 0;
@@ -5314,9 +5318,7 @@ int focus; /* called for GUI focus event */
* Return OK or FAIL. When FAIL "tobuf" is incomplete and/or "frombuf" is not
* empty.
*/
-static int move_lines(frombuf, tobuf)
-buf_T *frombuf;
-buf_T *tobuf;
+static int move_lines(buf_T *frombuf, buf_T *tobuf)
{
buf_T *tbuf = curbuf;
int retval = OK;
@@ -5358,9 +5360,11 @@ buf_T *tobuf;
* return 2 if a message has been displayed.
* return 0 otherwise.
*/
-int buf_check_timestamp(buf, focus)
-buf_T *buf;
-int focus UNUSED; /* called for GUI focus event */
+int
+buf_check_timestamp (
+ buf_T *buf,
+ int focus /* called for GUI focus event */
+)
{
struct stat st;
int stat_res;
@@ -5582,9 +5586,7 @@ int focus UNUSED; /* called for GUI focus event */
* "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
* buf->b_orig_mode may have been reset already.
*/
-void buf_reload(buf, orig_mode)
-buf_T *buf;
-int orig_mode;
+void buf_reload(buf_T *buf, int orig_mode)
{
exarg_T ea;
pos_T old_cursor;
@@ -5712,10 +5714,7 @@ int orig_mode;
/* Careful: autocommands may have made "buf" invalid! */
}
-void buf_store_time(buf, st, fname)
-buf_T *buf;
-struct stat *st;
-char_u *fname UNUSED;
+void buf_store_time(buf_T *buf, struct stat *st, char_u *fname)
{
buf->b_mtime = (long)st->st_mtime;
buf->b_orig_size = st->st_size;
@@ -5730,8 +5729,7 @@ char_u *fname UNUSED;
* Adjust the line with missing eol, used for the next write.
* Used for do_filter(), when the input lines for the filter are deleted.
*/
-void write_lnum_adjust(offset)
-linenr_T offset;
+void write_lnum_adjust(linenr_T offset)
{
if (curbuf->b_no_eol_lnum != 0) /* only if there is a missing eol */
curbuf->b_no_eol_lnum += offset;
@@ -5743,7 +5741,7 @@ static long temp_count = 0; /* Temp filename counter. */
/*
* Delete the temp directory and all files it contains.
*/
-void vim_deltempdir() {
+void vim_deltempdir(void) {
char_u **files;
int file_count;
int i;
@@ -5772,8 +5770,7 @@ void vim_deltempdir() {
* it in "vim_tempdir". This avoids that using ":cd" would confuse us.
* "tempdir" must be no longer than MAXPATHL.
*/
-static void vim_settempdir(tempdir)
-char_u *tempdir;
+static void vim_settempdir(char_u *tempdir)
{
char_u *buf;
@@ -5796,8 +5793,10 @@ char_u *tempdir;
* The returned pointer is to allocated memory.
* The returned pointer is NULL if no valid name was found.
*/
-char_u * vim_tempname(extra_char)
-int extra_char UNUSED; /* char to use in the name instead of '?' */
+char_u *
+vim_tempname (
+ int extra_char /* char to use in the name instead of '?' */
+)
{
#ifdef USE_TMPNAM
char_u itmp[L_tmpnam]; /* use tmpnam() */
@@ -5945,8 +5944,7 @@ int extra_char UNUSED; /* char to use in the name instead of '?' */
/*
* Convert all backslashes in fname to forward slashes in-place.
*/
-void forward_slash(fname)
-char_u *fname;
+void forward_slash(char_u *fname)
{
char_u *p;
@@ -6183,9 +6181,7 @@ static int autocmd_blocked = 0; /* block all autocmds */
/*
* Show the autocommands for one AutoPat.
*/
-static void show_autocmd(ap, event)
-AutoPat *ap;
-event_T event;
+static void show_autocmd(AutoPat *ap, event_T event)
{
AutoCmd *ac;
@@ -6241,8 +6237,7 @@ event_T event;
/*
* Mark an autocommand pattern for deletion.
*/
-static void au_remove_pat(ap)
-AutoPat *ap;
+static void au_remove_pat(AutoPat *ap)
{
vim_free(ap->pat);
ap->pat = NULL;
@@ -6253,8 +6248,7 @@ AutoPat *ap;
/*
* Mark all commands for a pattern for deletion.
*/
-static void au_remove_cmds(ap)
-AutoPat *ap;
+static void au_remove_cmds(AutoPat *ap)
{
AutoCmd *ac;
@@ -6269,7 +6263,7 @@ AutoPat *ap;
* Cleanup autocommands and patterns that have been deleted.
* This is only done when not executing autocommands.
*/
-static void au_cleanup() {
+static void au_cleanup(void) {
AutoPat *ap, **prev_ap;
AutoCmd *ac, **prev_ac;
event_T event;
@@ -6313,8 +6307,7 @@ static void au_cleanup() {
* Called when buffer is freed, to remove/invalidate related buffer-local
* autocmds.
*/
-void aubuflocal_remove(buf)
-buf_T *buf;
+void aubuflocal_remove(buf_T *buf)
{
AutoPat *ap;
event_T event;
@@ -6347,8 +6340,7 @@ buf_T *buf;
* Add an autocmd group name.
* Return it's ID. Returns AUGROUP_ERROR (< 0) for error.
*/
-static int au_new_group(name)
-char_u *name;
+static int au_new_group(char_u *name)
{
int i;
@@ -6371,8 +6363,7 @@ char_u *name;
return i;
}
-static void au_del_group(name)
-char_u *name;
+static void au_del_group(char_u *name)
{
int i;
@@ -6389,8 +6380,7 @@ char_u *name;
* Find the ID of an autocmd group name.
* Return it's ID. Returns AUGROUP_ERROR (< 0) for error.
*/
-static int au_find_group(name)
-char_u *name;
+static int au_find_group(char_u *name)
{
int i;
@@ -6403,8 +6393,7 @@ char_u *name;
/*
* Return TRUE if augroup "name" exists.
*/
-int au_has_group(name)
-char_u *name;
+int au_has_group(char_u *name)
{
return au_find_group(name) != AUGROUP_ERROR;
}
@@ -6412,9 +6401,7 @@ char_u *name;
/*
* ":augroup {name}".
*/
-void do_augroup(arg, del_group)
-char_u *arg;
-int del_group;
+void do_augroup(char_u *arg, int del_group)
{
int i;
@@ -6443,7 +6430,7 @@ int del_group;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_all_autocmds() {
+void free_all_autocmds(void) {
for (current_augroup = -1; current_augroup < augroups.ga_len;
++current_augroup)
do_autocmd((char_u *)"", TRUE);
@@ -6457,9 +6444,7 @@ void free_all_autocmds() {
* Return NUM_EVENTS if the event name was not found.
* Return a pointer to the next event name in "end".
*/
-static event_T event_name2nr(start, end)
-char_u *start;
-char_u **end;
+static event_T event_name2nr(char_u *start, char_u **end)
{
char_u *p;
int i;
@@ -6484,8 +6469,7 @@ char_u **end;
/*
* Return the name for event "event".
*/
-static char_u * event_nr2name(event)
-event_T event;
+static char_u *event_nr2name(event_T event)
{
int i;
@@ -6498,9 +6482,11 @@ event_T event;
/*
* Scan over the events. "*" stands for all events.
*/
-static char_u * find_end_event(arg, have_group)
-char_u *arg;
-int have_group; /* TRUE when group name was found */
+static char_u *
+find_end_event (
+ char_u *arg,
+ int have_group /* TRUE when group name was found */
+)
{
char_u *pat;
char_u *p;
@@ -6528,8 +6514,7 @@ int have_group; /* TRUE when group name was found */
/*
* Return TRUE if "event" is included in 'eventignore'.
*/
-static int event_ignored(event)
-event_T event;
+static int event_ignored(event_T event)
{
char_u *p = p_ei;
@@ -6546,7 +6531,7 @@ event_T event;
/*
* Return OK when the contents of p_ei is valid, FAIL otherwise.
*/
-int check_ei() {
+int check_ei(void) {
char_u *p = p_ei;
while (*p) {
@@ -6566,8 +6551,7 @@ int check_ei() {
* buffer loaded into the window. "what" must start with a comma.
* Returns the old value of 'eventignore' in allocated memory.
*/
-char_u * au_event_disable(what)
-char *what;
+char_u *au_event_disable(char *what)
{
char_u *new_ei;
char_u *save_ei;
@@ -6588,8 +6572,7 @@ char *what;
return save_ei;
}
-void au_event_restore(old_ei)
-char_u *old_ei;
+void au_event_restore(char_u *old_ei)
{
if (old_ei != NULL) {
set_string_option_direct((char_u *)"ei", -1, old_ei,
@@ -6630,9 +6613,7 @@ char_u *old_ei;
*
* Mostly a {group} argument can optionally appear before <event>.
*/
-void do_autocmd(arg, forceit)
-char_u *arg;
-int forceit;
+void do_autocmd(char_u *arg, int forceit)
{
char_u *pat;
char_u *envpat = NULL;
@@ -6740,8 +6721,7 @@ int forceit;
*
* Returns the group ID, AUGROUP_ERROR for error (out of memory).
*/
-static int au_get_grouparg(argp)
-char_u **argp;
+static int au_get_grouparg(char_u **argp)
{
char_u *group_name;
char_u *p;
@@ -6770,13 +6750,7 @@ char_u **argp;
* If forceit == TRUE delete entries.
* If group is not AUGROUP_ALL, only use this group.
*/
-static int do_autocmd_event(event, pat, nested, cmd, forceit, group)
-event_T event;
-char_u *pat;
-int nested;
-char_u *cmd;
-int forceit;
-int group;
+static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, int forceit, int group)
{
AutoPat *ap;
AutoPat **prev_ap;
@@ -6991,9 +6965,11 @@ int group;
* Implementation of ":doautocmd [group] event [fname]".
* Return OK for success, FAIL for failure;
*/
-int do_doautocmd(arg, do_msg)
-char_u *arg;
-int do_msg; /* give message for no matching autocmds? */
+int
+do_doautocmd (
+ char_u *arg,
+ int do_msg /* give message for no matching autocmds? */
+)
{
char_u *fname;
int nothing_done = TRUE;
@@ -7038,8 +7014,7 @@ int do_msg; /* give message for no matching autocmds? */
/*
* ":doautoall": execute autocommands for each loaded buffer.
*/
-void ex_doautoall(eap)
-exarg_T *eap;
+void ex_doautoall(exarg_T *eap)
{
int retval;
aco_save_T aco;
@@ -7086,8 +7061,7 @@ exarg_T *eap;
* return TRUE and advance *argp to after it.
* Thus return TRUE when do_modelines() should be called.
*/
-int check_nomodeline(argp)
-char_u **argp;
+int check_nomodeline(char_u **argp)
{
if (STRNCMP(*argp, "<nomodeline>", 12) == 0) {
*argp = skipwhite(*argp + 12);
@@ -7103,9 +7077,11 @@ char_u **argp;
* Set "curbuf" and "curwin" to match "buf".
* When FEAT_AUTOCMD is not defined another version is used, see below.
*/
-void aucmd_prepbuf(aco, buf)
-aco_save_T *aco; /* structure to save values in */
-buf_T *buf; /* new curbuf */
+void
+aucmd_prepbuf (
+ aco_save_T *aco, /* structure to save values in */
+ buf_T *buf /* new curbuf */
+)
{
win_T *win;
int save_ea;
@@ -7187,8 +7163,10 @@ buf_T *buf; /* new curbuf */
* Restore the window as it was (if possible).
* When FEAT_AUTOCMD is not defined another version is used, see below.
*/
-void aucmd_restbuf(aco)
-aco_save_T *aco; /* structure holding saved values */
+void
+aucmd_restbuf (
+ aco_save_T *aco /* structure holding saved values */
+)
{
int dummy;
@@ -7270,12 +7248,14 @@ static int autocmd_nested = FALSE;
* Execute autocommands for "event" and file name "fname".
* Return TRUE if some commands were executed.
*/
-int apply_autocmds(event, fname, fname_io, force, buf)
-event_T event;
-char_u *fname; /* NULL or empty means use actual file name */
-char_u *fname_io; /* fname to use for <afile> on cmdline */
-int force; /* when TRUE, ignore autocmd_busy */
-buf_T *buf; /* buffer for <abuf> */
+int
+apply_autocmds (
+ event_T event,
+ char_u *fname, /* NULL or empty means use actual file name */
+ char_u *fname_io, /* fname to use for <afile> on cmdline */
+ int force, /* when TRUE, ignore autocmd_busy */
+ buf_T *buf /* buffer for <abuf> */
+)
{
return apply_autocmds_group(event, fname, fname_io, force,
AUGROUP_ALL, buf, NULL);
@@ -7285,13 +7265,7 @@ buf_T *buf; /* buffer for <abuf> */
* Like apply_autocmds(), but with extra "eap" argument. This takes care of
* setting v:filearg.
*/
-static int apply_autocmds_exarg(event, fname, fname_io, force, buf, eap)
-event_T event;
-char_u *fname;
-char_u *fname_io;
-int force;
-buf_T *buf;
-exarg_T *eap;
+static int apply_autocmds_exarg(event_T event, char_u *fname, char_u *fname_io, int force, buf_T *buf, exarg_T *eap)
{
return apply_autocmds_group(event, fname, fname_io, force,
AUGROUP_ALL, buf, eap);
@@ -7303,13 +7277,15 @@ exarg_T *eap;
* conditional, no autocommands are executed. If otherwise the autocommands
* cause the script to be aborted, retval is set to FAIL.
*/
-int apply_autocmds_retval(event, fname, fname_io, force, buf, retval)
-event_T event;
-char_u *fname; /* NULL or empty means use actual file name */
-char_u *fname_io; /* fname to use for <afile> on cmdline */
-int force; /* when TRUE, ignore autocmd_busy */
-buf_T *buf; /* buffer for <abuf> */
-int *retval; /* pointer to caller's retval */
+int
+apply_autocmds_retval (
+ event_T event,
+ char_u *fname, /* NULL or empty means use actual file name */
+ char_u *fname_io, /* fname to use for <afile> on cmdline */
+ int force, /* when TRUE, ignore autocmd_busy */
+ buf_T *buf, /* buffer for <abuf> */
+ int *retval /* pointer to caller's retval */
+)
{
int did_cmd;
@@ -7328,7 +7304,7 @@ int *retval; /* pointer to caller's retval */
/*
* Return TRUE when there is a CursorHold autocommand defined.
*/
-int has_cursorhold() {
+int has_cursorhold(void) {
return first_autopat[(int)(get_real_state() == NORMAL_BUSY
? EVENT_CURSORHOLD : EVENT_CURSORHOLDI)] != NULL;
}
@@ -7336,7 +7312,7 @@ int has_cursorhold() {
/*
* Return TRUE if the CursorHold event can be triggered.
*/
-int trigger_cursorhold() {
+int trigger_cursorhold(void) {
int state;
if (!did_cursorhold
@@ -7355,47 +7331,49 @@ int trigger_cursorhold() {
/*
* Return TRUE when there is a CursorMoved autocommand defined.
*/
-int has_cursormoved() {
+int has_cursormoved(void) {
return first_autopat[(int)EVENT_CURSORMOVED] != NULL;
}
/*
* Return TRUE when there is a CursorMovedI autocommand defined.
*/
-int has_cursormovedI() {
+int has_cursormovedI(void) {
return first_autopat[(int)EVENT_CURSORMOVEDI] != NULL;
}
/*
* Return TRUE when there is a TextChanged autocommand defined.
*/
-int has_textchanged() {
+int has_textchanged(void) {
return first_autopat[(int)EVENT_TEXTCHANGED] != NULL;
}
/*
* Return TRUE when there is a TextChangedI autocommand defined.
*/
-int has_textchangedI() {
+int has_textchangedI(void) {
return first_autopat[(int)EVENT_TEXTCHANGEDI] != NULL;
}
/*
* Return TRUE when there is an InsertCharPre autocommand defined.
*/
-int has_insertcharpre() {
+int has_insertcharpre(void) {
return first_autopat[(int)EVENT_INSERTCHARPRE] != NULL;
}
-static int apply_autocmds_group(event, fname, fname_io, force, group, buf, eap)
-event_T event;
-char_u *fname; /* NULL or empty means use actual file name */
-char_u *fname_io; /* fname to use for <afile> on cmdline, NULL means
+static int
+apply_autocmds_group (
+ event_T event,
+ char_u *fname, /* NULL or empty means use actual file name */
+ char_u *fname_io, /* fname to use for <afile> on cmdline, NULL means
use fname */
-int force; /* when TRUE, ignore autocmd_busy */
-int group; /* group ID, or AUGROUP_ALL */
-buf_T *buf; /* buffer for <abuf> */
-exarg_T *eap; /* command arguments */
+ int force, /* when TRUE, ignore autocmd_busy */
+ int group, /* group ID, or AUGROUP_ALL */
+ buf_T *buf, /* buffer for <abuf> */
+ exarg_T *eap /* command arguments */
+)
{
char_u *sfname = NULL; /* short file name */
char_u *tail;
@@ -7716,14 +7694,14 @@ static char_u *old_termresponse = NULL;
* Block triggering autocommands until unblock_autocmd() is called.
* Can be used recursively, so long as it's symmetric.
*/
-void block_autocmds() {
+void block_autocmds(void) {
/* Remember the value of v:termresponse. */
if (autocmd_blocked == 0)
old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
++autocmd_blocked;
}
-void unblock_autocmds() {
+void unblock_autocmds(void) {
--autocmd_blocked;
/* When v:termresponse was set while autocommands were blocked, trigger
@@ -7734,16 +7712,18 @@ void unblock_autocmds() {
apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
}
-int is_autocmd_blocked() {
+int is_autocmd_blocked(void) {
return autocmd_blocked != 0;
}
/*
* Find next autocommand pattern that matches.
*/
-static void auto_next_pat(apc, stop_at_last)
-AutoPatCmd *apc;
-int stop_at_last; /* stop when 'last' flag is set */
+static void
+auto_next_pat (
+ AutoPatCmd *apc,
+ int stop_at_last /* stop when 'last' flag is set */
+)
{
AutoPat *ap;
AutoCmd *cp;
@@ -7801,10 +7781,7 @@ int stop_at_last; /* stop when 'last' flag is set */
* Called by do_cmdline() to get the next line for ":if".
* Returns allocated string, or NULL for end of autocommands.
*/
-char_u * getnextac(c, cookie, indent)
-int c UNUSED;
-void *cookie;
-int indent UNUSED;
+char_u *getnextac(int c, void *cookie, int indent)
{
AutoPatCmd *acp = (AutoPatCmd *)cookie;
char_u *retval;
@@ -7860,10 +7837,7 @@ int indent UNUSED;
* To account for buffer-local autocommands, function needs to know
* in which buffer the file will be opened.
*/
-int has_autocmd(event, sfname, buf)
-event_T event;
-char_u *sfname;
-buf_T *buf;
+int has_autocmd(event_T event, char_u *sfname, buf_T *buf)
{
AutoPat *ap;
char_u *fname;
@@ -7908,9 +7882,7 @@ buf_T *buf;
* Function given to ExpandGeneric() to obtain the list of autocommand group
* names.
*/
-char_u * get_augroup_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_augroup_name(expand_T *xp, int idx)
{
if (idx == augroups.ga_len) /* add "END" add the end */
return (char_u *)"END";
@@ -7923,10 +7895,12 @@ int idx;
static int include_groups = FALSE;
-char_u * set_context_in_autocmd(xp, arg, doautocmd)
-expand_T *xp;
-char_u *arg;
-int doautocmd; /* TRUE for :doauto*, FALSE for :autocmd */
+char_u *
+set_context_in_autocmd (
+ expand_T *xp,
+ char_u *arg,
+ int doautocmd /* TRUE for :doauto*, FALSE for :autocmd */
+)
{
char_u *p;
int group;
@@ -7972,9 +7946,7 @@ int doautocmd; /* TRUE for :doauto*, FALSE for :autocmd */
/*
* Function given to ExpandGeneric() to obtain the list of event names.
*/
-char_u * get_event_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_event_name(expand_T *xp, int idx)
{
if (idx < augroups.ga_len) { /* First list group names, if wanted */
if (!include_groups || AUGROUP_NAME(idx) == NULL)
@@ -7988,8 +7960,7 @@ int idx;
/*
* Return TRUE if autocmd is supported.
*/
-int autocmd_supported(name)
-char_u *name;
+int autocmd_supported(char_u *name)
{
char_u *p;
@@ -8008,8 +7979,7 @@ char_u *name;
* exists("#Event") or
* exists("#Event#pat")
*/
-int au_exists(arg)
-char_u *arg;
+int au_exists(char_u *arg)
{
char_u *arg_save;
char_u *pattern = NULL;
@@ -8098,13 +8068,15 @@ theend:
* Used for autocommands and 'wildignore'.
* Returns TRUE if there is a match, FALSE otherwise.
*/
-int match_file_pat(pattern, prog, fname, sfname, tail, allow_dirs)
-char_u *pattern; /* pattern to match with */
-regprog_T *prog; /* pre-compiled regprog or NULL */
-char_u *fname; /* full path of file name */
-char_u *sfname; /* short file name or NULL */
-char_u *tail; /* tail of path */
-int allow_dirs; /* allow matching with dir */
+int
+match_file_pat (
+ char_u *pattern, /* pattern to match with */
+ regprog_T *prog, /* pre-compiled regprog or NULL */
+ char_u *fname, /* full path of file name */
+ char_u *sfname, /* short file name or NULL */
+ char_u *tail, /* tail of path */
+ int allow_dirs /* allow matching with dir */
+)
{
regmatch_T regmatch;
int result = FALSE;
@@ -8185,10 +8157,7 @@ int allow_dirs; /* allow matching with dir */
* "list" is a comma-separated list of patterns, like 'wildignore'.
* "sfname" is the short file name or NULL, "ffname" the long file name.
*/
-int match_file_list(list, sfname, ffname)
-char_u *list;
-char_u *sfname;
-char_u *ffname;
+int match_file_list(char_u *list, char_u *sfname, char_u *ffname)
{
char_u buf[100];
char_u *tail;
@@ -8227,11 +8196,13 @@ char_u *ffname;
*
* Returns NULL when out of memory.
*/
-char_u * file_pat_to_reg_pat(pat, pat_end, allow_dirs, no_bslash)
-char_u *pat;
-char_u *pat_end; /* first char after pattern or NULL */
-char *allow_dirs; /* Result passed back out in here */
-int no_bslash UNUSED; /* Don't use a backward slash as pathsep */
+char_u *
+file_pat_to_reg_pat (
+ char_u *pat,
+ char_u *pat_end, /* first char after pattern or NULL */
+ char *allow_dirs, /* Result passed back out in here */
+ int no_bslash /* Don't use a backward slash as pathsep */
+)
{
int size;
char_u *endp;
diff --git a/src/proto/fileio.pro b/src/fileio.h
index ec83342e4d..add97d37d6 100644
--- a/src/proto/fileio.pro
+++ b/src/fileio.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_FILEIO_H
+#define NEOVIM_FILEIO_H
/* fileio.c */
void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from,
@@ -80,3 +82,4 @@ char_u *file_pat_to_reg_pat __ARGS((char_u *pat, char_u *pat_end,
long read_eintr __ARGS((int fd, void *buf, size_t bufsize));
long write_eintr __ARGS((int fd, void *buf, size_t bufsize));
/* vim: set ft=c : */
+#endif /* NEOVIM_FILEIO_H */
diff --git a/src/fold.c b/src/fold.c
index b3a3d84a2b..47e5cdfdd2 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -13,7 +13,21 @@
*/
#include "vim.h"
-
+#include "fold.h"
+#include "charset.h"
+#include "diff.h"
+#include "eval.h"
+#include "ex_docmd.h"
+#include "mark.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "screen.h"
+#include "syntax.h"
+#include "undo.h"
/* local declarations. {{{1 */
/* typedef fold_T {{{2 */
@@ -104,9 +118,7 @@ static int foldendmarkerlen;
/*
* Copy that folding state from window "wp_from" to window "wp_to".
*/
-void copyFoldingState(wp_from, wp_to)
-win_T *wp_from;
-win_T *wp_to;
+void copyFoldingState(win_T *wp_from, win_T *wp_to)
{
wp_to->w_fold_manual = wp_from->w_fold_manual;
wp_to->w_foldinvalid = wp_from->w_foldinvalid;
@@ -117,8 +129,7 @@ win_T *wp_to;
/*
* Return TRUE if there may be folded lines in the current window.
*/
-int hasAnyFolding(win)
-win_T *win;
+int hasAnyFolding(win_T *win)
{
/* very simple now, but can become more complex later */
return win->w_p_fen
@@ -132,22 +143,21 @@ win_T *win;
* When returning TRUE, *firstp and *lastp are set to the first and last
* lnum of the sequence of folded lines (skipped when NULL).
*/
-int hasFolding(lnum, firstp, lastp)
-linenr_T lnum;
-linenr_T *firstp;
-linenr_T *lastp;
+int hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
{
return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
}
/* hasFoldingWin() {{{2 */
-int hasFoldingWin(win, lnum, firstp, lastp, cache, infop)
-win_T *win;
-linenr_T lnum;
-linenr_T *firstp;
-linenr_T *lastp;
-int cache; /* when TRUE: use cached values of window */
-foldinfo_T *infop; /* where to store fold info */
+int
+hasFoldingWin (
+ win_T *win,
+ linenr_T lnum,
+ linenr_T *firstp,
+ linenr_T *lastp,
+ int cache, /* when TRUE: use cached values of window */
+ foldinfo_T *infop /* where to store fold info */
+)
{
int had_folded = FALSE;
linenr_T first = 0;
@@ -242,8 +252,7 @@ foldinfo_T *infop; /* where to store fold info */
/*
* Return fold level at line number "lnum" in the current window.
*/
-int foldLevel(lnum)
-linenr_T lnum;
+int foldLevel(linenr_T lnum)
{
/* While updating the folds lines between invalid_top and invalid_bot have
* an undefined fold level. Otherwise update the folds first. */
@@ -268,9 +277,7 @@ linenr_T lnum;
* Return FALSE if line is not folded.
* Return MAYBE if the line is folded when next to a folded line.
*/
-int lineFolded(win, lnum)
-win_T *win;
-linenr_T lnum;
+int lineFolded(win_T *win, linenr_T lnum)
{
return foldedCount(win, lnum, NULL) != 0;
}
@@ -284,10 +291,7 @@ linenr_T lnum;
* Returns number of folded lines from "lnum", or 0 if line is not folded.
* When "infop" is not NULL, fills *infop with the fold level info.
*/
-long foldedCount(win, lnum, infop)
-win_T *win;
-linenr_T lnum;
-foldinfo_T *infop;
+long foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop)
{
linenr_T last;
@@ -300,8 +304,7 @@ foldinfo_T *infop;
/*
* Return TRUE if 'foldmethod' is "manual"
*/
-int foldmethodIsManual(wp)
-win_T *wp;
+int foldmethodIsManual(win_T *wp)
{
return wp->w_p_fdm[3] == 'u';
}
@@ -310,8 +313,7 @@ win_T *wp;
/*
* Return TRUE if 'foldmethod' is "indent"
*/
-int foldmethodIsIndent(wp)
-win_T *wp;
+int foldmethodIsIndent(win_T *wp)
{
return wp->w_p_fdm[0] == 'i';
}
@@ -320,8 +322,7 @@ win_T *wp;
/*
* Return TRUE if 'foldmethod' is "expr"
*/
-int foldmethodIsExpr(wp)
-win_T *wp;
+int foldmethodIsExpr(win_T *wp)
{
return wp->w_p_fdm[1] == 'x';
}
@@ -330,8 +331,7 @@ win_T *wp;
/*
* Return TRUE if 'foldmethod' is "marker"
*/
-int foldmethodIsMarker(wp)
-win_T *wp;
+int foldmethodIsMarker(win_T *wp)
{
return wp->w_p_fdm[2] == 'r';
}
@@ -340,8 +340,7 @@ win_T *wp;
/*
* Return TRUE if 'foldmethod' is "syntax"
*/
-int foldmethodIsSyntax(wp)
-win_T *wp;
+int foldmethodIsSyntax(win_T *wp)
{
return wp->w_p_fdm[0] == 's';
}
@@ -350,8 +349,7 @@ win_T *wp;
/*
* Return TRUE if 'foldmethod' is "diff"
*/
-int foldmethodIsDiff(wp)
-win_T *wp;
+int foldmethodIsDiff(win_T *wp)
{
return wp->w_p_fdm[0] == 'd';
}
@@ -361,9 +359,7 @@ win_T *wp;
* Close fold for current window at line "lnum".
* Repeat "count" times.
*/
-void closeFold(lnum, count)
-linenr_T lnum;
-long count;
+void closeFold(linenr_T lnum, long count)
{
setFoldRepeat(lnum, count, FALSE);
}
@@ -372,8 +368,7 @@ long count;
/*
* Close fold for current window at line "lnum" recursively.
*/
-void closeFoldRecurse(lnum)
-linenr_T lnum;
+void closeFoldRecurse(linenr_T lnum)
{
(void)setManualFold(lnum, FALSE, TRUE, NULL);
}
@@ -383,12 +378,14 @@ linenr_T lnum;
* Open or Close folds for current window in lines "first" to "last".
* Used for "zo", "zO", "zc" and "zC" in Visual mode.
*/
-void opFoldRange(first, last, opening, recurse, had_visual)
-linenr_T first;
-linenr_T last;
-int opening; /* TRUE to open, FALSE to close */
-int recurse; /* TRUE to do it recursively */
-int had_visual; /* TRUE when Visual selection used */
+void
+opFoldRange (
+ linenr_T first,
+ linenr_T last,
+ int opening, /* TRUE to open, FALSE to close */
+ int recurse, /* TRUE to do it recursively */
+ int had_visual /* TRUE when Visual selection used */
+)
{
int done = DONE_NOTHING; /* avoid error messages */
linenr_T lnum;
@@ -418,9 +415,7 @@ int had_visual; /* TRUE when Visual selection used */
* Open fold for current window at line "lnum".
* Repeat "count" times.
*/
-void openFold(lnum, count)
-linenr_T lnum;
-long count;
+void openFold(linenr_T lnum, long count)
{
setFoldRepeat(lnum, count, TRUE);
}
@@ -429,8 +424,7 @@ long count;
/*
* Open fold for current window at line "lnum" recursively.
*/
-void openFoldRecurse(lnum)
-linenr_T lnum;
+void openFoldRecurse(linenr_T lnum)
{
(void)setManualFold(lnum, TRUE, TRUE, NULL);
}
@@ -439,7 +433,7 @@ linenr_T lnum;
/*
* Open folds until the cursor line is not in a closed fold.
*/
-void foldOpenCursor() {
+void foldOpenCursor(void) {
int done;
checkupdate(curwin);
@@ -456,7 +450,7 @@ void foldOpenCursor() {
/*
* Set new foldlevel for current window.
*/
-void newFoldLevel() {
+void newFoldLevel(void) {
newFoldLevelWin(curwin);
if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
@@ -475,8 +469,7 @@ void newFoldLevel() {
}
}
-static void newFoldLevelWin(wp)
-win_T *wp;
+static void newFoldLevelWin(win_T *wp)
{
fold_T *fp;
int i;
@@ -498,7 +491,7 @@ win_T *wp;
/*
* Apply 'foldlevel' to all folds that don't contain the cursor.
*/
-void foldCheckClose() {
+void foldCheckClose(void) {
if (*p_fcl != NUL) { /* can only be "all" right now */
checkupdate(curwin);
if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum,
@@ -508,10 +501,7 @@ void foldCheckClose() {
}
/* checkCloseRec() {{{2 */
-static int checkCloseRec(gap, lnum, level)
-garray_T *gap;
-linenr_T lnum;
-int level;
+static int checkCloseRec(garray_T *gap, linenr_T lnum, int level)
{
fold_T *fp;
int retval = FALSE;
@@ -538,8 +528,7 @@ int level;
* Return TRUE if it's allowed to manually create or delete a fold.
* Give an error message and return FALSE if not.
*/
-int foldManualAllowed(create)
-int create;
+int foldManualAllowed(int create)
{
if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin))
return TRUE;
@@ -555,9 +544,7 @@ int create;
* Create a fold from line "start" to line "end" (inclusive) in the current
* window.
*/
-void foldCreate(start, end)
-linenr_T start;
-linenr_T end;
+void foldCreate(linenr_T start, linenr_T end)
{
fold_T *fp;
garray_T *gap;
@@ -671,11 +658,13 @@ linenr_T end;
* When "end" is not 0, delete all folds from "start" to "end".
* When "recursive" is TRUE delete recursively.
*/
-void deleteFold(start, end, recursive, had_visual)
-linenr_T start;
-linenr_T end;
-int recursive;
-int had_visual; /* TRUE when Visual selection used */
+void
+deleteFold (
+ linenr_T start,
+ linenr_T end,
+ int recursive,
+ int had_visual /* TRUE when Visual selection used */
+)
{
garray_T *gap;
fold_T *fp;
@@ -757,8 +746,7 @@ int had_visual; /* TRUE when Visual selection used */
/*
* Remove all folding for window "win".
*/
-void clearFolding(win)
-win_T *win;
+void clearFolding(win_T *win)
{
deleteFoldRecurse(&win->w_folds);
win->w_foldinvalid = FALSE;
@@ -771,10 +759,7 @@ win_T *win;
* calling foldMarkAdjust().
* The changes in lines from top to bot (inclusive).
*/
-void foldUpdate(wp, top, bot)
-win_T *wp;
-linenr_T top;
-linenr_T bot;
+void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
{
fold_T *fp;
@@ -807,8 +792,7 @@ linenr_T bot;
* The actual updating is postponed until fold info is used, to avoid doing
* every time a setting is changed or a syntax item is added.
*/
-void foldUpdateAll(win)
-win_T *win;
+void foldUpdateAll(win_T *win)
{
win->w_foldinvalid = TRUE;
redraw_win_later(win, NOT_VALID);
@@ -820,10 +804,12 @@ win_T *win;
* If "updown" is TRUE: move to fold at the same level.
* If not moved return FAIL.
*/
-int foldMoveTo(updown, dir, count)
-int updown;
-int dir; /* FORWARD or BACKWARD */
-long count;
+int
+foldMoveTo (
+ int updown,
+ int dir, /* FORWARD or BACKWARD */
+ long count
+)
{
long n;
int retval = FAIL;
@@ -936,8 +922,7 @@ long count;
/*
* Init the fold info in a new window.
*/
-void foldInitWin(new_win)
-win_T *new_win;
+void foldInitWin(win_T *new_win)
{
ga_init2(&new_win->w_folds, (int)sizeof(fold_T), 10);
}
@@ -949,9 +934,7 @@ win_T *new_win;
* line number can be wrong).
* Returns index of entry or -1 if not found.
*/
-int find_wl_entry(win, lnum)
-win_T *win;
-linenr_T lnum;
+int find_wl_entry(win_T *win, linenr_T lnum)
{
int i;
@@ -969,7 +952,7 @@ linenr_T lnum;
/*
* Adjust the Visual area to include any fold at the start or end completely.
*/
-void foldAdjustVisual() {
+void foldAdjustVisual(void) {
pos_T *start, *end;
char_u *ptr;
@@ -1000,7 +983,7 @@ void foldAdjustVisual() {
/*
* Move the cursor to the first line of a closed fold.
*/
-void foldAdjustCursor() {
+void foldAdjustCursor(void) {
(void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL);
}
@@ -1011,9 +994,7 @@ void foldAdjustCursor() {
*
* Return FAIL if the operation cannot be completed, otherwise OK.
*/
-void cloneFoldGrowArray(from, to)
-garray_T *from;
-garray_T *to;
+void cloneFoldGrowArray(garray_T *from, garray_T *to)
{
int i;
fold_T *from_p;
@@ -1045,10 +1026,7 @@ garray_T *to;
* the first fold below it (careful: it can be beyond the end of the array!).
* Returns FALSE when there is no fold that contains "lnum".
*/
-static int foldFind(gap, lnum, fpp)
-garray_T *gap;
-linenr_T lnum;
-fold_T **fpp;
+static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp)
{
linenr_T low, high;
fold_T *fp;
@@ -1084,9 +1062,7 @@ fold_T **fpp;
/*
* Return fold level at line number "lnum" in window "wp".
*/
-static int foldLevelWin(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+static int foldLevelWin(win_T *wp, linenr_T lnum)
{
fold_T *fp;
linenr_T lnum_rel = lnum;
@@ -1111,8 +1087,7 @@ linenr_T lnum;
/*
* Check if the folds in window "wp" are invalid and update them if needed.
*/
-static void checkupdate(wp)
-win_T *wp;
+static void checkupdate(win_T *wp)
{
if (wp->w_foldinvalid) {
foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */
@@ -1125,10 +1100,7 @@ win_T *wp;
* Open or close fold for current window at line "lnum".
* Repeat "count" times.
*/
-static void setFoldRepeat(lnum, count, do_open)
-linenr_T lnum;
-long count;
-int do_open;
+static void setFoldRepeat(linenr_T lnum, long count, int do_open)
{
int done;
long n;
@@ -1150,11 +1122,13 @@ int do_open;
* Open or close the fold in the current window which contains "lnum".
* Also does this for other windows in diff mode when needed.
*/
-static linenr_T setManualFold(lnum, opening, recurse, donep)
-linenr_T lnum;
-int opening; /* TRUE when opening, FALSE when closing */
-int recurse; /* TRUE when closing/opening recursive */
-int *donep;
+static linenr_T
+setManualFold (
+ linenr_T lnum,
+ int opening, /* TRUE when opening, FALSE when closing */
+ int recurse, /* TRUE when closing/opening recursive */
+ int *donep
+)
{
if (foldmethodIsDiff(curwin) && curwin->w_p_scb) {
win_T *wp;
@@ -1187,12 +1161,14 @@ int *donep;
* Return the line number of the next line that could be closed.
* It's only valid when "opening" is TRUE!
*/
-static linenr_T setManualFoldWin(wp, lnum, opening, recurse, donep)
-win_T *wp;
-linenr_T lnum;
-int opening; /* TRUE when opening, FALSE when closing */
-int recurse; /* TRUE when closing/opening recursive */
-int *donep;
+static linenr_T
+setManualFoldWin (
+ win_T *wp,
+ linenr_T lnum,
+ int opening, /* TRUE when opening, FALSE when closing */
+ int recurse, /* TRUE when closing/opening recursive */
+ int *donep
+)
{
fold_T *fp;
fold_T *fp2;
@@ -1286,8 +1262,7 @@ int *donep;
/*
* Open all nested folds in fold "fpr" recursively.
*/
-static void foldOpenNested(fpr)
-fold_T *fpr;
+static void foldOpenNested(fold_T *fpr)
{
int i;
fold_T *fp;
@@ -1305,10 +1280,7 @@ fold_T *fpr;
* When "recursive" is TRUE also delete all the folds contained in it.
* When "recursive" is FALSE contained folds are moved one level up.
*/
-static void deleteFoldEntry(gap, idx, recursive)
-garray_T *gap;
-int idx;
-int recursive;
+static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
{
fold_T *fp;
int i;
@@ -1356,8 +1328,7 @@ int recursive;
/*
* Delete nested folds in a fold.
*/
-void deleteFoldRecurse(gap)
-garray_T *gap;
+void deleteFoldRecurse(garray_T *gap)
{
int i;
@@ -1370,12 +1341,7 @@ garray_T *gap;
/*
* Update line numbers of folds for inserted/deleted lines.
*/
-void foldMarkAdjust(wp, line1, line2, amount, amount_after)
-win_T *wp;
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
/* If deleting marks from line1 to line2, but not deleting all those
* lines, set line2 so that only deleted lines have their folds removed. */
@@ -1389,12 +1355,7 @@ long amount_after;
}
/* foldMarkAdjustRecurse() {{{2 */
-static void foldMarkAdjustRecurse(gap, line1, line2, amount, amount_after)
-garray_T *gap;
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
fold_T *fp;
int i;
@@ -1487,13 +1448,12 @@ long amount_after;
* Get the lowest 'foldlevel' value that makes the deepest nested fold in the
* current window open.
*/
-int getDeepestNesting() {
+int getDeepestNesting(void) {
checkupdate(curwin);
return getDeepestNestingRecurse(&curwin->w_folds);
}
-static int getDeepestNestingRecurse(gap)
-garray_T *gap;
+static int getDeepestNestingRecurse(garray_T *gap)
{
int i;
int level;
@@ -1514,13 +1474,15 @@ garray_T *gap;
/*
* Check if a fold is closed and update the info needed to check nested folds.
*/
-static int check_closed(win, fp, use_levelp, level, maybe_smallp, lnum_off)
-win_T *win;
-fold_T *fp;
-int *use_levelp; /* TRUE: outer fold had FD_LEVEL */
-int level; /* folding depth */
-int *maybe_smallp; /* TRUE: outer this had fd_small == MAYBE */
-linenr_T lnum_off; /* line number offset for fp->fd_top */
+static int
+check_closed (
+ win_T *win,
+ fold_T *fp,
+ int *use_levelp, /* TRUE: outer fold had FD_LEVEL */
+ int level, /* folding depth */
+ int *maybe_smallp, /* TRUE: outer this had fd_small == MAYBE */
+ linenr_T lnum_off /* line number offset for fp->fd_top */
+)
{
int closed = FALSE;
@@ -1550,10 +1512,12 @@ linenr_T lnum_off; /* line number offset for fp->fd_top */
/*
* Update fd_small field of fold "fp".
*/
-static void checkSmall(wp, fp, lnum_off)
-win_T *wp;
-fold_T *fp;
-linenr_T lnum_off; /* offset for fp->fd_top */
+static void
+checkSmall (
+ win_T *wp,
+ fold_T *fp,
+ linenr_T lnum_off /* offset for fp->fd_top */
+)
{
int count;
int n;
@@ -1582,8 +1546,7 @@ linenr_T lnum_off; /* offset for fp->fd_top */
/*
* Set small flags in "gap" to MAYBE.
*/
-static void setSmallMaybe(gap)
-garray_T *gap;
+static void setSmallMaybe(garray_T *gap)
{
int i;
fold_T *fp;
@@ -1598,9 +1561,7 @@ garray_T *gap;
* Create a fold from line "start" to line "end" (inclusive) in the current
* window by adding markers.
*/
-static void foldCreateMarkers(start, end)
-linenr_T start;
-linenr_T end;
+static void foldCreateMarkers(linenr_T start, linenr_T end)
{
if (!curbuf->b_p_ma) {
EMSG(_(e_modifiable));
@@ -1620,10 +1581,7 @@ linenr_T end;
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(lnum, marker, markerlen)
-linenr_T lnum;
-char_u *marker;
-int markerlen;
+static void foldAddMarker(linenr_T lnum, char_u *marker, int markerlen)
{
char_u *cms = curbuf->b_p_cms;
char_u *line;
@@ -1656,10 +1614,12 @@ int markerlen;
/*
* Delete the markers for a fold, causing it to be deleted.
*/
-static void deleteFoldMarkers(fp, recursive, lnum_off)
-fold_T *fp;
-int recursive;
-linenr_T lnum_off; /* offset for fp->fd_top */
+static void
+deleteFoldMarkers (
+ fold_T *fp,
+ int recursive,
+ linenr_T lnum_off /* offset for fp->fd_top */
+)
{
int i;
@@ -1679,10 +1639,7 @@ linenr_T lnum_off; /* offset for fp->fd_top */
* If the marker is not found, there is no error message. Could a missing
* close-marker.
*/
-static void foldDelMarker(lnum, marker, markerlen)
-linenr_T lnum;
-char_u *marker;
-int markerlen;
+static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
{
char_u *line;
char_u *newline;
@@ -1727,11 +1684,7 @@ int markerlen;
* When 'foldtext' isn't set puts the result in "buf[51]". Otherwise the
* result is in allocated memory.
*/
-char_u * get_foldtext(wp, lnum, lnume, foldinfo, buf)
-win_T *wp;
-linenr_T lnum, lnume;
-foldinfo_T *foldinfo;
-char_u *buf;
+char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T *foldinfo, char_u *buf)
{
char_u *text = NULL;
/* an error occurred when evaluating 'fdt' setting */
@@ -1827,8 +1780,7 @@ char_u *buf;
/*
* Remove 'foldmarker' and 'commentstring' from "str" (in-place).
*/
-void foldtext_cleanup(str)
-char_u *str;
+void foldtext_cleanup(char_u *str)
{
char_u *cms_start; /* first part or the whole comment */
int cms_slen = 0; /* length of cms_start */
@@ -1943,10 +1895,7 @@ static void foldlevelSyntax __ARGS((fline_T *flp));
* Update the folding for window "wp", at least from lines "top" to "bot".
* Return TRUE if any folds did change.
*/
-static void foldUpdateIEMS(wp, top, bot)
-win_T *wp;
-linenr_T top;
-linenr_T bot;
+static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
{
linenr_T start;
linenr_T end;
@@ -2550,9 +2499,7 @@ int topflags; /* flags used by containing fold */
* Insert a new fold in "gap" at position "i".
* Returns OK for success, FAIL for failure.
*/
-static int foldInsert(gap, i)
-garray_T *gap;
-int i;
+static int foldInsert(garray_T *gap, int i)
{
fold_T *fp;
@@ -2574,11 +2521,7 @@ int i;
* The caller must first have taken care of any nested folds from "top" to
* "bot"!
*/
-static void foldSplit(gap, i, top, bot)
-garray_T *gap;
-int i;
-linenr_T top;
-linenr_T bot;
+static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
{
fold_T *fp;
fold_T *fp2;
@@ -2635,10 +2578,7 @@ linenr_T bot;
* 5: made to start below "bot".
* 6: not changed
*/
-static void foldRemove(gap, top, bot)
-garray_T *gap;
-linenr_T top;
-linenr_T bot;
+static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
{
fold_T *fp = NULL;
@@ -2692,10 +2632,7 @@ linenr_T bot;
* The resulting fold is "fp1", nested folds are moved from "fp2" to "fp1".
* Fold entry "fp2" in "gap" is deleted.
*/
-static void foldMerge(fp1, gap, fp2)
-fold_T *fp1;
-garray_T *gap;
-fold_T *fp2;
+static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
{
fold_T *fp3;
fold_T *fp4;
@@ -2730,8 +2667,7 @@ fold_T *fp2;
* Doesn't use any caching.
* Returns a level of -1 if the foldlevel depends on surrounding lines.
*/
-static void foldlevelIndent(flp)
-fline_T *flp;
+static void foldlevelIndent(fline_T *flp)
{
char_u *s;
buf_T *buf;
@@ -2762,8 +2698,7 @@ fline_T *flp;
* Low level function to get the foldlevel for the "diff" method.
* Doesn't use any caching.
*/
-static void foldlevelDiff(flp)
-fline_T *flp;
+static void foldlevelDiff(fline_T *flp)
{
if (diff_infold(flp->wp, flp->lnum + flp->off))
flp->lvl = 1;
@@ -2777,8 +2712,7 @@ fline_T *flp;
* Doesn't use any caching.
* Returns a level of -1 if the foldlevel depends on surrounding lines.
*/
-static void foldlevelExpr(flp)
-fline_T *flp;
+static void foldlevelExpr(fline_T *flp)
{
win_T *win;
int n;
@@ -2869,8 +2803,7 @@ fline_T *flp;
* "foldendmarkerlen".
* Relies on the option value to have been checked for correctness already.
*/
-static void parseMarker(wp)
-win_T *wp;
+static void parseMarker(win_T *wp)
{
foldendmarker = vim_strchr(wp->w_p_fmr, ',');
foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
@@ -2887,8 +2820,7 @@ win_T *wp;
* Doesn't use any caching.
* Sets flp->start when a start marker was found.
*/
-static void foldlevelMarker(flp)
-fline_T *flp;
+static void foldlevelMarker(fline_T *flp)
{
char_u *startmarker;
int cstart;
@@ -2958,8 +2890,7 @@ fline_T *flp;
* Low level function to get the foldlevel for the "syntax" method.
* Doesn't use any caching.
*/
-static void foldlevelSyntax(flp)
-fline_T *flp;
+static void foldlevelSyntax(fline_T *flp)
{
linenr_T lnum = flp->lnum + flp->off;
int n;
@@ -2987,9 +2918,7 @@ static int put_fold_open_close __ARGS((FILE *fd, fold_T *fp, linenr_T off));
* Write commands to "fd" to restore the manual folds in window "wp".
* Return FAIL if writing fails.
*/
-int put_folds(fd, wp)
-FILE *fd;
-win_T *wp;
+int put_folds(FILE *fd, win_T *wp)
{
if (foldmethodIsManual(wp)) {
if (put_line(fd, "silent! normal! zE") == FAIL
@@ -3009,10 +2938,7 @@ win_T *wp;
* Write commands to "fd" to recreate manually created folds.
* Returns FAIL when writing failed.
*/
-static int put_folds_recurse(fd, gap, off)
-FILE *fd;
-garray_T *gap;
-linenr_T off;
+static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off)
{
int i;
fold_T *fp;
@@ -3036,11 +2962,7 @@ linenr_T off;
* Write commands to "fd" to open and close manually opened/closed folds.
* Returns FAIL when writing failed.
*/
-static int put_foldopen_recurse(fd, wp, gap, off)
-FILE *fd;
-win_T *wp;
-garray_T *gap;
-linenr_T off;
+static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off)
{
int i;
int level;
@@ -3086,10 +3008,7 @@ linenr_T off;
* Write the open or close command to "fd".
* Returns FAIL when writing failed.
*/
-static int put_fold_open_close(fd, fp, off)
-FILE *fd;
-fold_T *fp;
-linenr_T off;
+static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off)
{
if (fprintf(fd, "%ld", fp->fd_top + off) < 0
|| put_eol(fd) == FAIL
diff --git a/src/proto/fold.pro b/src/fold.h
index 6f498872e7..3ad08b01e5 100644
--- a/src/proto/fold.pro
+++ b/src/fold.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_FOLD_H
+#define NEOVIM_FOLD_H
/* fold.c */
void copyFoldingState __ARGS((win_T *wp_from, win_T *wp_to));
int hasAnyFolding __ARGS((win_T *win));
@@ -48,3 +50,4 @@ char_u *get_foldtext __ARGS((win_T *wp, linenr_T lnum, linenr_T lnume,
void foldtext_cleanup __ARGS((char_u *str));
int put_folds __ARGS((FILE *fd, win_T *wp));
/* vim: set ft=c : */
+#endif /* NEOVIM_FOLD_H */
diff --git a/src/getchar.c b/src/getchar.c
index 92e1ece639..7303e3739e 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -17,6 +17,27 @@
*/
#include "vim.h"
+#include "getchar.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "regexp.h"
+#include "screen.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
/*
* These buffers are used for storing:
@@ -134,8 +155,7 @@ static char_u *eval_map_expr __ARGS((char_u *str, int c));
/*
* Free and clear a buffer.
*/
-void free_buff(buf)
-struct buffheader *buf;
+void free_buff(struct buffheader *buf)
{
struct buffblock *p, *np;
@@ -150,9 +170,11 @@ struct buffheader *buf;
* Return the contents of a buffer as a single string.
* K_SPECIAL and CSI in the returned string are escaped.
*/
-static char_u * get_buffcont(buffer, dozero)
-struct buffheader *buffer;
-int dozero; /* count == zero is not an error */
+static char_u *
+get_buffcont (
+ struct buffheader *buffer,
+ int dozero /* count == zero is not an error */
+)
{
long_u count = 0;
char_u *p = NULL;
@@ -179,7 +201,7 @@ int dozero; /* count == zero is not an error */
* and clear the record buffer.
* K_SPECIAL and CSI in the returned string are escaped.
*/
-char_u * get_recorded() {
+char_u *get_recorded(void) {
char_u *p;
size_t len;
@@ -210,7 +232,7 @@ char_u * get_recorded() {
* Return the contents of the redo buffer as a single string.
* K_SPECIAL and CSI in the returned string are escaped.
*/
-char_u * get_inserted() {
+char_u *get_inserted(void) {
return get_buffcont(&redobuff, FALSE);
}
@@ -218,10 +240,12 @@ char_u * get_inserted() {
* Add string "s" after the current block of buffer "buf".
* K_SPECIAL and CSI should have been escaped already.
*/
-static void add_buff(buf, s, slen)
-struct buffheader *buf;
-char_u *s;
-long slen; /* length of "s" or -1 */
+static void
+add_buff (
+ struct buffheader *buf,
+ char_u *s,
+ long slen /* length of "s" or -1 */
+)
{
struct buffblock *p;
long_u len;
@@ -269,9 +293,7 @@ long slen; /* length of "s" or -1 */
/*
* Add number "n" to buffer "buf".
*/
-static void add_num_buff(buf, n)
-struct buffheader *buf;
-long n;
+static void add_num_buff(struct buffheader *buf, long n)
{
char_u number[32];
@@ -283,9 +305,7 @@ long n;
* Add character 'c' to buffer "buf".
* Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
*/
-static void add_char_buff(buf, c)
-struct buffheader *buf;
-int c;
+static void add_char_buff(struct buffheader *buf, int c)
{
char_u bytes[MB_MAXBYTES + 1];
int len;
@@ -319,8 +339,7 @@ int c;
* If advance == TRUE go to the next char.
* No translation is done K_SPECIAL and CSI are escaped.
*/
-static int read_stuff(advance)
-int advance;
+static int read_stuff(int advance)
{
char_u c;
struct buffblock *curr;
@@ -344,7 +363,7 @@ int advance;
/*
* Prepare the stuff buffer for reading (if it contains something).
*/
-static void start_stuff() {
+static void start_stuff(void) {
if (stuffbuff.bh_first.b_next != NULL) {
stuffbuff.bh_curr = &(stuffbuff.bh_first);
stuffbuff.bh_space = 0;
@@ -354,15 +373,14 @@ static void start_stuff() {
/*
* Return TRUE if the stuff buffer is empty.
*/
-int stuff_empty() {
+int stuff_empty(void) {
return stuffbuff.bh_first.b_next == NULL;
}
/*
* Set a typeahead character that won't be flushed.
*/
-void typeahead_noflush(c)
-int c;
+void typeahead_noflush(int c)
{
typeahead_char = c;
}
@@ -372,8 +390,7 @@ int c;
* typeahead buffer (used in case of an error). If "flush_typeahead" is true,
* flush all typeahead characters (used when interrupted by a CTRL-C).
*/
-void flush_buffers(flush_typeahead)
-int flush_typeahead;
+void flush_buffers(int flush_typeahead)
{
init_typebuf();
@@ -406,7 +423,7 @@ int flush_typeahead;
* The previous contents of the redo buffer is kept in old_redobuffer.
* This is used for the CTRL-O <.> command in insert mode.
*/
-void ResetRedobuff() {
+void ResetRedobuff(void) {
if (!block_redo) {
free_buff(&old_redobuff);
old_redobuff = redobuff;
@@ -418,7 +435,7 @@ void ResetRedobuff() {
* Discard the contents of the redo buffer and restore the previous redo
* buffer.
*/
-void CancelRedo() {
+void CancelRedo(void) {
if (!block_redo) {
free_buff(&redobuff);
redobuff = old_redobuff;
@@ -435,7 +452,7 @@ void CancelRedo() {
*/
static int save_level = 0;
-void saveRedobuff() {
+void saveRedobuff(void) {
char_u *s;
if (save_level++ == 0) {
@@ -457,7 +474,7 @@ void saveRedobuff() {
* Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
* Used after executing autocommands and user functions.
*/
-void restoreRedobuff() {
+void restoreRedobuff(void) {
if (--save_level == 0) {
free_buff(&redobuff);
redobuff = save_redobuff;
@@ -470,8 +487,7 @@ void restoreRedobuff() {
* Append "s" to the redo buffer.
* K_SPECIAL and CSI should already have been escaped.
*/
-void AppendToRedobuff(s)
-char_u *s;
+void AppendToRedobuff(char_u *s)
{
if (!block_redo)
add_buff(&redobuff, s, -1L);
@@ -481,9 +497,11 @@ char_u *s;
* Append to Redo buffer literally, escaping special characters with CTRL-V.
* K_SPECIAL and CSI are escaped as well.
*/
-void AppendToRedobuffLit(str, len)
-char_u *str;
-int len; /* length of "str" or -1 for up to the NUL */
+void
+AppendToRedobuffLit (
+ char_u *str,
+ int len /* length of "str" or -1 for up to the NUL */
+)
{
char_u *s = str;
int c;
@@ -532,8 +550,7 @@ int len; /* length of "str" or -1 for up to the NUL */
* Append a character to the redo buffer.
* Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
*/
-void AppendCharToRedobuff(c)
-int c;
+void AppendCharToRedobuff(int c)
{
if (!block_redo)
add_char_buff(&redobuff, c);
@@ -542,8 +559,7 @@ int c;
/*
* Append a number to the redo buffer.
*/
-void AppendNumberToRedobuff(n)
-long n;
+void AppendNumberToRedobuff(long n)
{
if (!block_redo)
add_num_buff(&redobuff, n);
@@ -553,15 +569,12 @@ long n;
* Append string "s" to the stuff buffer.
* CSI and K_SPECIAL must already have been escaped.
*/
-void stuffReadbuff(s)
-char_u *s;
+void stuffReadbuff(char_u *s)
{
add_buff(&stuffbuff, s, -1L);
}
-void stuffReadbuffLen(s, len)
-char_u *s;
-long len;
+void stuffReadbuffLen(char_u *s, long len)
{
add_buff(&stuffbuff, s, len);
}
@@ -571,8 +584,7 @@ long len;
* escaping other K_SPECIAL and CSI bytes.
* Change CR, LF and ESC into a space.
*/
-void stuffReadbuffSpec(s)
-char_u *s;
+void stuffReadbuffSpec(char_u *s)
{
int c;
@@ -594,8 +606,7 @@ char_u *s;
* Append a character to the stuff buffer.
* Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
*/
-void stuffcharReadbuff(c)
-int c;
+void stuffcharReadbuff(int c)
{
add_char_buff(&stuffbuff, c);
}
@@ -603,8 +614,7 @@ int c;
/*
* Append a number to the stuff buffer.
*/
-void stuffnumReadbuff(n)
-long n;
+void stuffnumReadbuff(long n)
{
add_num_buff(&stuffbuff, n);
}
@@ -617,9 +627,7 @@ long n;
* otherwise.
* If old is TRUE, use old_redobuff instead of redobuff.
*/
-static int read_redo(init, old_redo)
-int init;
-int old_redo;
+static int read_redo(int init, int old_redo)
{
static struct buffblock *bp;
static char_u *p;
@@ -675,8 +683,7 @@ int old_redo;
* If old_redo is TRUE, use old_redobuff instead of redobuff.
* The escaped K_SPECIAL and CSI are copied without translation.
*/
-static void copy_redo(old_redo)
-int old_redo;
+static void copy_redo(int old_redo)
{
int c;
@@ -693,9 +700,7 @@ int old_redo;
*
* return FAIL for failure, OK otherwise
*/
-int start_redo(count, old_redo)
-long count;
-int old_redo;
+int start_redo(long count, int old_redo)
{
int c;
@@ -744,7 +749,7 @@ int old_redo;
* the redo buffer into the stuffbuff.
* return FAIL for failure, OK otherwise
*/
-int start_redo_ins() {
+int start_redo_ins(void) {
int c;
if (read_redo(TRUE, FALSE) == FAIL)
@@ -766,7 +771,7 @@ int start_redo_ins() {
return OK;
}
-void stop_redo_ins() {
+void stop_redo_ins(void) {
block_redo = FALSE;
}
@@ -775,7 +780,7 @@ void stop_redo_ins() {
* alloc() cannot be used here: In out-of-memory situations it would
* be impossible to type anything.
*/
-static void init_typebuf() {
+static void init_typebuf(void) {
if (typebuf.tb_buf == NULL) {
typebuf.tb_buf = typebuf_init;
typebuf.tb_noremap = noremapbuf_init;
@@ -805,12 +810,7 @@ static void init_typebuf() {
*
* return FAIL for failure, OK otherwise
*/
-int ins_typebuf(str, noremap, offset, nottyped, silent)
-char_u *str;
-int noremap;
-int offset;
-int nottyped;
-int silent;
+int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, int silent)
{
char_u *s1, *s2;
int newlen;
@@ -931,8 +931,7 @@ int silent;
* Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
* the char.
*/
-void ins_char_typebuf(c)
-int c;
+void ins_char_typebuf(int c)
{
char_u buf[MB_MAXBYTES + 1];
if (IS_SPECIAL(c)) {
@@ -955,8 +954,10 @@ int c;
* Or "typebuf.tb_off" may have been changed and we would overwrite characters
* that was just added.
*/
-int typebuf_changed(tb_change_cnt)
-int tb_change_cnt; /* old value of typebuf.tb_change_cnt */
+int
+typebuf_changed (
+ int tb_change_cnt /* old value of typebuf.tb_change_cnt */
+)
{
return tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
|| typebuf_was_filled
@@ -967,23 +968,21 @@ int tb_change_cnt; /* old value of typebuf.tb_change_cnt */
* Return TRUE if there are no characters in the typeahead buffer that have
* not been typed (result from a mapping or come from ":normal").
*/
-int typebuf_typed() {
+int typebuf_typed(void) {
return typebuf.tb_maplen == 0;
}
/*
* Return the number of characters that are mapped (or not typed).
*/
-int typebuf_maplen() {
+int typebuf_maplen(void) {
return typebuf.tb_maplen;
}
/*
* remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
*/
-void del_typebuf(len, offset)
-int len;
-int offset;
+void del_typebuf(int len, int offset)
{
int i;
@@ -1053,9 +1052,7 @@ int offset;
* Write typed characters to script file.
* If recording is on put the character in the recordbuffer.
*/
-static void gotchars(chars, len)
-char_u *chars;
-int len;
+static void gotchars(char_u *chars, int len)
{
char_u *s = chars;
int c;
@@ -1095,7 +1092,7 @@ int len;
* - While reading a script file.
* - When no_u_sync is non-zero.
*/
-static void may_sync_undo() {
+static void may_sync_undo(void) {
if ((!(State & (INSERT + CMDLINE)) || arrow_used)
&& scriptin[curscript] == NULL)
u_sync(FALSE);
@@ -1105,7 +1102,7 @@ static void may_sync_undo() {
* Make "typebuf" empty and allocate new buffers.
* Returns FAIL when out of memory.
*/
-int alloc_typebuf() {
+int alloc_typebuf(void) {
typebuf.tb_buf = alloc(TYPELEN_INIT);
typebuf.tb_noremap = alloc(TYPELEN_INIT);
if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL) {
@@ -1126,7 +1123,7 @@ int alloc_typebuf() {
/*
* Free the buffers of "typebuf".
*/
-void free_typebuf() {
+void free_typebuf(void) {
if (typebuf.tb_buf == typebuf_init)
EMSG2(_(e_intern2), "Free typebuf 1");
else
@@ -1143,7 +1140,7 @@ void free_typebuf() {
*/
static typebuf_T saved_typebuf[NSCRIPT];
-int save_typebuf() {
+int save_typebuf(void) {
init_typebuf();
saved_typebuf[curscript] = typebuf;
/* If out of memory: restore typebuf and close file. */
@@ -1163,8 +1160,7 @@ static int old_mouse_col; /* mouse_col related to old_char */
/*
* Save all three kinds of typeahead, so that the user must type at a prompt.
*/
-void save_typeahead(tp)
-tasave_T *tp;
+void save_typeahead(tasave_T *tp)
{
tp->save_typebuf = typebuf;
tp->typebuf_valid = (alloc_typebuf() == OK);
@@ -1186,8 +1182,7 @@ tasave_T *tp;
* Restore the typeahead to what it was before calling save_typeahead().
* The allocated memory is freed, can only be called once!
*/
-void restore_typeahead(tp)
-tasave_T *tp;
+void restore_typeahead(tasave_T *tp)
{
if (tp->typebuf_valid) {
free_typebuf();
@@ -1207,9 +1202,11 @@ tasave_T *tp;
/*
* Open a new script file for the ":source!" command.
*/
-void openscript(name, directly)
-char_u *name;
-int directly; /* when TRUE execute directly */
+void
+openscript (
+ char_u *name,
+ int directly /* when TRUE execute directly */
+)
{
if (curscript + 1 == NSCRIPT) {
EMSG(_(e_nesting));
@@ -1272,7 +1269,7 @@ int directly; /* when TRUE execute directly */
/*
* Close the currently active input script.
*/
-static void closescript() {
+static void closescript(void) {
free_typebuf();
typebuf = saved_typebuf[curscript];
@@ -1283,7 +1280,7 @@ static void closescript() {
}
#if defined(EXITFREE) || defined(PROTO)
-void close_all_scripts() {
+void close_all_scripts(void) {
while (scriptin[0] != NULL)
closescript();
}
@@ -1293,7 +1290,7 @@ void close_all_scripts() {
/*
* Return TRUE when reading keys from a script file.
*/
-int using_script() {
+int using_script(void) {
return scriptin[curscript] != NULL;
}
@@ -1301,7 +1298,7 @@ int using_script() {
* This function is called just before doing a blocking wait. Thus after
* waiting 'updatetime' for a character to arrive.
*/
-void before_blocking() {
+void before_blocking(void) {
updatescript(0);
if (may_garbage_collect)
garbage_collect();
@@ -1314,8 +1311,7 @@ void before_blocking() {
* All the changed memfiles are synced if c == 0 or when the number of typed
* characters reaches 'updatecount' and 'updatecount' is non-zero.
*/
-void updatescript(c)
-int c;
+void updatescript(int c)
{
static int count = 0;
@@ -1336,7 +1332,7 @@ int c;
* Collects the bytes of a multibyte character into the whole character.
* Returns the modifiers in the global "mod_mask".
*/
-int vgetc() {
+int vgetc(void) {
int c, c2;
int n;
char_u buf[MB_MAXBYTES + 1];
@@ -1481,7 +1477,7 @@ int vgetc() {
* Like vgetc(), but never return a NUL when called recursively, get a key
* directly from the user (ignoring typeahead).
*/
-int safe_vgetc() {
+int safe_vgetc(void) {
int c;
c = vgetc();
@@ -1494,7 +1490,7 @@ int safe_vgetc() {
* Like safe_vgetc(), but loop to handle K_IGNORE.
* Also ignore scrollbar events.
*/
-int plain_vgetc() {
+int plain_vgetc(void) {
int c;
do {
@@ -1508,7 +1504,7 @@ int plain_vgetc() {
* If the next character is a special character or multi-byte, the returned
* character is not valid!.
*/
-int vpeekc() {
+int vpeekc(void) {
if (old_char != -1)
return old_char;
return vgetorpeek(FALSE);
@@ -1518,7 +1514,7 @@ int vpeekc() {
* Like vpeekc(), but don't allow mapping. Do allow checking for terminal
* codes.
*/
-int vpeekc_nomap() {
+int vpeekc_nomap(void) {
int c;
++no_mapping;
@@ -1534,7 +1530,7 @@ int vpeekc_nomap() {
* Trick: when no typeahead found, but there is something in the typeahead
* buffer, it must be an ESC that is recognized as the start of a key code.
*/
-int vpeekc_any() {
+int vpeekc_any(void) {
int c;
c = vpeekc();
@@ -1547,7 +1543,7 @@ int vpeekc_any() {
* Call vpeekc() without causing anything to be mapped.
* Return TRUE if a character is available, FALSE otherwise.
*/
-int char_avail() {
+int char_avail(void) {
int retval;
++no_mapping;
@@ -1556,8 +1552,10 @@ int char_avail() {
return retval != NUL;
}
-void vungetc(c) /* unget one character (can only be done once!) */
-int c;
+void
+vungetc ( /* unget one character (can only be done once!) */
+ int c
+)
{
old_char = c;
old_mod_mask = mod_mask;
@@ -1588,8 +1586,7 @@ int c;
* Only returns one byte (of a multi-byte character).
* K_SPECIAL and CSI may be escaped, need to get two more bytes then.
*/
-static int vgetorpeek(advance)
-int advance;
+static int vgetorpeek(int advance)
{
int c, c1;
int keylen;
@@ -2363,11 +2360,13 @@ int advance;
* Return the number of obtained characters.
* Return -1 when end of input script reached.
*/
-int inchar(buf, maxlen, wait_time, tb_change_cnt)
-char_u *buf;
-int maxlen;
-long wait_time; /* milli seconds */
-int tb_change_cnt;
+int
+inchar (
+ char_u *buf,
+ int maxlen,
+ long wait_time, /* milli seconds */
+ int tb_change_cnt
+)
{
int len = 0; /* init for GCC */
int retesc = FALSE; /* return ESC with gotint */
@@ -2464,10 +2463,12 @@ int tb_change_cnt;
* buf[] must have room to triple the number of bytes!
* Returns the new length.
*/
-int fix_input_buffer(buf, len, script)
-char_u *buf;
-int len;
-int script; /* TRUE when reading from a script */
+int
+fix_input_buffer (
+ char_u *buf,
+ int len,
+ int script /* TRUE when reading from a script */
+)
{
int i;
char_u *p = buf;
@@ -2505,7 +2506,7 @@ int script; /* TRUE when reading from a script */
* or feedkeys() may insert characters in the typeahead buffer while we are
* waiting for input to arrive.
*/
-int input_available() {
+int input_available(void) {
return !vim_is_input_buf_empty()
|| typebuf_was_filled
;
@@ -2551,11 +2552,13 @@ int input_available() {
* 4 for out of mem
* 5 for entry not unique
*/
-int do_map(maptype, arg, mode, abbrev)
-int maptype;
-char_u *arg;
-int mode;
-int abbrev; /* not a mapping but an abbreviation */
+int
+do_map (
+ int maptype,
+ char_u *arg,
+ int mode,
+ int abbrev /* not a mapping but an abbreviation */
+)
{
char_u *keys;
mapblock_T *mp, **mpp;
@@ -3020,8 +3023,7 @@ theend:
* Delete one entry from the abbrlist or maphash[].
* "mpp" is a pointer to the m_next field of the PREVIOUS entry!
*/
-static void map_free(mpp)
-mapblock_T **mpp;
+static void map_free(mapblock_T **mpp)
{
mapblock_T *mp;
@@ -3036,7 +3038,7 @@ mapblock_T **mpp;
/*
* Initialize maphash[] for first use.
*/
-static void validate_maphash() {
+static void validate_maphash(void) {
if (!maphash_valid) {
vim_memset(maphash, 0, sizeof(maphash));
maphash_valid = TRUE;
@@ -3046,9 +3048,7 @@ static void validate_maphash() {
/*
* Get the mapping mode from the command name.
*/
-int get_map_mode(cmdp, forceit)
-char_u **cmdp;
-int forceit;
+int get_map_mode(char_u **cmdp, int forceit)
{
char_u *p;
int modec;
@@ -3088,11 +3088,7 @@ int forceit;
* Clear all mappings or abbreviations.
* 'abbr' should be FALSE for mappings, TRUE for abbreviations.
*/
-void map_clear(cmdp, arg, forceit, abbr)
-char_u *cmdp;
-char_u *arg UNUSED;
-int forceit;
-int abbr;
+void map_clear(char_u *cmdp, char_u *arg, int forceit, int abbr)
{
int mode;
int local;
@@ -3112,11 +3108,13 @@ int abbr;
/*
* Clear all mappings in "mode".
*/
-void map_clear_int(buf, mode, local, abbr)
-buf_T *buf UNUSED; /* buffer for local mappings */
-int mode; /* mode in which to delete */
-int local UNUSED; /* TRUE for buffer-local mappings */
-int abbr; /* TRUE for abbreviations */
+void
+map_clear_int (
+ buf_T *buf, /* buffer for local mappings */
+ int mode, /* mode in which to delete */
+ int local, /* TRUE for buffer-local mappings */
+ int abbr /* TRUE for abbreviations */
+)
{
mapblock_T *mp, **mpp;
int hash;
@@ -3171,8 +3169,7 @@ int abbr; /* TRUE for abbreviations */
* Return characters to represent the map mode in an allocated string.
* Returns NULL when out of memory.
*/
-char_u * map_mode_to_chars(mode)
-int mode;
+char_u *map_mode_to_chars(int mode)
{
garray_T mapmode;
@@ -3208,9 +3205,11 @@ int mode;
return (char_u *)mapmode.ga_data;
}
-static void showmap(mp, local)
-mapblock_T *mp;
-int local; /* TRUE for buffer-local map */
+static void
+showmap (
+ mapblock_T *mp,
+ int local /* TRUE for buffer-local map */
+)
{
int len = 1;
char_u *mapchars;
@@ -3274,10 +3273,7 @@ int local; /* TRUE for buffer-local map */
* Recognize termcap codes in "str".
* Also checks mappings local to the current buffer.
*/
-int map_to_exists(str, modechars, abbr)
-char_u *str;
-char_u *modechars;
-int abbr;
+int map_to_exists(char_u *str, char_u *modechars, int abbr)
{
int mode = 0;
char_u *rhs;
@@ -3313,10 +3309,7 @@ int abbr;
* Return TRUE if a map exists that has "str" in the rhs for mode "mode".
* Also checks mappings local to the current buffer.
*/
-int map_to_exists_mode(rhs, mode, abbr)
-char_u *rhs;
-int mode;
-int abbr;
+int map_to_exists_mode(char_u *rhs, int mode, int abbr)
{
mapblock_T *mp;
int hash;
@@ -3363,15 +3356,16 @@ static int expand_buffer = FALSE;
* Work out what to complete when doing command line completion of mapping
* or abbreviation names.
*/
-char_u * set_context_in_map_cmd(xp, cmd, arg, forceit, isabbrev, isunmap,
- cmdidx)
-expand_T *xp;
-char_u *cmd;
-char_u *arg;
-int forceit; /* TRUE if '!' given */
-int isabbrev; /* TRUE if abbreviation */
-int isunmap; /* TRUE if unmap/unabbrev command */
-cmdidx_T cmdidx;
+char_u *
+set_context_in_map_cmd (
+ expand_T *xp,
+ char_u *cmd,
+ char_u *arg,
+ int forceit, /* TRUE if '!' given */
+ int isabbrev, /* TRUE if abbreviation */
+ int isunmap, /* TRUE if unmap/unabbrev command */
+ cmdidx_T cmdidx
+)
{
if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
xp->xp_context = EXPAND_NOTHING;
@@ -3425,10 +3419,7 @@ cmdidx_T cmdidx;
* For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
* Return OK if matches found, FAIL otherwise.
*/
-int ExpandMappings(regmatch, num_file, file)
-regmatch_T *regmatch;
-int *num_file;
-char_u ***file;
+int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
{
mapblock_T *mp;
int hash;
@@ -3551,11 +3542,7 @@ char_u ***file;
*
* return TRUE if there is an abbreviation, FALSE if not
*/
-int check_abbr(c, ptr, col, mincol)
-int c;
-char_u *ptr;
-int col;
-int mincol;
+int check_abbr(int c, char_u *ptr, int col, int mincol)
{
int len;
int scol; /* starting column of the abbr. */
@@ -3703,9 +3690,11 @@ int mincol;
* Evaluate the RHS of a mapping or abbreviations and take care of escaping
* special characters.
*/
-static char_u * eval_map_expr(str, c)
-char_u *str;
-int c; /* NUL or typed character for abbreviation */
+static char_u *
+eval_map_expr (
+ char_u *str,
+ int c /* NUL or typed character for abbreviation */
+)
{
char_u *res;
char_u *p;
@@ -3760,8 +3749,7 @@ int c; /* NUL or typed character for abbreviation */
* can be put in the typeahead buffer.
* Returns NULL when out of memory.
*/
-char_u * vim_strsave_escape_csi(p)
-char_u *p;
+char_u *vim_strsave_escape_csi(char_u *p)
{
char_u *res;
char_u *s, *d;
@@ -3799,8 +3787,7 @@ char_u *p;
* Remove escaping from CSI and K_SPECIAL characters. Reverse of
* vim_strsave_escape_csi(). Works in-place.
*/
-void vim_unescape_csi(p)
-char_u *p;
+void vim_unescape_csi(char_u *p)
{
char_u *s = p, *d = p;
@@ -3822,9 +3809,11 @@ char_u *p;
* Write map commands for the current mappings to an .exrc file.
* Return FAIL on error, OK otherwise.
*/
-int makemap(fd, buf)
-FILE *fd;
-buf_T *buf; /* buffer for local mappings or NULL */
+int
+makemap (
+ FILE *fd,
+ buf_T *buf /* buffer for local mappings or NULL */
+)
{
mapblock_T *mp;
char_u c1, c2, c3;
@@ -4019,10 +4008,7 @@ buf_T *buf; /* buffer for local mappings or NULL */
*
* return FAIL for failure, OK otherwise
*/
-int put_escstr(fd, strstart, what)
-FILE *fd;
-char_u *strstart;
-int what;
+int put_escstr(FILE *fd, char_u *strstart, int what)
{
char_u *str = strstart;
int c;
@@ -4118,7 +4104,7 @@ int what;
* Check all mappings for the presence of special key codes.
* Used after ":set term=xxx".
*/
-void check_map_keycodes() {
+void check_map_keycodes(void) {
mapblock_T *mp;
char_u *p;
int i;
@@ -4187,14 +4173,16 @@ void check_map_keycodes() {
* Return pointer to rhs of mapping (mapblock->m_str).
* NULL when no mapping found.
*/
-char_u * check_map(keys, mode, exact, ign_mod, abbr, mp_ptr, local_ptr)
-char_u *keys;
-int mode;
-int exact; /* require exact match */
-int ign_mod; /* ignore preceding modifier */
-int abbr; /* do abbreviations */
-mapblock_T **mp_ptr; /* return: pointer to mapblock or NULL */
-int *local_ptr; /* return: buffer-local mapping or NULL */
+char_u *
+check_map (
+ char_u *keys,
+ int mode,
+ int exact, /* require exact match */
+ int ign_mod, /* ignore preceding modifier */
+ int abbr, /* do abbreviations */
+ mapblock_T **mp_ptr, /* return: pointer to mapblock or NULL */
+ int *local_ptr /* return: buffer-local mapping or NULL */
+)
{
int hash;
int len, minlen;
@@ -4255,9 +4243,7 @@ int *local_ptr; /* return: buffer-local mapping or NULL */
* Add a mapping "map" for mode "mode".
* Need to put string in allocated memory, because do_map() will modify it.
*/
-void add_map(map, mode)
-char_u *map;
-int mode;
+void add_map(char_u *map, int mode)
{
char_u *s;
char_u *cpo_save = p_cpo;
diff --git a/src/proto/getchar.pro b/src/getchar.h
index df3c9836cd..131286ee50 100644
--- a/src/proto/getchar.pro
+++ b/src/getchar.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_GETCHAR_H
+#define NEOVIM_GETCHAR_H
/* getchar.c */
void free_buff __ARGS((struct buffheader *buf));
char_u *get_recorded __ARGS((void));
@@ -72,3 +74,4 @@ char_u *check_map __ARGS((char_u *keys, int mode, int exact, int ign_mod,
void init_mappings __ARGS((void));
void add_map __ARGS((char_u *map, int mode));
/* vim: set ft=c : */
+#endif /* NEOVIM_GETCHAR_H */
diff --git a/src/globals.h b/src/globals.h
index e6db0d866b..056c098368 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -6,6 +6,11 @@
* Do ":help credits" in Vim to see a list of people who contributed.
*/
+#ifndef NEOVIM_GLOBALS_H
+#define NEOVIM_GLOBALS_H
+
+#include "mbyte.h"
+
/*
* definition of global variables
*/
@@ -1197,3 +1202,5 @@ EXTERN char *ignoredp;
* Optional Arabic support. Include it here, so EXTERN and INIT are defined.
*/
# include "arabic.h"
+
+#endif /* NEOVIM_GLOBALS_H */
diff --git a/src/hangulin.c b/src/hangulin.c
index 7f41509e83..185bf0a5bd 100644
--- a/src/hangulin.c
+++ b/src/hangulin.c
@@ -8,6 +8,12 @@
*/
#include "vim.h"
+#include "hangulin.h"
+#include "message.h"
+#include "misc1.h"
+#include "screen.h"
+#include "term.h"
+#include "ui.h"
#ifndef HANGUL_DEFAULT_KEYBOARD
# define HANGUL_DEFAULT_KEYBOARD 3
@@ -96,9 +102,7 @@ static short_u kind_table_for_3[] =
* 3 bulsik: (current initial sound, input english) -> compound initial sound.
*/
-static int comfcon3(v, c)
-int v;
-int c;
+static int comfcon3(int v, int c)
{
if (v == 2 && c == 2)
return 3;
@@ -117,9 +121,7 @@ int c;
* 3 bulsik: (current vowel, input english) -> compound vowel.
*/
-static int comvow3(v, c)
-int v;
-int c;
+static int comvow3(int v, int c)
{
switch (v) {
case 13: /* ¤Ç */
@@ -156,9 +158,7 @@ int c;
* VIM: V = initial sound, I = medial vowel, M = final consonant.
*/
-static int comcon3(k, c)
-int k;
-int c;
+static int comcon3(int k, int c)
{
switch (k) {
case 2: /* ¤¡ */
@@ -212,8 +212,7 @@ int c;
/****** 2 ¹ú½ÄÀÚÆÇÀ» À§ÇÑ ·çƾ (Routines for 2 bulsik keyboard) ******/
/**********************************************************************/
-static int kind_table_for_2(c)
-int c;
+static int kind_table_for_2(int c)
{
static char_u table[] =
{
@@ -235,8 +234,7 @@ int c;
* (2 bulsik: conversion english char. to initial sound of compound type)
* °á°ú: ÃʼºÀÌ ¾Æ´Ï¸é 0 (If it is not initial sound, return 0).
*/
-static int fcon(c)
-int c;
+static int fcon(int c)
{
static char_u table[] =
{
@@ -259,8 +257,7 @@ int c;
* (2 bulsik: conversion english char. to medial vowel)
* °á°ú: Áß¼ºÀÌ ¾Æ´Ï¸é 0 (If it is not medial vowel, return 0).
*/
-static int vow(c)
-int c;
+static int vow(int c)
{
static char_u table[] =
{
@@ -282,8 +279,7 @@ int c;
* (2 bulsik: conversion english char. to prop)
* °á°ú: ¹ÞħÀÌ ¾Æ´Ï¸é 0 (If not prop, return 0)
*/
-static int lcon(c)
-int c;
+static int lcon(int c)
{
static char_u table[] =
{
@@ -304,9 +300,7 @@ int c;
* (2 bulsik: conversion (curr. prop, input english) to prop)
*/
-static int comcon2(k, c)
-int k;
-int c;
+static int comcon2(int k, int c)
{
switch (k) {
case 2: /* ¤¡ */
@@ -359,9 +353,7 @@ int c;
* vowel)
*/
-static int comvow2(v, c)
-int v;
-int c;
+static int comvow2(int v, int c)
{
switch (v) {
case 13: /* ¤Ç */
@@ -396,22 +388,21 @@ int c;
return 0;
}
-int hangul_input_state_get() {
+int hangul_input_state_get(void) {
return hangul_input_state;
}
-void hangul_input_state_set(state)
-int state;
+void hangul_input_state_set(int state)
{
hangul_input_state = state;
hangul_input_clear();
}
-int im_get_status() {
+int im_get_status(void) {
return hangul_input_state_get();
}
-void hangul_input_state_toggle() {
+void hangul_input_state_toggle(void) {
if (hangul_input_state_get()) {
hangul_input_state_set(0);
if (composing_hangul) {
@@ -428,9 +419,7 @@ void hangul_input_state_toggle() {
}
-static int hangul_automata2(buf, c)
-char_u *buf;
-int_u *c;
+static int hangul_automata2(char_u *buf, int_u *c)
{
int t,t2;
@@ -570,9 +559,7 @@ int_u *c;
return AUTOMATA_ERROR; /* RrEeAaLlLlYy EeRrRrOoRr */
}
-static int hangul_automata3(buf, c)
-char_u *buf;
-int_u *c;
+static int hangul_automata3(char_u *buf, int_u *c)
{
int t, t2;
@@ -665,7 +652,7 @@ int_u *c;
return AUTOMATA_SPECIAL;
}
-void hangul_keyboard_set() {
+void hangul_keyboard_set(void) {
int keyboard;
char *s;
@@ -683,9 +670,7 @@ void hangul_keyboard_set() {
}
}
-int hangul_input_process(s, len)
-char_u *s;
-int len;
+int hangul_input_process(char_u *s, int len)
{
int n;
unsigned int c;
@@ -746,7 +731,7 @@ int len;
return len;
}
-void hangul_input_clear() {
+void hangul_input_clear(void) {
sp = 0;
f = F_NULL;
m = M_NULL;
@@ -1416,11 +1401,7 @@ static const char_u johab_lcon_to_wan[] =
0xbb, 0xbc, 0xbd, 0xbe /* ¤», ¤¼, ¤½, ¤¾ */
};
-static void convert_ks_to_3(src, fp, mp, lp)
-const char_u *src;
-int *fp;
-int *mp;
-int *lp;
+static void convert_ks_to_3(const char_u *src, int *fp, int *mp, int *lp)
{
int h = *src;
int low = *(src + 1);
@@ -1447,11 +1428,7 @@ int *lp;
}
}
-static int convert_3_to_ks(fv, mv, lv, des)
-int fv;
-int mv;
-int lv;
-char_u *des;
+static int convert_3_to_ks(int fv, int mv, int lv, char_u *des)
{
char_u key[3];
register int hi, lo, mi = 0, result, found;
diff --git a/src/proto/hangulin.pro b/src/hangulin.h
index adfde142ff..1023955c0d 100644
--- a/src/proto/hangulin.pro
+++ b/src/hangulin.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_HANGULIN_H
+#define NEOVIM_HANGULIN_H
/* hangulin.c */
int hangul_input_state_get __ARGS((void));
void hangul_input_state_set __ARGS((int state));
@@ -7,3 +9,4 @@ void hangul_keyboard_set __ARGS((void));
int hangul_input_process __ARGS((char_u *s, int len));
void hangul_input_clear __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_HANGULIN_H */
diff --git a/src/hardcopy.c b/src/hardcopy.c
index 5869b55a49..4f5ef53799 100644
--- a/src/hardcopy.c
+++ b/src/hardcopy.c
@@ -12,7 +12,24 @@
*/
#include "vim.h"
-#include "version.h"
+#include "version_defs.h"
+#include "hardcopy.h"
+#include "buffer.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "fileio.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "screen.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
/*
* To implement printing on a platform, the following functions must be
@@ -151,7 +168,7 @@ static void prt_get_attr __ARGS((int hl_id, prt_text_attr_T* pattr, int modec));
* Parse 'printoptions' and set the flags in "printer_opts".
* Returns an error message or NULL;
*/
-char_u * parse_printoptions() {
+char_u *parse_printoptions(void) {
return parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
}
@@ -159,7 +176,7 @@ char_u * parse_printoptions() {
* Parse 'printoptions' and set the flags in "printer_opts".
* Returns an error message or NULL;
*/
-char_u * parse_printmbfont() {
+char_u *parse_printmbfont(void) {
return parse_list_options(p_pmfn, mbfont_opts, OPT_MBFONT_NUM_OPTIONS);
}
@@ -172,10 +189,7 @@ char_u * parse_printmbfont() {
* Returns an error message for an illegal option, NULL otherwise.
* Only used for the printer at the moment...
*/
-static char_u * parse_list_options(option_str, table, table_size)
-char_u *option_str;
-option_table_T *table;
-int table_size;
+static char_u *parse_list_options(char_u *option_str, option_table_T *table, int table_size)
{
char_u *stringp;
char_u *colonp;
@@ -234,16 +248,14 @@ int table_size;
* If using a dark background, the colors will probably be too bright to show
* up well on white paper, so reduce their brightness.
*/
-static long_u darken_rgb(rgb)
-long_u rgb;
+static long_u darken_rgb(long_u rgb)
{
return ((rgb >> 17) << 16)
+ (((rgb & 0xff00) >> 9) << 8)
+ ((rgb & 0xff) >> 1);
}
-static long_u prt_get_term_color(colorindex)
-int colorindex;
+static long_u prt_get_term_color(int colorindex)
{
/* TODO: Should check for xterm with 88 or 256 colors. */
if (t_colors > 8)
@@ -251,10 +263,7 @@ int colorindex;
return cterm_color_8[colorindex % 8];
}
-static void prt_get_attr(hl_id, pattr, modec)
-int hl_id;
-prt_text_attr_T *pattr;
-int modec;
+static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
{
int colorindex;
long_u fg_color;
@@ -290,8 +299,7 @@ int modec;
pattr->bg_color = bg_color;
}
-static void prt_set_fg(fg)
-long_u fg;
+static void prt_set_fg(long_u fg)
{
if (fg != curr_fg) {
curr_fg = fg;
@@ -299,8 +307,7 @@ long_u fg;
}
}
-static void prt_set_bg(bg)
-long_u bg;
+static void prt_set_bg(long_u bg)
{
if (bg != curr_bg) {
curr_bg = bg;
@@ -308,10 +315,7 @@ long_u bg;
}
}
-static void prt_set_font(bold, italic, underline)
-int bold;
-int italic;
-int underline;
+static void prt_set_font(int bold, int italic, int underline)
{
if (curr_bold != bold
|| curr_italic != italic
@@ -326,10 +330,7 @@ int underline;
/*
* Print the line number in the left margin.
*/
-static void prt_line_number(psettings, page_line, lnum)
-prt_settings_T *psettings;
-int page_line;
-linenr_T lnum;
+static void prt_line_number(prt_settings_T *psettings, int page_line, linenr_T lnum)
{
int i;
char_u tbuf[20];
@@ -360,7 +361,7 @@ linenr_T lnum;
/*
* Get the currently effective header height.
*/
-int prt_header_height() {
+int prt_header_height(void) {
if (printer_opts[OPT_PRINT_HEADERHEIGHT].present)
return printer_opts[OPT_PRINT_HEADERHEIGHT].number;
return 2;
@@ -369,7 +370,7 @@ int prt_header_height() {
/*
* Return TRUE if using a line number for printing.
*/
-int prt_use_number() {
+int prt_use_number(void) {
return printer_opts[OPT_PRINT_NUMBER].present
&& TOLOWER_ASC(printer_opts[OPT_PRINT_NUMBER].string[0]) == 'y';
}
@@ -378,8 +379,7 @@ int prt_use_number() {
* Return the unit used in a margin item in 'printoptions'.
* Returns PRT_UNIT_NONE if not recognized.
*/
-int prt_get_unit(idx)
-int idx;
+int prt_get_unit(int idx)
{
int u = PRT_UNIT_NONE;
int i;
@@ -397,10 +397,7 @@ int idx;
/*
* Print the page header.
*/
-static void prt_header(psettings, pagenum, lnum)
-prt_settings_T *psettings;
-int pagenum;
-linenr_T lnum UNUSED;
+static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
{
int width = psettings->chars_per_line;
int page_line;
@@ -481,16 +478,14 @@ linenr_T lnum UNUSED;
/*
* Display a print status message.
*/
-static void prt_message(s)
-char_u *s;
+static void prt_message(char_u *s)
{
screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
screen_puts(s, (int)Rows - 1, 0, hl_attr(HLF_R));
out_flush();
}
-void ex_hardcopy(eap)
-exarg_T *eap;
+void ex_hardcopy(exarg_T *eap)
{
linenr_T lnum;
int collated_copies, uncollated_copies;
@@ -726,10 +721,7 @@ print_fail_no_begin:
* Print one page line.
* Return the next column to print, or zero if the line is finished.
*/
-static colnr_T hardcopy_line(psettings, page_line, ppos)
-prt_settings_T *psettings;
-int page_line;
-prt_pos_T *ppos;
+static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T *ppos)
{
colnr_T col;
char_u *line;
@@ -1337,9 +1329,7 @@ static int prt_half_width;
static char *prt_ascii_encoding;
static char_u prt_hexchar[] = "0123456789abcdef";
-static void prt_write_file_raw_len(buffer, bytes)
-char_u *buffer;
-int bytes;
+static void prt_write_file_raw_len(char_u *buffer, int bytes)
{
if (!prt_file_error
&& fwrite(buffer, sizeof(char_u), bytes, prt_ps_fd)
@@ -1349,15 +1339,12 @@ int bytes;
}
}
-static void prt_write_file(buffer)
-char_u *buffer;
+static void prt_write_file(char_u *buffer)
{
prt_write_file_len(buffer, (int)STRLEN(buffer));
}
-static void prt_write_file_len(buffer, bytes)
-char_u *buffer;
-int bytes;
+static void prt_write_file_len(char_u *buffer, int bytes)
{
prt_write_file_raw_len(buffer, bytes);
}
@@ -1365,8 +1352,7 @@ int bytes;
/*
* Write a string.
*/
-static void prt_write_string(s)
-char *s;
+static void prt_write_string(char *s)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%s", s);
prt_write_file(prt_line_buffer);
@@ -1375,8 +1361,7 @@ char *s;
/*
* Write an int and a space.
*/
-static void prt_write_int(i)
-int i;
+static void prt_write_int(int i)
{
sprintf((char *)prt_line_buffer, "%d ", i);
prt_write_file(prt_line_buffer);
@@ -1385,8 +1370,7 @@ int i;
/*
* Write a boolean and a space.
*/
-static void prt_write_boolean(b)
-int b;
+static void prt_write_boolean(int b)
{
sprintf((char *)prt_line_buffer, "%s ", (b ? "T" : "F"));
prt_write_file(prt_line_buffer);
@@ -1395,11 +1379,7 @@ int b;
/*
* Write PostScript to re-encode and define the font.
*/
-static void prt_def_font(new_name, encoding, height, font)
-char *new_name;
-char *encoding;
-int height;
-char *font;
+static void prt_def_font(char *new_name, char *encoding, int height, char *font)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"/_%s /VIM-%s /%s ref\n", new_name, encoding, font);
@@ -1416,10 +1396,7 @@ char *font;
/*
* Write a line to define the CID font.
*/
-static void prt_def_cidfont(new_name, height, cidfont)
-char *new_name;
-int height;
-char *cidfont;
+static void prt_def_cidfont(char *new_name, int height, char *cidfont)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"/_%s /%s[/%s] vim_composefont\n", new_name, prt_cmap, cidfont);
@@ -1432,9 +1409,7 @@ char *cidfont;
/*
* Write a line to define a duplicate of a CID font
*/
-static void prt_dup_cidfont(original_name, new_name)
-char *original_name;
-char *new_name;
+static void prt_dup_cidfont(char *original_name, char *new_name)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"/%s %s d\n", new_name, original_name);
@@ -1446,11 +1421,7 @@ char *new_name;
* the fractional part being in the range [0,10^precision). The fractional part
* is also rounded based on the precision + 1'th fractional digit.
*/
-static void prt_real_bits(real, precision, pinteger, pfraction)
-double real;
-int precision;
-int *pinteger;
-int *pfraction;
+static void prt_real_bits(double real, int precision, int *pinteger, int *pfraction)
{
int i;
int integer;
@@ -1472,9 +1443,7 @@ int *pfraction;
* We use prt_real_bits() as %f in sprintf uses the locale setting to decide
* what decimal point character to use, but PS always requires a '.'.
*/
-static void prt_write_real(val, prec)
-double val;
-int prec;
+static void prt_write_real(double val, int prec)
{
int integer;
int fraction;
@@ -1501,10 +1470,7 @@ int prec;
/*
* Write a line to define a numeric variable.
*/
-static void prt_def_var(name, value, prec)
-char *name;
-double value;
-int prec;
+static void prt_def_var(char *name, double value, int prec)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"/%s ", name);
@@ -1517,7 +1483,7 @@ int prec;
/* Convert size from font space to user space at current font scale */
#define PRT_PS_FONT_TO_USER(scale, size) ((size) * ((scale)/1000.0))
-static void prt_flush_buffer() {
+static void prt_flush_buffer(void) {
if (prt_ps_buffer.ga_len > 0) {
/* Any background color must be drawn first */
if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE)) {
@@ -1585,9 +1551,7 @@ static void prt_flush_buffer() {
}
}
-static void prt_resource_name(filename, cookie)
-char_u *filename;
-void *cookie;
+static void prt_resource_name(char_u *filename, void *cookie)
{
char_u *resource_filename = cookie;
@@ -1597,9 +1561,7 @@ void *cookie;
STRCPY(resource_filename, filename);
}
-static int prt_find_resource(name, resource)
-char *name;
-struct prt_ps_resource_S *resource;
+static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
{
char_u *buffer;
int retval;
@@ -1638,7 +1600,7 @@ struct prt_resfile_buffer_S {
static struct prt_resfile_buffer_S prt_resfile;
-static int prt_resfile_next_line() {
+static int prt_resfile_next_line(void) {
int idx;
/* Move to start of next line and then find end of line */
@@ -1660,10 +1622,7 @@ static int prt_resfile_next_line() {
return idx < prt_resfile.len;
}
-static int prt_resfile_strncmp(offset, string, len)
-int offset;
-char *string;
-int len;
+static int prt_resfile_strncmp(int offset, char *string, int len)
{
/* Force not equal if string is longer than remainder of line */
if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset)))
@@ -1673,8 +1632,7 @@ int len;
string, len);
}
-static int prt_resfile_skip_nonws(offset)
-int offset;
+static int prt_resfile_skip_nonws(int offset)
{
int idx;
@@ -1687,8 +1645,7 @@ int offset;
return -1;
}
-static int prt_resfile_skip_ws(offset)
-int offset;
+static int prt_resfile_skip_ws(int offset)
{
int idx;
@@ -1703,8 +1660,7 @@ int offset;
/* prt_next_dsc() - returns detail on next DSC comment line found. Returns true
* if a DSC comment is found, else false */
-static int prt_next_dsc(p_dsc_line)
-struct prt_dsc_line_S *p_dsc_line;
+static int prt_next_dsc(struct prt_dsc_line_S *p_dsc_line)
{
int comment;
int offset;
@@ -1749,8 +1705,7 @@ struct prt_dsc_line_S *p_dsc_line;
/* Improved hand crafted parser to get the type, title, and version number of a
* PS resource file so the file details can be added to the DSC header comments.
*/
-static int prt_open_resource(resource)
-struct prt_ps_resource_S *resource;
+static int prt_open_resource(struct prt_ps_resource_S *resource)
{
int offset;
int seen_all;
@@ -1866,9 +1821,7 @@ struct prt_ps_resource_S *resource;
return TRUE;
}
-static int prt_check_resource(resource, version)
-struct prt_ps_resource_S *resource;
-char_u *version;
+static int prt_check_resource(struct prt_ps_resource_S *resource, char_u *version)
{
/* Version number m.n should match, the revision number does not matter */
if (STRNCMP(resource->version, version, STRLEN(version))) {
@@ -1881,30 +1834,25 @@ char_u *version;
return TRUE;
}
-static void prt_dsc_start() {
+static void prt_dsc_start(void) {
prt_write_string("%!PS-Adobe-3.0\n");
}
-static void prt_dsc_noarg(comment)
-char *comment;
+static void prt_dsc_noarg(char *comment)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"%%%%%s\n", comment);
prt_write_file(prt_line_buffer);
}
-static void prt_dsc_textline(comment, text)
-char *comment;
-char *text;
+static void prt_dsc_textline(char *comment, char *text)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"%%%%%s: %s\n", comment, text);
prt_write_file(prt_line_buffer);
}
-static void prt_dsc_text(comment, text)
-char *comment;
-char *text;
+static void prt_dsc_text(char *comment, char *text)
{
/* TODO - should scan 'text' for any chars needing escaping! */
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
@@ -1914,10 +1862,7 @@ char *text;
#define prt_dsc_atend(c) prt_dsc_text((c), "atend")
-static void prt_dsc_ints(comment, count, ints)
-char *comment;
-int count;
-int *ints;
+static void prt_dsc_ints(char *comment, int count, int *ints)
{
int i;
@@ -1933,10 +1878,12 @@ int *ints;
prt_write_string("\n");
}
-static void prt_dsc_resources(comment, type, string)
-char *comment; /* if NULL add to previous */
-char *type;
-char *string;
+static void
+prt_dsc_resources (
+ char *comment, /* if NULL add to previous */
+ char *type,
+ char *string
+)
{
if (comment != NULL)
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
@@ -1951,9 +1898,7 @@ char *string;
prt_write_file(prt_line_buffer);
}
-static void prt_dsc_font_resource(resource, ps_font)
-char *resource;
-struct prt_ps_font_S *ps_font;
+static void prt_dsc_font_resource(char *resource, struct prt_ps_font_S *ps_font)
{
int i;
@@ -1964,12 +1909,7 @@ struct prt_ps_font_S *ps_font;
prt_dsc_resources(NULL, "font", ps_font->ps_fontname[i]);
}
-static void prt_dsc_requirements(duplex, tumble, collate, color, num_copies)
-int duplex;
-int tumble;
-int collate;
-int color;
-int num_copies;
+static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, int num_copies)
{
/* Only output the comment if we need to.
* Note: tumble is ignored if we are not duplexing
@@ -1999,13 +1939,7 @@ int num_copies;
prt_write_string("\n");
}
-static void prt_dsc_docmedia(paper_name, width, height, weight, colour, type)
-char *paper_name;
-double width;
-double height;
-double weight;
-char *colour;
-char *type;
+static void prt_dsc_docmedia(char *paper_name, double width, double height, double weight, char *colour, char *type)
{
vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer),
"%%%%DocumentMedia: %s ", paper_name);
@@ -2025,7 +1959,7 @@ char *type;
prt_write_string("\n");
}
-void mch_print_cleanup() {
+void mch_print_cleanup(void) {
if (prt_out_mbyte) {
int i;
@@ -2055,10 +1989,7 @@ void mch_print_cleanup() {
}
}
-static float to_device_units(idx, physsize, def_number)
-int idx;
-double physsize;
-int def_number;
+static float to_device_units(int idx, double physsize, int def_number)
{
float ret;
int u;
@@ -2093,13 +2024,7 @@ int def_number;
/*
* Calculate margins for given width and height from printoptions settings.
*/
-static void prt_page_margins(width, height, left, right, top, bottom)
-double width;
-double height;
-double *left;
-double *right;
-double *top;
-double *bottom;
+static void prt_page_margins(double width, double height, double *left, double *right, double *top, double *bottom)
{
*left = to_device_units(OPT_PRINT_LEFT, width, 10);
*right = width - to_device_units(OPT_PRINT_RIGHT, width, 5);
@@ -2107,15 +2032,14 @@ double *bottom;
*bottom = to_device_units(OPT_PRINT_BOT, height, 5);
}
-static void prt_font_metrics(font_scale)
-int font_scale;
+static void prt_font_metrics(int font_scale)
{
prt_line_height = (float)font_scale;
prt_char_width = (float)PRT_PS_FONT_TO_USER(font_scale, prt_ps_font->wx);
}
-static int prt_get_cpl() {
+static int prt_get_cpl(void) {
if (prt_use_number()) {
prt_number_width = PRINT_NUMBER_WIDTH * prt_char_width;
/* If we are outputting multi-byte characters then line numbers will be
@@ -2130,10 +2054,7 @@ static int prt_get_cpl() {
return (int)((prt_right_margin - prt_left_margin) / prt_char_width);
}
-static int prt_build_cid_fontname(font, name, name_len)
-int font;
-char_u *name;
-int name_len;
+static int prt_build_cid_fontname(int font, char_u *name, int name_len)
{
char *fontname;
@@ -2149,7 +2070,7 @@ int name_len;
/*
* Get number of lines of text that fit on a page (excluding the header).
*/
-static int prt_get_lpp() {
+static int prt_get_lpp(void) {
int lpp;
/*
@@ -2177,10 +2098,7 @@ static int prt_get_lpp() {
return lpp - prt_header_height();
}
-static int prt_match_encoding(p_encoding, p_cmap, pp_mbenc)
-char *p_encoding;
-struct prt_ps_mbfont_S *p_cmap;
-struct prt_ps_encoding_S **pp_mbenc;
+static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S **pp_mbenc)
{
int mbenc;
int enc_len;
@@ -2200,10 +2118,7 @@ struct prt_ps_encoding_S **pp_mbenc;
return FALSE;
}
-static int prt_match_charset(p_charset, p_cmap, pp_mbchar)
-char *p_charset;
-struct prt_ps_mbfont_S *p_cmap;
-struct prt_ps_charset_S **pp_mbchar;
+static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_charset_S **pp_mbchar)
{
int mbchar;
int char_len;
@@ -2224,10 +2139,7 @@ struct prt_ps_charset_S **pp_mbchar;
return FALSE;
}
-int mch_print_init(psettings, jobname, forceit)
-prt_settings_T *psettings;
-char_u *jobname;
-int forceit UNUSED;
+int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
{
int i;
char *paper_name;
@@ -2510,8 +2422,7 @@ int forceit UNUSED;
return OK;
}
-static int prt_add_resource(resource)
-struct prt_ps_resource_S *resource;
+static int prt_add_resource(struct prt_ps_resource_S *resource)
{
FILE* fd_resource;
char_u resource_buffer[512];
@@ -2553,8 +2464,7 @@ struct prt_ps_resource_S *resource;
return TRUE;
}
-int mch_print_begin(psettings)
-prt_settings_T *psettings;
+int mch_print_begin(prt_settings_T *psettings)
{
time_t now;
int bbox[4];
@@ -2925,8 +2835,7 @@ theend:
return retval;
}
-void mch_print_end(psettings)
-prt_settings_T *psettings;
+void mch_print_end(prt_settings_T *psettings)
{
prt_dsc_noarg("Trailer");
@@ -2960,7 +2869,7 @@ prt_settings_T *psettings;
mch_print_cleanup();
}
-int mch_print_end_page() {
+int mch_print_end_page(void) {
prt_flush_buffer();
prt_write_string("re sp\n");
@@ -2970,8 +2879,7 @@ int mch_print_end_page() {
return !prt_file_error;
}
-int mch_print_begin_page(str)
-char_u *str UNUSED;
+int mch_print_begin_page(char_u *str)
{
int page_num[2];
@@ -3008,16 +2916,14 @@ char_u *str UNUSED;
return !prt_file_error;
}
-int mch_print_blank_page() {
+int mch_print_blank_page(void) {
return mch_print_begin_page(NULL) ? (mch_print_end_page()) : FALSE;
}
static float prt_pos_x = 0;
static float prt_pos_y = 0;
-void mch_print_start_line(margin, page_line)
-int margin;
-int page_line;
+void mch_print_start_line(int margin, int page_line)
{
prt_pos_x = prt_left_margin;
if (margin)
@@ -3031,9 +2937,7 @@ int page_line;
prt_half_width = FALSE;
}
-int mch_print_text_out(p, len)
-char_u *p;
-int len UNUSED;
+int mch_print_text_out(char_u *p, int len)
{
int need_break;
char_u ch;
@@ -3214,10 +3118,7 @@ int len UNUSED;
return need_break;
}
-void mch_print_set_font(iBold, iItalic, iUnderline)
-int iBold;
-int iItalic;
-int iUnderline;
+void mch_print_set_font(int iBold, int iItalic, int iUnderline)
{
int font = 0;
@@ -3238,16 +3139,14 @@ int iUnderline;
}
}
-void mch_print_set_bg(bgcol)
-long_u bgcol;
+void mch_print_set_bg(long_u bgcol)
{
prt_bgcol = (int)bgcol;
prt_attribute_change = TRUE;
prt_need_bgcol = TRUE;
}
-void mch_print_set_fg(fgcol)
-long_u fgcol;
+void mch_print_set_fg(long_u fgcol)
{
if (fgcol != (long_u)prt_fgcol) {
prt_fgcol = (int)fgcol;
diff --git a/src/proto/hardcopy.pro b/src/hardcopy.h
index 3744181371..84cbe02be8 100644
--- a/src/proto/hardcopy.pro
+++ b/src/hardcopy.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_HARDCOPY_H
+#define NEOVIM_HARDCOPY_H
/* hardcopy.c */
char_u *parse_printoptions __ARGS((void));
char_u *parse_printmbfont __ARGS((void));
@@ -19,3 +21,4 @@ void mch_print_set_font __ARGS((int iBold, int iItalic, int iUnderline));
void mch_print_set_bg __ARGS((long_u bgcol));
void mch_print_set_fg __ARGS((long_u fgcol));
/* vim: set ft=c : */
+#endif /* NEOVIM_HARDCOPY_H */
diff --git a/src/hashtab.c b/src/hashtab.c
index 4bab277f78..cdea743777 100644
--- a/src/hashtab.c
+++ b/src/hashtab.c
@@ -28,8 +28,9 @@
*/
#include "vim.h"
-
-
+#include "hashtab.h"
+#include "message.h"
+#include "misc2.h"
/* Magic value for algorithm that walks through the array. */
#define PERTURB_SHIFT 5
@@ -40,8 +41,7 @@ static int hash_may_resize __ARGS((hashtab_T *ht, int minitems));
/*
* Initialize an empty hash table.
*/
-void hash_init(ht)
-hashtab_T *ht;
+void hash_init(hashtab_T *ht)
{
/* This zeroes all "ht_" entries and all the "hi_key" in "ht_smallarray". */
vim_memset(ht, 0, sizeof(hashtab_T));
@@ -53,8 +53,7 @@ hashtab_T *ht;
* Free the array of a hash table. Does not free the items it contains!
* If "ht" is not freed then you should call hash_init() next!
*/
-void hash_clear(ht)
-hashtab_T *ht;
+void hash_clear(hashtab_T *ht)
{
if (ht->ht_array != ht->ht_smallarray)
vim_free(ht->ht_array);
@@ -65,9 +64,7 @@ hashtab_T *ht;
* have been allocated. "off" is the offset from the start of the allocate
* memory to the location of the key (it's always positive).
*/
-void hash_clear_all(ht, off)
-hashtab_T *ht;
-int off;
+void hash_clear_all(hashtab_T *ht, int off)
{
long todo;
hashitem_T *hi;
@@ -90,9 +87,7 @@ int off;
* WARNING: The returned pointer becomes invalid when the hashtable is changed
* (adding, setting or removing an item)!
*/
-hashitem_T * hash_find(ht, key)
-hashtab_T *ht;
-char_u *key;
+hashitem_T *hash_find(hashtab_T *ht, char_u *key)
{
return hash_lookup(ht, key, hash_hash(key));
}
@@ -100,10 +95,7 @@ char_u *key;
/*
* Like hash_find(), but caller computes "hash".
*/
-hashitem_T * hash_lookup(ht, key, hash)
-hashtab_T *ht;
-char_u *key;
-hash_T hash;
+hashitem_T *hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
{
hash_T perturb;
hashitem_T *freeitem;
@@ -163,7 +155,7 @@ hash_T hash;
* Useful when trying different hash algorithms.
* Called when exiting.
*/
-void hash_debug_results() {
+void hash_debug_results(void) {
#ifdef HT_DEBUG
fprintf(stderr, "\r\n\r\n\r\n\r\n");
fprintf(stderr, "Number of hashtable lookups: %ld\r\n", hash_count_lookup);
@@ -177,9 +169,7 @@ void hash_debug_results() {
* Add item with key "key" to hashtable "ht".
* Returns FAIL when out of memory or the key is already present.
*/
-int hash_add(ht, key)
-hashtab_T *ht;
-char_u *key;
+int hash_add(hashtab_T *ht, char_u *key)
{
hash_T hash = hash_hash(key);
hashitem_T *hi;
@@ -198,11 +188,7 @@ char_u *key;
* "hi" is invalid after this!
* Returns OK or FAIL (out of memory).
*/
-int hash_add_item(ht, hi, key, hash)
-hashtab_T *ht;
-hashitem_T *hi;
-char_u *key;
-hash_T hash;
+int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash)
{
/* If resizing failed before and it fails again we can't add an item. */
if (ht->ht_error && hash_may_resize(ht, 0) == FAIL)
@@ -224,9 +210,7 @@ hash_T hash;
* hash_lookup().
* The caller must take care of freeing the item itself.
*/
-void hash_remove(ht, hi)
-hashtab_T *ht;
-hashitem_T *hi;
+void hash_remove(hashtab_T *ht, hashitem_T *hi)
{
--ht->ht_used;
hi->hi_key = HI_KEY_REMOVED;
@@ -238,8 +222,7 @@ hashitem_T *hi;
* Don't use this when items are to be added!
* Must call hash_unlock() later.
*/
-void hash_lock(ht)
-hashtab_T *ht;
+void hash_lock(hashtab_T *ht)
{
++ht->ht_locked;
}
@@ -250,8 +233,7 @@ hashtab_T *ht;
* Table will be resized (shrink) when necessary.
* This must balance a call to hash_lock().
*/
-void hash_unlock(ht)
-hashtab_T *ht;
+void hash_unlock(hashtab_T *ht)
{
--ht->ht_locked;
(void)hash_may_resize(ht, 0);
@@ -262,9 +244,11 @@ hashtab_T *ht;
* Grow a hashtable when there is not enough empty space.
* Returns OK or FAIL (out of memory).
*/
-static int hash_may_resize(ht, minitems)
-hashtab_T *ht;
-int minitems; /* minimal number of items */
+static int
+hash_may_resize (
+ hashtab_T *ht,
+ int minitems /* minimal number of items */
+)
{
hashitem_T temparray[HT_INIT_SIZE];
hashitem_T *oldarray, *newarray;
@@ -395,8 +379,7 @@ int minitems; /* minimal number of items */
* when exiting. Try that with the current hash algorithm and yours. The
* lower the percentage the better.
*/
-hash_T hash_hash(key)
-char_u *key;
+hash_T hash_hash(char_u *key)
{
hash_T hash;
char_u *p;
diff --git a/src/proto/hashtab.pro b/src/hashtab.h
index c90f44898e..a1dfa63162 100644
--- a/src/proto/hashtab.pro
+++ b/src/hashtab.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_HASHTAB_H
+#define NEOVIM_HASHTAB_H
/* hashtab.c */
void hash_init __ARGS((hashtab_T *ht));
void hash_clear __ARGS((hashtab_T *ht));
@@ -13,3 +15,4 @@ void hash_lock __ARGS((hashtab_T *ht));
void hash_unlock __ARGS((hashtab_T *ht));
hash_T hash_hash __ARGS((char_u *key));
/* vim: set ft=c : */
+#endif /* NEOVIM_HASHTAB_H */
diff --git a/src/if_cscope.c b/src/if_cscope.c
index 2ef1d61cba..47a835a314 100644
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -10,14 +10,25 @@
*/
#include "vim.h"
-
+#include "if_cscope.h"
+#include "charset.h"
+#include "eval.h"
+#include "fileio.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "tag.h"
+#include "ui.h"
+#include "window.h"
#include <sys/types.h>
#include <sys/stat.h>
#if defined(UNIX)
# include <sys/wait.h>
#endif
-#include "if_cscope.h"
+#include "if_cscope_defs.h"
static void cs_usage_msg __ARGS((csid_e x));
static int cs_add __ARGS((exarg_T *eap));
@@ -83,8 +94,7 @@ static cscmd_T cs_cmds[] =
{ NULL, NULL, NULL, NULL, 0 }
};
-static void cs_usage_msg(x)
-csid_e x;
+static void cs_usage_msg(csid_e x)
{
(void)EMSG2(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
}
@@ -101,9 +111,7 @@ static enum {
* Function given to ExpandGeneric() to obtain the cscope command
* expansion.
*/
-char_u * get_cscope_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_cscope_name(expand_T *xp, int idx)
{
int current_idx;
int i;
@@ -160,10 +168,7 @@ int idx;
/*
* Handle command line completion for :cscope command.
*/
-void set_context_in_cscope_cmd(xp, arg, cmdidx)
-expand_T *xp;
-char_u *arg;
-cmdidx_T cmdidx;
+void set_context_in_cscope_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
{
char_u *p;
@@ -199,9 +204,11 @@ cmdidx_T cmdidx;
* Find the command, print help if invalid, and then call the corresponding
* command function.
*/
-static void do_cscope_general(eap, make_split)
-exarg_T *eap;
-int make_split; /* whether to split window */
+static void
+do_cscope_general (
+ exarg_T *eap,
+ int make_split /* whether to split window */
+)
{
cscmd_T *cmdp;
@@ -230,8 +237,7 @@ int make_split; /* whether to split window */
/*
* PUBLIC: do_cscope
*/
-void do_cscope(eap)
-exarg_T *eap;
+void do_cscope(exarg_T *eap)
{
do_cscope_general(eap, FALSE);
}
@@ -241,8 +247,7 @@ exarg_T *eap;
*
* same as do_cscope, but splits window, too.
*/
-void do_scscope(eap)
-exarg_T *eap;
+void do_scscope(exarg_T *eap)
{
do_cscope_general(eap, TRUE);
}
@@ -251,8 +256,7 @@ exarg_T *eap;
* PUBLIC: do_cstag
*
*/
-void do_cstag(eap)
-exarg_T *eap;
+void do_cstag(exarg_T *eap)
{
int ret = FALSE;
@@ -319,9 +323,7 @@ exarg_T *eap;
*
* returns TRUE if eof, FALSE otherwise
*/
-int cs_fgets(buf, size)
-char_u *buf;
-int size;
+int cs_fgets(char_u *buf, int size)
{
char *p;
@@ -338,7 +340,7 @@ int size;
*
* called only from do_tag(), when popping the tag stack
*/
-void cs_free_tags() {
+void cs_free_tags(void) {
cs_manage_matches(NULL, NULL, -1, Free);
}
@@ -347,7 +349,7 @@ void cs_free_tags() {
*
* called from do_tag()
*/
-void cs_print_tags() {
+void cs_print_tags(void) {
cs_manage_matches(NULL, NULL, -1, Print);
}
@@ -378,10 +380,7 @@ void cs_print_tags() {
*
* Note: All string comparisons are case sensitive!
*/
-int cs_connection(num, dbpath, ppath)
-int num;
-char_u *dbpath;
-char_u *ppath;
+int cs_connection(int num, char_u *dbpath, char_u *ppath)
{
int i;
@@ -439,8 +438,7 @@ char_u *ppath;
*
* MAXPATHL 256
*/
-static int cs_add(eap)
-exarg_T *eap UNUSED;
+static int cs_add(exarg_T *eap)
{
char *fname, *ppath, *flags = NULL;
@@ -454,8 +452,7 @@ exarg_T *eap UNUSED;
return cs_add_common(fname, ppath, flags);
}
-static void cs_stat_emsg(fname)
-char *fname;
+static void cs_stat_emsg(char *fname)
{
char *stat_emsg = _("E563: stat(%s) error: %d");
char *buf = (char *)alloc((unsigned)strlen(stat_emsg) + MAXPATHL + 10);
@@ -476,10 +473,12 @@ char *fname;
* cs_add() and cs_reset(). i really don't like to do this, but this
* routine uses a number of goto statements.
*/
-static int cs_add_common(arg1, arg2, flags)
-char *arg1; /* filename - may contain environment variables */
-char *arg2; /* prepend path - may contain environment variables */
-char *flags;
+static int
+cs_add_common (
+ char *arg1, /* filename - may contain environment variables */
+ char *arg2, /* prepend path - may contain environment variables */
+ char *flags
+)
{
struct stat statbuf;
int ret;
@@ -554,7 +553,7 @@ staterr:
#if defined(UNIX)
else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
#else
- /* WIN32 - substitute define S_ISREG from os_unix.h */
+ /* WIN32 - substitute define S_ISREG from os_unix_defs.h */
else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
#endif
{
@@ -595,11 +594,11 @@ add_err:
} /* cs_add_common */
-static int cs_check_for_connections() {
+static int cs_check_for_connections(void) {
return cs_cnt_connections() > 0;
} /* cs_check_for_connections */
-static int cs_check_for_tags() {
+static int cs_check_for_tags(void) {
return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
} /* cs_check_for_tags */
@@ -608,7 +607,7 @@ static int cs_check_for_tags() {
*
* count the number of cscope connections
*/
-static int cs_cnt_connections() {
+static int cs_cnt_connections(void) {
short i;
short cnt = 0;
@@ -619,8 +618,10 @@ static int cs_cnt_connections() {
return cnt;
} /* cs_cnt_connections */
-static void cs_reading_emsg(idx)
-int idx; /* connection index */
+static void
+cs_reading_emsg (
+ int idx /* connection index */
+)
{
EMSGN(_("E262: error reading cscope connection %ld"), idx);
}
@@ -631,8 +632,7 @@ int idx; /* connection index */
*
* count the number of matches for a given cscope connection.
*/
-static int cs_cnt_matches(idx)
-int idx;
+static int cs_cnt_matches(int idx)
{
char *stok;
char *buf;
@@ -689,9 +689,7 @@ int idx;
*
* Creates the actual cscope command query from what the user entered.
*/
-static char * cs_create_cmd(csoption, pattern)
-char *csoption;
-char *pattern;
+static char *cs_create_cmd(char *csoption, char *pattern)
{
char *cmd;
short search;
@@ -750,8 +748,7 @@ char *pattern;
* This piece of code was taken/adapted from nvi. do we need to add
* the BSD license notice?
*/
-static int cs_create_connection(i)
-int i;
+static int cs_create_connection(int i)
{
#ifdef UNIX
int to_cs[2], from_cs[2];
@@ -964,8 +961,7 @@ err_closing:
*
* returns TRUE if we jump to a tag or abort, FALSE if not.
*/
-static int cs_find(eap)
-exarg_T *eap;
+static int cs_find(exarg_T *eap)
{
char *opt, *pat;
int i;
@@ -1004,13 +1000,7 @@ exarg_T *eap;
*
* common code for cscope find, shared by cs_find() and do_cstag()
*/
-static int cs_find_common(opt, pat, forceit, verbose, use_ll, cmdline)
-char *opt;
-char *pat;
-int forceit;
-int verbose;
-int use_ll;
-char_u *cmdline;
+static int cs_find_common(char *opt, char *pat, int forceit, int verbose, int use_ll, char_u *cmdline)
{
int i;
char *cmd;
@@ -1191,8 +1181,7 @@ char_u *cmdline;
*
* print help
*/
-static int cs_help(eap)
-exarg_T *eap UNUSED;
+static int cs_help(exarg_T *eap)
{
cscmd_T *cmdp = cs_cmds;
@@ -1227,8 +1216,7 @@ exarg_T *eap UNUSED;
} /* cs_help */
-static void clear_csinfo(i)
-int i;
+static void clear_csinfo(int i)
{
csinfo[i].fname = NULL;
csinfo[i].ppath = NULL;
@@ -1249,7 +1237,7 @@ int i;
#ifndef UNIX
static char *GetWin32Error __ARGS((void));
-static char * GetWin32Error() {
+static char *GetWin32Error(void) {
char *msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), 0, (LPSTR)&msg, 0, NULL);
@@ -1269,11 +1257,7 @@ static char * GetWin32Error() {
*
* insert a new cscope database filename into the filelist
*/
-static int cs_insert_filelist(fname, ppath, flags, sb)
-char *fname;
-char *ppath;
-char *flags;
-struct stat *sb UNUSED;
+static int cs_insert_filelist(char *fname, char *ppath, char *flags, struct stat *sb)
{
short i, j;
#ifndef UNIX
@@ -1425,8 +1409,7 @@ exarg_T *eap;
*
* nuke em
*/
-static int cs_kill(eap)
-exarg_T *eap UNUSED;
+static int cs_kill(exarg_T *eap)
{
char *stok;
short i;
@@ -1473,9 +1456,11 @@ exarg_T *eap UNUSED;
*
* Actually kills a specific cscope connection.
*/
-static void cs_kill_execute(i, cname)
-int i; /* cscope table index */
-char *cname; /* cscope database name */
+static void
+cs_kill_execute (
+ int i, /* cscope table index */
+ char *cname /* cscope database name */
+)
{
if (p_csverbose) {
msg_clr_eos();
@@ -1506,11 +1491,7 @@ char *cname; /* cscope database name */
* would still have to be modified to escape all the special regular expression
* characters to comply with ctags formatting.
*/
-static char * cs_make_vim_style_matches(fname, slno, search, tagstr)
-char *fname;
-char *slno;
-char *search;
-char *tagstr;
+static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, char *tagstr)
{
/* vim style is ctags:
*
@@ -1563,11 +1544,7 @@ char *tagstr;
*
* Print: prints the tags
*/
-static char * cs_manage_matches(matches, contexts, totmatches, cmd)
-char **matches;
-char **contexts;
-int totmatches;
-mcmd_e cmd;
+static char *cs_manage_matches(char **matches, char **contexts, int totmatches, mcmd_e cmd)
{
static char **mp = NULL;
static char **cp = NULL;
@@ -1626,14 +1603,7 @@ mcmd_e cmd;
*
* parse cscope output
*/
-static char * cs_parse_results(cnumber, buf, bufsize, context, linenumber,
- search)
-int cnumber;
-char *buf;
-int bufsize;
-char **context;
-char **linenumber;
-char **search;
+static char *cs_parse_results(int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search)
{
int ch;
char *p;
@@ -1686,9 +1656,7 @@ char **search;
*
* write cscope find results to file
*/
-static void cs_file_results(f, nummatches_a)
-FILE *f;
-int *nummatches_a;
+static void cs_file_results(FILE *f, int *nummatches_a)
{
int i, j;
char *buf;
@@ -1741,15 +1709,7 @@ int *nummatches_a;
* into ctags format
* When there are no matches sets "*matches_p" to NULL.
*/
-static void cs_fill_results(tagstr, totmatches, nummatches_a, matches_p,
- cntxts_p,
- matched)
-char *tagstr;
-int totmatches;
-int *nummatches_a;
-char ***matches_p;
-char ***cntxts_p;
-int *matched;
+static void cs_fill_results(char *tagstr, int totmatches, int *nummatches_a, char ***matches_p, char ***cntxts_p, int *matched)
{
int i, j;
char *buf;
@@ -1819,8 +1779,7 @@ parse_out:
/* get the requested path components */
-static char * cs_pathcomponents(path)
-char *path;
+static char *cs_pathcomponents(char *path)
{
int i;
char *s;
@@ -1844,10 +1803,7 @@ char *path;
*
* called from cs_manage_matches()
*/
-static void cs_print_tags_priv(matches, cntxts, num_matches)
-char **matches;
-char **cntxts;
-int num_matches;
+static void cs_print_tags_priv(char **matches, char **cntxts, int num_matches)
{
char *buf = NULL;
int bufsize = 0; /* Track available bufsize */
@@ -1973,8 +1929,7 @@ int num_matches;
*
* read a cscope prompt (basically, skip over the ">> ")
*/
-static int cs_read_prompt(i)
-int i;
+static int cs_read_prompt(int i)
{
int ch;
char *buf = NULL; /* buffer for possible error message from cscope */
@@ -2065,9 +2020,7 @@ sig_handler SIGDEFARG(sigarg) {
* Does the actual free'ing for the cs ptr with an optional flag of whether
* or not to free the filename. Called by cs_kill and cs_reset.
*/
-static void cs_release_csp(i, freefnpp)
-int i;
-int freefnpp;
+static void cs_release_csp(int i, int freefnpp)
{
/*
* Trying to exit normally (not sure whether it is fit to UNIX cscope
@@ -2185,8 +2138,7 @@ int freefnpp;
*
* calls cs_kill on all cscope connections then reinits
*/
-static int cs_reset(eap)
-exarg_T *eap UNUSED;
+static int cs_reset(exarg_T *eap)
{
char **dblist = NULL, **pplist = NULL, **fllist = NULL;
int i;
@@ -2252,9 +2204,7 @@ exarg_T *eap UNUSED;
* ships with Solaris 2.6), the output never has the prefix prepended.
* Contrast this with my development system (Digital Unix), which does.
*/
-static char * cs_resolve_file(i, name)
-int i;
-char *name;
+static char *cs_resolve_file(int i, char *name)
{
char *fullname;
int len;
@@ -2307,8 +2257,7 @@ char *name;
*
* show all cscope connections
*/
-static int cs_show(eap)
-exarg_T *eap UNUSED;
+static int cs_show(exarg_T *eap)
{
short i;
if (cs_cnt_connections() == 0)
@@ -2340,7 +2289,7 @@ exarg_T *eap UNUSED;
*
* Only called when VIM exits to quit any cscope sessions.
*/
-void cs_end() {
+void cs_end(void) {
int i;
for (i = 0; i < csinfo_size; i++)
diff --git a/src/if_cscope.h b/src/if_cscope.h
index 3ed89715fc..35cf432c46 100644
--- a/src/if_cscope.h
+++ b/src/if_cscope.h
@@ -1,72 +1,16 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
- * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
- *
- * The basic idea/structure of cscope for Vim was borrowed from Nvi.
- * There might be a few lines of code that look similar to what Nvi
- * has. If this is a problem and requires inclusion of the annoying
- * BSD license, then sue me; I'm not worth much anyway.
- */
-
-
-#if defined(UNIX)
-# include <sys/types.h> /* pid_t */
-# include <sys/stat.h> /* dev_t, ino_t */
-#else
-#endif
-
-#define CSCOPE_SUCCESS 0
-#define CSCOPE_FAILURE -1
-
-#define CSCOPE_DBFILE "cscope.out"
-#define CSCOPE_PROMPT ">> "
-
-/*
- * s 0name Find this C symbol
- * g 1name Find this definition
- * d 2name Find functions called by this function
- * c 3name Find functions calling this function
- * t 4string find text string (cscope 12.9)
- * t 4name Find assignments to (cscope 13.3)
- * 5pattern change pattern -- NOT USED
- * e 6pattern Find this egrep pattern
- * f 7name Find this file
- * i 8name Find files #including this file
- */
-
-typedef struct {
- char * name;
- int (*func)__ARGS((exarg_T *eap));
- char * help;
- char * usage;
- int cansplit; /* if supports splitting window */
-} cscmd_T;
-
-typedef struct csi {
- char * fname; /* cscope db name */
- char * ppath; /* path to prepend (the -P option) */
- char * flags; /* additional cscope flags/options (e.g, -p2) */
-#if defined(UNIX)
- pid_t pid; /* PID of the connected cscope process. */
- dev_t st_dev; /* ID of dev containing cscope db */
- ino_t st_ino; /* inode number of cscope db */
-#else
-#endif
-
- FILE * fr_fp; /* from cscope: FILE. */
- FILE * to_fp; /* to cscope: FILE. */
-} csinfo_T;
-
-typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e;
-
-typedef enum {
- Store,
- Get,
- Free,
- Print
-} mcmd_e;
-
-
-
-/* the end */
+#ifndef NEOVIM_IF_CSCOPE_H
+#define NEOVIM_IF_CSCOPE_H
+/* if_cscope.c */
+char_u *get_cscope_name __ARGS((expand_T *xp, int idx));
+void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg,
+ cmdidx_T cmdidx));
+void do_cscope __ARGS((exarg_T *eap));
+void do_scscope __ARGS((exarg_T *eap));
+void do_cstag __ARGS((exarg_T *eap));
+int cs_fgets __ARGS((char_u *buf, int size));
+void cs_free_tags __ARGS((void));
+void cs_print_tags __ARGS((void));
+int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
+void cs_end __ARGS((void));
+/* vim: set ft=c : */
+#endif /* NEOVIM_IF_CSCOPE_H */
diff --git a/src/if_cscope_defs.h b/src/if_cscope_defs.h
new file mode 100644
index 0000000000..3ed89715fc
--- /dev/null
+++ b/src/if_cscope_defs.h
@@ -0,0 +1,72 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
+ * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
+ *
+ * The basic idea/structure of cscope for Vim was borrowed from Nvi.
+ * There might be a few lines of code that look similar to what Nvi
+ * has. If this is a problem and requires inclusion of the annoying
+ * BSD license, then sue me; I'm not worth much anyway.
+ */
+
+
+#if defined(UNIX)
+# include <sys/types.h> /* pid_t */
+# include <sys/stat.h> /* dev_t, ino_t */
+#else
+#endif
+
+#define CSCOPE_SUCCESS 0
+#define CSCOPE_FAILURE -1
+
+#define CSCOPE_DBFILE "cscope.out"
+#define CSCOPE_PROMPT ">> "
+
+/*
+ * s 0name Find this C symbol
+ * g 1name Find this definition
+ * d 2name Find functions called by this function
+ * c 3name Find functions calling this function
+ * t 4string find text string (cscope 12.9)
+ * t 4name Find assignments to (cscope 13.3)
+ * 5pattern change pattern -- NOT USED
+ * e 6pattern Find this egrep pattern
+ * f 7name Find this file
+ * i 8name Find files #including this file
+ */
+
+typedef struct {
+ char * name;
+ int (*func)__ARGS((exarg_T *eap));
+ char * help;
+ char * usage;
+ int cansplit; /* if supports splitting window */
+} cscmd_T;
+
+typedef struct csi {
+ char * fname; /* cscope db name */
+ char * ppath; /* path to prepend (the -P option) */
+ char * flags; /* additional cscope flags/options (e.g, -p2) */
+#if defined(UNIX)
+ pid_t pid; /* PID of the connected cscope process. */
+ dev_t st_dev; /* ID of dev containing cscope db */
+ ino_t st_ino; /* inode number of cscope db */
+#else
+#endif
+
+ FILE * fr_fp; /* from cscope: FILE. */
+ FILE * to_fp; /* to cscope: FILE. */
+} csinfo_T;
+
+typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e;
+
+typedef enum {
+ Store,
+ Get,
+ Free,
+ Print
+} mcmd_e;
+
+
+
+/* the end */
diff --git a/src/keymap.h b/src/keymap.h
index 766413c30c..140eee5322 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -14,7 +14,7 @@
/*
* For MSDOS some keys produce codes larger than 0xff. They are split into two
- * chars, the first one is K_NUL (same value used in term.h).
+ * chars, the first one is K_NUL (same value used in term_defs.h).
*/
#define K_NUL (0xce) /* for MSDOS: special key follows */
diff --git a/src/main.c b/src/main.c
index 02da51fb59..c5d7d528cf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -9,6 +9,38 @@
#define EXTERN
#include "vim.h"
+#include "main.h"
+#include "blowfish.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "if_cscope.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "ops.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "screen.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "version.h"
+#include "window.h"
/* Maximum number of commands from + or -c arguments. */
#define MAX_ARG_CMDS 10
@@ -70,7 +102,18 @@ static int get_number_arg __ARGS((char_u *p, int *idx, int def));
static void init_locale __ARGS((void));
# endif
static void parse_command_name __ARGS((mparm_T *parmp));
+static bool parse_char_i __ARGS((char_u **input, char val));
+static bool parse_string __ARGS((char_u **input, char* val, int len));
static void command_line_scan __ARGS((mparm_T *parmp));
+static void init_params __ARGS((mparm_T *parmp, int argc, char **argv));
+static void init_startuptime __ARGS((mparm_T *parmp));
+static void allocate_generic_buffers __ARGS((void));
+static void check_and_set_isatty __ARGS((mparm_T *parmp));
+static char_u* get_fname __ARGS((mparm_T *parmp));
+static void set_window_layout __ARGS((mparm_T *parmp));
+static void load_plugins __ARGS((void));
+static void handle_quickfix __ARGS((mparm_T *parmp));
+static void handle_tag __ARGS((char_u *tagname));
static void check_tty __ARGS((mparm_T *parmp));
static void read_stdin __ARGS((void));
static void create_windows __ARGS((mparm_T *parmp));
@@ -82,7 +125,7 @@ static void main_start_gui __ARGS((void));
# if defined(HAS_SWAP_EXISTS_ACTION)
static void check_swap_exists_action __ARGS((void));
# endif
-#endif
+#endif /* NO_VIM_MAIN */
/*
@@ -105,18 +148,11 @@ static char *(main_errors[]) =
};
#ifndef NO_VIM_MAIN /* skip this for unittests */
- int
-main(argc, argv)
- int argc;
- char **argv;
+ int main(int argc, char **argv)
{
char_u *fname = NULL; /* file name from command line */
mparm_T params; /* various parameters passed between
* main() and other functions. */
-#ifdef STARTUPTIME
- int i;
-#endif
-
/*
* Do any system-specific initialisations. These can NOT use IObuff or
* NameBuff. Thus emsg2() cannot be called!
@@ -126,30 +162,13 @@ main(argc, argv)
/* Many variables are in "params" so that we can pass them to invoked
* functions without a lot of arguments. "argc" and "argv" are also
* copied, so that they can be changed. */
- vim_memset(&params, 0, sizeof(params));
- params.argc = argc;
- params.argv = argv;
- params.want_full_screen = TRUE;
- params.use_debug_break_level = -1;
- params.window_count = -1;
-
-
+ init_params(&params, argc, argv);
#ifdef MEM_PROFILE
atexit(vim_mem_profile_dump);
#endif
-#ifdef STARTUPTIME
- for (i = 1; i < argc; ++i) {
- if (STRICMP(argv[i], "--startuptime") == 0 && i + 1 < argc) {
- time_fd = mch_fopen(argv[i + 1], "a");
- TIME_MSG("--- VIM STARTING ---");
- break;
- }
- }
-#endif
- starttime = time(NULL);
-
+ init_startuptime(&params);
(void)mb_init(); /* init mb_bytelen_tab[] to ones */
eval_init(); /* init global variables */
@@ -165,11 +184,7 @@ main(argc, argv)
* Allocate space for the generic buffers (needed for set_init_1() and
* EMSG2()).
*/
- if ((IObuff = alloc(IOSIZE)) == NULL
- || (NameBuff = alloc(MAXPATHL)) == NULL)
- mch_exit(0);
- TIME_MSG("Allocated generic buffers");
-
+ allocate_generic_buffers();
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
/*
@@ -178,18 +193,15 @@ main(argc, argv)
* work until set_init_1() has been called!
*/
init_locale();
- TIME_MSG("locale set");
#endif
-
/*
* Check if we have an interactive window.
* On the Amiga: If there is no window, we open one with a newcli command
* (needed for :! to * work). mch_check_win() will also handle the -d or
* -dev argument.
*/
- params.stdout_isatty = (mch_check_win(params.argc, params.argv) != FAIL);
- TIME_MSG("window checked");
+ check_and_set_isatty(&params);
/*
* Allocate the first window and buffer.
@@ -227,7 +239,6 @@ main(argc, argv)
* argument list "global_alist".
*/
command_line_scan(&params);
- TIME_MSG("parsing arguments");
/*
* On some systems, when we compile with the GUI, we always use it. On Mac
@@ -235,23 +246,8 @@ main(argc, argv)
* :gui.
*/
- if (GARGCOUNT > 0) {
-#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
- /*
- * Expand wildcards in file names.
- */
- if (!params.literal) {
- /* Temporarily add '(' and ')' to 'isfname'. These are valid
- * filename characters but are excluded from 'isfname' to make
- * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
- do_cmdline_cmd((char_u *)":set isf+=(,)");
- alist_expand(NULL, 0);
- do_cmdline_cmd((char_u *)":set isf&");
- }
-#endif
- fname = alist_name(&GARGLIST[0]);
- }
-
+ if (GARGCOUNT > 0)
+ fname = get_fname(&params);
TIME_MSG("expanding arguments");
@@ -342,18 +338,10 @@ main(argc, argv)
* Read all the plugin files.
* Only when compiled with +eval, since most plugins need it.
*/
- if (p_lpl) {
- source_runtime((char_u *)"plugin/**/*.vim", TRUE);
- TIME_MSG("loading plugins");
- }
+ load_plugins();
/* Decide about window layout for diff mode after reading vimrc. */
- if (params.diff_mode && params.window_layout == 0) {
- if (diffopt_horizontal())
- params.window_layout = WIN_HOR; /* use horizontal split */
- else
- params.window_layout = WIN_VER; /* use vertical split */
- }
+ set_window_layout(&params);
/*
* Recovery mode without a file name: List swap files.
@@ -401,17 +389,7 @@ main(argc, argv)
* "-q errorfile": Load the error file now.
* If the error file can't be read, exit before doing anything else.
*/
- if (params.edit_type == EDIT_QF) {
- if (params.use_ef != NULL)
- set_string_option_direct((char_u *)"ef", -1,
- params.use_ef, OPT_FREE, SID_CARG);
- vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
- if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0) {
- out_char('\n');
- mch_exit(3);
- }
- TIME_MSG("reading errorfile");
- }
+ handle_quickfix(&params);
/*
* Start putting things on the screen.
@@ -469,8 +447,7 @@ main(argc, argv)
/*
* Don't clear the screen when starting in Ex mode, unless using the GUI.
*/
- if (exmode_active
- )
+ if (exmode_active)
must_redraw = CLEAR;
else {
screenclear(); /* clear screen */
@@ -534,21 +511,7 @@ main(argc, argv)
* Need to jump to the tag before executing the '-c command'.
* Makes "vim -c '/return' -t main" work.
*/
- if (params.tagname != NULL) {
-#if defined(HAS_SWAP_EXISTS_ACTION)
- swap_exists_did_quit = FALSE;
-#endif
-
- vim_snprintf((char *)IObuff, IOSIZE, "ta %s", params.tagname);
- do_cmdline_cmd(IObuff);
- TIME_MSG("jumping to tag");
-
-#if defined(HAS_SWAP_EXISTS_ACTION)
- /* If the user doesn't want to edit the file then we quit here. */
- if (swap_exists_did_quit)
- getout(1);
-#endif
- }
+ handle_tag(params.tagname);
/* Execute any "+", "-c" and "-S" arguments. */
if (params.n_commands > 0)
@@ -605,9 +568,11 @@ main(argc, argv)
* Also used to handle ":visual" command after ":global": execute Normal mode
* commands, return when entering Ex mode. "noexmode" is TRUE then.
*/
-void main_loop(cmdwin, noexmode)
- int cmdwin; /* TRUE when working in the command-line window */
- int noexmode; /* TRUE when return on entering Ex mode */
+void
+main_loop (
+ int cmdwin, /* TRUE when working in the command-line window */
+ int noexmode /* TRUE when return on entering Ex mode */
+)
{
oparg_T oa; /* operator arguments */
int previous_got_int = FALSE; /* "got_int" was TRUE */
@@ -814,8 +779,7 @@ void main_loop(cmdwin, noexmode)
/* Exit properly */
-void getout(exitval)
- int exitval;
+void getout(int exitval)
{
buf_T *buf;
win_T *wp;
@@ -901,10 +865,12 @@ void getout(exitval)
/*
* Get a (optional) count for a Vim argument.
*/
-static int get_number_arg(p, idx, def)
- char_u *p; /* pointer to argument */
- int *idx; /* index in argument, is incremented */
- int def; /* default value */
+static int
+get_number_arg (
+ char_u *p, /* pointer to argument */
+ int *idx, /* index in argument, is incremented */
+ int def /* default value */
+)
{
if (vim_isdigit(p[*idx])) {
def = atoi((char *)&(p[*idx]));
@@ -918,7 +884,7 @@ static int get_number_arg(p, idx, def)
/*
* Setup to use the current locale (for ctype() and many other things).
*/
-static void init_locale() {
+static void init_locale(void) {
setlocale(LC_ALL, "");
# if defined(FEAT_FLOAT) && defined(LC_NUMERIC)
@@ -942,6 +908,7 @@ static void init_locale() {
vim_free(p);
textdomain(VIMPACKAGE);
}
+ TIME_MSG("locale set");
}
#endif
@@ -956,8 +923,7 @@ static void init_locale() {
* If the next characters are "ex" we start in Ex mode. If it's followed
* by "im" use improved Ex mode.
*/
-static void parse_command_name(parmp)
- mparm_T *parmp;
+static void parse_command_name(mparm_T *parmp)
{
char_u *initstr;
@@ -966,39 +932,33 @@ static void parse_command_name(parmp)
set_vim_var_string(VV_PROGNAME, initstr, -1);
- if (TOLOWER_ASC(initstr[0]) == 'r') {
+ if (STRNICMP(initstr, "editor", 6) == 0)
+ return;
+
+ if (parse_char_i(&initstr, 'r'))
restricted = TRUE;
- ++initstr;
- }
- /* Use evim mode for "evim" and "egvim", not for "editor". */
- if (TOLOWER_ASC(initstr[0]) == 'e'
- && (TOLOWER_ASC(initstr[1]) == 'v'
- || TOLOWER_ASC(initstr[1]) == 'g')) {
+ if (parse_char_i(&initstr, 'e'))
parmp->evim_mode = TRUE;
- ++initstr;
- }
/* "gvim" starts the GUI. Also accept "Gvim" for MS-Windows. */
- if (TOLOWER_ASC(initstr[0]) == 'g') {
+ if (parse_char_i(&initstr, 'g'))
main_start_gui();
- }
- if (STRNICMP(initstr, "view", 4) == 0) {
+ if (parse_string(&initstr, "view", 4)) {
readonlymode = TRUE;
curbuf->b_p_ro = TRUE;
p_uc = 10000; /* don't update very often */
- initstr += 4;
- } else if (STRNICMP(initstr, "vim", 3) == 0)
- initstr += 3;
+ } else {
+ parse_string(&initstr, "vim", 3); /* consume "vim" if it's there */
+ }
/* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
- if (STRICMP(initstr, "diff") == 0) {
+ if (parse_string(&initstr, "diff", 4))
parmp->diff_mode = TRUE;
- }
- if (STRNICMP(initstr, "ex", 2) == 0) {
- if (STRNICMP(initstr + 2, "im", 2) == 0)
+ if (parse_string(&initstr, "ex", 2)) {
+ if (parse_string(&initstr, "im", 2))
exmode_active = EXMODE_VIM;
else
exmode_active = EXMODE_NORMAL;
@@ -1006,11 +966,31 @@ static void parse_command_name(parmp)
}
}
+static bool parse_char_i(char_u **input, char val)
+{
+ if (TOLOWER_ASC(**input) == val) {
+ *input += 1; /* or (*input)++ WITH parens */
+ return true;
+ }
+ return false;
+}
+
+static bool parse_string(input, val, len)
+ char_u **input;
+ char *val;
+ int len;
+{
+ if (STRNICMP(*input, val, len) == 0) {
+ *input += len;
+ return true;
+ }
+ return false;
+}
+
/*
* Scan the command line arguments.
*/
-static void command_line_scan(parmp)
- mparm_T *parmp;
+static void command_line_scan(mparm_T *parmp)
{
int argc = parmp->argc;
char **argv = parmp->argv;
@@ -1500,14 +1480,158 @@ scripterror:
vim_free(p);
}
}
+ TIME_MSG("parsing arguments");
+}
+
+/*
+ * Many variables are in "params" so that we can pass them to invoked
+ * functions without a lot of arguments. "argc" and "argv" are also
+ * copied, so that they can be changed. */
+static void init_params(mparm_T *paramp, int argc, char **argv)
+{
+ vim_memset(paramp, 0, sizeof(*paramp));
+ paramp->argc = argc;
+ paramp->argv = argv;
+ paramp->want_full_screen = TRUE;
+ paramp->use_debug_break_level = -1;
+ paramp->window_count = -1;
+}
+
+/*
+ * Initialize global startuptime file if "--startuptime" passed as an argument.
+ */
+static void init_startuptime(mparm_T *paramp)
+{
+#ifdef STARTUPTIME
+ int i;
+ for (i = 1; i < paramp->argc; ++i) {
+ if (STRICMP(paramp->argv[i], "--startuptime") == 0 && i + 1 < paramp->argc) {
+ time_fd = mch_fopen(paramp->argv[i + 1], "a");
+ TIME_MSG("--- VIM STARTING ---");
+ break;
+ }
+ }
+#endif
+ starttime = time(NULL);
+}
+
+/*
+ * Allocate space for the generic buffers (needed for set_init_1() and
+ * EMSG2()).
+ */
+static void allocate_generic_buffers(void)
+{
+ if ((IObuff = alloc(IOSIZE)) == NULL
+ || (NameBuff = alloc(MAXPATHL)) == NULL)
+ mch_exit(0);
+ TIME_MSG("Allocated generic buffers");
+}
+
+/*
+ * Check if we have an interactive window.
+ * On the Amiga: If there is no window, we open one with a newcli command
+ * (needed for :! to * work). mch_check_win() will also handle the -d or
+ * -dev argument.
+ */
+static void check_and_set_isatty(mparm_T *paramp)
+{
+ paramp->stdout_isatty = (mch_check_win(paramp->argc, paramp->argv) != FAIL);
+ TIME_MSG("window checked");
+}
+
+/*
+ * Get filename from command line, given that there is one.
+ */
+static char_u *get_fname(mparm_T *parmp)
+{
+#if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
+ /*
+ * Expand wildcards in file names.
+ */
+ if (!parmp->literal) {
+ /* Temporarily add '(' and ')' to 'isfname'. These are valid
+ * filename characters but are excluded from 'isfname' to make
+ * "gf" work on a file name in parenthesis (e.g.: see vim.h). */
+ do_cmdline_cmd((char_u *)":set isf+=(,)");
+ alist_expand(NULL, 0);
+ do_cmdline_cmd((char_u *)":set isf&");
+ }
+#endif
+ return alist_name(&GARGLIST[0]);
+}
+
+/*
+ * Decide about window layout for diff mode after reading vimrc.
+ */
+static void set_window_layout(mparm_T *paramp)
+{
+ if (paramp->diff_mode && paramp->window_layout == 0) {
+ if (diffopt_horizontal())
+ paramp->window_layout = WIN_HOR; /* use horizontal split */
+ else
+ paramp->window_layout = WIN_VER; /* use vertical split */
+ }
+}
+
+/*
+ * Read all the plugin files.
+ * Only when compiled with +eval, since most plugins need it.
+ */
+static void load_plugins(void)
+{
+ if (p_lpl) {
+ source_runtime((char_u *)"plugin/**/*.vim", TRUE);
+ TIME_MSG("loading plugins");
+ }
+}
+
+/*
+ * "-q errorfile": Load the error file now.
+ * If the error file can't be read, exit before doing anything else.
+ */
+static void handle_quickfix(mparm_T *paramp)
+{
+ if (paramp->edit_type == EDIT_QF) {
+ if (paramp->use_ef != NULL)
+ set_string_option_direct((char_u *)"ef", -1,
+ paramp->use_ef, OPT_FREE, SID_CARG);
+ vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
+ if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0) {
+ out_char('\n');
+ mch_exit(3);
+ }
+ TIME_MSG("reading errorfile");
+ }
+}
+
+/*
+ * Need to jump to the tag before executing the '-c command'.
+ * Makes "vim -c '/return' -t main" work.
+ */
+static void handle_tag(char_u *tagname)
+{
+ if (tagname != NULL) {
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ swap_exists_did_quit = FALSE;
+#endif
+
+ vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname);
+ do_cmdline_cmd(IObuff);
+ TIME_MSG("jumping to tag");
+
+#if defined(HAS_SWAP_EXISTS_ACTION)
+ /* If the user doesn't want to edit the file then we quit here. */
+ if (swap_exists_did_quit)
+ getout(1);
+#endif
+ }
}
/*
* Print a warning if stdout is not a terminal.
* When starting in Ex mode and commands come from a file, set Silent mode.
*/
-static void check_tty(parmp)
- mparm_T *parmp;
+static void check_tty(mparm_T *parmp)
{
int input_isatty; /* is active input a terminal? */
@@ -1531,7 +1655,7 @@ static void check_tty(parmp)
/*
* Read text from stdin.
*/
-static void read_stdin() {
+static void read_stdin(void) {
int i;
#if defined(HAS_SWAP_EXISTS_ACTION)
@@ -1561,8 +1685,7 @@ static void read_stdin() {
* Create the requested number of windows and edit buffers in them.
* Also does recovery if "recoverymode" set.
*/
-static void create_windows(parmp)
- mparm_T *parmp UNUSED;
+static void create_windows(mparm_T *parmp)
{
int dorewind;
int done = 0;
@@ -1677,8 +1800,7 @@ static void create_windows(parmp)
* If opened more than one window, start editing files in the other
* windows. make_windows() has already opened the windows.
*/
-static void edit_buffers(parmp)
- mparm_T *parmp;
+static void edit_buffers(mparm_T *parmp)
{
int arg_idx; /* index in argument list */
int i;
@@ -1780,8 +1902,7 @@ static void edit_buffers(parmp)
/*
* Execute the commands from --cmd arguments "cmds[cnt]".
*/
-static void exe_pre_commands(parmp)
- mparm_T *parmp;
+static void exe_pre_commands(mparm_T *parmp)
{
char_u **cmds = parmp->pre_commands;
int cnt = parmp->n_pre_commands;
@@ -1802,8 +1923,7 @@ static void exe_pre_commands(parmp)
/*
* Execute "+", "-c" and "-S" arguments.
*/
-static void exe_commands(parmp)
- mparm_T *parmp;
+static void exe_commands(mparm_T *parmp)
{
int i;
@@ -1839,8 +1959,7 @@ static void exe_commands(parmp)
/*
* Source startup scripts.
*/
-static void source_startup_scripts(parmp)
- mparm_T *parmp;
+static void source_startup_scripts(mparm_T *parmp)
{
int i;
@@ -1969,21 +2088,23 @@ static void source_startup_scripts(parmp)
/*
* Setup to start using the GUI. Exit with an error when not available.
*/
-static void main_start_gui() {
+static void main_start_gui(void) {
mch_errmsg(_(e_nogvim));
mch_errmsg("\n");
mch_exit(2);
}
-#endif /* NO_VIM_MAIN */
+#endif /* NO_VIM_MAIN */
/*
* Get an environment variable, and execute it as Ex commands.
* Returns FAIL if the environment variable was not executed, OK otherwise.
*/
-int process_env(env, is_viminit)
- char_u *env;
- int is_viminit; /* when TRUE, called for VIMINIT */
+int
+process_env (
+ char_u *env,
+ int is_viminit /* when TRUE, called for VIMINIT */
+)
{
char_u *initstr;
char_u *save_sourcing_name;
@@ -2014,8 +2135,7 @@ int process_env(env, is_viminit)
* Used for ".vimrc" and ".exrc".
* Use both stat() and lstat() for extra security.
*/
-static int file_owned(fname)
- char *fname;
+static int file_owned(char *fname)
{
struct stat s;
# ifdef UNIX
@@ -2035,9 +2155,11 @@ static int file_owned(fname)
/*
* Give an error message main_errors["n"] and exit.
*/
-static void mainerr(n, str)
- int n; /* one of the ME_ defines */
- char_u *str; /* extra argument or NULL */
+static void
+mainerr (
+ int n, /* one of the ME_ defines */
+ char_u *str /* extra argument or NULL */
+)
{
#if defined(UNIX) || defined(__EMX__) || defined(VMS)
reset_signals(); /* kill us with CTRL-C here, if you like */
@@ -2056,8 +2178,7 @@ static void mainerr(n, str)
mch_exit(1);
}
-void mainerr_arg_missing(str)
- char_u *str;
+void mainerr_arg_missing(char_u *str)
{
mainerr(ME_ARG_MISSING, str);
}
@@ -2066,8 +2187,7 @@ void mainerr_arg_missing(str)
/*
* print a message with three spaces prepended and '\n' appended.
*/
-static void main_msg(s)
- char *s;
+static void main_msg(char *s)
{
mch_msg(" ");
mch_msg(s);
@@ -2077,7 +2197,7 @@ static void main_msg(s)
/*
* Print messages for "vim -h" or "vim --help" and exit.
*/
-static void usage() {
+static void usage(void) {
int i;
static char *(use[]) =
{
@@ -2166,7 +2286,7 @@ static void usage() {
* When "Quit" selected, exit Vim.
* When "Recover" selected, recover the file.
*/
-static void check_swap_exists_action() {
+static void check_swap_exists_action(void) {
if (swap_exists_action == SEA_QUIT)
getout(1);
handle_swap_exists(NULL);
@@ -2186,8 +2306,7 @@ static struct timeval prev_timeval;
* Save the previous time before doing something that could nest.
* set "*tv_rel" to the time elapsed so far.
*/
-void time_push(tv_rel, tv_start)
- void *tv_rel, *tv_start;
+void time_push(void *tv_rel, void *tv_start)
{
*((struct timeval *)tv_rel) = prev_timeval;
gettimeofday(&prev_timeval, NULL);
@@ -2208,8 +2327,10 @@ void time_push(tv_rel, tv_start)
* Note: The arguments are (void *) to avoid trouble with systems that don't
* have struct timeval.
*/
-void time_pop(tp)
- void *tp; /* actually (struct timeval *) */
+void
+time_pop (
+ void *tp /* actually (struct timeval *) */
+)
{
prev_timeval.tv_usec -= ((struct timeval *)tp)->tv_usec;
prev_timeval.tv_sec -= ((struct timeval *)tp)->tv_sec;
@@ -2219,9 +2340,7 @@ void time_pop(tp)
}
}
-static void time_diff(then, now)
- struct timeval *then;
- struct timeval *now;
+static void time_diff(struct timeval *then, struct timeval *now)
{
long usec;
long msec;
@@ -2232,10 +2351,12 @@ static void time_diff(then, now)
fprintf(time_fd, "%03ld.%03ld", msec, usec >= 0 ? usec : usec + 1000L);
}
-void time_msg(mesg, tv_start)
- char *mesg;
- void *tv_start; /* only for do_source: start time; actually
+void
+time_msg (
+ char *mesg,
+ void *tv_start /* only for do_source: start time; actually
(struct timeval *) */
+)
{
static struct timeval start;
struct timeval now;
diff --git a/src/proto/main.pro b/src/main.h
index a93b8de2ae..1e407ae154 100644
--- a/src/proto/main.pro
+++ b/src/main.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MAIN_H
+#define NEOVIM_MAIN_H
/* main.c */
void main_loop __ARGS((int cmdwin, int noexmode));
void getout_preserve_modified __ARGS((int exitval));
@@ -25,3 +27,4 @@ void farsi_fkey __ARGS((cmdarg_T *cap));
int arabic_shape __ARGS((int c, int *ccp, int *c1p, int prev_c, int prev_c1,
int next_c));
/* vim: set ft=c : */
+#endif /* NEOVIM_MAIN_H */
diff --git a/src/mark.c b/src/mark.c
index 67d962dc9e..db274cda50 100644
--- a/src/mark.c
+++ b/src/mark.c
@@ -12,6 +12,25 @@
*/
#include "vim.h"
+#include "mark.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "fileio.h"
+#include "fold.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "quickfix.h"
+#include "search.h"
+#include "term.h"
+#include "ui.h"
+#include "os/os.h"
/*
* This file contains routines to maintain and manipulate marks.
@@ -38,8 +57,7 @@ static void write_one_filemark __ARGS((FILE *fp, xfmark_T *fm, int c1, int c2));
* Set named mark "c" at current cursor position.
* Returns OK on success, FAIL if bad name given.
*/
-int setmark(c)
-int c;
+int setmark(int c)
{
return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
}
@@ -49,10 +67,7 @@ int c;
* When "c" is upper case use file "fnum".
* Returns OK on success, FAIL if bad name given.
*/
-int setmark_pos(c, pos, fnum)
-int c;
-pos_T *pos;
-int fnum;
+int setmark_pos(int c, pos_T *pos, int fnum)
{
int i;
@@ -120,7 +135,7 @@ int fnum;
* Set the previous context mark to the current position and add it to the
* jump list.
*/
-void setpcmark() {
+void setpcmark(void) {
int i;
xfmark_T *fm;
#ifdef JUMPLIST_ROTATE
@@ -172,7 +187,7 @@ void setpcmark() {
* context will only be changed if the cursor moved to a different line.
* If pcmark was deleted (with "dG") the previous mark is restored.
*/
-void checkpcmark() {
+void checkpcmark(void) {
if (curwin->w_prev_pcmark.lnum != 0
&& (equalpos(curwin->w_pcmark, curwin->w_cursor)
|| curwin->w_pcmark.lnum == 0)) {
@@ -184,8 +199,7 @@ void checkpcmark() {
/*
* move "count" positions in the jump list (count may be negative)
*/
-pos_T * movemark(count)
-int count;
+pos_T *movemark(int count)
{
pos_T *pos;
xfmark_T *jmp;
@@ -238,8 +252,7 @@ int count;
/*
* Move "count" positions in the changelist (count may be negative).
*/
-pos_T * movechangelist(count)
-int count;
+pos_T *movechangelist(int count)
{
int n;
@@ -272,26 +285,17 @@ int count;
* - NULL if there is no mark called 'c'.
* - -1 if mark is in other file and jumped there (only if changefile is TRUE)
*/
-pos_T * getmark_buf(buf, c, changefile)
-buf_T *buf;
-int c;
-int changefile;
+pos_T *getmark_buf(buf_T *buf, int c, int changefile)
{
return getmark_buf_fnum(buf, c, changefile, NULL);
}
-pos_T * getmark(c, changefile)
-int c;
-int changefile;
+pos_T *getmark(int c, int changefile)
{
return getmark_buf_fnum(curbuf, c, changefile, NULL);
}
-pos_T * getmark_buf_fnum(buf, c, changefile, fnum)
-buf_T *buf;
-int c;
-int changefile;
-int *fnum;
+pos_T *getmark_buf_fnum(buf_T *buf, int c, int changefile, int *fnum)
{
pos_T *posp;
pos_T *startp, *endp;
@@ -404,10 +408,12 @@ int *fnum;
*
* Returns pointer to pos_T of the next mark or NULL if no mark is found.
*/
-pos_T * getnextmark(startpos, dir, begin_line)
-pos_T *startpos; /* where to start */
-int dir; /* direction for search */
-int begin_line;
+pos_T *
+getnextmark (
+ pos_T *startpos, /* where to start */
+ int dir, /* direction for search */
+ int begin_line
+)
{
int i;
pos_T *result = NULL;
@@ -446,8 +452,7 @@ int begin_line;
* This is used for marks obtained from the .viminfo file. It's postponed
* until the mark is used to avoid a long startup delay.
*/
-static void fname2fnum(fm)
-xfmark_T *fm;
+static void fname2fnum(xfmark_T *fm)
{
char_u *p;
@@ -483,8 +488,7 @@ xfmark_T *fm;
* May replace the name with an fnum.
* Used for marks that come from the .viminfo file.
*/
-void fmarks_check_names(buf)
-buf_T *buf;
+void fmarks_check_names(buf_T *buf)
{
char_u *name;
int i;
@@ -509,10 +513,7 @@ buf_T *buf;
vim_free(name);
}
-static void fmarks_check_one(fm, name, buf)
-xfmark_T *fm;
-char_u *name;
-buf_T *buf;
+static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf)
{
if (fm->fmark.fnum == 0
&& fm->fname != NULL
@@ -527,8 +528,7 @@ buf_T *buf;
* Check a if a position from a mark is valid.
* Give and error message and return FAIL if not.
*/
-int check_mark(pos)
-pos_T *pos;
+int check_mark(pos_T *pos)
{
if (pos == NULL) {
EMSG(_(e_umark));
@@ -553,8 +553,7 @@ pos_T *pos;
*
* Used mainly when trashing the entire buffer during ":e" type commands
*/
-void clrallmarks(buf)
-buf_T *buf;
+void clrallmarks(buf_T *buf)
{
static int i = -1;
@@ -581,9 +580,7 @@ buf_T *buf;
* When it's in the current buffer, return the text at the mark.
* Returns an allocated string.
*/
-char_u * fm_getname(fmark, lead_len)
-fmark_T *fmark;
-int lead_len;
+char_u *fm_getname(fmark_T *fmark, int lead_len)
{
if (fmark->fnum == curbuf->b_fnum) /* current buffer */
return mark_line(&(fmark->mark), lead_len);
@@ -594,9 +591,7 @@ int lead_len;
* Return the line at mark "mp". Truncate to fit in window.
* The returned string has been allocated.
*/
-static char_u * mark_line(mp, lead_len)
-pos_T *mp;
-int lead_len;
+static char_u *mark_line(pos_T *mp, int lead_len)
{
char_u *s, *p;
int len;
@@ -620,8 +615,7 @@ int lead_len;
/*
* print the marks
*/
-void do_marks(eap)
-exarg_T *eap;
+void do_marks(exarg_T *eap)
{
char_u *arg = eap->arg;
int i;
@@ -656,12 +650,14 @@ exarg_T *eap;
show_one_mark(-1, arg, NULL, NULL, FALSE);
}
-static void show_one_mark(c, arg, p, name, current)
-int c;
-char_u *arg;
-pos_T *p;
-char_u *name;
-int current; /* in current file */
+static void
+show_one_mark (
+ int c,
+ char_u *arg,
+ pos_T *p,
+ char_u *name,
+ int current /* in current file */
+)
{
static int did_title = FALSE;
int mustfree = FALSE;
@@ -706,8 +702,7 @@ int current; /* in current file */
/*
* ":delmarks[!] [marks]"
*/
-void ex_delmarks(eap)
-exarg_T *eap;
+void ex_delmarks(exarg_T *eap)
{
char_u *p;
int from, to;
@@ -778,8 +773,7 @@ exarg_T *eap;
/*
* print the jumplist
*/
-void ex_jumps(eap)
-exarg_T *eap UNUSED;
+void ex_jumps(exarg_T *eap)
{
int i;
char_u *name;
@@ -822,8 +816,7 @@ exarg_T *eap UNUSED;
/*
* print the changelist
*/
-void ex_changes(eap)
-exarg_T *eap UNUSED;
+void ex_changes(exarg_T *eap)
{
int i;
char_u *name;
@@ -896,11 +889,7 @@ exarg_T *eap UNUSED;
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
* or: mark_adjust(56, 55, MAXLNUM, 2);
*/
-void mark_adjust(line1, line2, amount, amount_after)
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
{
int i;
int fnum = curbuf->b_fnum;
@@ -1043,11 +1032,7 @@ long amount_after;
* "lnum_amount" to the line number and add "col_amount" to the column
* position.
*/
-void mark_col_adjust(lnum, mincol, lnum_amount, col_amount)
-linenr_T lnum;
-colnr_T mincol;
-long lnum_amount;
-long col_amount;
+void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_amount)
{
int i;
int fnum = curbuf->b_fnum;
@@ -1118,7 +1103,7 @@ long col_amount;
* When deleting lines, this may create duplicate marks in the
* jumplist. They will be removed here for the current window.
*/
-static void cleanup_jumplist() {
+static void cleanup_jumplist(void) {
int i;
int from, to;
@@ -1146,9 +1131,7 @@ static void cleanup_jumplist() {
/*
* Copy the jumplist from window "from" to window "to".
*/
-void copy_jumplist(from, to)
-win_T *from;
-win_T *to;
+void copy_jumplist(win_T *from, win_T *to)
{
int i;
@@ -1164,8 +1147,7 @@ win_T *to;
/*
* Free items in the jumplist of window "wp".
*/
-void free_jumplist(wp)
-win_T *wp;
+void free_jumplist(win_T *wp)
{
int i;
@@ -1173,15 +1155,14 @@ win_T *wp;
vim_free(wp->w_jumplist[i].fname);
}
-void set_last_cursor(win)
-win_T *win;
+void set_last_cursor(win_T *win)
{
if (win->w_buffer != NULL)
win->w_buffer->b_last_cursor = win->w_cursor;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_all_marks() {
+void free_all_marks(void) {
int i;
for (i = 0; i < NMARKS + EXTRA_MARKS; i++)
@@ -1191,9 +1172,7 @@ void free_all_marks() {
#endif
-int read_viminfo_filemark(virp, force)
-vir_T *virp;
-int force;
+int read_viminfo_filemark(vir_T *virp, int force)
{
char_u *str;
xfmark_T *fm;
@@ -1239,8 +1218,7 @@ int force;
return vim_fgets(virp->vir_line, LSIZE, virp->vir_fd);
}
-void write_viminfo_filemarks(fp)
-FILE *fp;
+void write_viminfo_filemarks(FILE *fp)
{
int i;
char_u *name;
@@ -1295,11 +1273,7 @@ FILE *fp;
}
}
-static void write_one_filemark(fp, fm, c1, c2)
-FILE *fp;
-xfmark_T *fm;
-int c1;
-int c2;
+static void write_one_filemark(FILE *fp, xfmark_T *fm, int c1, int c2)
{
char_u *name;
@@ -1323,8 +1297,7 @@ int c2;
/*
* Return TRUE if "name" is on removable media (depending on 'viminfo').
*/
-int removable(name)
-char_u *name;
+int removable(char_u *name)
{
char_u *p;
char_u part[51];
@@ -1354,8 +1327,7 @@ static void write_one_mark __ARGS((FILE *fp_out, int c, pos_T *pos));
* Write all the named marks for all buffers.
* Return the number of buffers for which marks have been written.
*/
-int write_viminfo_marks(fp_out)
-FILE *fp_out;
+int write_viminfo_marks(FILE *fp_out)
{
int count;
buf_T *buf;
@@ -1409,10 +1381,7 @@ FILE *fp_out;
return count;
}
-static void write_one_mark(fp_out, c, pos)
-FILE *fp_out;
-int c;
-pos_T *pos;
+static void write_one_mark(FILE *fp_out, int c, pos_T *pos)
{
if (pos->lnum != 0)
fprintf(fp_out, "\t%c\t%ld\t%d\n", c, (long)pos->lnum, (int)pos->col);
@@ -1424,12 +1393,7 @@ pos_T *pos;
* fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only
* fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles
*/
-void copy_viminfo_marks(virp, fp_out, count, eof, flags)
-vir_T *virp;
-FILE *fp_out;
-int count;
-int eof;
-int flags;
+void copy_viminfo_marks(vir_T *virp, FILE *fp_out, int count, int eof, int flags)
{
char_u *line = virp->vir_line;
buf_T *buf;
diff --git a/src/proto/mark.pro b/src/mark.h
index 47623f4847..f78a41bbc4 100644
--- a/src/proto/mark.pro
+++ b/src/mark.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MARK_H
+#define NEOVIM_MARK_H
/* mark.c */
int setmark __ARGS((int c));
int setmark_pos __ARGS((int c, pos_T *pos, int fnum));
@@ -32,3 +34,4 @@ int write_viminfo_marks __ARGS((FILE *fp_out));
void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof,
int flags));
/* vim: set ft=c : */
+#endif /* NEOVIM_MARK_H */
diff --git a/src/mbyte.c b/src/mbyte.c
index 8b7abe15ee..8a1fbef901 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -78,6 +78,17 @@
*/
#include "vim.h"
+#include "mbyte.h"
+#include "charset.h"
+#include "fileio.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "screen.h"
+#include "spell.h"
+#include "ui.h"
# define WINBYTE BYTE
@@ -380,8 +391,7 @@ enc_alias_table[] =
* Find encoding "name" in the list of canonical encoding names.
* Returns -1 if not found.
*/
-static int enc_canon_search(name)
-char_u *name;
+static int enc_canon_search(char_u *name)
{
int i;
@@ -397,8 +407,7 @@ char_u *name;
* Find canonical encoding "name" in the list and return its properties.
* Returns 0 if not found.
*/
-int enc_canon_props(name)
-char_u *name;
+int enc_canon_props(char_u *name)
{
int i;
@@ -445,7 +454,7 @@ char_u * mb_init() {
output_conv.vc_type = CONV_NONE;
return NULL;
} else if (STRNCMP(p_enc, "8bit-", 5) == 0
- || STRNCMP(p_enc, "iso-8859-", 9) == 0) {
+ || STRNCMP(p_enc, "iso-8859-", 9) == 0) {
/* Accept any "8bit-" or "iso-8859-" name. */
enc_unicode = 0;
enc_utf8 = FALSE;
@@ -484,7 +493,7 @@ char_u * mb_init() {
/* Detect an encoding that uses latin1 characters. */
enc_latin1like = (enc_utf8 || STRCMP(p_enc, "latin1") == 0
- || STRCMP(p_enc, "iso-8859-15") == 0);
+ || STRCMP(p_enc, "iso-8859-15") == 0);
/*
* Set the function pointers.
@@ -651,7 +660,7 @@ int bomb_size() {
} else if (STRCMP(curbuf->b_p_fenc, "utf-8") == 0)
n = 3;
else if (STRNCMP(curbuf->b_p_fenc, "ucs-2", 5) == 0
- || STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0)
+ || STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0)
n = 2;
else if (STRNCMP(curbuf->b_p_fenc, "ucs-4", 5) == 0)
n = 4;
@@ -662,8 +671,7 @@ int bomb_size() {
/*
* Remove all BOM from "s" by moving remaining text.
*/
-void remove_bom(s)
-char_u *s;
+void remove_bom(char_u *s)
{
if (enc_utf8) {
char_u *p = s;
@@ -684,15 +692,12 @@ char_u *s;
* 2 for an (ASCII) word character
* >2 for other word characters
*/
-int mb_get_class(p)
-char_u *p;
+int mb_get_class(char_u *p)
{
return mb_get_class_buf(p, curbuf);
}
-int mb_get_class_buf(p, buf)
-char_u *p;
-buf_T *buf;
+int mb_get_class_buf(char_u *p, buf_T *buf)
{
if (MB_BYTE2LEN(p[0]) == 1) {
if (p[0] == NUL || vim_iswhite(p[0]))
@@ -712,143 +717,141 @@ buf_T *buf;
* Get class of a double-byte character. This always returns 3 or bigger.
* TODO: Should return 1 for punctuation.
*/
-int dbcs_class(lead, trail)
-unsigned lead;
-unsigned trail;
+int dbcs_class(unsigned lead, unsigned trail)
{
switch (enc_dbcs) {
- /* please add classify routine for your language in here */
-
- case DBCS_JPNU: /* ? */
- case DBCS_JPN:
- {
- /* JIS code classification */
- unsigned char lb = lead;
- unsigned char tb = trail;
-
- /* convert process code to JIS */
- /*
- * XXX: Code page identification can not use with all
- * system! So, some other encoding information
- * will be needed.
- * In japanese: SJIS,EUC,UNICODE,(JIS)
- * Note that JIS-code system don't use as
- * process code in most system because it uses
- * escape sequences(JIS is context depend encoding).
- */
- /* assume process code is JAPANESE-EUC */
- lb &= 0x7f;
- tb &= 0x7f;
- /* exceptions */
- switch (lb << 8 | tb) {
- case 0x2121: /* ZENKAKU space */
- return 0;
- case 0x2122: /* TOU-TEN (Japanese comma) */
- case 0x2123: /* KU-TEN (Japanese period) */
- case 0x2124: /* ZENKAKU comma */
- case 0x2125: /* ZENKAKU period */
- return 1;
- case 0x213c: /* prolongedsound handled as KATAKANA */
- return 13;
- }
- /* sieved by KU code */
- switch (lb) {
- case 0x21:
- case 0x22:
- /* special symbols */
- return 10;
- case 0x23:
- /* alpha-numeric */
- return 11;
- case 0x24:
- /* hiragana */
- return 12;
- case 0x25:
- /* katakana */
- return 13;
- case 0x26:
- /* greek */
- return 14;
- case 0x27:
- /* russian */
- return 15;
- case 0x28:
- /* lines */
- return 16;
- default:
- /* kanji */
- return 17;
- }
- }
-
- case DBCS_KORU: /* ? */
- case DBCS_KOR:
- {
- /* KS code classification */
- unsigned char c1 = lead;
- unsigned char c2 = trail;
-
- /*
- * 20 : Hangul
- * 21 : Hanja
- * 22 : Symbols
- * 23 : Alpha-numeric/Roman Letter (Full width)
- * 24 : Hangul Letter(Alphabet)
- * 25 : Roman Numeral/Greek Letter
- * 26 : Box Drawings
- * 27 : Unit Symbols
- * 28 : Circled/Parenthesized Letter
- * 29 : Hiragana/Katakana
- * 30 : Cyrillic Letter
- */
+ /* please add classify routine for your language in here */
+
+ case DBCS_JPNU: /* ? */
+ case DBCS_JPN:
+ {
+ /* JIS code classification */
+ unsigned char lb = lead;
+ unsigned char tb = trail;
+
+ /* convert process code to JIS */
+ /*
+ * XXX: Code page identification can not use with all
+ * system! So, some other encoding information
+ * will be needed.
+ * In japanese: SJIS,EUC,UNICODE,(JIS)
+ * Note that JIS-code system don't use as
+ * process code in most system because it uses
+ * escape sequences(JIS is context depend encoding).
+ */
+ /* assume process code is JAPANESE-EUC */
+ lb &= 0x7f;
+ tb &= 0x7f;
+ /* exceptions */
+ switch (lb << 8 | tb) {
+ case 0x2121: /* ZENKAKU space */
+ return 0;
+ case 0x2122: /* TOU-TEN (Japanese comma) */
+ case 0x2123: /* KU-TEN (Japanese period) */
+ case 0x2124: /* ZENKAKU comma */
+ case 0x2125: /* ZENKAKU period */
+ return 1;
+ case 0x213c: /* prolongedsound handled as KATAKANA */
+ return 13;
+ }
+ /* sieved by KU code */
+ switch (lb) {
+ case 0x21:
+ case 0x22:
+ /* special symbols */
+ return 10;
+ case 0x23:
+ /* alpha-numeric */
+ return 11;
+ case 0x24:
+ /* hiragana */
+ return 12;
+ case 0x25:
+ /* katakana */
+ return 13;
+ case 0x26:
+ /* greek */
+ return 14;
+ case 0x27:
+ /* russian */
+ return 15;
+ case 0x28:
+ /* lines */
+ return 16;
+ default:
+ /* kanji */
+ return 17;
+ }
+ }
- if (c1 >= 0xB0 && c1 <= 0xC8)
- /* Hangul */
- return 20;
-
- else if (c1 >= 0xCA && c1 <= 0xFD)
- /* Hanja */
- return 21;
- else switch (c1) {
- case 0xA1:
- case 0xA2:
- /* Symbols */
- return 22;
- case 0xA3:
- /* Alpha-numeric */
- return 23;
- case 0xA4:
- /* Hangul Letter(Alphabet) */
- return 24;
- case 0xA5:
- /* Roman Numeral/Greek Letter */
- return 25;
- case 0xA6:
- /* Box Drawings */
- return 26;
- case 0xA7:
- /* Unit Symbols */
- return 27;
- case 0xA8:
- case 0xA9:
- if (c2 <= 0xAF)
- return 25; /* Roman Letter */
- else if (c2 >= 0xF6)
- return 22; /* Symbols */
- else
- /* Circled/Parenthesized Letter */
- return 28;
- case 0xAA:
- case 0xAB:
- /* Hiragana/Katakana */
- return 29;
- case 0xAC:
- /* Cyrillic Letter */
- return 30;
+ case DBCS_KORU: /* ? */
+ case DBCS_KOR:
+ {
+ /* KS code classification */
+ unsigned char c1 = lead;
+ unsigned char c2 = trail;
+
+ /*
+ * 20 : Hangul
+ * 21 : Hanja
+ * 22 : Symbols
+ * 23 : Alpha-numeric/Roman Letter (Full width)
+ * 24 : Hangul Letter(Alphabet)
+ * 25 : Roman Numeral/Greek Letter
+ * 26 : Box Drawings
+ * 27 : Unit Symbols
+ * 28 : Circled/Parenthesized Letter
+ * 29 : Hiragana/Katakana
+ * 30 : Cyrillic Letter
+ */
+
+ if (c1 >= 0xB0 && c1 <= 0xC8)
+ /* Hangul */
+ return 20;
+
+ else if (c1 >= 0xCA && c1 <= 0xFD)
+ /* Hanja */
+ return 21;
+ else switch (c1) {
+ case 0xA1:
+ case 0xA2:
+ /* Symbols */
+ return 22;
+ case 0xA3:
+ /* Alpha-numeric */
+ return 23;
+ case 0xA4:
+ /* Hangul Letter(Alphabet) */
+ return 24;
+ case 0xA5:
+ /* Roman Numeral/Greek Letter */
+ return 25;
+ case 0xA6:
+ /* Box Drawings */
+ return 26;
+ case 0xA7:
+ /* Unit Symbols */
+ return 27;
+ case 0xA8:
+ case 0xA9:
+ if (c2 <= 0xAF)
+ return 25; /* Roman Letter */
+ else if (c2 >= 0xF6)
+ return 22; /* Symbols */
+ else
+ /* Circled/Parenthesized Letter */
+ return 28;
+ case 0xAA:
+ case 0xAB:
+ /* Hiragana/Katakana */
+ return 29;
+ case 0xAC:
+ /* Cyrillic Letter */
+ return 30;
+ }
}
- }
- default:
- break;
+ default:
+ break;
}
return 3;
}
@@ -858,14 +861,12 @@ unsigned trail;
* Return length in bytes of character "c".
* Returns 1 for a single-byte character.
*/
-int latin_char2len(c)
-int c UNUSED;
+int latin_char2len(int c)
{
return 1;
}
-static int dbcs_char2len(c)
-int c;
+static int dbcs_char2len(int c)
{
if (c >= 0x100)
return 2;
@@ -877,17 +878,13 @@ int c;
* Convert a character to its bytes.
* Returns the length in bytes.
*/
-int latin_char2bytes(c, buf)
-int c;
-char_u *buf;
+int latin_char2bytes(int c, char_u *buf)
{
buf[0] = c;
return 1;
}
-static int dbcs_char2bytes(c, buf)
-int c;
-char_u *buf;
+static int dbcs_char2bytes(int c, char_u *buf)
{
if (c >= 0x100) {
buf[0] = (unsigned)c >> 8;
@@ -908,14 +905,12 @@ char_u *buf;
* For UTF-8 this includes following composing characters.
* Returns 0 when *p is NUL.
*/
-int latin_ptr2len(p)
-char_u *p;
+int latin_ptr2len(char_u *p)
{
return MB_BYTE2LEN(*p);
}
-static int dbcs_ptr2len(p)
-char_u *p;
+static int dbcs_ptr2len(char_u *p)
{
int len;
@@ -932,18 +927,14 @@ char_u *p;
* Returns 0 for an empty string.
* Returns 1 for an illegal char or an incomplete byte sequence.
*/
-int latin_ptr2len_len(p, size)
-char_u *p;
-int size;
+int latin_ptr2len_len(char_u *p, int size)
{
if (size < 1 || *p == NUL)
return 0;
return 1;
}
-static int dbcs_ptr2len_len(p, size)
-char_u *p;
-int size;
+static int dbcs_ptr2len_len(char_u *p, int size)
{
int len;
@@ -967,10 +958,7 @@ static int intable __ARGS((struct interval *table, size_t size, int c));
/*
* Return TRUE if "c" is in "table[size / sizeof(struct interval)]".
*/
-static int intable(table, size, c)
-struct interval *table;
-size_t size;
-int c;
+static int intable(struct interval *table, size_t size, int c)
{
int mid, bot, top;
@@ -1000,8 +988,7 @@ int c;
* When p_ambw is "double", return 2 for a character with East Asian Width
* class 'A'(mbiguous).
*/
-int utf_char2cells(c)
-int c;
+int utf_char2cells(int c)
{
/* Sorted list of non-overlapping intervals of East Asian double width
* characters, generated with ../runtime/tools/unicode.vim. */
@@ -1267,14 +1254,12 @@ int c;
* Return the number of display cells character at "*p" occupies.
* This doesn't take care of unprintable characters, use ptr2cells() for that.
*/
-int latin_ptr2cells(p)
-char_u *p UNUSED;
+int latin_ptr2cells(char_u *p)
{
return 1;
}
-int utf_ptr2cells(p)
-char_u *p;
+int utf_ptr2cells(char_u *p)
{
int c;
@@ -1292,8 +1277,7 @@ char_u *p;
return 1;
}
-int dbcs_ptr2cells(p)
-char_u *p;
+int dbcs_ptr2cells(char_u *p)
{
/* Number of cells is equal to number of bytes, except for euc-jp when
* the first byte is 0x8e. */
@@ -1307,16 +1291,12 @@ char_u *p;
* Like mb_ptr2cells(), but limit string length to "size".
* For an empty string or truncated character returns 1.
*/
-int latin_ptr2cells_len(p, size)
-char_u *p UNUSED;
-int size UNUSED;
+int latin_ptr2cells_len(char_u *p, int size)
{
return 1;
}
-static int utf_ptr2cells_len(p, size)
-char_u *p;
-int size;
+static int utf_ptr2cells_len(char_u *p, int size)
{
int c;
@@ -1336,9 +1316,7 @@ int size;
return 1;
}
-static int dbcs_ptr2cells_len(p, size)
-char_u *p;
-int size;
+static int dbcs_ptr2cells_len(char_u *p, int size)
{
/* Number of cells is equal to number of bytes, except for euc-jp when
* the first byte is 0x8e. */
@@ -1352,14 +1330,12 @@ int size;
* Return the number of display cells character "c" occupies.
* Only takes care of multi-byte chars, not "^C" and such.
*/
-int latin_char2cells(c)
-int c UNUSED;
+int latin_char2cells(int c)
{
return 1;
}
-static int dbcs_char2cells(c)
-int c;
+static int dbcs_char2cells(int c)
{
/* Number of cells is equal to number of bytes, except for euc-jp when
* the first byte is 0x8e. */
@@ -1373,9 +1349,7 @@ int c;
* Return the number of cells occupied by string "p".
* Stop at a NUL character. When "len" >= 0 stop at character "p[len]".
*/
-int mb_string2cells(p, len)
-char_u *p;
-int len;
+int mb_string2cells(char_u *p, int len)
{
int i;
int clen = 0;
@@ -1390,16 +1364,12 @@ int len;
* Return number of display cells for char at ScreenLines[off].
* We make sure that the offset used is less than "max_off".
*/
-int latin_off2cells(off, max_off)
-unsigned off UNUSED;
-unsigned max_off UNUSED;
+int latin_off2cells(unsigned off, unsigned max_off)
{
return 1;
}
-int dbcs_off2cells(off, max_off)
-unsigned off;
-unsigned max_off;
+int dbcs_off2cells(unsigned off, unsigned max_off)
{
/* never check beyond end of the line */
if (off >= max_off)
@@ -1412,9 +1382,7 @@ unsigned max_off;
return MB_BYTE2LEN(ScreenLines[off]);
}
-int utf_off2cells(off, max_off)
-unsigned off;
-unsigned max_off;
+int utf_off2cells(unsigned off, unsigned max_off)
{
return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
}
@@ -1423,14 +1391,12 @@ unsigned max_off;
* mb_ptr2char() function pointer.
* Convert a byte sequence into a character.
*/
-int latin_ptr2char(p)
-char_u *p;
+int latin_ptr2char(char_u *p)
{
return *p;
}
-static int dbcs_ptr2char(p)
-char_u *p;
+static int dbcs_ptr2char(char_u *p)
{
if (MB_BYTE2LEN(*p) > 1 && p[1] != NUL)
return (p[0] << 8) + p[1];
@@ -1443,8 +1409,7 @@ char_u *p;
* returned.
* Does not include composing characters, of course.
*/
-int utf_ptr2char(p)
-char_u *p;
+int utf_ptr2char(char_u *p)
{
int len;
@@ -1458,20 +1423,20 @@ char_u *p;
if ((p[2] & 0xc0) == 0x80) {
if (len == 3)
return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
- + (p[2] & 0x3f);
+ + (p[2] & 0x3f);
if ((p[3] & 0xc0) == 0x80) {
if (len == 4)
return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
- + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
+ + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
if ((p[4] & 0xc0) == 0x80) {
if (len == 5)
return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
- + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
- + (p[4] & 0x3f);
+ + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
+ + (p[4] & 0x3f);
if ((p[5] & 0xc0) == 0x80 && len == 6)
return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
- + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
- + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
+ + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
+ + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
}
}
}
@@ -1496,9 +1461,7 @@ char_u *p;
* If byte sequence is illegal or incomplete, returns -1 and does not advance
* "s".
*/
-static int utf_safe_read_char_adv(s, n)
-char_u **s;
-size_t *n;
+static int utf_safe_read_char_adv(char_u **s, size_t *n)
{
int c, k;
@@ -1540,8 +1503,7 @@ size_t *n;
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are skipped!
*/
-int mb_ptr2char_adv(pp)
-char_u **pp;
+int mb_ptr2char_adv(char_u **pp)
{
int c;
@@ -1554,8 +1516,7 @@ char_u **pp;
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are returned as separate characters.
*/
-int mb_cptr2char_adv(pp)
-char_u **pp;
+int mb_cptr2char_adv(char_u **pp)
{
int c;
@@ -1571,9 +1532,10 @@ char_u **pp;
* Check whether we are dealing with Arabic combining characters.
* Note: these are NOT really composing characters!
*/
-int arabic_combine(one, two)
-int one; /* first character */
-int two; /* character just after "one" */
+int arabic_combine(
+ int one, /* first character */
+ int two /* character just after "one" */
+ )
{
if (one == a_LAM)
return arabic_maycombine(two);
@@ -1584,14 +1546,13 @@ int two; /* character just after "one" */
* Check whether we are dealing with a character that could be regarded as an
* Arabic combining character, need to check the character before this.
*/
-int arabic_maycombine(two)
-int two;
+int arabic_maycombine(int two)
{
if (p_arshape && !p_tbidi)
return two == a_ALEF_MADDA
- || two == a_ALEF_HAMZA_ABOVE
- || two == a_ALEF_HAMZA_BELOW
- || two == a_ALEF;
+ || two == a_ALEF_HAMZA_ABOVE
+ || two == a_ALEF_HAMZA_BELOW
+ || two == a_ALEF;
return FALSE;
}
@@ -1600,9 +1561,7 @@ int two;
* comes after "p1". For Arabic sometimes "ab" is replaced with "c", which
* behaves like a composing character.
*/
-int utf_composinglike(p1, p2)
-char_u *p1;
-char_u *p2;
+int utf_composinglike(char_u *p1, char_u *p2)
{
int c2;
@@ -1618,9 +1577,10 @@ char_u *p2;
* Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
* composing characters.
*/
-int utfc_ptr2char(p, pcc)
-char_u *p;
-int *pcc; /* return: composing chars, last one is 0 */
+int utfc_ptr2char(
+ char_u *p,
+ int *pcc /* return: composing chars, last one is 0 */
+ )
{
int len;
int c;
@@ -1655,10 +1615,11 @@ int *pcc; /* return: composing chars, last one is 0 */
* Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
* composing characters. Use no more than p[maxlen].
*/
-int utfc_ptr2char_len(p, pcc, maxlen)
-char_u *p;
-int *pcc; /* return: composing chars, last one is 0 */
-int maxlen;
+int utfc_ptr2char_len(
+ char_u *p,
+ int *pcc, /* return: composing chars, last one is 0 */
+ int maxlen
+ )
{
int len;
int c;
@@ -1698,9 +1659,7 @@ int maxlen;
* Only to be used when ScreenLinesUC[off] != 0.
* Returns the produced number of bytes.
*/
-int utfc_char2bytes(off, buf)
-int off;
-char_u *buf;
+int utfc_char2bytes(int off, char_u *buf)
{
int len;
int i;
@@ -1720,8 +1679,7 @@ char_u *buf;
* Returns 0 for "".
* Returns 1 for an illegal byte sequence.
*/
-int utf_ptr2len(p)
-char_u *p;
+int utf_ptr2len(char_u *p)
{
int len;
int i;
@@ -1740,8 +1698,7 @@ char_u *p;
* "b" must be between 0 and 255!
* Returns 1 for an invalid first byte value.
*/
-int utf_byte2len(b)
-int b;
+int utf_byte2len(int b)
{
return utf8len_tab[b];
}
@@ -1754,9 +1711,7 @@ int b;
* Returns number > "size" for an incomplete byte sequence.
* Never returns zero.
*/
-int utf_ptr2len_len(p, size)
-char_u *p;
-int size;
+int utf_ptr2len_len(char_u *p, int size)
{
int len;
int i;
@@ -1779,8 +1734,7 @@ int size;
* Return the number of bytes the UTF-8 encoding of the character at "p" takes.
* This includes following composing characters.
*/
-int utfc_ptr2len(p)
-char_u *p;
+int utfc_ptr2len(char_u *p)
{
int len;
int b0 = *p;
@@ -1819,9 +1773,7 @@ char_u *p;
* Returns 0 for an empty string.
* Returns 1 for an illegal char or an incomplete byte sequence.
*/
-int utfc_ptr2len_len(p, size)
-char_u *p;
-int size;
+int utfc_ptr2len_len(char_u *p, int size)
{
int len;
int prevlen;
@@ -1871,8 +1823,7 @@ int size;
* Return the number of bytes the UTF-8 encoding of character "c" takes.
* This does not include composing characters.
*/
-int utf_char2len(c)
-int c;
+int utf_char2len(int c)
{
if (c < 0x80)
return 1;
@@ -1892,9 +1843,7 @@ int c;
* Returns the number of bytes.
* This does not include composing characters.
*/
-int utf_char2bytes(c, buf)
-int c;
-char_u *buf;
+int utf_char2bytes(int c, char_u *buf)
{
if (c < 0x80) { /* 7 bits */
buf[0] = c;
@@ -1941,8 +1890,7 @@ char_u *buf;
* drawn on top of the preceding character.
* Based on code from Markus Kuhn.
*/
-int utf_iscomposing(c)
-int c;
+int utf_iscomposing(int c)
{
/* Sorted list of non-overlapping intervals.
* Generated by ../runtime/tools/unicode.vim. */
@@ -2145,8 +2093,7 @@ int c;
* Return TRUE for characters that can be displayed in a normal way.
* Only for characters of 0x100 and above!
*/
-int utf_printable(c)
-int c;
+int utf_printable(int c)
{
#ifdef USE_WCHAR_FUNCTIONS
/*
@@ -2173,8 +2120,7 @@ int c;
* 1: punctuation
* 2 or bigger: some class of word character.
*/
-int utf_class(c)
-int c;
+int utf_class(int c)
{
/* sorted list of non-overlapping intervals */
static struct clinterval {
@@ -2467,10 +2413,7 @@ static int utf_strnicmp __ARGS((char_u *s1, char_u *s2, size_t n1, size_t n2));
* Return the converted equivalent of "a", which is a UCS-4 character. Use
* the given conversion "table". Uses binary search on "table".
*/
-static int utf_convert(a, table, tableSize)
-int a;
-convertStruct table[];
-int tableSize;
+static int utf_convert(int a, convertStruct *table, int tableSize)
{
int start, mid, end; /* indices into table */
int entries = tableSize / sizeof(convertStruct);
@@ -2498,8 +2441,7 @@ int tableSize;
* Return the folded-case equivalent of "a", which is a UCS-4 character. Uses
* simple case folding.
*/
-int utf_fold(a)
-int a;
+int utf_fold(int a)
{
return utf_convert(a, foldCase, (int)sizeof(foldCase));
}
@@ -2810,8 +2752,7 @@ static convertStruct toUpper[] =
* Return the upper-case equivalent of "a", which is a UCS-4 character. Use
* simple case folding.
*/
-int utf_toupper(a)
-int a;
+int utf_toupper(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style toupper(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -2831,8 +2772,7 @@ int a;
return utf_convert(a, toUpper, (int)sizeof(toUpper));
}
-int utf_islower(a)
-int a;
+int utf_islower(int a)
{
/* German sharp s is lower case but has no upper case equivalent. */
return (utf_toupper(a) != a) || a == 0xdf;
@@ -2842,8 +2782,7 @@ int a;
* Return the lower-case equivalent of "a", which is a UCS-4 character. Use
* simple case folding.
*/
-int utf_tolower(a)
-int a;
+int utf_tolower(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style tolower(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -2863,15 +2802,12 @@ int a;
return utf_convert(a, toLower, (int)sizeof(toLower));
}
-int utf_isupper(a)
-int a;
+int utf_isupper(int a)
{
return utf_tolower(a) != a;
}
-static int utf_strnicmp(s1, s2, n1, n2)
-char_u *s1, *s2;
-size_t n1, n2;
+static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
{
int c1, c2, cdiff;
char_u buffer[6];
@@ -2944,9 +2880,7 @@ size_t n1, n2;
* Returns zero if s1 and s2 are equal (ignoring case), the difference between
* two characters otherwise.
*/
-int mb_strnicmp(s1, s2, nn)
-char_u *s1, *s2;
-size_t nn;
+int mb_strnicmp(char_u *s1, char_u *s2, size_t nn)
{
int i, l;
int cdiff;
@@ -3027,16 +2961,12 @@ void show_utf8() {
* If "p" points to the NUL at the end of the string return 0.
* Returns 0 when already at the first byte of a character.
*/
-int latin_head_off(base, p)
-char_u *base UNUSED;
-char_u *p UNUSED;
+int latin_head_off(char_u *base, char_u *p)
{
return 0;
}
-int dbcs_head_off(base, p)
-char_u *base;
-char_u *p;
+int dbcs_head_off(char_u *base, char_u *p)
{
char_u *q;
@@ -3057,9 +2987,7 @@ char_u *p;
* Special version of dbcs_head_off() that works for ScreenLines[], where
* single-width DBCS_JPNU characters are stored separately.
*/
-int dbcs_screen_head_off(base, p)
-char_u *base;
-char_u *p;
+int dbcs_screen_head_off(char_u *base, char_u *p)
{
char_u *q;
@@ -3087,9 +3015,7 @@ char_u *p;
return (q == p) ? 0 : 1;
}
-int utf_head_off(base, p)
-char_u *base;
-char_u *p;
+int utf_head_off(char_u *base, char_u *p)
{
char_u *q;
char_u *s;
@@ -3141,9 +3067,7 @@ char_u *p;
/*
* Copy a character from "*fp" to "*tp" and advance the pointers.
*/
-void mb_copy_char(fp, tp)
-char_u **fp;
-char_u **tp;
+void mb_copy_char(char_u **fp, char_u **tp)
{
int l = (*mb_ptr2len)(*fp);
@@ -3157,9 +3081,7 @@ char_u **tp;
* at the start of a character 0 is returned, otherwise the offset to the next
* character. Can start anywhere in a stream of bytes.
*/
-int mb_off_next(base, p)
-char_u *base;
-char_u *p;
+int mb_off_next(char_u *base, char_u *p)
{
int i;
int j;
@@ -3191,9 +3113,7 @@ char_u *p;
* Return the offset from "p" to the last byte of the character it points
* into. Can start anywhere in a stream of bytes.
*/
-int mb_tail_off(base, p)
-char_u *base;
-char_u *p;
+int mb_tail_off(char_u *base, char_u *p)
{
int i;
int j;
@@ -3257,7 +3177,7 @@ void utf_find_illegal() {
* utf_ptr2len()) or too many of them (overlong sequence). */
len = utf_ptr2len(p);
if (*p >= 0x80 && (len == 1
- || utf_char2len(utf_ptr2char(p)) != len)) {
+ || utf_char2len(utf_ptr2char(p)) != len)) {
if (vimconv.vc_type == CONV_NONE)
curwin->w_cursor.col += (colnr_T)(p - ml_get_cursor());
else {
@@ -3301,15 +3221,13 @@ void mb_adjust_cursor() {
* Adjust position "*lp" to point to the first byte of a multi-byte character.
* If it points to a tail byte it's moved backwards to the head byte.
*/
-void mb_adjustpos(buf, lp)
-buf_T *buf;
-pos_T *lp;
+void mb_adjustpos(buf_T *buf, pos_T *lp)
{
char_u *p;
if (lp->col > 0
|| lp->coladd > 1
- ) {
+ ) {
p = ml_get_buf(buf, lp->lnum, FALSE);
lp->col -= (*mb_head_off)(p, p + lp->col);
/* Reset "coladd" when the cursor would be on the right half of a
@@ -3325,9 +3243,10 @@ pos_T *lp;
/*
* Return a pointer to the character before "*p", if there is one.
*/
-char_u * mb_prevptr(line, p)
-char_u *line; /* start of the string */
-char_u *p;
+char_u * mb_prevptr(
+ char_u *line, /* start of the string */
+ char_u *p
+ )
{
if (p > line)
mb_ptr_back(line, p);
@@ -3338,8 +3257,7 @@ char_u *p;
* Return the character length of "str". Each multi-byte character (with
* following composing characters) counts as one.
*/
-int mb_charlen(str)
-char_u *str;
+int mb_charlen(char_u *str)
{
char_u *p = str;
int count;
@@ -3356,9 +3274,7 @@ char_u *str;
/*
* Like mb_charlen() but for a string with specified length.
*/
-int mb_charlen_len(str, len)
-char_u *str;
-int len;
+int mb_charlen_len(char_u *str, int len)
{
char_u *p = str;
int count;
@@ -3376,8 +3292,7 @@ int len;
* "pp" to just after the bytes that formed it.
* Return NULL if no multi-byte char was found.
*/
-char_u * mb_unescape(pp)
-char_u **pp;
+char_u * mb_unescape(char_u **pp)
{
static char_u buf[6];
int n;
@@ -3394,13 +3309,13 @@ char_u **pp;
buf[m++] = K_SPECIAL;
n += 2;
} else if ((str[n] == K_SPECIAL
- )
- && str[n + 1] == KS_EXTRA
- && str[n + 2] == (int)KE_CSI) {
+ )
+ && str[n + 1] == KS_EXTRA
+ && str[n + 2] == (int)KE_CSI) {
buf[m++] = CSI;
n += 2;
} else if (str[n] == K_SPECIAL
- )
+ )
break; /* a special key can't be a multibyte char */
else
buf[m++] = str[n];
@@ -3425,32 +3340,28 @@ char_u **pp;
* of a double-width character.
* Caller must make sure "row" and "col" are not invalid!
*/
-int mb_lefthalve(row, col)
-int row;
-int col;
+int mb_lefthalve(int row, int col)
{
if (composing_hangul)
return TRUE;
return (*mb_off2cells)(LineOffset[row] + col,
- LineOffset[row] + screen_Columns) > 1;
+ LineOffset[row] + screen_Columns) > 1;
}
/*
* Correct a position on the screen, if it's the right half of a double-wide
* char move it to the left half. Returns the corrected column.
*/
-int mb_fix_col(col, row)
-int col;
-int row;
+int mb_fix_col(int col, int row)
{
col = check_col(col);
row = check_row(row);
if (has_mbyte && ScreenLines != NULL && col > 0
&& ((enc_dbcs
- && ScreenLines[LineOffset[row] + col] != NUL
- && dbcs_screen_head_off(ScreenLines + LineOffset[row],
- ScreenLines + LineOffset[row] + col))
- || (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
+ && ScreenLines[LineOffset[row] + col] != NUL
+ && dbcs_screen_head_off(ScreenLines + LineOffset[row],
+ ScreenLines + LineOffset[row] + col))
+ || (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
return col - 1;
return col;
}
@@ -3460,8 +3371,7 @@ static int enc_alias_search __ARGS((char_u *name));
/*
* Skip the Vim specific head of a 'encoding' name.
*/
-char_u * enc_skip(p)
-char_u *p;
+char_u * enc_skip(char_u *p)
{
if (STRNCMP(p, "2byte-", 6) == 0)
return p + 6;
@@ -3476,8 +3386,7 @@ char_u *p;
* case characters and '_' replaced with '-'.
* Returns an allocated string. NULL for out-of-memory.
*/
-char_u * enc_canonize(enc)
-char_u *enc;
+char_u * enc_canonize(char_u *enc)
{
char_u *r;
char_u *p, *s;
@@ -3544,8 +3453,7 @@ char_u *enc;
* Search for an encoding alias of "name".
* Returns -1 when not found.
*/
-static int enc_alias_search(name)
-char_u *name;
+static int enc_alias_search(char_u *name)
{
int i;
@@ -3573,11 +3481,11 @@ char_u * enc_locale() {
if ((s = nl_langinfo(CODESET)) == NULL || *s == NUL)
# endif
# if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
- if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
+ if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL)
# endif
- if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
- if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
- s = getenv("LANG");
+ if ((s = getenv("LC_ALL")) == NULL || *s == NUL)
+ if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL)
+ s = getenv("LANG");
if (s == NULL || *s == NUL)
return FAIL;
@@ -3619,7 +3527,7 @@ char_u * enc_locale() {
static char_u *
iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp,
- int *resultlenp));
+ int *resultlenp));
/*
* Call iconv_open() with a check if iconv() works properly (there are broken
@@ -3627,9 +3535,7 @@ iconv_string __ARGS((vimconv_T *vcp, char_u *str, int slen, int *unconvlenp,
* Returns (void *)-1 if failed.
* (should return iconv_t, but that causes problems with prototypes).
*/
-void * my_iconv_open(to, from)
-char_u *to;
-char_u *from;
+void * my_iconv_open(char_u *to, char_u *from)
{
iconv_t fd;
#define ICONV_TESTLEN 400
@@ -3678,12 +3584,7 @@ char_u *from;
* Returns the converted string in allocated memory. NULL for an error.
* If resultlenp is not NULL, sets it to the result length in bytes.
*/
-static char_u * iconv_string(vcp, str, slen, unconvlenp, resultlenp)
-vimconv_T *vcp;
-char_u *str;
-int slen;
-int *unconvlenp;
-int *resultlenp;
+static char_u * iconv_string(vimconv_T *vcp, char_u *str, int slen, int *unconvlenp, int *resultlenp)
{
const char *from;
size_t fromlen;
@@ -3734,8 +3635,8 @@ int *resultlenp;
/* Check both ICONV_EILSEQ and EILSEQ, because the dynamically loaded
* iconv library may use one of them. */
else if (!vcp->vc_fail
- && (ICONV_ERRNO == ICONV_EILSEQ || ICONV_ERRNO == EILSEQ
- || ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL)) {
+ && (ICONV_ERRNO == ICONV_EILSEQ || ICONV_ERRNO == EILSEQ
+ || ICONV_ERRNO == ICONV_EINVAL || ICONV_ERRNO == EINVAL)) {
/* Can't convert: insert a '?' and skip a character. This assumes
* conversion from 'encoding' to something else. In other
* situations we don't know what to skip anyway. */
@@ -3804,9 +3705,9 @@ static void * get_iconv_import_func(HINSTANCE hInst,
if (pPE->Signature != IMAGE_NT_SIGNATURE)
return NULL;
pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
- + pPE->OptionalHeader.DataDirectory[
- IMAGE_DIRECTORY_ENTRY_IMPORT]
- .VirtualAddress);
+ + pPE->OptionalHeader.DataDirectory[
+ IMAGE_DIRECTORY_ENTRY_IMPORT]
+ .VirtualAddress);
for (; pImpDesc->FirstThunk; ++pImpDesc) {
if (!pImpDesc->OriginalFirstThunk)
continue;
@@ -3816,7 +3717,7 @@ static void * get_iconv_import_func(HINSTANCE hInst,
if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
continue;
pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
- + (UINT_PTR)(pINT->u1.AddressOfData));
+ + (UINT_PTR)(pINT->u1.AddressOfData));
if (strcmp(pImpName->Name, funcname) == 0)
return (void *)pIAT->u1.Function;
}
@@ -3827,8 +3728,7 @@ static void * get_iconv_import_func(HINSTANCE hInst,
/*
* Try opening the iconv.dll and return TRUE if iconv() can be used.
*/
-int iconv_enabled(verbose)
-int verbose;
+int iconv_enabled(int verbose)
{
if (hIconvDLL != 0 && hMsvcrtDLL != 0)
return TRUE;
@@ -3901,9 +3801,9 @@ void iconv_end() {
* Return FAIL when conversion is not supported, OK otherwise.
*/
int convert_setup(vcp, from, to)
-vimconv_T *vcp;
-char_u *from;
-char_u *to;
+ vimconv_T *vcp;
+ char_u *from;
+ char_u *to;
{
return convert_setup_ext(vcp, from, TRUE, to, TRUE);
}
@@ -3913,11 +3813,11 @@ char_u *to;
* "from" unicode charsets be considered utf-8. Same for "to".
*/
int convert_setup_ext(vcp, from, from_unicode_is_utf8, to, to_unicode_is_utf8)
-vimconv_T *vcp;
-char_u *from;
-int from_unicode_is_utf8;
-char_u *to;
-int to_unicode_is_utf8;
+ vimconv_T *vcp;
+ char_u *from;
+ int from_unicode_is_utf8;
+ char_u *to;
+ int to_unicode_is_utf8;
{
int from_prop;
int to_prop;
@@ -3990,9 +3890,9 @@ int to_unicode_is_utf8;
* Returns the length after conversion.
*/
int convert_input(ptr, len, maxlen)
-char_u *ptr;
-int len;
-int maxlen;
+ char_u *ptr;
+ int len;
+ int maxlen;
{
return convert_input_safe(ptr, len, maxlen, NULL, NULL);
}
@@ -4004,11 +3904,11 @@ int maxlen;
* the length. If "restp" is NULL it is not used.
*/
int convert_input_safe(ptr, len, maxlen, restp, restlenp)
-char_u *ptr;
-int len;
-int maxlen;
-char_u **restp;
-int *restlenp;
+ char_u *ptr;
+ int len;
+ int maxlen;
+ char_u **restp;
+ int *restlenp;
{
char_u *d;
int dlen = len;
@@ -4043,9 +3943,9 @@ int *restlenp;
* When something goes wrong, NULL is returned and "*lenp" is unchanged.
*/
char_u * string_convert(vcp, ptr, lenp)
-vimconv_T *vcp;
-char_u *ptr;
-int *lenp;
+ vimconv_T *vcp;
+ char_u *ptr;
+ int *lenp;
{
return string_convert_ext(vcp, ptr, lenp, NULL);
}
@@ -4056,10 +3956,10 @@ int *lenp;
* set to the number of remaining bytes.
*/
char_u * string_convert_ext(vcp, ptr, lenp, unconvlenp)
-vimconv_T *vcp;
-char_u *ptr;
-int *lenp;
-int *unconvlenp;
+ vimconv_T *vcp;
+ char_u *ptr;
+ int *lenp;
+ int *unconvlenp;
{
char_u *retval = NULL;
char_u *d;
@@ -4076,140 +3976,140 @@ int *unconvlenp;
return vim_strsave((char_u *)"");
switch (vcp->vc_type) {
- case CONV_TO_UTF8: /* latin1 to utf-8 conversion */
- retval = alloc(len * 2 + 1);
- if (retval == NULL)
- break;
- d = retval;
- for (i = 0; i < len; ++i) {
- c = ptr[i];
- if (c < 0x80)
- *d++ = c;
- else {
- *d++ = 0xc0 + ((unsigned)c >> 6);
- *d++ = 0x80 + (c & 0x3f);
+ case CONV_TO_UTF8: /* latin1 to utf-8 conversion */
+ retval = alloc(len * 2 + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ c = ptr[i];
+ if (c < 0x80)
+ *d++ = c;
+ else {
+ *d++ = 0xc0 + ((unsigned)c >> 6);
+ *d++ = 0x80 + (c & 0x3f);
+ }
}
- }
- *d = NUL;
- if (lenp != NULL)
- *lenp = (int)(d - retval);
- break;
-
- case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */
- retval = alloc(len * 3 + 1);
- if (retval == NULL)
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
break;
- d = retval;
- for (i = 0; i < len; ++i) {
- c = ptr[i];
- switch (c) {
- case 0xa4: c = 0x20ac; break; /* euro */
- case 0xa6: c = 0x0160; break; /* S hat */
- case 0xa8: c = 0x0161; break; /* S -hat */
- case 0xb4: c = 0x017d; break; /* Z hat */
- case 0xb8: c = 0x017e; break; /* Z -hat */
- case 0xbc: c = 0x0152; break; /* OE */
- case 0xbd: c = 0x0153; break; /* oe */
- case 0xbe: c = 0x0178; break; /* Y */
- }
- d += utf_char2bytes(c, d);
- }
- *d = NUL;
- if (lenp != NULL)
- *lenp = (int)(d - retval);
- break;
- case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */
- case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */
- retval = alloc(len + 1);
- if (retval == NULL)
- break;
- d = retval;
- for (i = 0; i < len; ++i) {
- l = utf_ptr2len_len(ptr + i, len - i);
- if (l == 0)
- *d++ = NUL;
- else if (l == 1) {
- int l_w = utf8len_tab_zero[ptr[i]];
-
- if (l_w == 0) {
- /* Illegal utf-8 byte cannot be converted */
- vim_free(retval);
- return NULL;
- }
- if (unconvlenp != NULL && l_w > len - i) {
- /* Incomplete sequence at the end. */
- *unconvlenp = len - i;
- break;
+ case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */
+ retval = alloc(len * 3 + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ c = ptr[i];
+ switch (c) {
+ case 0xa4: c = 0x20ac; break; /* euro */
+ case 0xa6: c = 0x0160; break; /* S hat */
+ case 0xa8: c = 0x0161; break; /* S -hat */
+ case 0xb4: c = 0x017d; break; /* Z hat */
+ case 0xb8: c = 0x017e; break; /* Z -hat */
+ case 0xbc: c = 0x0152; break; /* OE */
+ case 0xbd: c = 0x0153; break; /* oe */
+ case 0xbe: c = 0x0178; break; /* Y */
}
- *d++ = ptr[i];
- } else {
- c = utf_ptr2char(ptr + i);
- if (vcp->vc_type == CONV_TO_LATIN9)
- switch (c) {
- case 0x20ac: c = 0xa4; break; /* euro */
- case 0x0160: c = 0xa6; break; /* S hat */
- case 0x0161: c = 0xa8; break; /* S -hat */
- case 0x017d: c = 0xb4; break; /* Z hat */
- case 0x017e: c = 0xb8; break; /* Z -hat */
- case 0x0152: c = 0xbc; break; /* OE */
- case 0x0153: c = 0xbd; break; /* oe */
- case 0x0178: c = 0xbe; break; /* Y */
- case 0xa4:
- case 0xa6:
- case 0xa8:
- case 0xb4:
- case 0xb8:
- case 0xbc:
- case 0xbd:
- case 0xbe: c = 0x100; break; /* not in latin9 */
- }
- if (!utf_iscomposing(c)) { /* skip composing chars */
- if (c < 0x100)
- *d++ = c;
- else if (vcp->vc_fail) {
+ d += utf_char2bytes(c, d);
+ }
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
+ break;
+
+ case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */
+ case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */
+ retval = alloc(len + 1);
+ if (retval == NULL)
+ break;
+ d = retval;
+ for (i = 0; i < len; ++i) {
+ l = utf_ptr2len_len(ptr + i, len - i);
+ if (l == 0)
+ *d++ = NUL;
+ else if (l == 1) {
+ int l_w = utf8len_tab_zero[ptr[i]];
+
+ if (l_w == 0) {
+ /* Illegal utf-8 byte cannot be converted */
vim_free(retval);
return NULL;
- } else {
- *d++ = 0xbf;
- if (utf_char2cells(c) > 1)
- *d++ = '?';
}
+ if (unconvlenp != NULL && l_w > len - i) {
+ /* Incomplete sequence at the end. */
+ *unconvlenp = len - i;
+ break;
+ }
+ *d++ = ptr[i];
+ } else {
+ c = utf_ptr2char(ptr + i);
+ if (vcp->vc_type == CONV_TO_LATIN9)
+ switch (c) {
+ case 0x20ac: c = 0xa4; break; /* euro */
+ case 0x0160: c = 0xa6; break; /* S hat */
+ case 0x0161: c = 0xa8; break; /* S -hat */
+ case 0x017d: c = 0xb4; break; /* Z hat */
+ case 0x017e: c = 0xb8; break; /* Z -hat */
+ case 0x0152: c = 0xbc; break; /* OE */
+ case 0x0153: c = 0xbd; break; /* oe */
+ case 0x0178: c = 0xbe; break; /* Y */
+ case 0xa4:
+ case 0xa6:
+ case 0xa8:
+ case 0xb4:
+ case 0xb8:
+ case 0xbc:
+ case 0xbd:
+ case 0xbe: c = 0x100; break; /* not in latin9 */
+ }
+ if (!utf_iscomposing(c)) { /* skip composing chars */
+ if (c < 0x100)
+ *d++ = c;
+ else if (vcp->vc_fail) {
+ vim_free(retval);
+ return NULL;
+ } else {
+ *d++ = 0xbf;
+ if (utf_char2cells(c) > 1)
+ *d++ = '?';
+ }
+ }
+ i += l - 1;
}
- i += l - 1;
}
- }
- *d = NUL;
- if (lenp != NULL)
- *lenp = (int)(d - retval);
- break;
+ *d = NUL;
+ if (lenp != NULL)
+ *lenp = (int)(d - retval);
+ break;
# ifdef MACOS_CONVERT
- case CONV_MAC_LATIN1:
- retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
- 'm', 'l', unconvlenp);
- break;
+ case CONV_MAC_LATIN1:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'm', 'l', unconvlenp);
+ break;
- case CONV_LATIN1_MAC:
- retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
- 'l', 'm', unconvlenp);
- break;
+ case CONV_LATIN1_MAC:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'l', 'm', unconvlenp);
+ break;
- case CONV_MAC_UTF8:
- retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
- 'm', 'u', unconvlenp);
- break;
+ case CONV_MAC_UTF8:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'm', 'u', unconvlenp);
+ break;
- case CONV_UTF8_MAC:
- retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
- 'u', 'm', unconvlenp);
- break;
+ case CONV_UTF8_MAC:
+ retval = mac_string_convert(ptr, len, lenp, vcp->vc_fail,
+ 'u', 'm', unconvlenp);
+ break;
# endif
# ifdef USE_ICONV
- case CONV_ICONV: /* conversion with output_conv.vc_fd */
- retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
- break;
+ case CONV_ICONV: /* conversion with output_conv.vc_fd */
+ retval = iconv_string(vcp, ptr, len, unconvlenp, lenp);
+ break;
# endif
}
diff --git a/src/proto/mbyte.pro b/src/mbyte.h
index c440d62a4e..b9b5aa05d7 100644
--- a/src/proto/mbyte.pro
+++ b/src/mbyte.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MBYTE_H
+#define NEOVIM_MBYTE_H
/* mbyte.c */
int enc_canon_props __ARGS((char_u *name));
char_u *mb_init __ARGS((void));
@@ -98,3 +100,4 @@ char_u *string_convert __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp));
char_u *string_convert_ext __ARGS((vimconv_T *vcp, char_u *ptr, int *lenp,
int *unconvlenp));
/* vim: set ft=c : */
+#endif /* NEOVIM_MBYTE_H */
diff --git a/src/memfile.c b/src/memfile.c
index 2969a19795..d3b8bed6cc 100644
--- a/src/memfile.c
+++ b/src/memfile.c
@@ -33,6 +33,14 @@
*/
#include "vim.h"
+#include "memfile.h"
+#include "fileio.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "os_unix.h"
+#include "ui.h"
/*
* Some systems have the page size in statfs.f_bsize, some in stat.st_blksize
@@ -109,9 +117,7 @@ static int mf_hash_grow __ARGS((mf_hashtab_T *));
*
* return value: identifier for this memory block file.
*/
-memfile_T * mf_open(fname, flags)
-char_u *fname;
-int flags;
+memfile_T *mf_open(char_u *fname, int flags)
{
memfile_T *mfp;
off_t size;
@@ -203,9 +209,7 @@ int flags;
*
* return value: FAIL if file could not be opened, OK otherwise
*/
-int mf_open_file(mfp, fname)
-memfile_T *mfp;
-char_u *fname;
+int mf_open_file(memfile_T *mfp, char_u *fname)
{
mf_do_open(mfp, fname, O_RDWR|O_CREAT|O_EXCL); /* try to open the file */
@@ -219,9 +223,7 @@ char_u *fname;
/*
* Close a memory file and delete the associated file if 'del_file' is TRUE.
*/
-void mf_close(mfp, del_file)
-memfile_T *mfp;
-int del_file;
+void mf_close(memfile_T *mfp, int del_file)
{
bhdr_T *hp, *nextp;
@@ -251,9 +253,11 @@ int del_file;
/*
* Close the swap file for a memfile. Used when 'swapfile' is reset.
*/
-void mf_close_file(buf, getlines)
-buf_T *buf;
-int getlines; /* get all lines into memory? */
+void
+mf_close_file (
+ buf_T *buf,
+ int getlines /* get all lines into memory? */
+)
{
memfile_T *mfp;
linenr_T lnum;
@@ -288,9 +292,7 @@ int getlines; /* get all lines into memory? */
* Set new size for a memfile. Used when block 0 of a swapfile has been read
* and the size it indicates differs from what was guessed.
*/
-void mf_new_page_size(mfp, new_size)
-memfile_T *mfp;
-unsigned new_size;
+void mf_new_page_size(memfile_T *mfp, unsigned new_size)
{
/* Correct the memory used for block 0 to the new size, because it will be
* freed with that size later on. */
@@ -303,10 +305,7 @@ unsigned new_size;
*
* negative: TRUE if negative block number desired (data block)
*/
-bhdr_T * mf_new(mfp, negative, page_count)
-memfile_T *mfp;
-int negative;
-int page_count;
+bhdr_T *mf_new(memfile_T *mfp, int negative, int page_count)
{
bhdr_T *hp; /* new bhdr_T */
bhdr_T *freep; /* first block in free list */
@@ -384,10 +383,7 @@ int page_count;
*
* Note: The caller should first check a negative nr with mf_trans_del()
*/
-bhdr_T * mf_get(mfp, nr, page_count)
-memfile_T *mfp;
-blocknr_T nr;
-int page_count;
+bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, int page_count)
{
bhdr_T *hp;
/* doesn't exist */
@@ -440,11 +436,7 @@ int page_count;
*
* no return value, function cannot fail
*/
-void mf_put(mfp, hp, dirty, infile)
-memfile_T *mfp;
-bhdr_T *hp;
-int dirty;
-int infile;
+void mf_put(memfile_T *mfp, bhdr_T *hp, int dirty, int infile)
{
int flags;
@@ -465,9 +457,7 @@ int infile;
/*
* block *hp is no longer in used, may put it in the free list of memfile *mfp
*/
-void mf_free(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+void mf_free(memfile_T *mfp, bhdr_T *hp)
{
vim_free(hp->bh_data); /* free the memory */
mf_rem_hash(mfp, hp); /* get *hp out of the hash list */
@@ -502,9 +492,7 @@ static unsigned long fdtofh(int filedescriptor) {
*
* Return FAIL for failure, OK otherwise
*/
-int mf_sync(mfp, flags)
-memfile_T *mfp;
-int flags;
+int mf_sync(memfile_T *mfp, int flags)
{
int status;
bhdr_T *hp;
@@ -603,8 +591,7 @@ int flags;
* the dirty flag. These are blocks that need to be written to a newly
* created swapfile.
*/
-void mf_set_dirty(mfp)
-memfile_T *mfp;
+void mf_set_dirty(memfile_T *mfp)
{
bhdr_T *hp;
@@ -617,9 +604,7 @@ memfile_T *mfp;
/*
* insert block *hp in front of hashlist of memfile *mfp
*/
-static void mf_ins_hash(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static void mf_ins_hash(memfile_T *mfp, bhdr_T *hp)
{
mf_hash_add_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
}
@@ -627,9 +612,7 @@ bhdr_T *hp;
/*
* remove block *hp from hashlist of memfile list *mfp
*/
-static void mf_rem_hash(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static void mf_rem_hash(memfile_T *mfp, bhdr_T *hp)
{
mf_hash_rem_item(&mfp->mf_hash, (mf_hashitem_T *)hp);
}
@@ -637,9 +620,7 @@ bhdr_T *hp;
/*
* look in hash lists of memfile *mfp for block header with number 'nr'
*/
-static bhdr_T * mf_find_hash(mfp, nr)
-memfile_T *mfp;
-blocknr_T nr;
+static bhdr_T *mf_find_hash(memfile_T *mfp, blocknr_T nr)
{
return (bhdr_T *)mf_hash_find(&mfp->mf_hash, nr);
}
@@ -647,9 +628,7 @@ blocknr_T nr;
/*
* insert block *hp in front of used list of memfile *mfp
*/
-static void mf_ins_used(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static void mf_ins_used(memfile_T *mfp, bhdr_T *hp)
{
hp->bh_next = mfp->mf_used_first;
mfp->mf_used_first = hp;
@@ -665,9 +644,7 @@ bhdr_T *hp;
/*
* remove block *hp from used list of memfile *mfp
*/
-static void mf_rem_used(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static void mf_rem_used(memfile_T *mfp, bhdr_T *hp)
{
if (hp->bh_next == NULL) /* last block in used list */
mfp->mf_used_last = hp->bh_prev;
@@ -688,9 +665,7 @@ bhdr_T *hp;
* Return the block header to the caller, including the memory block, so
* it can be re-used. Make sure the page_count is right.
*/
-static bhdr_T * mf_release(mfp, page_count)
-memfile_T *mfp;
-int page_count;
+static bhdr_T *mf_release(memfile_T *mfp, int page_count)
{
bhdr_T *hp;
int need_release;
@@ -768,7 +743,7 @@ int page_count;
*
* return TRUE if any memory was released
*/
-int mf_release_all() {
+int mf_release_all(void) {
buf_T *buf;
memfile_T *mfp;
bhdr_T *hp;
@@ -804,9 +779,7 @@ int mf_release_all() {
/*
* Allocate a block header and a block of memory for it
*/
-static bhdr_T * mf_alloc_bhdr(mfp, page_count)
-memfile_T *mfp;
-int page_count;
+static bhdr_T *mf_alloc_bhdr(memfile_T *mfp, int page_count)
{
bhdr_T *hp;
@@ -824,8 +797,7 @@ int page_count;
/*
* Free a block header and the block of memory for it
*/
-static void mf_free_bhdr(hp)
-bhdr_T *hp;
+static void mf_free_bhdr(bhdr_T *hp)
{
vim_free(hp->bh_data);
vim_free(hp);
@@ -834,9 +806,7 @@ bhdr_T *hp;
/*
* insert entry *hp in the free list
*/
-static void mf_ins_free(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static void mf_ins_free(memfile_T *mfp, bhdr_T *hp)
{
hp->bh_next = mfp->mf_free_first;
mfp->mf_free_first = hp;
@@ -846,8 +816,7 @@ bhdr_T *hp;
* remove the first entry from the free list and return a pointer to it
* Note: caller must check that mfp->mf_free_first is not NULL!
*/
-static bhdr_T * mf_rem_free(mfp)
-memfile_T *mfp;
+static bhdr_T *mf_rem_free(memfile_T *mfp)
{
bhdr_T *hp;
@@ -861,9 +830,7 @@ memfile_T *mfp;
*
* Return FAIL for failure, OK otherwise
*/
-static int mf_read(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static int mf_read(memfile_T *mfp, bhdr_T *hp)
{
off_t offset;
unsigned page_size;
@@ -896,9 +863,7 @@ bhdr_T *hp;
*
* Return FAIL for failure, OK otherwise
*/
-static int mf_write(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static int mf_write(memfile_T *mfp, bhdr_T *hp)
{
off_t offset; /* offset in the file */
blocknr_T nr; /* block nr which is being written */
@@ -969,11 +934,7 @@ bhdr_T *hp;
* Takes care of encryption.
* Return FAIL or OK.
*/
-static int mf_write_block(mfp, hp, offset, size)
-memfile_T *mfp;
-bhdr_T *hp;
-off_t offset UNUSED;
-unsigned size;
+static int mf_write_block(memfile_T *mfp, bhdr_T *hp, off_t offset, unsigned size)
{
char_u *data = hp->bh_data;
int result = OK;
@@ -999,9 +960,7 @@ unsigned size;
*
* Return FAIL for failure, OK otherwise
*/
-static int mf_trans_add(mfp, hp)
-memfile_T *mfp;
-bhdr_T *hp;
+static int mf_trans_add(memfile_T *mfp, bhdr_T *hp)
{
bhdr_T *freep;
blocknr_T new_bnum;
@@ -1057,9 +1016,7 @@ bhdr_T *hp;
*
* Return the positive new number when found, the old number when not found
*/
-blocknr_T mf_trans_del(mfp, old_nr)
-memfile_T *mfp;
-blocknr_T old_nr;
+blocknr_T mf_trans_del(memfile_T *mfp, blocknr_T old_nr)
{
NR_TRANS *np;
blocknr_T new_bnum;
@@ -1085,8 +1042,7 @@ blocknr_T old_nr;
* Only called when creating or renaming the swapfile. Either way it's a new
* name so we must work out the full path name.
*/
-void mf_set_ffname(mfp)
-memfile_T *mfp;
+void mf_set_ffname(memfile_T *mfp)
{
mfp->mf_ffname = FullName_save(mfp->mf_fname, FALSE);
}
@@ -1095,8 +1051,7 @@ memfile_T *mfp;
* Make the name of the file used for the memfile a full path.
* Used before doing a :cd
*/
-void mf_fullname(mfp)
-memfile_T *mfp;
+void mf_fullname(memfile_T *mfp)
{
if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_ffname != NULL) {
vim_free(mfp->mf_fname);
@@ -1108,8 +1063,7 @@ memfile_T *mfp;
/*
* return TRUE if there are any translations pending for 'mfp'
*/
-int mf_need_trans(mfp)
-memfile_T *mfp;
+int mf_need_trans(memfile_T *mfp)
{
return mfp->mf_fname != NULL && mfp->mf_neg_count > 0;
}
@@ -1119,10 +1073,12 @@ memfile_T *mfp;
* The "fname" must be in allocated memory, and is consumed (also when an
* error occurs).
*/
-static void mf_do_open(mfp, fname, flags)
-memfile_T *mfp;
-char_u *fname;
-int flags; /* flags for open() */
+static void
+mf_do_open (
+ memfile_T *mfp,
+ char_u *fname,
+ int flags /* flags for open() */
+)
{
#ifdef HAVE_LSTAT
struct stat sb;
@@ -1191,8 +1147,7 @@ int flags; /* flags for open() */
/*
* Initialize an empty hash table.
*/
-static void mf_hash_init(mht)
-mf_hashtab_T *mht;
+static void mf_hash_init(mf_hashtab_T *mht)
{
vim_memset(mht, 0, sizeof(mf_hashtab_T));
mht->mht_buckets = mht->mht_small_buckets;
@@ -1203,8 +1158,7 @@ mf_hashtab_T *mht;
* Free the array of a hash table. Does not free the items it contains!
* The hash table must not be used again without another mf_hash_init() call.
*/
-static void mf_hash_free(mht)
-mf_hashtab_T *mht;
+static void mf_hash_free(mf_hashtab_T *mht)
{
if (mht->mht_buckets != mht->mht_small_buckets)
vim_free(mht->mht_buckets);
@@ -1213,8 +1167,7 @@ mf_hashtab_T *mht;
/*
* Free the array of a hash table and all the items it contains.
*/
-static void mf_hash_free_all(mht)
-mf_hashtab_T *mht;
+static void mf_hash_free_all(mf_hashtab_T *mht)
{
long_u idx;
mf_hashitem_T *mhi;
@@ -1233,9 +1186,7 @@ mf_hashtab_T *mht;
* Find "key" in hashtable "mht".
* Returns a pointer to a mf_hashitem_T or NULL if the item was not found.
*/
-static mf_hashitem_T * mf_hash_find(mht, key)
-mf_hashtab_T *mht;
-blocknr_T key;
+static mf_hashitem_T *mf_hash_find(mf_hashtab_T *mht, blocknr_T key)
{
mf_hashitem_T *mhi;
@@ -1250,9 +1201,7 @@ blocknr_T key;
* Add item "mhi" to hashtable "mht".
* "mhi" must not be NULL.
*/
-static void mf_hash_add_item(mht, mhi)
-mf_hashtab_T *mht;
-mf_hashitem_T *mhi;
+static void mf_hash_add_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{
long_u idx;
@@ -1282,9 +1231,7 @@ mf_hashitem_T *mhi;
* Remove item "mhi" from hashtable "mht".
* "mhi" must not be NULL and must have been inserted into "mht".
*/
-static void mf_hash_rem_item(mht, mhi)
-mf_hashtab_T *mht;
-mf_hashitem_T *mhi;
+static void mf_hash_rem_item(mf_hashtab_T *mht, mf_hashitem_T *mhi)
{
if (mhi->mhi_prev == NULL)
mht->mht_buckets[mhi->mhi_key & mht->mht_mask] = mhi->mhi_next;
@@ -1305,8 +1252,7 @@ mf_hashitem_T *mhi;
* rehash items.
* Returns FAIL when out of memory.
*/
-static int mf_hash_grow(mht)
-mf_hashtab_T *mht;
+static int mf_hash_grow(mf_hashtab_T *mht)
{
long_u i, j;
int shift;
diff --git a/src/proto/memfile.pro b/src/memfile.h
index 3983b4799c..0ea6b9fd17 100644
--- a/src/proto/memfile.pro
+++ b/src/memfile.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MEMFILE_H
+#define NEOVIM_MEMFILE_H
/* memfile.c */
memfile_T *mf_open __ARGS((char_u *fname, int flags));
int mf_open_file __ARGS((memfile_T *mfp, char_u *fname));
@@ -16,3 +18,4 @@ void mf_set_ffname __ARGS((memfile_T *mfp));
void mf_fullname __ARGS((memfile_T *mfp));
int mf_need_trans __ARGS((memfile_T *mfp));
/* vim: set ft=c : */
+#endif /* NEOVIM_MEMFILE_H */
diff --git a/src/memline.c b/src/memline.c
index 15d5416829..292d09a37a 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -43,8 +43,30 @@
*/
#include "vim.h"
-
-#ifndef UNIX /* it's in os_unix.h for Unix */
+#include "memline.h"
+#include "blowfish.h"
+#include "buffer.h"
+#include "eval.h"
+#include "fileio.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memfile.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "os_unix.h"
+#include "screen.h"
+#include "sha256.h"
+#include "spell.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
+#include "os/os.h"
+
+#ifndef UNIX /* it's in os_unix_defs.h for Unix */
# include <time.h>
#endif
@@ -255,8 +277,7 @@ static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype)
*
* Return FAIL for failure, OK otherwise.
*/
-int ml_open(buf)
-buf_T *buf;
+int ml_open(buf_T *buf)
{
memfile_T *mfp;
bhdr_T *hp = NULL;
@@ -389,9 +410,7 @@ error:
/*
* Prepare encryption for "buf" with block 0 "b0p".
*/
-static void ml_set_b0_crypt(buf, b0p)
-buf_T *buf;
-ZERO_BL *b0p;
+static void ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p)
{
if (*buf->b_p_key == NUL)
b0p->b0_id[1] = BLOCK0_ID1;
@@ -415,10 +434,7 @@ ZERO_BL *b0p;
* "old_cm" is the previous 'cryptmethod'. It is equal to the current
* 'cryptmethod' when 'key' is changed.
*/
-void ml_set_crypt_key(buf, old_key, old_cm)
-buf_T *buf;
-char_u *old_key;
-int old_cm;
+void ml_set_crypt_key(buf_T *buf, char_u *old_key, int old_cm)
{
memfile_T *mfp = buf->b_ml.ml_mfp;
bhdr_T *hp;
@@ -533,8 +549,7 @@ int old_cm;
* ml_setname() is called when the file name of "buf" has been changed.
* It may rename the swap file.
*/
-void ml_setname(buf)
-buf_T *buf;
+void ml_setname(buf_T *buf)
{
int success = FALSE;
memfile_T *mfp;
@@ -615,7 +630,7 @@ buf_T *buf;
* been modified.
* Used when 'updatecount' changes from zero to non-zero.
*/
-void ml_open_files() {
+void ml_open_files(void) {
buf_T *buf;
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
@@ -628,8 +643,7 @@ void ml_open_files() {
* If we are unable to find a file name, mf_fname will be NULL
* and the memfile will be in memory only (no recovery possible).
*/
-void ml_open_file(buf)
-buf_T *buf;
+void ml_open_file(buf_T *buf)
{
memfile_T *mfp;
char_u *fname;
@@ -696,8 +710,10 @@ buf_T *buf;
* If still need to create a swap file, and starting to edit a not-readonly
* file, or reading into an existing buffer, create a swap file now.
*/
-void check_need_swap(newfile)
-int newfile; /* reading file into new buffer */
+void
+check_need_swap (
+ int newfile /* reading file into new buffer */
+)
{
if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
ml_open_file(curbuf);
@@ -707,9 +723,7 @@ int newfile; /* reading file into new buffer */
* Close memline for buffer 'buf'.
* If 'del_file' is TRUE, delete the swap file
*/
-void ml_close(buf, del_file)
-buf_T *buf;
-int del_file;
+void ml_close(buf_T *buf, int del_file)
{
if (buf->b_ml.ml_mfp == NULL) /* not open */
return;
@@ -732,8 +746,7 @@ int del_file;
* When 'del_file' is TRUE, delete the memfiles.
* But don't delete files that were ":preserve"d when we are POSIX compatible.
*/
-void ml_close_all(del_file)
-int del_file;
+void ml_close_all(int del_file)
{
buf_T *buf;
@@ -750,7 +763,7 @@ int del_file;
* Close all memfiles for not modified buffers.
* Only use just before exiting!
*/
-void ml_close_notmod() {
+void ml_close_notmod(void) {
buf_T *buf;
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
@@ -762,8 +775,7 @@ void ml_close_notmod() {
* Update the timestamp in the .swp file.
* Used when the file has been written.
*/
-void ml_timestamp(buf)
-buf_T *buf;
+void ml_timestamp(buf_T *buf)
{
ml_upd_block0(buf, UB_FNAME);
}
@@ -771,8 +783,7 @@ buf_T *buf;
/*
* Return FAIL when the ID of "b0p" is wrong.
*/
-static int ml_check_b0_id(b0p)
-ZERO_BL *b0p;
+static int ml_check_b0_id(ZERO_BL *b0p)
{
if (b0p->b0_id[0] != BLOCK0_ID0
|| (b0p->b0_id[1] != BLOCK0_ID1
@@ -786,9 +797,7 @@ ZERO_BL *b0p;
/*
* Update the timestamp or the B0_SAME_DIR flag of the .swp file.
*/
-static void ml_upd_block0(buf, what)
-buf_T *buf;
-upd_block0_T what;
+static void ml_upd_block0(buf_T *buf, upd_block0_T what)
{
memfile_T *mfp;
bhdr_T *hp;
@@ -816,9 +825,7 @@ upd_block0_T what;
* Also set buf->b_mtime.
* Don't use NameBuff[]!!!
*/
-static void set_b0_fname(b0p, buf)
-ZERO_BL *b0p;
-buf_T *buf;
+static void set_b0_fname(ZERO_BL *b0p, buf_T *buf)
{
struct stat st;
@@ -878,9 +885,7 @@ buf_T *buf;
* This is fail safe: if we are not sure the directories are equal the flag is
* not set.
*/
-static void set_b0_dir_flag(b0p, buf)
-ZERO_BL *b0p;
-buf_T *buf;
+static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
{
if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
b0p->b0_flags |= B0_SAME_DIR;
@@ -891,9 +896,7 @@ buf_T *buf;
/*
* When there is room, add the 'fileencoding' to block zero.
*/
-static void add_b0_fenc(b0p, buf)
-ZERO_BL *b0p;
-buf_T *buf;
+static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf)
{
int n;
int size = B0_FNAME_SIZE_NOCRYPT;
@@ -919,7 +922,7 @@ buf_T *buf;
/*
* Try to recover curbuf from the .swp file.
*/
-void ml_recover() {
+void ml_recover(void) {
buf_T *buf = NULL;
memfile_T *mfp = NULL;
char_u *fname;
@@ -1490,11 +1493,13 @@ theend:
* - list the swap files when recovering
* - find the name of the n'th swap file when recovering
*/
-int recover_names(fname, list, nr, fname_out)
-char_u *fname; /* base for swap file name */
-int list; /* when TRUE, list the swap file names */
-int nr; /* when non-zero, return nr'th swap file name */
-char_u **fname_out; /* result when "nr" > 0 */
+int
+recover_names (
+ char_u *fname, /* base for swap file name */
+ int list, /* when TRUE, list the swap file names */
+ int nr, /* when non-zero, return nr'th swap file name */
+ char_u **fname_out /* result when "nr" > 0 */
+)
{
int num_names;
char_u *(names[6]);
@@ -1694,9 +1699,7 @@ char_u **fname_out; /* result when "nr" > 0 */
* Append the full path to name with path separators made into percent
* signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
*/
-static char_u * make_percent_swname(dir, name)
-char_u *dir;
-char_u *name;
+static char_u *make_percent_swname(char_u *dir, char_u *name)
{
char_u *d, *s, *f;
@@ -1727,8 +1730,7 @@ static int process_still_running;
* Give information about an existing swap file.
* Returns timestamp (0 when unknown).
*/
-static time_t swapfile_info(fname)
-char_u *fname;
+static time_t swapfile_info(char_u *fname)
{
struct stat st;
int fd;
@@ -1817,10 +1819,7 @@ char_u *fname;
return x;
}
-static int recov_file_names(names, path, prepend_dot)
-char_u **names;
-char_u *path;
-int prepend_dot;
+static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
{
int num_names;
@@ -1909,9 +1908,7 @@ end:
* If 'check_char' is TRUE, stop syncing when character becomes available, but
* always sync at least one block.
*/
-void ml_sync_all(check_file, check_char)
-int check_file;
-int check_char;
+void ml_sync_all(int check_file, int check_char)
{
buf_T *buf;
struct stat st;
@@ -1956,9 +1953,7 @@ int check_char;
*
* when message is TRUE the success of preserving is reported
*/
-void ml_preserve(buf, message)
-buf_T *buf;
-int message;
+void ml_preserve(buf_T *buf, int message)
{
bhdr_T *hp;
linenr_T lnum;
@@ -2036,8 +2031,7 @@ theend:
* On failure an error message is given and IObuff is returned (to avoid
* having to check for error everywhere).
*/
-char_u * ml_get(lnum)
-linenr_T lnum;
+char_u *ml_get(linenr_T lnum)
{
return ml_get_buf(curbuf, lnum, FALSE);
}
@@ -2045,8 +2039,7 @@ linenr_T lnum;
/*
* Return pointer to position "pos".
*/
-char_u * ml_get_pos(pos)
-pos_T *pos;
+char_u *ml_get_pos(pos_T *pos)
{
return ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col;
}
@@ -2054,14 +2047,14 @@ pos_T *pos;
/*
* Return pointer to cursor line.
*/
-char_u * ml_get_curline() {
+char_u *ml_get_curline(void) {
return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
}
/*
* Return pointer to cursor position.
*/
-char_u * ml_get_cursor() {
+char_u *ml_get_cursor(void) {
return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
curwin->w_cursor.col;
}
@@ -2072,10 +2065,12 @@ char_u * ml_get_cursor() {
* "will_change": if TRUE mark the buffer dirty (chars in the line will be
* changed)
*/
-char_u * ml_get_buf(buf, lnum, will_change)
-buf_T *buf;
-linenr_T lnum;
-int will_change; /* line will be changed */
+char_u *
+ml_get_buf (
+ buf_T *buf,
+ linenr_T lnum,
+ int will_change /* line will be changed */
+)
{
bhdr_T *hp;
DATA_BL *dp;
@@ -2143,7 +2138,7 @@ errorret:
* Check if a line that was just obtained by a call to ml_get
* is in allocated memory.
*/
-int ml_line_alloced() {
+int ml_line_alloced(void) {
return curbuf->b_ml.ml_flags & ML_LINE_DIRTY;
}
@@ -2159,11 +2154,13 @@ int ml_line_alloced() {
*
* return FAIL for failure, OK otherwise
*/
-int ml_append(lnum, line, len, newfile)
-linenr_T lnum; /* append after this line (can be 0) */
-char_u *line; /* text of the new line */
-colnr_T len; /* length of new line, including NUL, or 0 */
-int newfile; /* flag, see above */
+int
+ml_append (
+ linenr_T lnum, /* append after this line (can be 0) */
+ char_u *line, /* text of the new line */
+ colnr_T len, /* length of new line, including NUL, or 0 */
+ int newfile /* flag, see above */
+)
{
/* When starting up, we might still need to create the memfile */
if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
@@ -2178,12 +2175,14 @@ int newfile; /* flag, see above */
* Like ml_append() but for an arbitrary buffer. The buffer must already have
* a memline.
*/
-int ml_append_buf(buf, lnum, line, len, newfile)
-buf_T *buf;
-linenr_T lnum; /* append after this line (can be 0) */
-char_u *line; /* text of the new line */
-colnr_T len; /* length of new line, including NUL, or 0 */
-int newfile; /* flag, see above */
+int
+ml_append_buf (
+ buf_T *buf,
+ linenr_T lnum, /* append after this line (can be 0) */
+ char_u *line, /* text of the new line */
+ colnr_T len, /* length of new line, including NUL, or 0 */
+ int newfile /* flag, see above */
+)
{
if (buf->b_ml.ml_mfp == NULL)
return FAIL;
@@ -2193,13 +2192,15 @@ int newfile; /* flag, see above */
return ml_append_int(buf, lnum, line, len, newfile, FALSE);
}
-static int ml_append_int(buf, lnum, line, len, newfile, mark)
-buf_T *buf;
-linenr_T lnum; /* append after this line (can be 0) */
-char_u *line; /* text of the new line */
-colnr_T len; /* length of line, including NUL, or 0 */
-int newfile; /* flag, see above */
-int mark; /* mark the new line */
+static int
+ml_append_int (
+ buf_T *buf,
+ linenr_T lnum, /* append after this line (can be 0) */
+ char_u *line, /* text of the new line */
+ colnr_T len, /* length of line, including NUL, or 0 */
+ int newfile, /* flag, see above */
+ int mark /* mark the new line */
+)
{
int i;
int line_count; /* number of indexes in current block */
@@ -2656,10 +2657,7 @@ int mark; /* mark the new line */
*
* return FAIL for failure, OK otherwise
*/
-int ml_replace(lnum, line, copy)
-linenr_T lnum;
-char_u *line;
-int copy;
+int ml_replace(linenr_T lnum, char_u *line, int copy)
{
if (line == NULL) /* just checking... */
return FAIL;
@@ -2689,18 +2687,13 @@ int copy;
*
* return FAIL for failure, OK otherwise
*/
-int ml_delete(lnum, message)
-linenr_T lnum;
-int message;
+int ml_delete(linenr_T lnum, int message)
{
ml_flush_line(curbuf);
return ml_delete_int(curbuf, lnum, message);
}
-static int ml_delete_int(buf, lnum, message)
-buf_T *buf;
-linenr_T lnum;
-int message;
+static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
{
bhdr_T *hp;
memfile_T *mfp;
@@ -2842,8 +2835,7 @@ int message;
/*
* set the B_MARKED flag for line 'lnum'
*/
-void ml_setmarked(lnum)
-linenr_T lnum;
+void ml_setmarked(linenr_T lnum)
{
bhdr_T *hp;
DATA_BL *dp;
@@ -2871,7 +2863,7 @@ linenr_T lnum;
/*
* find the first line with its B_MARKED flag set
*/
-linenr_T ml_firstmarked() {
+linenr_T ml_firstmarked(void) {
bhdr_T *hp;
DATA_BL *dp;
linenr_T lnum;
@@ -2911,7 +2903,7 @@ linenr_T ml_firstmarked() {
/*
* clear all DB_MARKED flags
*/
-void ml_clearmarked() {
+void ml_clearmarked(void) {
bhdr_T *hp;
DATA_BL *dp;
linenr_T lnum;
@@ -2949,8 +2941,7 @@ void ml_clearmarked() {
/*
* flush ml_line if necessary
*/
-static void ml_flush_line(buf)
-buf_T *buf;
+static void ml_flush_line(buf_T *buf)
{
bhdr_T *hp;
DATA_BL *dp;
@@ -3046,10 +3037,7 @@ buf_T *buf;
/*
* create a new, empty, data block
*/
-static bhdr_T * ml_new_data(mfp, negative, page_count)
-memfile_T *mfp;
-int negative;
-int page_count;
+static bhdr_T *ml_new_data(memfile_T *mfp, int negative, int page_count)
{
bhdr_T *hp;
DATA_BL *dp;
@@ -3069,8 +3057,7 @@ int page_count;
/*
* create a new, empty, pointer block
*/
-static bhdr_T * ml_new_ptr(mfp)
-memfile_T *mfp;
+static bhdr_T *ml_new_ptr(memfile_T *mfp)
{
bhdr_T *hp;
PTR_BL *pp;
@@ -3102,10 +3089,7 @@ memfile_T *mfp;
*
* return: NULL for failure, pointer to block header otherwise
*/
-static bhdr_T * ml_find_line(buf, lnum, action)
-buf_T *buf;
-linenr_T lnum;
-int action;
+static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
{
DATA_BL *dp;
PTR_BL *pp;
@@ -3286,8 +3270,7 @@ error_noblock:
*
* return -1 for failure, number of the new entry otherwise
*/
-static int ml_add_stack(buf)
-buf_T *buf;
+static int ml_add_stack(buf_T *buf)
{
int top;
infoptr_T *newstack;
@@ -3323,9 +3306,7 @@ buf_T *buf;
*
* Count is the number of lines added, negative if lines have been deleted.
*/
-static void ml_lineadd(buf, count)
-buf_T *buf;
-int count;
+static void ml_lineadd(buf_T *buf, int count)
{
int idx;
infoptr_T *ip;
@@ -3357,9 +3338,7 @@ int count;
* If it worked returns OK and the resolved link in "buf[MAXPATHL]".
* Otherwise returns FAIL.
*/
-int resolve_symlink(fname, buf)
-char_u *fname;
-char_u *buf;
+int resolve_symlink(char_u *fname, char_u *buf)
{
char_u tmp[MAXPATHL];
int ret;
@@ -3427,11 +3406,7 @@ char_u *buf;
* Make swap file name out of the file name and a directory name.
* Returns pointer to allocated memory or NULL.
*/
-char_u * makeswapname(fname, ffname, buf, dir_name)
-char_u *fname;
-char_u *ffname UNUSED;
-buf_T *buf;
-char_u *dir_name;
+char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name)
{
char_u *r, *s;
char_u *fname_res = fname;
@@ -3494,9 +3469,11 @@ char_u *dir_name;
*
* The return value is an allocated string and can be NULL.
*/
-char_u * get_file_in_dir(fname, dname)
-char_u *fname;
-char_u *dname; /* don't use "dirname", it is a global for Alpha */
+char_u *
+get_file_in_dir (
+ char_u *fname,
+ char_u *dname /* don't use "dirname", it is a global for Alpha */
+)
{
char_u *t;
char_u *tail;
@@ -3534,9 +3511,11 @@ static void attention_message __ARGS((buf_T *buf, char_u *fname));
/*
* Print the ATTENTION message: info about an existing swap file.
*/
-static void attention_message(buf, fname)
-buf_T *buf; /* buffer being edited */
-char_u *fname; /* swap file name */
+static void
+attention_message (
+ buf_T *buf, /* buffer being edited */
+ char_u *fname /* swap file name */
+)
{
struct stat st;
time_t x, sx;
@@ -3591,9 +3570,7 @@ static int do_swapexists __ARGS((buf_T *buf, char_u *fname));
* 5: quit
* 6: abort
*/
-static int do_swapexists(buf, fname)
-buf_T *buf;
-char_u *fname;
+static int do_swapexists(buf_T *buf, char_u *fname)
{
set_vim_var_string(VV_SWAPNAME, fname, -1);
set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
@@ -3629,10 +3606,12 @@ char_u *fname;
* not being able to open the swap or undo file
* Note: May trigger SwapExists autocmd, pointers may change!
*/
-static char_u * findswapname(buf, dirp, old_fname)
-buf_T *buf;
-char_u **dirp; /* pointer to list of directories */
-char_u *old_fname; /* don't give warning for this file name */
+static char_u *
+findswapname (
+ buf_T *buf,
+ char_u **dirp, /* pointer to list of directories */
+ char_u *old_fname /* don't give warning for this file name */
+)
{
char_u *fname;
int n;
@@ -4030,8 +4009,7 @@ char_u *old_fname; /* don't give warning for this file name */
return fname;
}
-static int b0_magic_wrong(b0p)
-ZERO_BL *b0p;
+static int b0_magic_wrong(ZERO_BL *b0p)
{
return b0p->b0_magic_long != (long)B0_MAGIC_LONG
|| b0p->b0_magic_int != (int)B0_MAGIC_INT
@@ -4089,10 +4067,12 @@ ZERO_BL *b0p;
* versions.
*/
-static int fnamecmp_ino(fname_c, fname_s, ino_block0)
-char_u *fname_c; /* current file name */
-char_u *fname_s; /* file name from swap file */
-long ino_block0;
+static int
+fnamecmp_ino (
+ char_u *fname_c, /* current file name */
+ char_u *fname_s, /* file name from swap file */
+ long ino_block0
+)
{
struct stat st;
ino_t ino_c = 0; /* ino of current file */
@@ -4141,9 +4121,7 @@ long ino_block0;
* Move a long integer into a four byte character array.
* Used for machine independency in block zero.
*/
-static void long_to_char(n, s)
-long n;
-char_u *s;
+static void long_to_char(long n, char_u *s)
{
s[0] = (char_u)(n & 0xff);
n = (unsigned)n >> 8;
@@ -4154,8 +4132,7 @@ char_u *s;
s[3] = (char_u)(n & 0xff);
}
-static long char_to_long(s)
-char_u *s;
+static long char_to_long(char_u *s)
{
long retval;
@@ -4176,8 +4153,7 @@ char_u *s;
* - 'fileformat'
* - 'fileencoding'
*/
-void ml_setflags(buf)
-buf_T *buf;
+void ml_setflags(buf_T *buf)
{
bhdr_T *hp;
ZERO_BL *b0p;
@@ -4203,11 +4179,7 @@ buf_T *buf;
* in allocated memory. Return NULL when out of memory.
* Otherwise return "data".
*/
-char_u * ml_encrypt_data(mfp, data, offset, size)
-memfile_T *mfp;
-char_u *data;
-off_t offset;
-unsigned size;
+char_u *ml_encrypt_data(memfile_T *mfp, char_u *data, off_t offset, unsigned size)
{
DATA_BL *dp = (DATA_BL *)data;
char_u *head_end;
@@ -4244,11 +4216,7 @@ unsigned size;
/*
* Decrypt the text in "data" if it points to a data block.
*/
-void ml_decrypt_data(mfp, data, offset, size)
-memfile_T *mfp;
-char_u *data;
-off_t offset;
-unsigned size;
+void ml_decrypt_data(memfile_T *mfp, char_u *data, off_t offset, unsigned size)
{
DATA_BL *dp = (DATA_BL *)data;
char_u *head_end;
@@ -4275,10 +4243,7 @@ unsigned size;
/*
* Prepare for encryption/decryption, using the key, seed and offset.
*/
-static void ml_crypt_prepare(mfp, offset, reading)
-memfile_T *mfp;
-off_t offset;
-int reading;
+static void ml_crypt_prepare(memfile_T *mfp, off_t offset, int reading)
{
buf_T *buf = mfp->mf_buffer;
char_u salt[50];
@@ -4323,11 +4288,7 @@ int reading;
* ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
* ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
*/
-static void ml_updatechunk(buf, line, len, updtype)
-buf_T *buf;
-linenr_T line;
-long len;
-int updtype;
+static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
{
static buf_T *ml_upd_lastbuf = NULL;
static linenr_T ml_upd_lastline;
@@ -4533,10 +4494,7 @@ int updtype;
* Find offset of line if "lnum" > 0
* return -1 if information is not available
*/
-long ml_find_line_or_offset(buf, lnum, offp)
-buf_T *buf;
-linenr_T lnum;
-long *offp;
+long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
{
linenr_T curline;
int curix;
@@ -4652,8 +4610,7 @@ long *offp;
/*
* Goto byte in buffer with offset 'cnt'.
*/
-void goto_byte(cnt)
-long cnt;
+void goto_byte(long cnt)
{
long boff = cnt;
linenr_T lnum;
diff --git a/src/proto/memline.pro b/src/memline.h
index 97806d38a2..7a18633d25 100644
--- a/src/proto/memline.pro
+++ b/src/memline.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MEMLINE_H
+#define NEOVIM_MEMLINE_H
/* memline.c */
int ml_open __ARGS((buf_T *buf));
void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, int old_cm));
@@ -39,3 +41,4 @@ void ml_decrypt_data __ARGS((memfile_T *mfp, char_u *data, off_t offset,
long ml_find_line_or_offset __ARGS((buf_T *buf, linenr_T lnum, long *offp));
void goto_byte __ARGS((long cnt));
/* vim: set ft=c : */
+#endif /* NEOVIM_MEMLINE_H */
diff --git a/src/menu.c b/src/menu.c
index 12e91b0ae6..95ac7bd5f5 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -13,6 +13,15 @@
*/
#include "vim.h"
+#include "menu.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_docmd.h"
+#include "getchar.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "term.h"
#define MENUDEPTH 10 /* maximum depth of menus */
@@ -53,8 +62,10 @@ static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
/*
* Do the :menu command and relatives.
*/
-void ex_menu(eap)
-exarg_T *eap; /* Ex command arguments */
+void
+ex_menu (
+ exarg_T *eap /* Ex command arguments */
+)
{
char_u *menu_path;
int modes;
@@ -262,12 +273,14 @@ theend:
/*
* Add the menu with the given name to the menu hierarchy
*/
-static int add_menu_path(menu_path, menuarg, pri_tab, call_data)
-char_u *menu_path;
-vimmenu_T *menuarg; /* passes modes, iconfile, iconidx,
+static int
+add_menu_path (
+ char_u *menu_path,
+ vimmenu_T *menuarg, /* passes modes, iconfile, iconidx,
icon_builtin, silent[0], noremap[0] */
-int *pri_tab;
-char_u *call_data;
+ int *pri_tab,
+ char_u *call_data
+)
{
char_u *path_name;
int modes = menuarg->modes;
@@ -506,11 +519,7 @@ erret:
* Set the (sub)menu with the given name to enabled or disabled.
* Called recursively.
*/
-static int menu_nable_recurse(menu, name, modes, enable)
-vimmenu_T *menu;
-char_u *name;
-int modes;
-int enable;
+static int menu_nable_recurse(vimmenu_T *menu, char_u *name, int modes, int enable)
{
char_u *p;
@@ -559,11 +568,13 @@ int enable;
* Remove the (sub)menu with the given name from the menu hierarchy
* Called recursively.
*/
-static int remove_menu(menup, name, modes, silent)
-vimmenu_T **menup;
-char_u *name;
-int modes;
-int silent; /* don't give error messages */
+static int
+remove_menu (
+ vimmenu_T **menup,
+ char_u *name,
+ int modes,
+ int silent /* don't give error messages */
+)
{
vimmenu_T *menu;
vimmenu_T *child;
@@ -666,8 +677,7 @@ int silent; /* don't give error messages */
/*
* Free the given menu structure and remove it from the linked list.
*/
-static void free_menu(menup)
-vimmenu_T **menup;
+static void free_menu(vimmenu_T **menup)
{
int i;
vimmenu_T *menu;
@@ -692,9 +702,7 @@ vimmenu_T **menup;
/*
* Free the menu->string with the given index.
*/
-static void free_menu_string(menu, idx)
-vimmenu_T *menu;
-int idx;
+static void free_menu_string(vimmenu_T *menu, int idx)
{
int count = 0;
int i;
@@ -710,9 +718,7 @@ int idx;
/*
* Show the mapping associated with a menu item or hierarchy in a sub-menu.
*/
-static int show_menus(path_name, modes)
-char_u *path_name;
-int modes;
+static int show_menus(char_u *path_name, int modes)
{
char_u *p;
char_u *name;
@@ -765,10 +771,7 @@ int modes;
/*
* Recursively show the mappings associated with the menus under the given one
*/
-static void show_menus_recursive(menu, modes, depth)
-vimmenu_T *menu;
-int modes;
-int depth;
+static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
{
int i;
int bit;
@@ -844,11 +847,7 @@ static int expand_emenu; /* TRUE for ":emenu" command */
/*
* Work out what to complete when doing command line completion of menu names.
*/
-char_u * set_context_in_menu_cmd(xp, cmd, arg, forceit)
-expand_T *xp;
-char_u *cmd;
-char_u *arg;
-int forceit;
+char_u *set_context_in_menu_cmd(expand_T *xp, char_u *cmd, char_u *arg, int forceit)
{
char_u *after_dot;
char_u *p;
@@ -952,9 +951,7 @@ int forceit;
* Function given to ExpandGeneric() to obtain the list of (sub)menus (not
* entries).
*/
-char_u * get_menu_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_menu_name(expand_T *xp, int idx)
{
static vimmenu_T *menu = NULL;
char_u *str;
@@ -999,9 +996,7 @@ int idx;
* Function given to ExpandGeneric() to obtain the list of menus and menu
* entries.
*/
-char_u * get_menu_names(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_menu_names(expand_T *xp, int idx)
{
static vimmenu_T *menu = NULL;
#define TBUFFER_LEN 256
@@ -1065,8 +1060,7 @@ int idx;
* element. Any \ and ^Vs are removed from the current element.
* "name" may be modified.
*/
-char_u * menu_name_skip(name)
-char_u *name;
+char_u *menu_name_skip(char_u *name)
{
char_u *p;
@@ -1086,9 +1080,7 @@ char_u *name;
* Return TRUE when "name" matches with menu "menu". The name is compared in
* two ways: raw menu name and menu name without '&'. ignore part after a TAB.
*/
-static int menu_name_equal(name, menu)
-char_u *name;
-vimmenu_T *menu;
+static int menu_name_equal(char_u *name, vimmenu_T *menu)
{
if (menu->en_name != NULL
&& (menu_namecmp(name, menu->en_name)
@@ -1097,9 +1089,7 @@ vimmenu_T *menu;
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
}
-static int menu_namecmp(name, mname)
-char_u *name;
-char_u *mname;
+static int menu_namecmp(char_u *name, char_u *mname)
{
int i;
@@ -1118,11 +1108,13 @@ char_u *mname;
* If "unmenu" is not NULL, then the flag it points to is set according to
* whether the command is an "unmenu" command.
*/
-static int get_menu_cmd_modes(cmd, forceit, noremap, unmenu)
-char_u *cmd;
-int forceit; /* Was there a "!" after the command? */
-int *noremap;
-int *unmenu;
+static int
+get_menu_cmd_modes (
+ char_u *cmd,
+ int forceit, /* Was there a "!" after the command? */
+ int *noremap,
+ int *unmenu
+)
{
int modes;
@@ -1179,9 +1171,7 @@ int *unmenu;
* Modify a menu name starting with "PopUp" to include the mode character.
* Returns the name in allocated memory (NULL for failure).
*/
-static char_u * popup_mode_name(name, idx)
-char_u *name;
-int idx;
+static char_u *popup_mode_name(char_u *name, int idx)
{
char_u *p;
int len = (int)STRLEN(name);
@@ -1202,10 +1192,7 @@ int idx;
* If mnemonic != NULL, *mnemonic is set to the character after the first '&'.
* If actext != NULL, *actext is set to the text after the first TAB.
*/
-static char_u * menu_text(str, mnemonic, actext)
-char_u *str;
-int *mnemonic;
-char_u **actext;
+static char_u *menu_text(char_u *str, int *mnemonic, char_u **actext)
{
char_u *p;
char_u *text;
@@ -1251,8 +1238,7 @@ char_u **actext;
/*
* Return TRUE if "name" can be a menu in the MenuBar.
*/
-int menu_is_menubar(name)
-char_u *name;
+int menu_is_menubar(char_u *name)
{
return !menu_is_popup(name)
&& !menu_is_toolbar(name)
@@ -1262,8 +1248,7 @@ char_u *name;
/*
* Return TRUE if "name" is a popup menu name.
*/
-int menu_is_popup(name)
-char_u *name;
+int menu_is_popup(char_u *name)
{
return STRNCMP(name, "PopUp", 5) == 0;
}
@@ -1272,8 +1257,7 @@ char_u *name;
/*
* Return TRUE if "name" is a toolbar menu name.
*/
-int menu_is_toolbar(name)
-char_u *name;
+int menu_is_toolbar(char_u *name)
{
return STRNCMP(name, "ToolBar", 7) == 0;
}
@@ -1282,8 +1266,7 @@ char_u *name;
* Return TRUE if the name is a menu separator identifier: Starts and ends
* with '-'
*/
-int menu_is_separator(name)
-char_u *name;
+int menu_is_separator(char_u *name)
{
return name[0] == '-' && name[STRLEN(name) - 1] == '-';
}
@@ -1291,8 +1274,7 @@ char_u *name;
/*
* Return TRUE if the menu is hidden: Starts with ']'
*/
-static int menu_is_hidden(name)
-char_u *name;
+static int menu_is_hidden(char_u *name)
{
return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
}
@@ -1302,8 +1284,7 @@ char_u *name;
/*
* Return TRUE if the menu is the tearoff menu.
*/
-static int menu_is_tearoff(name)
-char_u *name UNUSED;
+static int menu_is_tearoff(char_u *name)
{
return FALSE;
}
@@ -1315,8 +1296,7 @@ char_u *name UNUSED;
* Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy and
* execute it.
*/
-void ex_emenu(eap)
-exarg_T *eap;
+void ex_emenu(exarg_T *eap)
{
vimmenu_T *menu;
char_u *name;
@@ -1430,8 +1410,7 @@ exarg_T *eap;
/*
* Given a menu descriptor, e.g. "File.New", find it in the menu hierarchy.
*/
-vimmenu_T * gui_find_menu(path_name)
-char_u *path_name;
+vimmenu_T *gui_find_menu(char_u *path_name)
{
vimmenu_T *menu = NULL;
char_u *name;
@@ -1499,8 +1478,7 @@ static garray_T menutrans_ga = {0, 0, 0, 0, NULL};
* This function is also defined without the +multi_lang feature, in which
* case the commands are ignored.
*/
-void ex_menutranslate(eap)
-exarg_T *eap UNUSED;
+void ex_menutranslate(exarg_T *eap)
{
char_u *arg = eap->arg;
menutrans_T *tp;
@@ -1562,8 +1540,7 @@ exarg_T *eap UNUSED;
/*
* Find the character just after one part of a menu name.
*/
-static char_u * menu_skip_part(p)
-char_u *p;
+static char_u *menu_skip_part(char_u *p)
{
while (*p != NUL && *p != '.' && !vim_iswhite(*p)) {
if ((*p == '\\' || *p == Ctrl_V) && p[1] != NUL)
@@ -1577,9 +1554,7 @@ char_u *p;
* Lookup part of a menu name in the translations.
* Return a pointer to the translation or NULL if not found.
*/
-static char_u * menutrans_lookup(name, len)
-char_u *name;
-int len;
+static char_u *menutrans_lookup(char_u *name, int len)
{
menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
int i;
@@ -1609,8 +1584,7 @@ int len;
/*
* Unescape the name in the translate dictionary table.
*/
-static void menu_unescape_name(name)
-char_u *name;
+static void menu_unescape_name(char_u *name)
{
char_u *p;
@@ -1623,8 +1597,7 @@ char_u *name;
* Isolate the menu name.
* Skip the menu name, and translate <Tab> into a real TAB.
*/
-static char_u * menu_translate_tab_and_shift(arg_start)
-char_u *arg_start;
+static char_u *menu_translate_tab_and_shift(char_u *arg_start)
{
char_u *arg = arg_start;
diff --git a/src/proto/menu.pro b/src/menu.h
index 80460d2de2..0d76b523bd 100644
--- a/src/proto/menu.pro
+++ b/src/menu.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MENU_H
+#define NEOVIM_MENU_H
/* menu.c */
void ex_menu __ARGS((exarg_T *eap));
char_u *set_context_in_menu_cmd __ARGS((expand_T *xp, char_u *cmd, char_u *arg,
@@ -21,3 +23,4 @@ void ex_emenu __ARGS((exarg_T *eap));
vimmenu_T *gui_find_menu __ARGS((char_u *path_name));
void ex_menutranslate __ARGS((exarg_T *eap));
/* vim: set ft=c : */
+#endif /* NEOVIM_MENU_H */
diff --git a/src/message.c b/src/message.c
index 9a9fd87f72..99d52380a4 100644
--- a/src/message.c
+++ b/src/message.c
@@ -14,6 +14,20 @@
#define MESSAGE_FILE /* don't include prototype for smsg() */
#include "vim.h"
+#include "message.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_eval.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "mbyte.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "ops.h"
+#include "option.h"
+#include "screen.h"
+#include "term.h"
+#include "ui.h"
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
# include <math.h>
@@ -100,8 +114,7 @@ static int verbose_did_open = FALSE;
* When terminal not initialized (yet) mch_errmsg(..) is used.
* return TRUE if wait_return not called
*/
-int msg(s)
-char_u *s;
+int msg(char_u *s)
{
return msg_attr_keep(s, 0, FALSE);
}
@@ -111,8 +124,7 @@ char_u *s;
/*
* Like msg() but keep it silent when 'verbosefile' is set.
*/
-int verb_msg(s)
-char_u *s;
+int verb_msg(char_u *s)
{
int n;
@@ -124,17 +136,17 @@ char_u *s;
}
#endif
-int msg_attr(s, attr)
-char_u *s;
-int attr;
+int msg_attr(char_u *s, int attr)
{
return msg_attr_keep(s, attr, FALSE);
}
-int msg_attr_keep(s, attr, keep)
-char_u *s;
-int attr;
-int keep; /* TRUE: set keep_msg if it doesn't scroll */
+int
+msg_attr_keep (
+ char_u *s,
+ int attr,
+ int keep /* TRUE: set keep_msg if it doesn't scroll */
+)
{
static int entered = 0;
int retval;
@@ -189,9 +201,11 @@ int keep; /* TRUE: set keep_msg if it doesn't scroll */
* Truncate a string such that it can be printed without causing a scroll.
* Returns an allocated string or NULL when no truncating is done.
*/
-char_u * msg_strtrunc(s, force)
-char_u *s;
-int force; /* always truncate */
+char_u *
+msg_strtrunc (
+ char_u *s,
+ int force /* always truncate */
+)
{
char_u *buf = NULL;
int len;
@@ -229,11 +243,7 @@ int force; /* always truncate */
* Truncate a string "s" to "buf" with cell width "room".
* "s" and "buf" may be equal.
*/
-void trunc_string(s, buf, room, buflen)
-char_u *s;
-char_u *buf;
-int room;
-int buflen;
+void trunc_string(char_u *s, char_u *buf, int room, int buflen)
{
int half;
int len;
@@ -331,18 +341,13 @@ int vim_snprintf __ARGS((char *, size_t, char *, long, long, long,
*/
/* VARARGS */
-int smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
-char_u *s;
-long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+int smsg(char_u *s, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10)
{
return smsg_attr(0, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
/* VARARGS */
-int smsg_attr(attr, s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
-int attr;
-char_u *s;
-long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+int smsg_attr(int attr, char_u *s, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10)
{
vim_snprintf((char *)IObuff, IOSIZE, (char *)s,
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
@@ -384,7 +389,7 @@ static char_u *last_sourcing_name = NULL;
* Reset the last used sourcing name/lnum. Makes sure it is displayed again
* for the next error message;
*/
-void reset_last_sourcing() {
+void reset_last_sourcing(void) {
vim_free(last_sourcing_name);
last_sourcing_name = NULL;
last_sourcing_lnum = 0;
@@ -393,7 +398,7 @@ void reset_last_sourcing() {
/*
* Return TRUE if "sourcing_name" differs from "last_sourcing_name".
*/
-static int other_sourcing_name() {
+static int other_sourcing_name(void) {
if (sourcing_name != NULL) {
if (last_sourcing_name != NULL)
return STRCMP(sourcing_name, last_sourcing_name) != 0;
@@ -407,7 +412,7 @@ static int other_sourcing_name() {
* Returns an allocated string with room for one more character.
* Returns NULL when no message is to be given.
*/
-static char_u * get_emsg_source() {
+static char_u *get_emsg_source(void) {
char_u *Buf, *p;
if (sourcing_name != NULL && other_sourcing_name()) {
@@ -425,7 +430,7 @@ static char_u * get_emsg_source() {
* Returns an allocated string with room for one more character.
* Returns NULL when no message is to be given.
*/
-static char_u * get_emsg_lnum() {
+static char_u *get_emsg_lnum(void) {
char_u *Buf, *p;
/* lnum is 0 when executing a command from the command line
@@ -447,8 +452,7 @@ static char_u * get_emsg_lnum() {
* Remember the file name and line number, so that for the next error the info
* is only displayed if it changed.
*/
-void msg_source(attr)
-int attr;
+void msg_source(int attr)
{
char_u *p;
@@ -482,7 +486,7 @@ int attr;
* If "msg" is in 'debug': do error message but without side effects.
* If "emsg_skip" is set: never do error messages.
*/
-int emsg_not_now() {
+int emsg_not_now(void) {
if ((emsg_off > 0 && vim_strchr(p_debug, 'm') == NULL
&& vim_strchr(p_debug, 't') == NULL)
|| emsg_skip > 0
@@ -499,8 +503,7 @@ int emsg_not_now() {
*
* return TRUE if wait_return not called
*/
-int emsg(s)
-char_u *s;
+int emsg(char_u *s)
{
int attr;
char_u *p;
@@ -598,16 +601,14 @@ char_u *s;
/*
* Print an error message with one "%s" and one string argument.
*/
-int emsg2(s, a1)
-char_u *s, *a1;
+int emsg2(char_u *s, char_u *a1)
{
return emsg3(s, a1, NULL);
}
/* emsg3() and emsgn() are in misc2.c to avoid warnings for the prototypes. */
-void emsg_invreg(name)
-int name;
+void emsg_invreg(int name)
{
EMSG2(_("E354: Invalid register name: '%s'"), transchar(name));
}
@@ -618,10 +619,7 @@ int name;
* Careful: The string may be changed by msg_may_trunc()!
* Returns a pointer to the printed message, if wait_return() not called.
*/
-char_u * msg_trunc_attr(s, force, attr)
-char_u *s;
-int force;
-int attr;
+char_u *msg_trunc_attr(char_u *s, int force, int attr)
{
int n;
@@ -644,9 +642,7 @@ int attr;
* Return a pointer to where the truncated message starts.
* Note: May change the message by replacing a character with '<'.
*/
-char_u * msg_may_trunc(force, s)
-int force;
-char_u *s;
+char_u *msg_may_trunc(int force, char_u *s)
{
int n;
int room;
@@ -673,10 +669,12 @@ char_u *s;
return s;
}
-static void add_msg_hist(s, len, attr)
-char_u *s;
-int len; /* -1 for undetermined length */
-int attr;
+static void
+add_msg_hist (
+ char_u *s,
+ int len, /* -1 for undetermined length */
+ int attr
+)
{
struct msg_hist *p;
@@ -715,7 +713,7 @@ int attr;
* Delete the first (oldest) message from the history.
* Returns FAIL if there are no messages.
*/
-int delete_first_msg() {
+int delete_first_msg(void) {
struct msg_hist *p;
if (msg_hist_len <= 0)
@@ -733,8 +731,7 @@ int delete_first_msg() {
/*
* ":messages" command.
*/
-void ex_messages(eap)
-exarg_T *eap UNUSED;
+void ex_messages(exarg_T *eap)
{
struct msg_hist *p;
char_u *s;
@@ -758,7 +755,7 @@ exarg_T *eap UNUSED;
* Call this after prompting the user. This will avoid a hit-return message
* and a delay.
*/
-void msg_end_prompt() {
+void msg_end_prompt(void) {
need_wait_return = FALSE;
emsg_on_display = FALSE;
cmdline_row = msg_row;
@@ -773,8 +770,7 @@ void msg_end_prompt() {
* if 'redraw' is FALSE, just redraw the screen
* if 'redraw' is -1, don't redraw at all
*/
-void wait_return(redraw)
-int redraw;
+void wait_return(int redraw)
{
int c;
int oldState;
@@ -977,7 +973,7 @@ int redraw;
/*
* Write the hit-return prompt.
*/
-static void hit_return_msg() {
+static void hit_return_msg(void) {
int save_p_more = p_more;
p_more = FALSE; /* don't want see this message when scrolling back */
@@ -995,9 +991,7 @@ static void hit_return_msg() {
/*
* Set "keep_msg" to "s". Free the old value and check for NULL pointer.
*/
-void set_keep_msg(s, attr)
-char_u *s;
-int attr;
+void set_keep_msg(char_u *s, int attr)
{
vim_free(keep_msg);
if (s != NULL && msg_silent == 0)
@@ -1012,7 +1006,7 @@ int attr;
* If there currently is a message being displayed, set "keep_msg" to it, so
* that it will be displayed again after redraw.
*/
-void set_keep_msg_from_hist() {
+void set_keep_msg_from_hist(void) {
if (keep_msg == NULL && last_msg_hist != NULL && msg_scrolled == 0
&& (State & NORMAL))
set_keep_msg(last_msg_hist->msg, last_msg_hist->attr);
@@ -1021,7 +1015,7 @@ void set_keep_msg_from_hist() {
/*
* Prepare for outputting characters in the command line.
*/
-void msg_start() {
+void msg_start(void) {
int did_return = FALSE;
if (!msg_silent) {
@@ -1062,20 +1056,17 @@ void msg_start() {
/*
* Note that the current msg position is where messages start.
*/
-void msg_starthere() {
+void msg_starthere(void) {
lines_left = cmdline_row;
msg_didany = FALSE;
}
-void msg_putchar(c)
-int c;
+void msg_putchar(int c)
{
msg_putchar_attr(c, 0);
}
-void msg_putchar_attr(c, attr)
-int c;
-int attr;
+void msg_putchar_attr(int c, int attr)
{
char_u buf[MB_MAXBYTES + 1];
@@ -1090,8 +1081,7 @@ int attr;
msg_puts_attr(buf, attr);
}
-void msg_outnum(n)
-long n;
+void msg_outnum(long n)
{
char_u buf[20];
@@ -1099,21 +1089,17 @@ long n;
msg_puts(buf);
}
-void msg_home_replace(fname)
-char_u *fname;
+void msg_home_replace(char_u *fname)
{
msg_home_replace_attr(fname, 0);
}
-void msg_home_replace_hl(fname)
-char_u *fname;
+void msg_home_replace_hl(char_u *fname)
{
msg_home_replace_attr(fname, hl_attr(HLF_D));
}
-static void msg_home_replace_attr(fname, attr)
-char_u *fname;
-int attr;
+static void msg_home_replace_attr(char_u *fname, int attr)
{
char_u *name;
@@ -1129,22 +1115,17 @@ int attr;
* Use attributes 'attr'.
* Return the number of characters it takes on the screen.
*/
-int msg_outtrans(str)
-char_u *str;
+int msg_outtrans(char_u *str)
{
return msg_outtrans_attr(str, 0);
}
-int msg_outtrans_attr(str, attr)
-char_u *str;
-int attr;
+int msg_outtrans_attr(char_u *str, int attr)
{
return msg_outtrans_len_attr(str, (int)STRLEN(str), attr);
}
-int msg_outtrans_len(str, len)
-char_u *str;
-int len;
+int msg_outtrans_len(char_u *str, int len)
{
return msg_outtrans_len_attr(str, len, 0);
}
@@ -1153,9 +1134,7 @@ int len;
* Output one character at "p". Return pointer to the next character.
* Handles multi-byte characters.
*/
-char_u * msg_outtrans_one(p, attr)
-char_u *p;
-int attr;
+char_u *msg_outtrans_one(char_u *p, int attr)
{
int l;
@@ -1167,10 +1146,7 @@ int attr;
return p + 1;
}
-int msg_outtrans_len_attr(msgstr, len, attr)
-char_u *msgstr;
-int len;
-int attr;
+int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
{
int retval = 0;
char_u *str = msgstr;
@@ -1243,8 +1219,7 @@ int attr;
return retval;
}
-void msg_make(arg)
-char_u *arg;
+void msg_make(char_u *arg)
{
int i;
static char_u *str = (char_u *)"eeffoc", *rs = (char_u *)"Plon#dqg#vxjduB";
@@ -1274,9 +1249,11 @@ char_u *arg;
* This function is used to show mappings, where we want to see how to type
* the character/string -- webb
*/
-int msg_outtrans_special(strstart, from)
-char_u *strstart;
-int from; /* TRUE for lhs of a mapping */
+int
+msg_outtrans_special (
+ char_u *strstart,
+ int from /* TRUE for lhs of a mapping */
+)
{
char_u *str = strstart;
int retval = 0;
@@ -1306,9 +1283,11 @@ int from; /* TRUE for lhs of a mapping */
* Return the lhs or rhs of a mapping, with the key codes turned into printable
* strings, in an allocated string.
*/
-char_u * str2special_save(str, is_lhs)
-char_u *str;
-int is_lhs; /* TRUE for lhs, FALSE for rhs */
+char_u *
+str2special_save (
+ char_u *str,
+ int is_lhs /* TRUE for lhs, FALSE for rhs */
+)
{
garray_T ga;
char_u *p = str;
@@ -1325,9 +1304,11 @@ int is_lhs; /* TRUE for lhs, FALSE for rhs */
* Used for translating the lhs or rhs of a mapping to printable chars.
* Advances "sp" to the next code.
*/
-char_u * str2special(sp, from)
-char_u **sp;
-int from; /* TRUE for lhs of mapping */
+char_u *
+str2special (
+ char_u **sp,
+ int from /* TRUE for lhs of mapping */
+)
{
int c;
static char_u buf[7];
@@ -1390,10 +1371,7 @@ int from; /* TRUE for lhs of mapping */
/*
* Translate a key sequence into special key names.
*/
-void str2specialbuf(sp, buf, len)
-char_u *sp;
-char_u *buf;
-int len;
+void str2specialbuf(char_u *sp, char_u *buf, int len)
{
char_u *s;
@@ -1408,9 +1386,7 @@ int len;
/*
* print line for :print or :list command
*/
-void msg_prt_line(s, list)
-char_u *s;
-int list;
+void msg_prt_line(char_u *s, int list)
{
int c;
int col = 0;
@@ -1508,10 +1484,7 @@ int list;
* Use screen_puts() to output one multi-byte character.
* Return the pointer "s" advanced to the next character.
*/
-static char_u * screen_puts_mbyte(s, l, attr)
-char_u *s;
-int l;
-int attr;
+static char_u *screen_puts_mbyte(char_u *s, int l, int attr)
{
int cw;
@@ -1546,14 +1519,12 @@ int attr;
* Output a string to the screen at position msg_row, msg_col.
* Update msg_row and msg_col for the next message.
*/
-void msg_puts(s)
-char_u *s;
+void msg_puts(char_u *s)
{
msg_puts_attr(s, 0);
}
-void msg_puts_title(s)
-char_u *s;
+void msg_puts_title(char_u *s)
{
msg_puts_attr(s, hl_attr(HLF_T));
}
@@ -1563,17 +1534,12 @@ char_u *s;
* part in the middle and replace it with "..." when necessary.
* Does not handle multi-byte characters!
*/
-void msg_puts_long_attr(longstr, attr)
-char_u *longstr;
-int attr;
+void msg_puts_long_attr(char_u *longstr, int attr)
{
msg_puts_long_len_attr(longstr, (int)STRLEN(longstr), attr);
}
-void msg_puts_long_len_attr(longstr, len, attr)
-char_u *longstr;
-int len;
-int attr;
+void msg_puts_long_len_attr(char_u *longstr, int len, int attr)
{
int slen = len;
int room;
@@ -1590,9 +1556,7 @@ int attr;
/*
* Basic function for writing a message with highlight attributes.
*/
-void msg_puts_attr(s, attr)
-char_u *s;
-int attr;
+void msg_puts_attr(char_u *s, int attr)
{
msg_puts_attr_len(s, -1, attr);
}
@@ -1602,10 +1566,7 @@ int attr;
* When "maxlen" is -1 there is no maximum length.
* When "maxlen" is >= 0 the message is not put in the history.
*/
-static void msg_puts_attr_len(str, maxlen, attr)
-char_u *str;
-int maxlen;
-int attr;
+static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
{
/*
* If redirection is on, also write to the redirection file.
@@ -1651,11 +1612,7 @@ int attr;
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
*/
-static void msg_puts_display(str, maxlen, attr, recurse)
-char_u *str;
-int maxlen;
-int attr;
-int recurse;
+static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
{
char_u *s = str;
char_u *t_s = str; /* string from "t_s" to "s" is still todo */
@@ -1841,7 +1798,7 @@ int recurse;
/*
* Scroll the screen up one line for displaying the next message line.
*/
-static void msg_scroll_up() {
+static void msg_scroll_up(void) {
/* scrolling up always works */
screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
@@ -1862,7 +1819,7 @@ static void msg_scroll_up() {
/*
* Increment "msg_scrolled".
*/
-static void inc_msg_scrolled() {
+static void inc_msg_scrolled(void) {
if (*get_vim_var_str(VV_SCROLLSTART) == NUL) {
char_u *p = sourcing_name;
char_u *tofree = NULL;
@@ -1911,12 +1868,14 @@ static int do_clear_sb_text = FALSE; /* clear text on next msg */
/*
* Store part of a printed message for displaying when scrolling back.
*/
-static void store_sb_text(sb_str, s, attr, sb_col, finish)
-char_u **sb_str; /* start of string */
-char_u *s; /* just after string */
-int attr;
-int *sb_col;
-int finish; /* line ends */
+static void
+store_sb_text (
+ char_u **sb_str, /* start of string */
+ char_u *s, /* just after string */
+ int attr,
+ int *sb_col,
+ int finish /* line ends */
+)
{
msgchunk_T *mp;
@@ -1953,7 +1912,7 @@ int finish; /* line ends */
/*
* Finished showing messages, clear the scroll-back text on the next message.
*/
-void may_clear_sb_text() {
+void may_clear_sb_text(void) {
do_clear_sb_text = TRUE;
}
@@ -1961,7 +1920,7 @@ void may_clear_sb_text() {
* Clear any text remembered for scrolling back.
* Called when redrawing the screen.
*/
-void clear_sb_text() {
+void clear_sb_text(void) {
msgchunk_T *mp;
while (last_msgchunk != NULL) {
@@ -1974,7 +1933,7 @@ void clear_sb_text() {
/*
* "g<" command.
*/
-void show_sb_text() {
+void show_sb_text(void) {
msgchunk_T *mp;
/* Only show something if there is more than one line, otherwise it looks
@@ -1991,8 +1950,7 @@ void show_sb_text() {
/*
* Move to the start of screen line in already displayed text.
*/
-static msgchunk_T * msg_sb_start(mps)
-msgchunk_T *mps;
+static msgchunk_T *msg_sb_start(msgchunk_T *mps)
{
msgchunk_T *mp = mps;
@@ -2004,7 +1962,7 @@ msgchunk_T *mps;
/*
* Mark the last message chunk as finishing the line.
*/
-void msg_sb_eol() {
+void msg_sb_eol(void) {
if (last_msgchunk != NULL)
last_msgchunk->sb_eol = TRUE;
}
@@ -2013,9 +1971,7 @@ void msg_sb_eol() {
* Display a screen line from previously displayed text at row "row".
* Returns a pointer to the text for the next line (can be NULL).
*/
-static msgchunk_T * disp_sb_line(row, smp)
-int row;
-msgchunk_T *smp;
+static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
{
msgchunk_T *mp = smp;
char_u *p;
@@ -2037,11 +1993,7 @@ msgchunk_T *smp;
/*
* Output any postponed text for msg_puts_attr_len().
*/
-static void t_puts(t_col, t_s, s, attr)
-int *t_col;
-char_u *t_s;
-char_u *s;
-int attr;
+static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr)
{
/* output postponed text */
msg_didout = TRUE; /* remember that line is not empty */
@@ -2066,7 +2018,7 @@ int attr;
* different, e.g. for Win32 console) or we just don't know where the
* cursor is.
*/
-int msg_use_printf() {
+int msg_use_printf(void) {
return !msg_check_screen()
|| (swapping_screen() && !termcap_active)
;
@@ -2075,9 +2027,7 @@ int msg_use_printf() {
/*
* Print a message when there is no valid screen.
*/
-static void msg_puts_printf(str, maxlen)
-char_u *str;
-int maxlen;
+static void msg_puts_printf(char_u *str, int maxlen)
{
char_u *s = str;
char_u buf[4];
@@ -2126,8 +2076,7 @@ int maxlen;
* otherwise it's NUL.
* Returns TRUE when jumping ahead to "confirm_msg_tail".
*/
-static int do_more_prompt(typed_char)
-int typed_char;
+static int do_more_prompt(int typed_char)
{
int used_typed_char = typed_char;
int oldState = State;
@@ -2332,8 +2281,7 @@ int typed_char;
* yet. When stderr can't be used, collect error messages until the GUI has
* started and they can be displayed in a message box.
*/
-void mch_errmsg(str)
-char *str;
+void mch_errmsg(char *str)
{
int len;
@@ -2386,8 +2334,7 @@ char *str;
* When there is no tty, collect messages until the GUI has started and they
* can be displayed in a message box.
*/
-void mch_msg(str)
-char *str;
+void mch_msg(char *str)
{
#if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI)
/* On Unix use stdout if we have a tty. This allows "vim -h | more" and
@@ -2411,9 +2358,7 @@ char *str;
* Put a character on the screen at the current message position and advance
* to the next position. Only for printable ASCII!
*/
-static void msg_screen_putchar(c, attr)
-int c;
-int attr;
+static void msg_screen_putchar(int c, int attr)
{
msg_didout = TRUE; /* remember that line is not empty */
screen_putchar(c, msg_row, msg_col, attr);
@@ -2430,8 +2375,7 @@ int attr;
}
}
-void msg_moremsg(full)
-int full;
+void msg_moremsg(int full)
{
int attr;
char_u *s = (char_u *)_("-- More --");
@@ -2448,7 +2392,7 @@ int full;
* Repeat the message for the current mode: ASKMORE, EXTERNCMD, CONFIRM or
* exmode_active.
*/
-void repeat_message() {
+void repeat_message(void) {
if (State == ASKMORE) {
msg_moremsg(TRUE); /* display --more-- message again */
msg_row = Rows - 1;
@@ -2477,7 +2421,7 @@ void repeat_message() {
* While starting the GUI the terminal codes will be set for the GUI, but the
* output goes to the terminal. Don't use the terminal codes then.
*/
-static int msg_check_screen() {
+static int msg_check_screen(void) {
if (!full_screen || !screen_valid(FALSE))
return FALSE;
@@ -2492,7 +2436,7 @@ static int msg_check_screen() {
* Clear from current message position to end of screen.
* Skip this when ":silent" was used, no need to clear for redirection.
*/
-void msg_clr_eos() {
+void msg_clr_eos(void) {
if (msg_silent == 0)
msg_clr_eos_force();
}
@@ -2502,7 +2446,7 @@ void msg_clr_eos() {
* Note: msg_col is not updated, so we remember the end of the message
* for msg_check().
*/
-void msg_clr_eos_force() {
+void msg_clr_eos_force(void) {
if (msg_use_printf()) {
if (full_screen) { /* only when termcap codes are valid */
if (*T_CD)
@@ -2525,7 +2469,7 @@ void msg_clr_eos_force() {
/*
* Clear the command line.
*/
-void msg_clr_cmdline() {
+void msg_clr_cmdline(void) {
msg_row = cmdline_row;
msg_col = 0;
msg_clr_eos_force();
@@ -2536,7 +2480,7 @@ void msg_clr_cmdline() {
* call wait_return if the message does not fit in the available space
* return TRUE if wait_return not called.
*/
-int msg_end() {
+int msg_end(void) {
/*
* If the string is larger than the window,
* or the ruler option is set and we run into it,
@@ -2555,7 +2499,7 @@ int msg_end() {
* If the written message runs into the shown command or ruler, we have to
* wait for hit-return and redraw the window later.
*/
-void msg_check() {
+void msg_check(void) {
if (msg_row == Rows - 1 && msg_col >= sc_col) {
need_wait_return = TRUE;
redraw_cmdline = TRUE;
@@ -2566,9 +2510,7 @@ void msg_check() {
* May write a string to the redirection file.
* When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes.
*/
-static void redir_write(str, maxlen)
-char_u *str;
-int maxlen;
+static void redir_write(char_u *str, int maxlen)
{
char_u *s = str;
static int cur_col = 0;
@@ -2623,7 +2565,7 @@ int maxlen;
}
}
-int redirecting() {
+int redirecting(void) {
return redir_fd != NULL || *p_vfile != NUL
|| redir_reg || redir_vname
;
@@ -2633,7 +2575,7 @@ int redirecting() {
* Before giving verbose message.
* Must always be called paired with verbose_leave()!
*/
-void verbose_enter() {
+void verbose_enter(void) {
if (*p_vfile != NUL)
++msg_silent;
}
@@ -2642,7 +2584,7 @@ void verbose_enter() {
* After giving verbose message.
* Must always be called paired with verbose_enter()!
*/
-void verbose_leave() {
+void verbose_leave(void) {
if (*p_vfile != NUL)
if (--msg_silent < 0)
msg_silent = 0;
@@ -2651,7 +2593,7 @@ void verbose_leave() {
/*
* Like verbose_enter() and set msg_scroll when displaying the message.
*/
-void verbose_enter_scroll() {
+void verbose_enter_scroll(void) {
if (*p_vfile != NUL)
++msg_silent;
else
@@ -2662,7 +2604,7 @@ void verbose_enter_scroll() {
/*
* Like verbose_leave() and set cmdline_row when displaying the message.
*/
-void verbose_leave_scroll() {
+void verbose_leave_scroll(void) {
if (*p_vfile != NUL) {
if (--msg_silent < 0)
msg_silent = 0;
@@ -2673,7 +2615,7 @@ void verbose_leave_scroll() {
/*
* Called when 'verbosefile' is set: stop writing to the file.
*/
-void verbose_stop() {
+void verbose_stop(void) {
if (verbose_fd != NULL) {
fclose(verbose_fd);
verbose_fd = NULL;
@@ -2685,7 +2627,7 @@ void verbose_stop() {
* Open the file 'verbosefile'.
* Return FAIL or OK.
*/
-int verbose_open() {
+int verbose_open(void) {
if (verbose_fd == NULL && !verbose_did_open) {
/* Only give the error message once. */
verbose_did_open = TRUE;
@@ -2703,9 +2645,7 @@ int verbose_open() {
* Give a warning message (for searching).
* Use 'w' highlighting and may repeat the message after redrawing
*/
-void give_warning(message, hl)
-char_u *message;
-int hl;
+void give_warning(char_u *message, int hl)
{
/* Don't do this for ":silent". */
if (msg_silent != 0)
@@ -2733,8 +2673,7 @@ int hl;
/*
* Advance msg cursor to column "col".
*/
-void msg_advance(col)
-int col;
+void msg_advance(int col)
{
if (msg_silent != 0) { /* nothing to advance to */
msg_col = col; /* for redirection, may fill it up later */
@@ -2768,16 +2707,18 @@ int col;
* A '&' in a button name becomes a shortcut, so each '&' should be before a
* different letter.
*/
-int do_dialog(type, title, message, buttons, dfltbutton, textfield, ex_cmd)
-int type UNUSED;
-char_u *title UNUSED;
-char_u *message;
-char_u *buttons;
-int dfltbutton;
-char_u *textfield UNUSED; /* IObuff for inputdialog(), NULL
+int
+do_dialog (
+ int type,
+ char_u *title,
+ char_u *message,
+ char_u *buttons,
+ int dfltbutton,
+ char_u *textfield, /* IObuff for inputdialog(), NULL
otherwise */
-int ex_cmd; /* when TRUE pressing : accepts default and starts
+ int ex_cmd /* when TRUE pressing : accepts default and starts
Ex command */
+)
{
int oldState;
int retval = 0;
@@ -2862,10 +2803,12 @@ static int copy_char __ARGS((char_u *from, char_u *to, int lowercase));
* Copy one character from "*from" to "*to", taking care of multi-byte
* characters. Return the length of the character in bytes.
*/
-static int copy_char(from, to, lowercase)
-char_u *from;
-char_u *to;
-int lowercase; /* make character lower case */
+static int
+copy_char (
+ char_u *from,
+ char_u *to,
+ int lowercase /* make character lower case */
+)
{
int len;
int c;
@@ -2897,10 +2840,7 @@ int lowercase; /* make character lower case */
*
* Returns an allocated string with hotkeys, or NULL for error.
*/
-static char_u * msg_show_console_dialog(message, buttons, dfltbutton)
-char_u *message;
-char_u *buttons;
-int dfltbutton;
+static char_u *msg_show_console_dialog(char_u *message, char_u *buttons, int dfltbutton)
{
int len = 0;
# define HOTK_LEN (has_mbyte ? MB_MAXBYTES : 1)
@@ -3032,7 +2972,7 @@ int dfltbutton;
/*
* Display the ":confirm" message. Also called when screen resized.
*/
-void display_confirm_msg() {
+void display_confirm_msg(void) {
/* avoid that 'q' at the more prompt truncates the message here */
++confirm_msg_used;
if (confirm_msg != NULL)
@@ -3040,11 +2980,7 @@ void display_confirm_msg() {
--confirm_msg_used;
}
-int vim_dialog_yesno(type, title, message, dflt)
-int type;
-char_u *title;
-char_u *message;
-int dflt;
+int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt)
{
if (do_dialog(type,
title == NULL ? (char_u *)_("Question") : title,
@@ -3054,11 +2990,7 @@ int dflt;
return VIM_NO;
}
-int vim_dialog_yesnocancel(type, title, message, dflt)
-int type;
-char_u *title;
-char_u *message;
-int dflt;
+int vim_dialog_yesnocancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
title == NULL ? (char_u *)_("Question") : title,
@@ -3070,11 +3002,7 @@ int dflt;
return VIM_CANCEL;
}
-int vim_dialog_yesnoallcancel(type, title, message, dflt)
-int type;
-char_u *title;
-char_u *message;
-int dflt;
+int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt)
{
switch (do_dialog(type,
title == NULL ? (char_u *)"Question" : title,
@@ -3101,9 +3029,7 @@ static double tv_float __ARGS((typval_T *tvs, int *idxp));
/*
* Get number argument from "idxp" entry in "tvs". First entry is 1.
*/
-static long tv_nr(tvs, idxp)
-typval_T *tvs;
-int *idxp;
+static long tv_nr(typval_T *tvs, int *idxp)
{
int idx = *idxp - 1;
long n = 0;
@@ -3124,9 +3050,7 @@ int *idxp;
* Get string argument from "idxp" entry in "tvs". First entry is 1.
* Returns NULL for an error.
*/
-static char * tv_str(tvs, idxp)
-typval_T *tvs;
-int *idxp;
+static char *tv_str(typval_T *tvs, int *idxp)
{
int idx = *idxp - 1;
char *s = NULL;
@@ -3143,9 +3067,7 @@ int *idxp;
/*
* Get float argument from "idxp" entry in "tvs". First entry is 1.
*/
-static double tv_float(tvs, idxp)
-typval_T *tvs;
-int *idxp;
+static double tv_float(typval_T *tvs, int *idxp)
{
int idx = *idxp - 1;
double f = 0;
@@ -3230,11 +3152,7 @@ int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...) {
# else
/* Like vim_vsnprintf() but append to the string. */
-int vim_snprintf_add(str, str_m, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
-char *str;
-size_t str_m;
-char *fmt;
-long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
+int vim_snprintf_add(char *str, size_t str_m, char *fmt, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10)
{
size_t len = STRLEN(str);
size_t space;
diff --git a/src/proto/message.pro b/src/message.h
index ece1985213..bd1ef4242c 100644
--- a/src/proto/message.pro
+++ b/src/message.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MESSAGE_H
+#define NEOVIM_MESSAGE_H
/* message.c */
int msg __ARGS((char_u *s));
int verb_msg __ARGS((char_u *s));
@@ -78,3 +80,4 @@ char_u *do_browse __ARGS((int flags, char_u *title, char_u *dflt, char_u *ext,
char_u *initdir, char_u *filter,
buf_T *buf));
/* vim: set ft=c : */
+#endif /* NEOVIM_MESSAGE_H */
diff --git a/src/misc1.c b/src/misc1.c
index 92fc47189b..2d59948e60 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -12,7 +12,37 @@
*/
#include "vim.h"
-#include "version.h"
+#include "version_defs.h"
+#include "misc1.h"
+#include "charset.h"
+#include "diff.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
+#include "os/os.h"
static char_u *vim_version_dir __ARGS((char_u *vimdir));
static char_u *remove_tail __ARGS((char_u *p, char_u *pend, char_u *name));
@@ -25,15 +55,14 @@ static garray_T ga_users;
/*
* Count the size (in window cells) of the indent in the current line.
*/
-int get_indent() {
+int get_indent(void) {
return get_indent_str(ml_get_curline(), (int)curbuf->b_p_ts);
}
/*
* Count the size (in window cells) of the indent in line "lnum".
*/
-int get_indent_lnum(lnum)
-linenr_T lnum;
+int get_indent_lnum(linenr_T lnum)
{
return get_indent_str(ml_get(lnum), (int)curbuf->b_p_ts);
}
@@ -42,9 +71,7 @@ linenr_T lnum;
* Count the size (in window cells) of the indent in line "lnum" of buffer
* "buf".
*/
-int get_indent_buf(buf, lnum)
-buf_T *buf;
-linenr_T lnum;
+int get_indent_buf(buf_T *buf, linenr_T lnum)
{
return get_indent_str(ml_get_buf(buf, lnum, FALSE), (int)buf->b_p_ts);
}
@@ -53,9 +80,7 @@ linenr_T lnum;
* count the size (in window cells) of the indent in line "ptr", with
* 'tabstop' at "ts"
*/
-int get_indent_str(ptr, ts)
-char_u *ptr;
-int ts;
+int get_indent_str(char_u *ptr, int ts)
{
int count = 0;
@@ -80,9 +105,11 @@ int ts;
* SIN_UNDO: save line for undo before changing it.
* Returns TRUE if the line was changed.
*/
-int set_indent(size, flags)
-int size; /* measured in spaces */
-int flags;
+int
+set_indent (
+ int size, /* measured in spaces */
+ int flags
+)
{
char_u *p;
char_u *newline;
@@ -291,9 +318,7 @@ int flags;
* Leaves the cursor on the first non-blank in the line.
* Returns TRUE if the line was changed.
*/
-static int copy_indent(size, src)
-int size;
-char_u *src;
+static int copy_indent(int size, char_u *src)
{
char_u *p = NULL;
char_u *line = NULL;
@@ -385,8 +410,7 @@ char_u *src;
* number was found. Used for 'n' in 'formatoptions': numbered list.
* Since a pattern is used it can actually handle more than numbers.
*/
-int get_number_indent(lnum)
-linenr_T lnum;
+int get_number_indent(linenr_T lnum)
{
colnr_T col;
pos_T pos;
@@ -427,8 +451,7 @@ static int cin_is_cinword __ARGS((char_u *line));
/*
* Return TRUE if the string "line" starts with a word from 'cinwords'.
*/
-static int cin_is_cinword(line)
-char_u *line;
+static int cin_is_cinword(char_u *line)
{
char_u *cinw;
char_u *cinw_buf;
@@ -473,10 +496,12 @@ char_u *line;
*
* Return TRUE for success, FALSE for failure
*/
-int open_line(dir, flags, second_line_indent)
-int dir; /* FORWARD or BACKWARD */
-int flags;
-int second_line_indent;
+int
+open_line (
+ int dir, /* FORWARD or BACKWARD */
+ int flags,
+ int second_line_indent
+)
{
char_u *saved_line; /* copy of the original line */
char_u *next_line = NULL; /* copy of the next line */
@@ -1348,11 +1373,7 @@ theend:
* If "include_space" is set, include trailing whitespace while calculating the
* length.
*/
-int get_leader_len(line, flags, backward, include_space)
-char_u *line;
-char_u **flags;
-int backward;
-int include_space;
+int get_leader_len(char_u *line, char_u **flags, int backward, int include_space)
{
int i, j;
int result;
@@ -1486,9 +1507,7 @@ int include_space;
* When "flags" is not null, it is set to point to the flags describing the
* recognized comment leader.
*/
-int get_last_leader_offset(line, flags)
-char_u *line;
-char_u **flags;
+int get_last_leader_offset(char_u *line, char_u **flags)
{
int result = -1;
int i, j;
@@ -1618,32 +1637,34 @@ char_u **flags;
/*
* Return the number of window lines occupied by buffer line "lnum".
*/
-int plines(lnum)
-linenr_T lnum;
+int plines(linenr_T lnum)
{
return plines_win(curwin, lnum, TRUE);
}
-int plines_win(wp, lnum, winheight)
-win_T *wp;
-linenr_T lnum;
-int winheight; /* when TRUE limit to window height */
+int
+plines_win (
+ win_T *wp,
+ linenr_T lnum,
+ int winheight /* when TRUE limit to window height */
+)
{
/* Check for filler lines above this buffer line. When folded the result
* is one line anyway. */
return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
}
-int plines_nofill(lnum)
-linenr_T lnum;
+int plines_nofill(linenr_T lnum)
{
return plines_win_nofill(curwin, lnum, TRUE);
}
-int plines_win_nofill(wp, lnum, winheight)
-win_T *wp;
-linenr_T lnum;
-int winheight; /* when TRUE limit to window height */
+int
+plines_win_nofill (
+ win_T *wp,
+ linenr_T lnum,
+ int winheight /* when TRUE limit to window height */
+)
{
int lines;
@@ -1668,9 +1689,7 @@ int winheight; /* when TRUE limit to window height */
* Return number of window lines physical line "lnum" will occupy in window
* "wp". Does not care about folding, 'wrap' or 'diff'.
*/
-int plines_win_nofold(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+int plines_win_nofold(win_T *wp, linenr_T lnum)
{
char_u *s;
long col;
@@ -1705,10 +1724,7 @@ linenr_T lnum;
* Like plines_win(), but only reports the number of physical screen lines
* used from the start of the line to the given column number.
*/
-int plines_win_col(wp, lnum, column)
-win_T *wp;
-linenr_T lnum;
-long column;
+int plines_win_col(win_T *wp, linenr_T lnum, long column)
{
long col;
char_u *s;
@@ -1756,9 +1772,7 @@ long column;
return lines;
}
-int plines_m_win(wp, first, last)
-win_T *wp;
-linenr_T first, last;
+int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
{
int count = 0;
@@ -1786,8 +1800,7 @@ linenr_T first, last;
* Insert string "p" at the cursor position. Stops at a NUL byte.
* Handles Replace mode and multi-byte characters.
*/
-void ins_bytes(p)
-char_u *p;
+void ins_bytes(char_u *p)
{
ins_bytes_len(p, (int)STRLEN(p));
}
@@ -1798,9 +1811,7 @@ char_u *p;
* Insert string "p" with length "len" at the cursor position.
* Handles Replace mode and multi-byte characters.
*/
-void ins_bytes_len(p, len)
-char_u *p;
-int len;
+void ins_bytes_len(char_u *p, int len)
{
int i;
int n;
@@ -1827,8 +1838,7 @@ int len;
* For multi-byte characters we get the whole character, the caller must
* convert bytes to a character.
*/
-void ins_char(c)
-int c;
+void ins_char(int c)
{
char_u buf[MB_MAXBYTES + 1];
int n;
@@ -1843,9 +1853,7 @@ int c;
ins_char_bytes(buf, n);
}
-void ins_char_bytes(buf, charlen)
-char_u *buf;
-int charlen;
+void ins_char_bytes(char_u *buf, int charlen)
{
int c = buf[0];
int newlen; /* nr of bytes inserted */
@@ -1979,8 +1987,7 @@ int charlen;
* Note: Does NOT handle Replace mode.
* Caller must have prepared for undo.
*/
-void ins_str(s)
-char_u *s;
+void ins_str(char_u *s)
{
char_u *oldp, *newp;
int newlen = (int)STRLEN(s);
@@ -2014,8 +2021,7 @@ char_u *s;
*
* return FAIL for failure, OK otherwise
*/
-int del_char(fixpos)
-int fixpos;
+int del_char(int fixpos)
{
if (has_mbyte) {
/* Make sure the cursor is at the start of a character. */
@@ -2030,9 +2036,7 @@ int fixpos;
/*
* Like del_bytes(), but delete characters instead of bytes.
*/
-int del_chars(count, fixpos)
-long count;
-int fixpos;
+int del_chars(long count, int fixpos)
{
long bytes = 0;
long i;
@@ -2055,10 +2059,12 @@ int fixpos;
*
* return FAIL for failure, OK otherwise
*/
-int del_bytes(count, fixpos_arg, use_delcombine)
-long count;
-int fixpos_arg;
-int use_delcombine UNUSED; /* 'delcombine' option applies */
+int
+del_bytes (
+ long count,
+ int fixpos_arg,
+ int use_delcombine /* 'delcombine' option applies */
+)
{
char_u *oldp, *newp;
colnr_T oldlen;
@@ -2152,8 +2158,10 @@ int use_delcombine UNUSED; /* 'delcombine' option applies */
*
* return FAIL for failure, OK otherwise
*/
-int truncate_line(fixpos)
-int fixpos; /* if TRUE fix the cursor position when done */
+int
+truncate_line (
+ int fixpos /* if TRUE fix the cursor position when done */
+)
{
char_u *newp;
linenr_T lnum = curwin->w_cursor.lnum;
@@ -2185,9 +2193,11 @@ int fixpos; /* if TRUE fix the cursor position when done */
* Delete "nlines" lines at the cursor.
* Saves the lines for undo first if "undo" is TRUE.
*/
-void del_lines(nlines, undo)
-long nlines; /* number of lines to delete */
-int undo; /* if TRUE, prepare for undo */
+void
+del_lines (
+ long nlines, /* number of lines to delete */
+ int undo /* if TRUE, prepare for undo */
+)
{
long n;
linenr_T first = curwin->w_cursor.lnum;
@@ -2220,8 +2230,7 @@ int undo; /* if TRUE, prepare for undo */
deleted_lines_mark(first, n);
}
-int gchar_pos(pos)
-pos_T *pos;
+int gchar_pos(pos_T *pos)
{
char_u *ptr = ml_get_pos(pos);
@@ -2230,7 +2239,7 @@ pos_T *pos;
return (int)*ptr;
}
-int gchar_cursor() {
+int gchar_cursor(void) {
if (has_mbyte)
return (*mb_ptr2char)(ml_get_cursor());
return (int)*ml_get_cursor();
@@ -2240,8 +2249,7 @@ int gchar_cursor() {
* Write a character at the current cursor position.
* It is directly written into the block.
*/
-void pchar_cursor(c)
-int c;
+void pchar_cursor(int c)
{
*(ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE)
+ curwin->w_cursor.col) = c;
@@ -2253,8 +2261,7 @@ int c;
* When extra == 1: Return TRUE if the cursor is before the first non-blank in
* the line.
*/
-int inindent(extra)
-int extra;
+int inindent(int extra)
{
char_u *ptr;
colnr_T col;
@@ -2270,8 +2277,7 @@ int extra;
/*
* Skip to next part of an option argument: Skip space and comma.
*/
-char_u * skip_to_option_part(p)
-char_u *p;
+char_u *skip_to_option_part(char_u *p)
{
if (*p == ',')
++p;
@@ -2288,7 +2294,7 @@ char_u *p;
*
* Careful: may trigger autocommands that reload the buffer.
*/
-void changed() {
+void changed(void) {
if (!curbuf->b_changed) {
int save_msg_scroll = msg_scroll;
@@ -2323,7 +2329,7 @@ void changed() {
/*
* Internal part of changed(), no user interaction.
*/
-void changed_int() {
+void changed_int(void) {
curbuf->b_changed = TRUE;
ml_setflags(curbuf);
check_status(curbuf);
@@ -2344,9 +2350,7 @@ static void changed_common __ARGS((linenr_T lnum, colnr_T col, linenr_T lnume,
* - invalidates cached values
* Careful: may trigger autocommands that reload the buffer.
*/
-void changed_bytes(lnum, col)
-linenr_T lnum;
-colnr_T col;
+void changed_bytes(linenr_T lnum, colnr_T col)
{
changedOneline(curbuf, lnum);
changed_common(lnum, col, lnum + 1, 0L);
@@ -2366,9 +2370,7 @@ colnr_T col;
}
}
-static void changedOneline(buf, lnum)
-buf_T *buf;
-linenr_T lnum;
+static void changedOneline(buf_T *buf, linenr_T lnum)
{
if (buf->b_mod_set) {
/* find the maximum area that must be redisplayed */
@@ -2390,9 +2392,7 @@ linenr_T lnum;
* Must be called AFTER the change and after mark_adjust().
* Takes care of marking the buffer to be redrawn and sets the changed flag.
*/
-void appended_lines(lnum, count)
-linenr_T lnum;
-long count;
+void appended_lines(linenr_T lnum, long count)
{
changed_lines(lnum + 1, 0, lnum + 1, count);
}
@@ -2400,9 +2400,7 @@ long count;
/*
* Like appended_lines(), but adjust marks first.
*/
-void appended_lines_mark(lnum, count)
-linenr_T lnum;
-long count;
+void appended_lines_mark(linenr_T lnum, long count)
{
mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
changed_lines(lnum + 1, 0, lnum + 1, count);
@@ -2413,9 +2411,7 @@ long count;
* Must be called AFTER the change and after mark_adjust().
* Takes care of marking the buffer to be redrawn and sets the changed flag.
*/
-void deleted_lines(lnum, count)
-linenr_T lnum;
-long count;
+void deleted_lines(linenr_T lnum, long count)
{
changed_lines(lnum, 0, lnum + count, -count);
}
@@ -2425,9 +2421,7 @@ long count;
* Make sure the cursor is on a valid line before calling, a GUI callback may
* be triggered to display the cursor.
*/
-void deleted_lines_mark(lnum, count)
-linenr_T lnum;
-long count;
+void deleted_lines_mark(linenr_T lnum, long count)
{
mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count);
changed_lines(lnum, 0, lnum + count, -count);
@@ -2445,11 +2439,13 @@ long count;
* Takes care of calling changed() and updating b_mod_*.
* Careful: may trigger autocommands that reload the buffer.
*/
-void changed_lines(lnum, col, lnume, xtra)
-linenr_T lnum; /* first line with change */
-colnr_T col; /* column in first line with change */
-linenr_T lnume; /* line below last changed line */
-long xtra; /* number of extra lines (negative when deleting) */
+void
+changed_lines (
+ linenr_T lnum, /* first line with change */
+ colnr_T col, /* column in first line with change */
+ linenr_T lnume, /* line below last changed line */
+ long xtra /* number of extra lines (negative when deleting) */
+)
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
@@ -2473,11 +2469,13 @@ long xtra; /* number of extra lines (negative when deleting) */
changed_common(lnum, col, lnume, xtra);
}
-static void changed_lines_buf(buf, lnum, lnume, xtra)
-buf_T *buf;
-linenr_T lnum; /* first line with change */
-linenr_T lnume; /* line below last changed line */
-long xtra; /* number of extra lines (negative when deleting) */
+static void
+changed_lines_buf (
+ buf_T *buf,
+ linenr_T lnum, /* first line with change */
+ linenr_T lnume, /* line below last changed line */
+ long xtra /* number of extra lines (negative when deleting) */
+)
{
if (buf->b_mod_set) {
/* find the maximum area that must be redisplayed */
@@ -2506,11 +2504,7 @@ long xtra; /* number of extra lines (negative when deleting) */
* See changed_lines() for the arguments.
* Careful: may trigger autocommands that reload the buffer.
*/
-static void changed_common(lnum, col, lnume, xtra)
-linenr_T lnum;
-colnr_T col;
-linenr_T lnume;
-long xtra;
+static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra)
{
win_T *wp;
tabpage_T *tp;
@@ -2671,9 +2665,11 @@ long xtra;
/*
* unchanged() is called when the changed flag must be reset for buffer 'buf'
*/
-void unchanged(buf, ff)
-buf_T *buf;
-int ff; /* also reset 'fileformat' */
+void
+unchanged (
+ buf_T *buf,
+ int ff /* also reset 'fileformat' */
+)
{
if (buf->b_changed || (ff && file_ff_differs(buf, FALSE))) {
buf->b_changed = 0;
@@ -2691,8 +2687,7 @@ int ff; /* also reset 'fileformat' */
* check_status: called when the status bars for the buffer 'buf'
* need to be updated
*/
-void check_status(buf)
-buf_T *buf;
+void check_status(buf_T *buf)
{
win_T *wp;
@@ -2712,9 +2707,11 @@ buf_T *buf;
* will be TRUE.
* Careful: may trigger autocommands that reload the buffer.
*/
-void change_warning(col)
-int col; /* column for message; non-zero when in insert
+void
+change_warning (
+ int col /* column for message; non-zero when in insert
mode and 'showmode' is on */
+)
{
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
@@ -2759,9 +2756,7 @@ int col; /* column for message; non-zero when in insert
*
* return the 'y' or 'n'
*/
-int ask_yesno(str, direct)
-char_u *str;
-int direct;
+int ask_yesno(char_u *str, int direct)
{
int r = ' ';
int save_State = State;
@@ -2801,8 +2796,7 @@ int direct;
/*
* Return TRUE if "c" is a mouse key.
*/
-int is_mouse_key(c)
-int c;
+int is_mouse_key(int c)
{
return c == K_LEFTMOUSE
|| c == K_LEFTMOUSE_NM
@@ -2835,7 +2829,7 @@ int c;
* Disadvantage: typeahead is ignored.
* Translates the interrupt character for unix to ESC.
*/
-int get_keystroke() {
+int get_keystroke(void) {
char_u *buf = NULL;
int buflen = 150;
int maxlen;
@@ -2935,9 +2929,11 @@ int get_keystroke() {
* Get a number from the user.
* When "mouse_used" is not NULL allow using the mouse.
*/
-int get_number(colon, mouse_used)
-int colon; /* allow colon to abort */
-int *mouse_used;
+int
+get_number (
+ int colon, /* allow colon to abort */
+ int *mouse_used
+)
{
int n = 0;
int c;
@@ -2993,8 +2989,7 @@ int *mouse_used;
* When "mouse_used" is not NULL allow using the mouse and in that case return
* the line number.
*/
-int prompt_for_number(mouse_used)
-int *mouse_used;
+int prompt_for_number(int *mouse_used)
{
int i;
int save_cmdline_row;
@@ -3028,8 +3023,7 @@ int *mouse_used;
return i;
}
-void msgmore(n)
-long n;
+void msgmore(long n)
{
long pn;
@@ -3076,7 +3070,7 @@ long n;
/*
* flush map and typeahead buffers and give a warning for an error
*/
-void beep_flush() {
+void beep_flush(void) {
if (emsg_silent == 0) {
flush_buffers(FALSE);
vim_beep();
@@ -3086,7 +3080,7 @@ void beep_flush() {
/*
* give a warning for an error
*/
-void vim_beep() {
+void vim_beep(void) {
if (emsg_silent == 0) {
if (p_vb
) {
@@ -3115,7 +3109,7 @@ void vim_beep() {
*/
static char_u *homedir = NULL;
-void init_homedir() {
+void init_homedir(void) {
char_u *var;
/* In case we are called a second time (when 'encoding' changes). */
@@ -3147,11 +3141,11 @@ void init_homedir() {
}
#if defined(EXITFREE) || defined(PROTO)
-void free_homedir() {
+void free_homedir(void) {
vim_free(homedir);
}
-void free_users() {
+void free_users(void) {
ga_clear_strings(&ga_users);
}
@@ -3162,8 +3156,7 @@ void free_users() {
* This is not very memory efficient, this expects the result to be freed
* again soon.
*/
-char_u * expand_env_save(src)
-char_u *src;
+char_u *expand_env_save(char_u *src)
{
return expand_env_save_opt(src, FALSE);
}
@@ -3172,9 +3165,7 @@ char_u *src;
* Idem, but when "one" is TRUE handle the string as one file name, only
* expand "~" at the start.
*/
-char_u * expand_env_save_opt(src, one)
-char_u *src;
-int one;
+char_u *expand_env_save_opt(char_u *src, int one)
{
char_u *p;
@@ -3190,21 +3181,25 @@ int one;
* Skips over "\ ", "\~" and "\$" (not for Win32 though).
* If anything fails no expansion is done and dst equals src.
*/
-void expand_env(src, dst, dstlen)
-char_u *src; /* input string e.g. "$HOME/vim.hlp" */
-char_u *dst; /* where to put the result */
-int dstlen; /* maximum length of the result */
+void
+expand_env (
+ char_u *src, /* input string e.g. "$HOME/vim.hlp" */
+ char_u *dst, /* where to put the result */
+ int dstlen /* maximum length of the result */
+)
{
expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
}
-void expand_env_esc(srcp, dst, dstlen, esc, one, startstr)
-char_u *srcp; /* input string e.g. "$HOME/vim.hlp" */
-char_u *dst; /* where to put the result */
-int dstlen; /* maximum length of the result */
-int esc; /* escape spaces in expanded variables */
-int one; /* "srcp" is one file name */
-char_u *startstr; /* start again after this (can be NULL) */
+void
+expand_env_esc (
+ char_u *srcp, /* input string e.g. "$HOME/vim.hlp" */
+ char_u *dst, /* where to put the result */
+ int dstlen, /* maximum length of the result */
+ int esc, /* escape spaces in expanded variables */
+ int one, /* "srcp" is one file name */
+ char_u *startstr /* start again after this (can be NULL) */
+)
{
char_u *src;
char_u *tail;
@@ -3439,9 +3434,7 @@ char_u *startstr; /* start again after this (can be NULL) */
* "mustfree" is set to TRUE when returned is allocated, it must be
* initialized to FALSE by the caller.
*/
-char_u * vim_getenv(name, mustfree)
-char_u *name;
-int *mustfree;
+char_u *vim_getenv(char_u *name, int *mustfree)
{
char_u *p;
char_u *pend;
@@ -3581,8 +3574,7 @@ int *mustfree;
* Check if the directory "vimdir/<version>" or "vimdir/runtime" exists.
* Return NULL if not, return its name in allocated memory otherwise.
*/
-static char_u * vim_version_dir(vimdir)
-char_u *vimdir;
+static char_u *vim_version_dir(char_u *vimdir)
{
char_u *p;
@@ -3603,10 +3595,7 @@ char_u *vimdir;
* If the string between "p" and "pend" ends in "name/", return "pend" minus
* the length of "name/". Otherwise return "pend".
*/
-static char_u * remove_tail(p, pend, name)
-char_u *p;
-char_u *pend;
-char_u *name;
+static char_u *remove_tail(char_u *p, char_u *pend, char_u *name)
{
int len = (int)STRLEN(name) + 1;
char_u *newend = pend - len;
@@ -3621,9 +3610,7 @@ char_u *name;
/*
* Our portable version of setenv.
*/
-void vim_setenv(name, val)
-char_u *name;
-char_u *val;
+void vim_setenv(char_u *name, char_u *val)
{
#ifdef HAVE_SETENV
mch_setenv((char *)name, (char *)val, 1);
@@ -3657,9 +3644,7 @@ char_u *val;
/*
* Function given to ExpandGeneric() to obtain an environment variable name.
*/
-char_u * get_env_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_env_name(expand_T *xp, int idx)
{
# if defined(AMIGA) || defined(__MRC__) || defined(__SC__)
/*
@@ -3694,7 +3679,7 @@ int idx;
* Find all user names for user completion.
* Done only once and then cached.
*/
-static void init_users() {
+static void init_users(void) {
static int lazy_init_done = FALSE;
if (lazy_init_done)
@@ -3727,9 +3712,7 @@ static void init_users() {
/*
* Function given to ExpandGeneric() to obtain an user names.
*/
-char_u* get_users(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_users(expand_T *xp, int idx)
{
init_users();
if (idx < ga_users.ga_len)
@@ -3743,8 +3726,7 @@ int idx;
* 1 if name partially matches the beginning of a user name.
* 2 is name fully matches a user name.
*/
-int match_user(name)
-char_u* name;
+int match_user(char_u *name)
{
int i;
int n = (int)STRLEN(name);
@@ -3765,13 +3747,15 @@ char_u* name;
* 'src'.
* If anything fails (except when out of space) dst equals src.
*/
-void home_replace(buf, src, dst, dstlen, one)
-buf_T *buf; /* when not NULL, check for help files */
-char_u *src; /* input file name */
-char_u *dst; /* where to put the result */
-int dstlen; /* maximum length of the result */
-int one; /* if TRUE, only replace one file name, include
+void
+home_replace (
+ buf_T *buf, /* when not NULL, check for help files */
+ char_u *src, /* input file name */
+ char_u *dst, /* where to put the result */
+ int dstlen, /* maximum length of the result */
+ int one /* if TRUE, only replace one file name, include
spaces and commas in the file name. */
+)
{
size_t dirlen = 0, envlen = 0;
size_t len;
@@ -3876,9 +3860,11 @@ int one; /* if TRUE, only replace one file name, include
* Like home_replace, store the replaced string in allocated memory.
* When something fails, NULL is returned.
*/
-char_u * home_replace_save(buf, src)
-buf_T *buf; /* when not NULL, check for help files */
-char_u *src; /* input file name */
+char_u *
+home_replace_save (
+ buf_T *buf, /* when not NULL, check for help files */
+ char_u *src /* input file name */
+)
{
char_u *dst;
unsigned len;
@@ -3901,9 +3887,12 @@ char_u *src; /* input file name */
* FPC_DIFFX if one of them doesn't exist.
* For the first name environment variables are expanded
*/
-int fullpathcmp(s1, s2, checkname)
-char_u *s1, *s2;
-int checkname; /* when both don't exist, check file names */
+int
+fullpathcmp (
+ char_u *s1,
+ char_u *s2,
+ int checkname /* when both don't exist, check file names */
+)
{
#ifdef UNIX
char_u exp1[MAXPATHL];
@@ -3971,8 +3960,7 @@ int checkname; /* when both don't exist, check file names */
* When the path ends in a path separator the tail is the NUL after it.
* Fail safe: never returns NULL.
*/
-char_u * gettail(fname)
-char_u *fname;
+char_u *gettail(char_u *fname)
{
char_u *p1, *p2;
@@ -3994,8 +3982,7 @@ static char_u *gettail_dir __ARGS((char_u *fname));
* "/path/file", "/path/dir/", "/path//dir", "/file"
* ^ ^ ^ ^
*/
-static char_u * gettail_dir(fname)
-char_u *fname;
+static char_u *gettail_dir(char_u *fname)
{
char_u *dir_end = fname;
char_u *next_dir_end = fname;
@@ -4023,8 +4010,7 @@ char_u *fname;
* here leaves the directory name. Takes care of "c:/" and "//".
* Always returns a valid pointer.
*/
-char_u * gettail_sep(fname)
-char_u *fname;
+char_u *gettail_sep(char_u *fname)
{
char_u *p;
char_u *t;
@@ -4039,8 +4025,7 @@ char_u *fname;
/*
* get the next path component (just after the next path separator).
*/
-char_u * getnextcomp(fname)
-char_u *fname;
+char_u *getnextcomp(char_u *fname)
{
while (*fname && !vim_ispathsep(*fname))
mb_ptr_adv(fname);
@@ -4054,8 +4039,7 @@ char_u *fname;
* Unix: after "/"; DOS: after "c:\"; Amiga: after "disk:/"; Mac: no head.
* If there is no head, path is returned.
*/
-char_u * get_past_head(path)
-char_u *path;
+char_u *get_past_head(char_u *path)
{
char_u *retval;
@@ -4071,8 +4055,7 @@ char_u *path;
* Return TRUE if 'c' is a path separator.
* Note that for MS-Windows this includes the colon.
*/
-int vim_ispathsep(c)
-int c;
+int vim_ispathsep(int c)
{
#ifdef UNIX
return c == '/'; /* UNIX has ':' inside file names */
@@ -4088,8 +4071,7 @@ int c;
/*
* Like vim_ispathsep(c), but exclude the colon for MS-Windows.
*/
-int vim_ispathsep_nocolon(c)
-int c;
+int vim_ispathsep_nocolon(int c)
{
return vim_ispathsep(c)
#ifdef BACKSLASH_IN_FILENAME
@@ -4101,8 +4083,7 @@ int c;
/*
* return TRUE if 'c' is a path list separator.
*/
-int vim_ispathlistsep(c)
-int c;
+int vim_ispathlistsep(int c)
{
#ifdef UNIX
return c == ':';
@@ -4117,8 +4098,7 @@ int c;
* Shorten the path of a file from "~/foo/../.bar/fname" to "~/f/../.b/fname"
* It's done in-place.
*/
-void shorten_dir(str)
-char_u *str;
+void shorten_dir(char_u *str)
{
char_u *tail, *s, *d;
int skip = FALSE;
@@ -4153,8 +4133,7 @@ char_u *str;
* Also returns TRUE if there is no directory name.
* "fname" must be writable!.
*/
-int dir_of_file_exists(fname)
-char_u *fname;
+int dir_of_file_exists(char_u *fname)
{
char_u *p;
int c;
@@ -4174,8 +4153,7 @@ char_u *fname;
* Versions of fnamecmp() and fnamencmp() that handle '/' and '\' equally
* and deal with 'fileignorecase'.
*/
-int vim_fnamecmp(x, y)
-char_u *x, *y;
+int vim_fnamecmp(char_u *x, char_u *y)
{
#ifdef BACKSLASH_IN_FILENAME
return vim_fnamencmp(x, y, MAXPATHL);
@@ -4186,9 +4164,7 @@ char_u *x, *y;
#endif
}
-int vim_fnamencmp(x, y, len)
-char_u *x, *y;
-size_t len;
+int vim_fnamencmp(char_u *x, char_u *y, size_t len)
{
#ifdef BACKSLASH_IN_FILENAME
char_u *px = x;
@@ -4222,10 +4198,7 @@ size_t len;
* Concatenate file names fname1 and fname2 into allocated memory.
* Only add a '/' or '\\' when 'sep' is TRUE and it is necessary.
*/
-char_u * concat_fnames(fname1, fname2, sep)
-char_u *fname1;
-char_u *fname2;
-int sep;
+char_u *concat_fnames(char_u *fname1, char_u *fname2, int sep)
{
char_u *dest;
@@ -4243,9 +4216,7 @@ int sep;
* Concatenate two strings and return the result in allocated memory.
* Returns NULL when out of memory.
*/
-char_u * concat_str(str1, str2)
-char_u *str1;
-char_u *str2;
+char_u *concat_str(char_u *str1, char_u *str2)
{
char_u *dest;
size_t l = STRLEN(str1);
@@ -4262,8 +4233,7 @@ char_u *str2;
* Add a path separator to a file name, unless it already ends in a path
* separator.
*/
-void add_pathsep(p)
-char_u *p;
+void add_pathsep(char_u *p)
{
if (*p != NUL && !after_pathsep(p, p + STRLEN(p)))
STRCAT(p, PATHSEPSTR);
@@ -4273,10 +4243,12 @@ char_u *p;
* FullName_save - Make an allocated copy of a full file name.
* Returns NULL when out of memory.
*/
-char_u * FullName_save(fname, force)
-char_u *fname;
-int force; /* force expansion, even when it already looks
+char_u *
+FullName_save (
+ char_u *fname,
+ int force /* force expansion, even when it already looks
* like a full path name */
+)
{
char_u *buf;
char_u *new_fname = NULL;
@@ -4303,12 +4275,14 @@ static pos_T *ind_find_start_comment __ARGS((void));
* Find the start of a comment, not knowing if we are in a comment right now.
* Search starts at w_cursor.lnum and goes backwards.
*/
-static pos_T * ind_find_start_comment() { /* XXX */
+static pos_T *ind_find_start_comment(void) { /* XXX */
return find_start_comment(curbuf->b_ind_maxcomment);
}
-pos_T * find_start_comment(ind_maxcomment) /* XXX */
-int ind_maxcomment;
+pos_T *
+find_start_comment ( /* XXX */
+ int ind_maxcomment
+)
{
pos_T *pos;
char_u *line;
@@ -4342,8 +4316,7 @@ int ind_maxcomment;
* Skip to the end of a "string" and a 'c' character.
* If there is no string or character, return argument unmodified.
*/
-static char_u * skip_string(p)
-char_u *p;
+static char_u *skip_string(char_u *p)
{
int i;
@@ -4385,7 +4358,7 @@ char_u *p;
/*
* Do C or expression indenting on the current line.
*/
-void do_c_expr_indent() {
+void do_c_expr_indent(void) {
if (*curbuf->b_p_inde != NUL)
fixthisline(get_expr_indent);
else
@@ -4440,8 +4413,7 @@ static int cin_is_cpp_namespace __ARGS((char_u *));
* Skip over white space and C comments within the line.
* Also skip over Perl/shell comments if desired.
*/
-static char_u * cin_skipcomment(s)
-char_u *s;
+static char_u *cin_skipcomment(char_u *s)
{
while (*s) {
char_u *prev_s = s;
@@ -4476,8 +4448,7 @@ char_u *s;
* Return TRUE if there is no code at *s. White space and comments are
* not considered code.
*/
-static int cin_nocode(s)
-char_u *s;
+static int cin_nocode(char_u *s)
{
return *cin_skipcomment(s) == NUL;
}
@@ -4485,7 +4456,7 @@ char_u *s;
/*
* Check previous lines for a "//" line comment, skipping over blank lines.
*/
-static pos_T * find_line_comment() { /* XXX */
+static pos_T *find_line_comment(void) { /* XXX */
static pos_T pos;
char_u *line;
char_u *p;
@@ -4507,8 +4478,7 @@ static pos_T * find_line_comment() { /* XXX */
/*
* Check if string matches "label:"; move to character after ':' if true.
*/
-static int cin_islabel_skip(s)
-char_u **s;
+static int cin_islabel_skip(char_u **s)
{
if (!vim_isIDc(**s)) /* need at least one ID character */
return FALSE;
@@ -4526,7 +4496,7 @@ char_u **s;
* Recognize a label: "label:".
* Note: curwin->w_cursor must be where we are looking for the label.
*/
-int cin_islabel() { /* XXX */
+int cin_islabel(void) { /* XXX */
char_u *s;
s = cin_skipcomment(ml_get_curline());
@@ -4621,9 +4591,11 @@ static int cin_isinit(void) {
/*
* Recognize a switch label: "case .*:" or "default:".
*/
-int cin_iscase(s, strict)
-char_u *s;
-int strict; /* Allow relaxed check of case statement for JS */
+int
+cin_iscase (
+ char_u *s,
+ int strict /* Allow relaxed check of case statement for JS */
+)
{
s = cin_skipcomment(s);
if (cin_starts_with(s, "case")) {
@@ -4658,8 +4630,7 @@ int strict; /* Allow relaxed check of case statement for JS */
/*
* Recognize a "default" switch label.
*/
-static int cin_isdefault(s)
-char_u *s;
+static int cin_isdefault(char_u *s)
{
return STRNCMP(s, "default", 7) == 0
&& *(s = cin_skipcomment(s + 7)) == ':'
@@ -4669,8 +4640,7 @@ char_u *s;
/*
* Recognize a "public/private/protected" scope declaration label.
*/
-int cin_isscopedecl(s)
-char_u *s;
+int cin_isscopedecl(char_u *s)
{
int i;
@@ -4692,8 +4662,7 @@ char_u *s;
/*
* Recognize a "namespace" scope declaration.
*/
-static int cin_is_cpp_namespace(s)
-char_u *s;
+static int cin_is_cpp_namespace(char_u *s)
{
char_u *p;
int has_name = FALSE;
@@ -4726,8 +4695,7 @@ char_u *s;
* case 234: a = b;
* ^
*/
-static char_u * after_label(l)
-char_u *l;
+static char_u *after_label(char_u *l)
{
for (; *l; ++l) {
if (*l == ':') {
@@ -4750,8 +4718,10 @@ char_u *l;
* Get indent of line "lnum", skipping a label.
* Return 0 if there is nothing after the label.
*/
-static int get_indent_nolabel(lnum) /* XXX */
-linenr_T lnum;
+static int
+get_indent_nolabel ( /* XXX */
+ linenr_T lnum
+)
{
char_u *l;
pos_T fp;
@@ -4775,9 +4745,7 @@ linenr_T lnum;
* label: if (asdf && asdfasdf)
* ^
*/
-static int skip_label(lnum, pp)
-linenr_T lnum;
-char_u **pp;
+static int skip_label(linenr_T lnum, char_u **pp)
{
char_u *l;
int amount;
@@ -4809,7 +4777,7 @@ char_u **pp;
* enum bla c, indent of "c"
* Returns zero when it doesn't look like a declaration.
*/
-static int cin_first_id_amount() {
+static int cin_first_id_amount(void) {
char_u *line, *p, *s;
int len;
pos_T fp;
@@ -4856,8 +4824,7 @@ static int cin_first_id_amount() {
* asdf\
* here";
*/
-static int cin_get_equal_amount(lnum)
-linenr_T lnum;
+static int cin_get_equal_amount(linenr_T lnum)
{
char_u *line;
char_u *s;
@@ -4896,8 +4863,7 @@ linenr_T lnum;
/*
* Recognize a preprocessor statement: Any line that starts with '#'.
*/
-static int cin_ispreproc(s)
-char_u *s;
+static int cin_ispreproc(char_u *s)
{
if (*skipwhite(s) == '#')
return TRUE;
@@ -4909,9 +4875,7 @@ char_u *s;
* continuation line of a preprocessor statement. Decrease "*lnump" to the
* start and return the line in "*pp".
*/
-static int cin_ispreproc_cont(pp, lnump)
-char_u **pp;
-linenr_T *lnump;
+static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
{
char_u *line = *pp;
linenr_T lnum = *lnump;
@@ -4938,8 +4902,7 @@ linenr_T *lnump;
/*
* Recognize the start of a C or C++ comment.
*/
-static int cin_iscomment(p)
-char_u *p;
+static int cin_iscomment(char_u *p)
{
return p[0] == '/' && (p[1] == '*' || p[1] == '/');
}
@@ -4947,8 +4910,7 @@ char_u *p;
/*
* Recognize the start of a "//" comment.
*/
-static int cin_islinecomment(p)
-char_u *p;
+static int cin_islinecomment(char_u *p)
{
return p[0] == '/' && p[1] == '/';
}
@@ -4962,10 +4924,12 @@ char_u *p;
* Return the character terminating the line (ending char's have precedence if
* both apply in order to determine initializations).
*/
-static int cin_isterminated(s, incl_open, incl_comma)
-char_u *s;
-int incl_open; /* include '{' at the end as terminator */
-int incl_comma; /* recognize a trailing comma */
+static int
+cin_isterminated (
+ char_u *s,
+ int incl_open, /* include '{' at the end as terminator */
+ int incl_comma /* recognize a trailing comma */
+)
{
char_u found_start = 0;
unsigned n_open = 0;
@@ -5011,10 +4975,7 @@ int incl_comma; /* recognize a trailing comma */
* "lnum" is where we start looking.
* "min_lnum" is the line before which we will not be looking.
*/
-static int cin_isfuncdecl(sp, first_lnum, min_lnum)
-char_u **sp;
-linenr_T first_lnum;
-linenr_T min_lnum;
+static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
{
char_u *s;
linenr_T lnum = first_lnum;
@@ -5099,22 +5060,19 @@ done:
return retval;
}
-static int cin_isif(p)
-char_u *p;
+static int cin_isif(char_u *p)
{
return STRNCMP(p, "if", 2) == 0 && !vim_isIDc(p[2]);
}
-static int cin_iselse(p)
-char_u *p;
+static int cin_iselse(char_u *p)
{
if (*p == '}') /* accept "} else" */
p = cin_skipcomment(p + 1);
return STRNCMP(p, "else", 4) == 0 && !vim_isIDc(p[4]);
}
-static int cin_isdo(p)
-char_u *p;
+static int cin_isdo(char_u *p)
{
return STRNCMP(p, "do", 2) == 0 && !vim_isIDc(p[2]);
}
@@ -5124,9 +5082,11 @@ char_u *p;
* We only accept a "while (condition) ;", with only white space between the
* ')' and ';'. The condition may be spread over several lines.
*/
-static int cin_iswhileofdo(p, lnum) /* XXX */
-char_u *p;
-linenr_T lnum;
+static int
+cin_iswhileofdo ( /* XXX */
+ char_u *p,
+ linenr_T lnum
+)
{
pos_T cursor_save;
pos_T *trypos;
@@ -5159,9 +5119,7 @@ linenr_T lnum;
* Otherwise return !0 and update "*poffset" to point to the place where the
* string was found.
*/
-static int cin_is_if_for_while_before_offset(line, poffset)
-char_u *line;
-int *poffset;
+static int cin_is_if_for_while_before_offset(char_u *line, int *poffset)
{
int offset = *poffset;
@@ -5203,8 +5161,7 @@ probablyFound:
* && bar); <-- here
* Adjust the cursor to the line with "while".
*/
-static int cin_iswhileofdo_end(terminated)
-int terminated;
+static int cin_iswhileofdo_end(int terminated)
{
char_u *line;
char_u *p;
@@ -5247,8 +5204,7 @@ int terminated;
return FALSE;
}
-static int cin_isbreak(p)
-char_u *p;
+static int cin_isbreak(char_u *p)
{
return STRNCMP(p, "break", 5) == 0 && !vim_isIDc(p[5]);
}
@@ -5266,8 +5222,10 @@ char_u *p;
*
* This is a lot of guessing. Watch out for "cond ? func() : foo".
*/
-static int cin_is_cpp_baseclass(col)
-colnr_T *col; /* return: column to align with */
+static int
+cin_is_cpp_baseclass (
+ colnr_T *col /* return: column to align with */
+)
{
char_u *s;
int class_or_struct, lookfor_ctor_init, cpp_base_class;
@@ -5390,8 +5348,7 @@ colnr_T *col; /* return: column to align with */
return cpp_base_class;
}
-static int get_baseclass_amount(col)
-int col;
+static int get_baseclass_amount(int col)
{
int amount;
colnr_T vcol;
@@ -5419,10 +5376,7 @@ int col;
* white space and comments. Skip strings and comments.
* Ignore "ignore" after "find" if it's not NULL.
*/
-static int cin_ends_in(s, find, ignore)
-char_u *s;
-char_u *find;
-char_u *ignore;
+static int cin_ends_in(char_u *s, char_u *find, char_u *ignore)
{
char_u *p = s;
char_u *r;
@@ -5446,9 +5400,7 @@ char_u *ignore;
/*
* Return TRUE when "s" starts with "word" and then a non-ID character.
*/
-static int cin_starts_with(s, word)
-char_u *s;
-char *word;
+static int cin_starts_with(char_u *s, char *word)
{
int l = (int)STRLEN(word);
@@ -5459,8 +5411,7 @@ char *word;
* Skip strings, chars and comments until at or past "trypos".
* Return the column found.
*/
-static int cin_skip2pos(trypos)
-pos_T *trypos;
+static int cin_skip2pos(pos_T *trypos)
{
char_u *line;
char_u *p;
@@ -5486,7 +5437,7 @@ pos_T *trypos;
/* { */
/* } */
-static pos_T * find_start_brace() { /* XXX */
+static pos_T *find_start_brace(void) { /* XXX */
pos_T cursor_save;
pos_T *trypos;
pos_T *pos;
@@ -5513,8 +5464,10 @@ static pos_T * find_start_brace() { /* XXX */
* Find the matching '(', failing if it is in a comment.
* Return NULL if no match found.
*/
-static pos_T * find_match_paren(ind_maxparen) /* XXX */
-int ind_maxparen;
+static pos_T *
+find_match_paren ( /* XXX */
+ int ind_maxparen
+)
{
pos_T cursor_save;
pos_T *trypos;
@@ -5543,8 +5496,7 @@ int ind_maxparen;
* matching paren above the cursor line doesn't find a match because of
* looking a few lines further.
*/
-static int corr_ind_maxparen(startpos)
-pos_T *startpos;
+static int corr_ind_maxparen(pos_T *startpos)
{
long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum;
@@ -5557,9 +5509,7 @@ pos_T *startpos;
* Set w_cursor.col to the column number of the last unmatched ')' or '{' in
* line "l". "l" must point to the start of the line.
*/
-static int find_last_paren(l, start, end)
-char_u *l;
-int start, end;
+static int find_last_paren(char_u *l, int start, int end)
{
int i;
int retval = FALSE;
@@ -5588,8 +5538,7 @@ int start, end;
* Parse 'cinoptions' and set the values in "curbuf".
* Must be called when 'cinoptions', 'shiftwidth' and/or 'tabstop' changes.
*/
-void parse_cino(buf)
-buf_T *buf;
+void parse_cino(buf_T *buf)
{
char_u *p;
char_u *l;
@@ -5797,7 +5746,7 @@ buf_T *buf;
}
}
-int get_c_indent() {
+int get_c_indent(void) {
pos_T cur_curpos;
int amount;
int scope_amount;
@@ -7483,9 +7432,7 @@ theend:
return amount;
}
-static int find_match(lookfor, ourscope)
-int lookfor;
-linenr_T ourscope;
+static int find_match(int lookfor, linenr_T ourscope)
{
char_u *look;
pos_T *theirscope;
@@ -7590,7 +7537,7 @@ linenr_T ourscope;
/*
* Get indent level from 'indentexpr'.
*/
-int get_expr_indent() {
+int get_expr_indent(void) {
int indent;
pos_T save_pos;
colnr_T save_curswant;
@@ -7633,8 +7580,7 @@ int get_expr_indent() {
static int lisp_match __ARGS((char_u *p));
-static int lisp_match(p)
-char_u *p;
+static int lisp_match(char_u *p)
{
char_u buf[LSIZE];
int len;
@@ -7665,7 +7611,7 @@ char_u *p;
* Update from Sergey Khorev:
* I tried to fix the first two issues.
*/
-int get_lisp_indent() {
+int get_lisp_indent(void) {
pos_T *pos, realpos, paren;
int amount;
char_u *that;
@@ -7824,7 +7770,7 @@ int get_lisp_indent() {
return amount;
}
-void prepare_to_exit() {
+void prepare_to_exit(void) {
#if defined(SIGHUP) && defined(SIG_IGN)
/* Ignore SIGHUP, because a dropped connection causes a read error, which
* makes Vim exit and then handling SIGHUP causes various reentrance
@@ -7851,7 +7797,7 @@ void prepare_to_exit() {
* NOTE: This may be called from deathtrap() in a signal handler, avoid unsafe
* functions, such as allocating memory.
*/
-void preserve_exit() {
+void preserve_exit(void) {
buf_T *buf;
prepare_to_exit();
@@ -7886,8 +7832,7 @@ void preserve_exit() {
/*
* return TRUE if "fname" exists.
*/
-int vim_fexists(fname)
-char_u *fname;
+int vim_fexists(char_u *fname)
{
struct stat st;
@@ -7909,7 +7854,7 @@ char_u *fname;
static int breakcheck_count = 0;
-void line_breakcheck() {
+void line_breakcheck(void) {
if (++breakcheck_count >= BREAKCHECK_SKIP) {
breakcheck_count = 0;
ui_breakcheck();
@@ -7919,7 +7864,7 @@ void line_breakcheck() {
/*
* Like line_breakcheck() but check 10 times less often.
*/
-void fast_breakcheck() {
+void fast_breakcheck(void) {
if (++breakcheck_count >= BREAKCHECK_SKIP * 10) {
breakcheck_count = 0;
ui_breakcheck();
@@ -7931,11 +7876,13 @@ void fast_breakcheck() {
* Expand items like "%:h" before the expansion.
* Returns OK or FAIL.
*/
-int expand_wildcards_eval(pat, num_file, file, flags)
-char_u **pat; /* pointer to input pattern */
-int *num_file; /* resulting number of files */
-char_u ***file; /* array of resulting files */
-int flags; /* EW_DIR, etc. */
+int
+expand_wildcards_eval (
+ char_u **pat, /* pointer to input pattern */
+ int *num_file, /* resulting number of files */
+ char_u ***file, /* array of resulting files */
+ int flags /* EW_DIR, etc. */
+)
{
int ret = FAIL;
char_u *eval_pat = NULL;
@@ -7968,12 +7915,14 @@ int flags; /* EW_DIR, etc. */
* 'wildignore'.
* Returns OK or FAIL. When FAIL then "num_file" won't be set.
*/
-int expand_wildcards(num_pat, pat, num_file, file, flags)
-int num_pat; /* number of input patterns */
-char_u **pat; /* array of input patterns */
-int *num_file; /* resulting number of files */
-char_u ***file; /* array of resulting files */
-int flags; /* EW_DIR, etc. */
+int
+expand_wildcards (
+ int num_pat, /* number of input patterns */
+ char_u **pat, /* array of input patterns */
+ int *num_file, /* resulting number of files */
+ char_u ***file, /* array of resulting files */
+ int flags /* EW_DIR, etc. */
+)
{
int retval;
int i, j;
@@ -8034,8 +7983,7 @@ int flags; /* EW_DIR, etc. */
/*
* Return TRUE if "fname" matches with an entry in 'suffixes'.
*/
-int match_suffix(fname)
-char_u *fname;
+int match_suffix(char_u *fname)
{
int fnamelen, setsuflen;
char_u *setsuf;
@@ -8079,8 +8027,7 @@ static int expand_backtick __ARGS((garray_T *gap, char_u *pat, int flags));
*/
static int pstrcmp __ARGS((const void *, const void *));
-static int pstrcmp(a, b)
-const void *a, *b;
+static int pstrcmp(const void *a, const void *b)
{
return pathcmp(*(char **)a, *(char **)b, -1);
}
@@ -8093,12 +8040,14 @@ const void *a, *b;
* Return the number of matches found.
* NOTE: much of this is identical to dos_expandpath(), keep in sync!
*/
-int unix_expandpath(gap, path, wildoff, flags, didstar)
-garray_T *gap;
-char_u *path;
-int wildoff;
-int flags; /* EW_* flags */
-int didstar; /* expanded "**" once already */
+int
+unix_expandpath (
+ garray_T *gap,
+ char_u *path,
+ int wildoff,
+ int flags, /* EW_* flags */
+ int didstar /* expanded "**" once already */
+)
{
char_u *buf;
char_u *path_end;
@@ -8291,9 +8240,7 @@ static int expand_in_path __ARGS((garray_T *gap, char_u *pattern, int flags));
* Moves "*psep" back to the previous path separator in "path".
* Returns FAIL is "*psep" ends up at the beginning of "path".
*/
-static int find_previous_pathsep(path, psep)
-char_u *path;
-char_u **psep;
+static int find_previous_pathsep(char_u *path, char_u **psep)
{
/* skip the current separator */
if (*psep > path && vim_ispathsep(**psep))
@@ -8313,10 +8260,7 @@ char_u **psep;
* Returns TRUE if "maybe_unique" is unique wrt other_paths in "gap".
* "maybe_unique" is the end portion of "((char_u **)gap->ga_data)[i]".
*/
-static int is_unique(maybe_unique, gap, i)
-char_u *maybe_unique;
-garray_T *gap;
-int i;
+static int is_unique(char_u *maybe_unique, garray_T *gap, int i)
{
int j;
int candidate_len;
@@ -8351,9 +8295,7 @@ int i;
* TODO: handle upward search (;) and path limiter (**N) notations by
* expanding each into their equivalent path(s).
*/
-static void expand_path_option(curdir, gap)
-char_u *curdir;
-garray_T *gap;
+static void expand_path_option(char_u *curdir, garray_T *gap)
{
char_u *path_option = *curbuf->b_p_path == NUL
? p_path : curbuf->b_p_path;
@@ -8421,9 +8363,7 @@ garray_T *gap;
* fname: /foo/bar/baz/quux.txt
* returns: ^this
*/
-static char_u * get_path_cutoff(fname, gap)
-char_u *fname;
-garray_T *gap;
+static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
{
int i;
int maxlen = 0;
@@ -8455,9 +8395,7 @@ garray_T *gap;
* that they are unique with respect to each other while conserving the part
* that matches the pattern. Beware, this is at least O(n^2) wrt "gap->ga_len".
*/
-static void uniquefy_paths(gap, pattern)
-garray_T *gap;
-char_u *pattern;
+static void uniquefy_paths(garray_T *gap, char_u *pattern)
{
int i;
int len;
@@ -8608,10 +8546,12 @@ theend:
* result in "gap".
* Returns the total number of matches.
*/
-static int expand_in_path(gap, pattern, flags)
-garray_T *gap;
-char_u *pattern;
-int flags; /* EW_* flags */
+static int
+expand_in_path (
+ garray_T *gap,
+ char_u *pattern,
+ int flags /* EW_* flags */
+)
{
char_u *curdir;
garray_T path_ga;
@@ -8665,8 +8605,7 @@ int flags; /* EW_* flags */
* Sort "gap" and remove duplicate entries. "gap" is expected to contain a
* list of file names in allocated memory.
*/
-void remove_duplicates(gap)
-garray_T *gap;
+void remove_duplicates(garray_T *gap)
{
int i;
int j;
@@ -8688,8 +8627,7 @@ static int has_env_var __ARGS((char_u *p));
* Return TRUE if "p" contains what looks like an environment variable.
* Allowing for escaping.
*/
-static int has_env_var(p)
-char_u *p;
+static int has_env_var(char_u *p)
{
for (; *p; mb_ptr_adv(p)) {
if (*p == '\\' && p[1] != NUL)
@@ -8709,8 +8647,7 @@ static int has_special_wildchar __ARGS((char_u *p));
* Return TRUE if "p" contains a special wildcard character.
* Allowing for escaping.
*/
-static int has_special_wildchar(p)
-char_u *p;
+static int has_special_wildchar(char_u *p)
{
for (; *p; mb_ptr_adv(p)) {
if (*p == '\\' && p[1] != NUL)
@@ -8733,12 +8670,14 @@ char_u *p;
* Return OK when some files found. "num_file" is set to the number of
* matches, "file" to the array of matches. Call FreeWild() later.
*/
-int gen_expand_wildcards(num_pat, pat, num_file, file, flags)
-int num_pat; /* number of input patterns */
-char_u **pat; /* array of input patterns */
-int *num_file; /* resulting number of files */
-char_u ***file; /* array of resulting files */
-int flags; /* EW_* flags */
+int
+gen_expand_wildcards (
+ int num_pat, /* number of input patterns */
+ char_u **pat, /* array of input patterns */
+ int *num_file, /* resulting number of files */
+ char_u ***file, /* array of resulting files */
+ int flags /* EW_* flags */
+)
{
int i;
garray_T ga;
@@ -8868,8 +8807,7 @@ int flags; /* EW_* flags */
/*
* Return TRUE if we can expand this backtick thing here.
*/
-static int vim_backtick(p)
-char_u *p;
+static int vim_backtick(char_u *p)
{
return *p == '`' && *(p + 1) != NUL && *(p + STRLEN(p) - 1) == '`';
}
@@ -8879,10 +8817,12 @@ char_u *p;
* Currently only works when pat[] starts and ends with a `.
* Returns number of file names found.
*/
-static int expand_backtick(gap, pat, flags)
-garray_T *gap;
-char_u *pat;
-int flags; /* EW_* flags */
+static int
+expand_backtick (
+ garray_T *gap,
+ char_u *pat,
+ int flags /* EW_* flags */
+)
{
char_u *p;
char_u *cmd;
@@ -8935,10 +8875,12 @@ int flags; /* EW_* flags */
* EW_NOTFOUND add even when it doesn't exist
* EW_ADDSLASH add slash after directory name
*/
-void addfile(gap, f, flags)
-garray_T *gap;
-char_u *f; /* filename */
-int flags;
+void
+addfile (
+ garray_T *gap,
+ char_u *f, /* filename */
+ int flags
+)
{
char_u *p;
int isdir;
@@ -8996,10 +8938,12 @@ int flags;
* Get the stdout of an external command.
* Returns an allocated string, or NULL for error.
*/
-char_u * get_cmd_output(cmd, infile, flags)
-char_u *cmd;
-char_u *infile; /* optional input file name */
-int flags; /* can be SHELL_SILENT */
+char_u *
+get_cmd_output (
+ char_u *cmd,
+ char_u *infile, /* optional input file name */
+ int flags /* can be SHELL_SILENT */
+)
{
char_u *tempname;
char_u *command;
@@ -9075,9 +9019,7 @@ done:
* Free the list of files returned by expand_wildcards() or other expansion
* functions.
*/
-void FreeWild(count, files)
-int count;
-char_u **files;
+void FreeWild(int count, char_u **files)
{
if (count <= 0 || files == NULL)
return;
@@ -9091,7 +9033,7 @@ char_u **files;
* Don't do this when still processing a command or a mapping.
* Don't do this when inside a ":normal" command.
*/
-int goto_im() {
+int goto_im(void) {
return p_im && stuff_empty() && typebuf_typed();
}
diff --git a/src/proto/misc1.pro b/src/misc1.h
index 0497096791..ea7cb1b7e7 100644
--- a/src/proto/misc1.pro
+++ b/src/misc1.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MISC1_H
+#define NEOVIM_MISC1_H
/* misc1.c */
int get_indent __ARGS((void));
int get_indent_lnum __ARGS((linenr_T lnum));
@@ -115,3 +117,4 @@ char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags));
void FreeWild __ARGS((int count, char_u **files));
int goto_im __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_MISC1_H */
diff --git a/src/misc2.c b/src/misc2.c
index e18de18258..544a45a315 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -11,6 +11,29 @@
* misc2.c: Various functions.
*/
#include "vim.h"
+#include "misc2.h"
+#include "blowfish.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "mbyte.h"
+#include "memfile.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "move.h"
+#include "option.h"
+#include "os_unix.h"
+#include "screen.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "window.h"
+#include "os/os.h"
static char_u *username = NULL; /* cached result of mch_get_user_name() */
@@ -22,7 +45,7 @@ static int coladvance2 __ARGS((pos_T *pos, int addspaces, int finetune,
/*
* Return TRUE if in the current mode we need to use virtual.
*/
-int virtual_active() {
+int virtual_active(void) {
/* While an operator is being executed we return "virtual_op", because
* VIsual_active has already been reset, thus we can't check for "block"
* being used. */
@@ -36,7 +59,7 @@ int virtual_active() {
/*
* Get the screen position of the cursor.
*/
-int getviscol() {
+int getviscol(void) {
colnr_T x;
getvvcol(curwin, &curwin->w_cursor, &x, NULL, NULL);
@@ -46,9 +69,7 @@ int getviscol() {
/*
* Get the screen position of character col with a coladd in the cursor line.
*/
-int getviscol2(col, coladd)
-colnr_T col;
-colnr_T coladd;
+int getviscol2(colnr_T col, colnr_T coladd)
{
colnr_T x;
pos_T pos;
@@ -65,8 +86,7 @@ colnr_T coladd;
* cursor in that column.
* The caller must have saved the cursor line for undo!
*/
-int coladvance_force(wcol)
-colnr_T wcol;
+int coladvance_force(colnr_T wcol)
{
int rc = coladvance2(&curwin->w_cursor, TRUE, FALSE, wcol);
@@ -89,8 +109,7 @@ colnr_T wcol;
*
* return OK if desired column is reached, FAIL if not
*/
-int coladvance(wcol)
-colnr_T wcol;
+int coladvance(colnr_T wcol)
{
int rc = getvpos(&curwin->w_cursor, wcol);
@@ -108,18 +127,18 @@ colnr_T wcol;
* Return in "pos" the position of the cursor advanced to screen column "wcol".
* return OK if desired column is reached, FAIL if not
*/
-int getvpos(pos, wcol)
-pos_T *pos;
-colnr_T wcol;
+int getvpos(pos_T *pos, colnr_T wcol)
{
return coladvance2(pos, FALSE, virtual_active(), wcol);
}
-static int coladvance2(pos, addspaces, finetune, wcol)
-pos_T *pos;
-int addspaces; /* change the text to achieve our goal? */
-int finetune; /* change char offset for the exact column */
-colnr_T wcol; /* column to move to */
+static int
+coladvance2 (
+ pos_T *pos,
+ int addspaces, /* change the text to achieve our goal? */
+ int finetune, /* change char offset for the exact column */
+ colnr_T wcol /* column to move to */
+)
{
int idx;
char_u *ptr;
@@ -286,7 +305,7 @@ colnr_T wcol; /* column to move to */
/*
* Increment the cursor position. See inc() for return values.
*/
-int inc_cursor() {
+int inc_cursor(void) {
return inc(&curwin->w_cursor);
}
@@ -297,8 +316,7 @@ int inc_cursor() {
* Return -1 when at the end of file.
* Return 0 otherwise.
*/
-int inc(lp)
-pos_T *lp;
+int inc(pos_T *lp)
{
char_u *p = ml_get_pos(lp);
@@ -325,8 +343,7 @@ pos_T *lp;
/*
* incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
*/
-int incl(lp)
-pos_T *lp;
+int incl(pos_T *lp)
{
int r;
@@ -341,12 +358,11 @@ pos_T *lp;
* Decrement the line pointer 'p' crossing line boundaries as necessary.
* Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
*/
-int dec_cursor() {
+int dec_cursor(void) {
return dec(&curwin->w_cursor);
}
-int dec(lp)
-pos_T *lp;
+int dec(pos_T *lp)
{
char_u *p;
@@ -373,8 +389,7 @@ pos_T *lp;
/*
* decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
*/
-int decl(lp)
-pos_T *lp;
+int decl(pos_T *lp)
{
int r;
@@ -388,9 +403,11 @@ pos_T *lp;
* difference between line number and cursor position. Only look for lines that
* can be visible, folded lines don't count.
*/
-linenr_T get_cursor_rel_lnum(wp, lnum)
-win_T *wp;
-linenr_T lnum; /* line number to get the result for */
+linenr_T
+get_cursor_rel_lnum (
+ win_T *wp,
+ linenr_T lnum /* line number to get the result for */
+)
{
linenr_T cursor = wp->w_cursor.lnum;
linenr_T retval = 0;
@@ -427,7 +444,7 @@ linenr_T lnum; /* line number to get the result for */
/*
* Make sure curwin->w_cursor.lnum is valid.
*/
-void check_cursor_lnum() {
+void check_cursor_lnum(void) {
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
/* If there is a closed fold at the end of the file, put the cursor in
* its first line. Otherwise in the last line. */
@@ -442,15 +459,14 @@ void check_cursor_lnum() {
/*
* Make sure curwin->w_cursor.col is valid.
*/
-void check_cursor_col() {
+void check_cursor_col(void) {
check_cursor_col_win(curwin);
}
/*
* Make sure win->w_cursor.col is valid.
*/
-void check_cursor_col_win(win)
-win_T *win;
+void check_cursor_col_win(win_T *win)
{
colnr_T len;
colnr_T oldcol = win->w_cursor.col;
@@ -495,7 +511,7 @@ win_T *win;
/*
* make sure curwin->w_cursor in on a valid character
*/
-void check_cursor() {
+void check_cursor(void) {
check_cursor_lnum();
check_cursor_col();
}
@@ -504,7 +520,7 @@ void check_cursor() {
* Make sure curwin->w_cursor is not on the NUL at the end of the line.
* Allow it when in Visual mode and 'selection' is not "old".
*/
-void adjust_cursor_col() {
+void adjust_cursor_col(void) {
if (curwin->w_cursor.col > 0
&& (!VIsual_active || *p_sel == 'o')
&& gchar_cursor() == NUL)
@@ -515,7 +531,7 @@ void adjust_cursor_col() {
* When curwin->w_leftcol has changed, adjust the cursor position.
* Return TRUE if the cursor was moved.
*/
-int leftcol_changed() {
+int leftcol_changed(void) {
long lastcol;
colnr_T s, e;
int retval = FALSE;
@@ -579,21 +595,17 @@ static void mem_pre_alloc_l __ARGS((long_u *sizep));
static void mem_post_alloc __ARGS((void **pp, size_t size));
static void mem_pre_free __ARGS((void **pp));
-static void mem_pre_alloc_s(sizep)
-size_t *sizep;
+static void mem_pre_alloc_s(size_t *sizep)
{
*sizep += sizeof(size_t);
}
-static void mem_pre_alloc_l(sizep)
-long_u *sizep;
+static void mem_pre_alloc_l(long_u *sizep)
{
*sizep += sizeof(size_t);
}
-static void mem_post_alloc(pp, size)
-void **pp;
-size_t size;
+static void mem_post_alloc(void **pp, size_t size)
{
if (*pp == NULL)
return;
@@ -610,8 +622,7 @@ size_t size;
*pp = (void *)((char *)*pp + sizeof(size_t));
}
-static void mem_pre_free(pp)
-void **pp;
+static void mem_pre_free(void **pp)
{
long_u size;
@@ -628,7 +639,7 @@ void **pp;
/*
* called on exit via atexit()
*/
-void vim_mem_profile_dump() {
+void vim_mem_profile_dump(void) {
int i, j;
printf("\r\n");
@@ -673,8 +684,7 @@ void vim_mem_profile_dump() {
* Note: if unsigned is 16 bits we can only allocate up to 64K with alloc().
* Use lalloc for larger blocks.
*/
-char_u * alloc(size)
-unsigned size;
+char_u *alloc(unsigned size)
{
return lalloc((long_u)size, TRUE);
}
@@ -682,8 +692,7 @@ unsigned size;
/*
* Allocate memory and set all bytes to zero.
*/
-char_u * alloc_clear(size)
-unsigned size;
+char_u *alloc_clear(unsigned size)
{
char_u *p;
@@ -696,8 +705,7 @@ unsigned size;
/*
* alloc() with check for maximum line length
*/
-char_u * alloc_check(size)
-unsigned size;
+char_u *alloc_check(unsigned size)
{
#if !defined(UNIX) && !defined(__EMX__)
if (sizeof(int) == 2 && size > 0x7fff) {
@@ -713,9 +721,7 @@ unsigned size;
/*
* Allocate memory like lalloc() and set all bytes to zero.
*/
-char_u * lalloc_clear(size, message)
-long_u size;
-int message;
+char_u *lalloc_clear(long_u size, int message)
{
char_u *p;
@@ -729,9 +735,7 @@ int message;
* Low level memory allocation function.
* This is used often, KEEP IT FAST!
*/
-char_u * lalloc(size, message)
-long_u size;
-int message;
+char_u *lalloc(long_u size, int message)
{
char_u *p; /* pointer to new storage space */
static int releasing = FALSE; /* don't do mf_release_all() recursive */
@@ -817,9 +821,7 @@ theend:
/*
* realloc() with memory profiling.
*/
-void * mem_realloc(ptr, size)
-void *ptr;
-size_t size;
+void *mem_realloc(void *ptr, size_t size)
{
void *p;
@@ -838,8 +840,7 @@ size_t size;
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
*/
-void do_outofmem_msg(size)
-long_u size;
+void do_outofmem_msg(long_u size)
{
if (!did_outofmem_msg) {
/* Don't hide this message */
@@ -864,7 +865,7 @@ static void free_findfile __ARGS((void));
* surprised if Vim crashes...
* Some things can't be freed, esp. things local to a library function.
*/
-void free_all_mem() {
+void free_all_mem(void) {
buf_T *buf, *nextbuf;
static int entered = FALSE;
@@ -1008,8 +1009,7 @@ void free_all_mem() {
/*
* Copy "string" into newly allocated memory.
*/
-char_u * vim_strsave(string)
-char_u *string;
+char_u *vim_strsave(char_u *string)
{
char_u *p;
unsigned len;
@@ -1027,9 +1027,7 @@ char_u *string;
* The allocated memory always has size "len + 1", also when "string" is
* shorter.
*/
-char_u * vim_strnsave(string, len)
-char_u *string;
-int len;
+char_u *vim_strnsave(char_u *string, int len)
{
char_u *p;
@@ -1045,9 +1043,7 @@ int len;
* Same as vim_strsave(), but any characters found in esc_chars are preceded
* by a backslash.
*/
-char_u * vim_strsave_escaped(string, esc_chars)
-char_u *string;
-char_u *esc_chars;
+char_u *vim_strsave_escaped(char_u *string, char_u *esc_chars)
{
return vim_strsave_escaped_ext(string, esc_chars, '\\', FALSE);
}
@@ -1057,11 +1053,7 @@ char_u *esc_chars;
* characters where rem_backslash() would remove the backslash.
* Escape the characters with "cc".
*/
-char_u * vim_strsave_escaped_ext(string, esc_chars, cc, bsl)
-char_u *string;
-char_u *esc_chars;
-int cc;
-int bsl;
+char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars, int cc, int bsl)
{
char_u *p;
char_u *p2;
@@ -1106,7 +1098,7 @@ int bsl;
/*
* Return TRUE when 'shell' has "csh" in the tail.
*/
-int csh_like_shell() {
+int csh_like_shell(void) {
return strstr((char *)gettail(p_sh), "csh") != NULL;
}
@@ -1119,9 +1111,7 @@ int csh_like_shell() {
* with "<" like "<cfile>".
* Returns the result in allocated memory, NULL if we have run out.
*/
-char_u * vim_strsave_shellescape(string, do_special)
-char_u *string;
-int do_special;
+char_u *vim_strsave_shellescape(char_u *string, int do_special)
{
unsigned length;
char_u *p;
@@ -1198,8 +1188,7 @@ int do_special;
* Like vim_strsave(), but make all characters uppercase.
* This uses ASCII lower-to-upper case translation, language independent.
*/
-char_u * vim_strsave_up(string)
-char_u *string;
+char_u *vim_strsave_up(char_u *string)
{
char_u *p1;
@@ -1212,9 +1201,7 @@ char_u *string;
* Like vim_strnsave(), but make all characters uppercase.
* This uses ASCII lower-to-upper case translation, language independent.
*/
-char_u * vim_strnsave_up(string, len)
-char_u *string;
-int len;
+char_u *vim_strnsave_up(char_u *string, int len)
{
char_u *p1;
@@ -1226,8 +1213,7 @@ int len;
/*
* ASCII lower-to-upper case translation, language independent.
*/
-void vim_strup(p)
-char_u *p;
+void vim_strup(char_u *p)
{
char_u *p2;
int c;
@@ -1244,8 +1230,7 @@ char_u *p;
* Handles multi-byte characters as well as possible.
* Returns NULL when out of memory.
*/
-char_u * strup_save(orig)
-char_u *orig;
+char_u *strup_save(char_u *orig)
{
char_u *p;
char_u *res;
@@ -1295,9 +1280,7 @@ char_u *orig;
/*
* copy a space a number of times
*/
-void copy_spaces(ptr, count)
-char_u *ptr;
-size_t count;
+void copy_spaces(char_u *ptr, size_t count)
{
size_t i = count;
char_u *p = ptr;
@@ -1310,10 +1293,7 @@ size_t count;
* Copy a character a number of times.
* Does not work for multi-byte characters!
*/
-void copy_chars(ptr, count, c)
-char_u *ptr;
-size_t count;
-int c;
+void copy_chars(char_u *ptr, size_t count, int c)
{
size_t i = count;
char_u *p = ptr;
@@ -1325,8 +1305,7 @@ int c;
/*
* delete spaces at the end of a string
*/
-void del_trailing_spaces(ptr)
-char_u *ptr;
+void del_trailing_spaces(char_u *ptr)
{
char_u *q;
@@ -1339,10 +1318,7 @@ char_u *ptr;
* Like strncpy(), but always terminate the result with one NUL.
* "to" must be "len + 1" long!
*/
-void vim_strncpy(to, from, len)
-char_u *to;
-char_u *from;
-size_t len;
+void vim_strncpy(char_u *to, char_u *from, size_t len)
{
STRNCPY(to, from, len);
to[len] = NUL;
@@ -1352,10 +1328,7 @@ size_t len;
* Like strcat(), but make sure the result fits in "tosize" bytes and is
* always NUL terminated.
*/
-void vim_strcat(to, from, tosize)
-char_u *to;
-char_u *from;
-size_t tosize;
+void vim_strcat(char_u *to, char_u *from, size_t tosize)
{
size_t tolen = STRLEN(to);
size_t fromlen = STRLEN(from);
@@ -1374,11 +1347,7 @@ size_t tosize;
* "*option" is advanced to the next part.
* The length is returned.
*/
-int copy_option_part(option, buf, maxlen, sep_chars)
-char_u **option;
-char_u *buf;
-int maxlen;
-char *sep_chars;
+int copy_option_part(char_u **option, char_u *buf, int maxlen, char *sep_chars)
{
int len = 0;
char_u *p = *option;
@@ -1411,8 +1380,7 @@ char *sep_chars;
* Also skip free() when exiting for sure, this helps when we caught a deadly
* signal that was caused by a crash in free().
*/
-void vim_free(x)
-void *x;
+void vim_free(void *x)
{
if (x != NULL && !really_exiting) {
#ifdef MEM_PROFILE
@@ -1490,9 +1458,7 @@ size_t len;
* Doesn't work for multi-byte characters.
* return 0 for match, < 0 for smaller, > 0 for bigger
*/
-int vim_stricmp(s1, s2)
-char *s1;
-char *s2;
+int vim_stricmp(char *s1, char *s2)
{
int i;
@@ -1515,10 +1481,7 @@ char *s2;
* Doesn't work for multi-byte characters.
* return 0 for match, < 0 for smaller, > 0 for bigger
*/
-int vim_strnicmp(s1, s2, len)
-char *s1;
-char *s2;
-size_t len;
+int vim_strnicmp(char *s1, char *s2, size_t len)
{
int i;
@@ -1541,9 +1504,7 @@ size_t len;
* with characters from 128 to 255 correctly. It also doesn't return a
* pointer to the NUL at the end of the string.
*/
-char_u * vim_strchr(string, c)
-char_u *string;
-int c;
+char_u *vim_strchr(char_u *string, int c)
{
char_u *p;
int b;
@@ -1589,9 +1550,7 @@ int c;
* strings with characters above 128 correctly. It also doesn't return a
* pointer to the NUL at the end of the string.
*/
-char_u * vim_strbyte(string, c)
-char_u *string;
-int c;
+char_u *vim_strbyte(char_u *string, int c)
{
char_u *p = string;
@@ -1608,9 +1567,7 @@ int c;
* Return NULL if not found.
* Does not handle multi-byte char for "c"!
*/
-char_u * vim_strrchr(string, c)
-char_u *string;
-int c;
+char_u *vim_strrchr(char_u *string, int c)
{
char_u *retval = NULL;
char_u *p = string;
@@ -1631,9 +1588,7 @@ int c;
# ifdef vim_strpbrk
# undef vim_strpbrk
# endif
-char_u * vim_strpbrk(s, charset)
-char_u *s;
-char_u *charset;
+char_u *vim_strpbrk(char_u *s, char_u *charset)
{
while (*s) {
if (vim_strchr(charset, *s) != NULL)
@@ -1648,8 +1603,7 @@ char_u *charset;
* Vim has its own isspace() function, because on some machines isspace()
* can't handle characters above 128.
*/
-int vim_isspace(x)
-int x;
+int vim_isspace(int x)
{
return (x >= 9 && x <= 13) || x == ' ';
}
@@ -1661,8 +1615,7 @@ int x;
/*
* Clear an allocated growing array.
*/
-void ga_clear(gap)
-garray_T *gap;
+void ga_clear(garray_T *gap)
{
vim_free(gap->ga_data);
ga_init(gap);
@@ -1671,8 +1624,7 @@ garray_T *gap;
/*
* Clear a growing array that contains a list of strings.
*/
-void ga_clear_strings(gap)
-garray_T *gap;
+void ga_clear_strings(garray_T *gap)
{
int i;
@@ -1685,18 +1637,14 @@ garray_T *gap;
* Initialize a growing array. Don't forget to set ga_itemsize and
* ga_growsize! Or use ga_init2().
*/
-void ga_init(gap)
-garray_T *gap;
+void ga_init(garray_T *gap)
{
gap->ga_data = NULL;
gap->ga_maxlen = 0;
gap->ga_len = 0;
}
-void ga_init2(gap, itemsize, growsize)
-garray_T *gap;
-int itemsize;
-int growsize;
+void ga_init2(garray_T *gap, int itemsize, int growsize)
{
ga_init(gap);
gap->ga_itemsize = itemsize;
@@ -1707,9 +1655,7 @@ int growsize;
* Make room in growing array "gap" for at least "n" items.
* Return FAIL for failure, OK otherwise.
*/
-int ga_grow(gap, n)
-garray_T *gap;
-int n;
+int ga_grow(garray_T *gap, int n)
{
size_t old_len;
size_t new_len;
@@ -1736,8 +1682,7 @@ int n;
* strings with a separating comma.
* Returns NULL when out of memory.
*/
-char_u * ga_concat_strings(gap)
-garray_T *gap;
+char_u *ga_concat_strings(garray_T *gap)
{
int i;
int len = 0;
@@ -1762,9 +1707,7 @@ garray_T *gap;
* Concatenate a string to a growarray which contains characters.
* Note: Does NOT copy the NUL at the end!
*/
-void ga_concat(gap, s)
-garray_T *gap;
-char_u *s;
+void ga_concat(garray_T *gap, char_u *s)
{
int len = (int)STRLEN(s);
@@ -1777,9 +1720,7 @@ char_u *s;
/*
* Append one byte to a growarray which contains bytes.
*/
-void ga_append(gap, c)
-garray_T *gap;
-int c;
+void ga_append(garray_T *gap, int c)
{
if (ga_grow(gap, 1) == OK) {
*((char *)gap->ga_data + gap->ga_len) = c;
@@ -1791,8 +1732,7 @@ int c;
/*
* Append the text in "gap" below the cursor line and clear "gap".
*/
-void append_ga_line(gap)
-garray_T *gap;
+void append_ga_line(garray_T *gap)
{
/* Remove trailing CR. */
if (gap->ga_len > 0
@@ -2120,8 +2060,7 @@ static struct mousetable {
* Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
* modifier name ('S' for Shift, 'C' for Ctrl etc).
*/
-int name_to_mod_mask(c)
-int c;
+int name_to_mod_mask(int c)
{
int i;
@@ -2136,9 +2075,7 @@ int c;
* Check if if there is a special key code for "key" that includes the
* modifiers specified.
*/
-int simplify_key(key, modifiers)
-int key;
-int *modifiers;
+int simplify_key(int key, int *modifiers)
{
int i;
int key0;
@@ -2167,8 +2104,7 @@ int *modifiers;
/*
* Change <xHome> to <Home>, <xUp> to <Up>, etc.
*/
-int handle_x_keys(key)
-int key;
+int handle_x_keys(int key)
{
switch (key) {
case K_XUP: return K_UP;
@@ -2195,9 +2131,7 @@ int key;
* Return a string which contains the name of the given key when the given
* modifiers are down.
*/
-char_u * get_special_key_name(c, modifiers)
-int c;
-int modifiers;
+char_u *get_special_key_name(int c, int modifiers)
{
static char_u string[MAX_KEY_NAME_LEN + 1];
@@ -2293,10 +2227,12 @@ int modifiers;
* If there is a match, srcp is advanced to after the <> name.
* dst[] must be big enough to hold the result (up to six characters)!
*/
-int trans_special(srcp, dst, keycode)
-char_u **srcp;
-char_u *dst;
-int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
+int
+trans_special (
+ char_u **srcp,
+ char_u *dst,
+ int keycode /* prefer key code, e.g. K_DEL instead of DEL */
+)
{
int modifiers = 0;
int key;
@@ -2332,11 +2268,13 @@ int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
* srcp is advanced to after the <> name.
* returns 0 if there is no match.
*/
-int find_special_key(srcp, modp, keycode, keep_x_key)
-char_u **srcp;
-int *modp;
-int keycode; /* prefer key code, e.g. K_DEL instead of DEL */
-int keep_x_key; /* don't translate xHome to Home key */
+int
+find_special_key (
+ char_u **srcp,
+ int *modp,
+ int keycode, /* prefer key code, e.g. K_DEL instead of DEL */
+ int keep_x_key /* don't translate xHome to Home key */
+)
{
char_u *last_dash;
char_u *end_of_name;
@@ -2453,9 +2391,7 @@ int keep_x_key; /* don't translate xHome to Home key */
* Try to include modifiers in the key.
* Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
*/
-int extract_modifiers(key, modp)
-int key;
-int *modp;
+int extract_modifiers(int key, int *modp)
{
int modifiers = *modp;
@@ -2487,8 +2423,7 @@ int *modp;
* Try to find key "c" in the special key table.
* Return the index when found, -1 when not found.
*/
-int find_special_key_in_table(c)
-int c;
+int find_special_key_in_table(int c)
{
int i;
@@ -2507,8 +2442,7 @@ int c;
* termcap name.
* Return the key code, or 0 if not found.
*/
-int get_special_key_code(name)
-char_u *name;
+int get_special_key_code(char_u *name)
{
char_u *table_name;
char_u string[3];
@@ -2535,8 +2469,7 @@ char_u *name;
return 0;
}
-char_u * get_key_name(i)
-int i;
+char_u *get_key_name(int i)
{
if (i >= (int)KEY_NAMES_TABLE_LEN)
return NULL;
@@ -2547,10 +2480,7 @@ int i;
* Look up the given mouse code to return the relevant information in the other
* arguments. Return which button is down or was released.
*/
-int get_mouse_button(code, is_click, is_drag)
-int code;
-int *is_click;
-int *is_drag;
+int get_mouse_button(int code, int *is_click, int *is_drag)
{
int i;
@@ -2568,10 +2498,12 @@ int *is_drag;
* the given information about which mouse button is down, and whether the
* mouse was clicked, dragged or released.
*/
-int get_pseudo_mouse_code(button, is_click, is_drag)
-int button; /* eg MOUSE_LEFT */
-int is_click;
-int is_drag;
+int
+get_pseudo_mouse_code (
+ int button, /* eg MOUSE_LEFT */
+ int is_click,
+ int is_drag
+)
{
int i;
@@ -2587,8 +2519,7 @@ int is_drag;
/*
* Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
*/
-int get_fileformat(buf)
-buf_T *buf;
+int get_fileformat(buf_T *buf)
{
int c = *buf->b_p_ff;
@@ -2603,9 +2534,11 @@ buf_T *buf;
* Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
* argument.
*/
-int get_fileformat_force(buf, eap)
-buf_T *buf;
-exarg_T *eap; /* can be NULL! */
+int
+get_fileformat_force (
+ buf_T *buf,
+ exarg_T *eap /* can be NULL! */
+)
{
int c;
@@ -2629,9 +2562,11 @@ exarg_T *eap; /* can be NULL! */
* Sets both 'textmode' and 'fileformat'.
* Note: Does _not_ set global value of 'textmode'!
*/
-void set_fileformat(t, opt_flags)
-int t;
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+void
+set_fileformat (
+ int t,
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
char *p = NULL;
@@ -2662,7 +2597,7 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
/*
* Return the default fileformat from 'fileformats'.
*/
-int default_fileformat() {
+int default_fileformat(void) {
switch (*p_ffs) {
case 'm': return EOL_MAC;
case 'd': return EOL_DOS;
@@ -2673,9 +2608,7 @@ int default_fileformat() {
/*
* Call shell. Calls mch_call_shell, with 'shellxquote' added.
*/
-int call_shell(cmd, opt)
-char_u *cmd;
-int opt;
+int call_shell(char_u *cmd, int opt)
{
char_u *ncmd;
int retval;
@@ -2744,7 +2677,7 @@ int opt;
* VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
* NORMAL State with a condition. This function returns the real State.
*/
-int get_real_state() {
+int get_real_state(void) {
if (State & NORMAL) {
if (VIsual_active) {
if (VIsual_select)
@@ -2761,9 +2694,7 @@ int get_real_state() {
* Takes care of multi-byte characters.
* "b" must point to the start of the file name
*/
-int after_pathsep(b, p)
-char_u *b;
-char_u *p;
+int after_pathsep(char_u *b, char_u *p)
{
return p > b && vim_ispathsep(p[-1])
&& (!has_mbyte || (*mb_head_off)(b, p - 1) == 0);
@@ -2773,9 +2704,7 @@ char_u *p;
* Return TRUE if file names "f1" and "f2" are in the same directory.
* "f1" may be a short name, "f2" must be a full path.
*/
-int same_directory(f1, f2)
-char_u *f1;
-char_u *f2;
+int same_directory(char_u *f1, char_u *f2)
{
char_u ffname[MAXPATHL];
char_u *t1;
@@ -2802,8 +2731,7 @@ char_u *f2;
* Caller must call shorten_fnames()!
* Return OK or FAIL.
*/
-int vim_chdirfile(fname)
-char_u *fname;
+int vim_chdirfile(char_u *fname)
{
char_u dir[MAXPATHL];
@@ -2819,8 +2747,7 @@ char_u *fname;
* Used for systems where stat() ignores a trailing slash on a file name.
* The Vim code assumes a trailing slash is only ignored for a directory.
*/
-int illegal_slash(name)
-char *name;
+int illegal_slash(char *name)
{
if (name[0] == NUL)
return FALSE; /* no file name is not illegal */
@@ -2868,8 +2795,7 @@ cursorentry_T shape_table[SHAPE_IDX_COUNT] =
* ("what" is SHAPE_MOUSE).
* Returns error message for an illegal option, NULL otherwise.
*/
-char_u * parse_shape_opt(what)
-int what;
+char_u *parse_shape_opt(int what)
{
char_u *modep;
char_u *colonp;
@@ -3045,8 +2971,7 @@ int what;
* Return the index into shape_table[] for the current mode.
* When "mouse" is TRUE, consider indexes valid for the mouse pointer.
*/
-int get_shape_idx(mouse)
-int mouse;
+int get_shape_idx(int mouse)
{
if (!mouse && State == SHOWMATCH)
return SHAPE_IDX_SM;
@@ -3106,7 +3031,7 @@ static ulg crc_32_tab[256];
/*
* Fill the CRC table.
*/
-static void make_crc_tab() {
+static void make_crc_tab(void) {
ulg s,t,v;
static int done = FALSE;
@@ -3154,8 +3079,7 @@ static int saved_crypt_method;
* 0 for "zip", the old method. Also for any non-valid value.
* 1 for "blowfish".
*/
-int crypt_method_from_string(s)
-char_u *s;
+int crypt_method_from_string(char_u *s)
{
return *s == 'b' ? 1 : 0;
}
@@ -3163,8 +3087,7 @@ char_u *s;
/*
* Get the crypt method for buffer "buf" as a number.
*/
-int get_crypt_method(buf)
-buf_T *buf;
+int get_crypt_method(buf_T *buf)
{
return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
}
@@ -3173,9 +3096,7 @@ buf_T *buf;
* Set the crypt method for buffer "buf" to "method" using the int value as
* returned by crypt_method_from_string().
*/
-void set_crypt_method(buf, method)
-buf_T *buf;
-int method;
+void set_crypt_method(buf_T *buf, int method)
{
free_string_option(buf->b_p_cm);
buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
@@ -3186,7 +3107,7 @@ int method;
* the state.
* Must always be called symmetrically with crypt_pop_state().
*/
-void crypt_push_state() {
+void crypt_push_state(void) {
if (crypt_busy == 1) {
/* save the state */
if (use_crypt_method == 0) {
@@ -3206,7 +3127,7 @@ void crypt_push_state() {
* the saved state.
* Must always be called symmetrically with crypt_push_state().
*/
-void crypt_pop_state() {
+void crypt_pop_state(void) {
--crypt_busy;
if (crypt_busy == 1) {
use_crypt_method = saved_crypt_method;
@@ -3223,10 +3144,7 @@ void crypt_pop_state() {
* Encrypt "from[len]" into "to[len]".
* "from" and "to" can be equal to encrypt in place.
*/
-void crypt_encode(from, len, to)
-char_u *from;
-size_t len;
-char_u *to;
+void crypt_encode(char_u *from, size_t len, char_u *to)
{
size_t i;
int ztemp, t;
@@ -3245,9 +3163,7 @@ char_u *to;
/*
* Decrypt "ptr[len]" in place.
*/
-void crypt_decode(ptr, len)
-char_u *ptr;
-long len;
+void crypt_decode(char_u *ptr, long len)
{
char_u *p;
@@ -3268,8 +3184,10 @@ long len;
* the given password.
* If "passwd" is NULL or empty, don't do anything.
*/
-void crypt_init_keys(passwd)
-char_u *passwd; /* password string with which to modify keys */
+void
+crypt_init_keys (
+ char_u *passwd /* password string with which to modify keys */
+)
{
if (passwd != NULL && *passwd != NUL) {
if (use_crypt_method == 0) {
@@ -3291,8 +3209,7 @@ char_u *passwd; /* password string with which to modify keys */
* Free an allocated crypt key. Clear the text to make sure it doesn't stay
* in memory anywhere.
*/
-void free_crypt_key(key)
-char_u *key;
+void free_crypt_key(char_u *key)
{
char_u *p;
@@ -3310,9 +3227,11 @@ char_u *key;
* When "store" is FALSE, the typed key is returned in allocated memory.
* Returns NULL on failure.
*/
-char_u * get_crypt_key(store, twice)
-int store;
-int twice; /* Ask for the key twice. */
+char_u *
+get_crypt_key (
+ int store,
+ int twice /* Ask for the key twice. */
+)
{
char_u *p1, *p2 = NULL;
int round;
@@ -3599,19 +3518,18 @@ static char_u e_pathtoolong[] = N_("E854: path too long for completion");
* This function silently ignores a few errors, vim_findfile() will have
* limited functionality then.
*/
-void * vim_findfile_init(path, filename, stopdirs, level, free_visited,
- find_what,
- search_ctx_arg, tagfile,
- rel_fname)
-char_u *path;
-char_u *filename;
-char_u *stopdirs UNUSED;
-int level;
-int free_visited;
-int find_what;
-void *search_ctx_arg;
-int tagfile; /* expanding names of tags files */
-char_u *rel_fname; /* file name to use for "." */
+void *
+vim_findfile_init (
+ char_u *path,
+ char_u *filename,
+ char_u *stopdirs,
+ int level,
+ int free_visited,
+ int find_what,
+ void *search_ctx_arg,
+ int tagfile, /* expanding names of tags files */
+ char_u *rel_fname /* file name to use for "." */
+)
{
char_u *wc_part;
ff_stack_T *sptr;
@@ -3911,8 +3829,7 @@ error_return:
/*
* Get the stopdir string. Check that ';' is not escaped.
*/
-char_u * vim_findfile_stopdir(buf)
-char_u *buf;
+char_u *vim_findfile_stopdir(char_u *buf)
{
char_u *r_ptr = buf;
@@ -3936,8 +3853,7 @@ char_u *buf;
/*
* Clean up the given search context. Can handle a NULL pointer.
*/
-void vim_findfile_cleanup(ctx)
-void *ctx;
+void vim_findfile_cleanup(void *ctx)
{
if (ctx == NULL)
return;
@@ -3959,8 +3875,7 @@ void *ctx;
* stack with a list (don't forget to leave partly searched directories on the
* top of the list).
*/
-char_u * vim_findfile(search_ctx_arg)
-void *search_ctx_arg;
+char_u *vim_findfile(void *search_ctx_arg)
{
char_u *file_path;
char_u *rest_of_wildcards;
@@ -4344,8 +4259,7 @@ void *search_ctx_arg;
* Free the list of lists of visited files and directories
* Can handle it if the passed search_context is NULL;
*/
-void vim_findfile_free_visited(search_ctx_arg)
-void *search_ctx_arg;
+void vim_findfile_free_visited(void *search_ctx_arg)
{
ff_search_ctx_T *search_ctx;
@@ -4357,8 +4271,7 @@ void *search_ctx_arg;
vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
}
-static void vim_findfile_free_visited_list(list_headp)
-ff_visited_list_hdr_T **list_headp;
+static void vim_findfile_free_visited_list(ff_visited_list_hdr_T **list_headp)
{
ff_visited_list_hdr_T *vp;
@@ -4373,8 +4286,7 @@ ff_visited_list_hdr_T **list_headp;
*list_headp = NULL;
}
-static void ff_free_visited_list(vl)
-ff_visited_T *vl;
+static void ff_free_visited_list(ff_visited_T *vl)
{
ff_visited_T *vp;
@@ -4391,9 +4303,7 @@ ff_visited_T *vl;
* Returns the already visited list for the given filename. If none is found it
* allocates a new one.
*/
-static ff_visited_list_hdr_T* ff_get_visited_list(filename, list_headp)
-char_u *filename;
-ff_visited_list_hdr_T **list_headp;
+static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_list_hdr_T **list_headp)
{
ff_visited_list_hdr_T *retptr = NULL;
@@ -4456,9 +4366,7 @@ ff_visited_list_hdr_T **list_headp;
* - the only differences are in the counters behind a '**', so
* '**\20' is equal to '**\24'
*/
-static int ff_wc_equal(s1, s2)
-char_u *s1;
-char_u *s2;
+static int ff_wc_equal(char_u *s1, char_u *s2)
{
int i;
int prev1 = NUL;
@@ -4495,11 +4403,7 @@ char_u *s2;
* -> return TRUE - Better the file is found several times instead of
* never.
*/
-static int ff_check_visited(visited_list, fname
- , wc_path)
-ff_visited_T **visited_list;
-char_u *fname;
-char_u *wc_path;
+static int ff_check_visited(ff_visited_T **visited_list, char_u *fname, char_u *wc_path)
{
ff_visited_T *vp;
#ifdef UNIX
@@ -4576,13 +4480,7 @@ char_u *wc_path;
/*
* create stack element from given path pieces
*/
-static ff_stack_T * ff_create_stack_element(fix_part,
- wc_part,
- level, star_star_empty)
-char_u *fix_part;
-char_u *wc_part;
-int level;
-int star_star_empty;
+static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, int level, int star_star_empty)
{
ff_stack_T *new;
@@ -4620,9 +4518,7 @@ int star_star_empty;
/*
* Push a dir on the directory stack.
*/
-static void ff_push(search_ctx, stack_ptr)
-ff_search_ctx_T *search_ctx;
-ff_stack_T *stack_ptr;
+static void ff_push(ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr)
{
/* check for NULL pointer, not to return an error to the user, but
* to prevent a crash */
@@ -4636,8 +4532,7 @@ ff_stack_T *stack_ptr;
* Pop a dir from the directory stack.
* Returns NULL if stack is empty.
*/
-static ff_stack_T * ff_pop(search_ctx)
-ff_search_ctx_T *search_ctx;
+static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx)
{
ff_stack_T *sptr;
@@ -4651,8 +4546,7 @@ ff_search_ctx_T *search_ctx;
/*
* free the given stack element
*/
-static void ff_free_stack_element(stack_ptr)
-ff_stack_T *stack_ptr;
+static void ff_free_stack_element(ff_stack_T *stack_ptr)
{
/* vim_free handles possible NULL pointers */
vim_free(stack_ptr->ffs_fix_path);
@@ -4667,8 +4561,7 @@ ff_stack_T *stack_ptr;
/*
* Clear the search context, but NOT the visited list.
*/
-static void ff_clear(search_ctx)
-ff_search_ctx_T *search_ctx;
+static void ff_clear(ff_search_ctx_T *search_ctx)
{
ff_stack_T *sptr;
@@ -4704,10 +4597,7 @@ ff_search_ctx_T *search_ctx;
* check if the given path is in the stopdirs
* returns TRUE if yes else FALSE
*/
-static int ff_path_in_stoplist(path, path_len, stopdirs_v)
-char_u *path;
-int path_len;
-char_u **stopdirs_v;
+static int ff_path_in_stoplist(char_u *path, int path_len, char_u **stopdirs_v)
{
int i = 0;
@@ -4761,12 +4651,14 @@ char_u **stopdirs_v;
* Returns an allocated string for the file name. NULL for error.
*
*/
-char_u * find_file_in_path(ptr, len, options, first, rel_fname)
-char_u *ptr; /* file name */
-int len; /* length of file name */
-int options;
-int first; /* use count'th matching file name */
-char_u *rel_fname; /* file name searching relative to */
+char_u *
+find_file_in_path (
+ char_u *ptr, /* file name */
+ int len, /* length of file name */
+ int options,
+ int first, /* use count'th matching file name */
+ char_u *rel_fname /* file name searching relative to */
+)
{
return find_file_in_path_option(ptr, len, options, first,
*curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
@@ -4777,7 +4669,7 @@ static char_u *ff_file_to_find = NULL;
static void *fdip_search_ctx = NULL;
#if defined(EXITFREE)
-static void free_findfile() {
+static void free_findfile(void) {
vim_free(ff_file_to_find);
vim_findfile_cleanup(fdip_search_ctx);
}
@@ -4794,27 +4686,29 @@ static void free_findfile() {
*
* Returns an allocated string for the file name. NULL for error.
*/
-char_u * find_directory_in_path(ptr, len, options, rel_fname)
-char_u *ptr; /* file name */
-int len; /* length of file name */
-int options;
-char_u *rel_fname; /* file name searching relative to */
+char_u *
+find_directory_in_path (
+ char_u *ptr, /* file name */
+ int len, /* length of file name */
+ int options,
+ char_u *rel_fname /* file name searching relative to */
+)
{
return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
FINDFILE_DIR, rel_fname, (char_u *)"");
}
-char_u * find_file_in_path_option(ptr, len, options, first, path_option,
- find_what, rel_fname,
- suffixes)
-char_u *ptr; /* file name */
-int len; /* length of file name */
-int options;
-int first; /* use count'th matching file name */
-char_u *path_option; /* p_path or p_cdpath */
-int find_what; /* FINDFILE_FILE, _DIR or _BOTH */
-char_u *rel_fname; /* file name we are looking relative to. */
-char_u *suffixes; /* list of suffixes, 'suffixesadd' option */
+char_u *
+find_file_in_path_option (
+ char_u *ptr, /* file name */
+ int len, /* length of file name */
+ int options,
+ int first, /* use count'th matching file name */
+ char_u *path_option, /* p_path or p_cdpath */
+ int find_what, /* FINDFILE_FILE, _DIR or _BOTH */
+ char_u *rel_fname, /* file name we are looking relative to. */
+ char_u *suffixes /* list of suffixes, 'suffixesadd' option */
+)
{
static char_u *dir;
static int did_findfile_init = FALSE;
@@ -4973,8 +4867,7 @@ theend:
* Change directory to "new_dir". If FEAT_SEARCHPATH is defined, search
* 'cdpath' for relative directory names, otherwise just mch_chdir().
*/
-int vim_chdir(new_dir)
-char_u *new_dir;
+int vim_chdir(char_u *new_dir)
{
char_u *dir_name;
int r;
@@ -4995,9 +4888,7 @@ char_u *new_dir;
* cache the result.
* Returns OK or FAIL.
*/
-int get_user_name(buf, len)
-char_u *buf;
-int len;
+int get_user_name(char_u *buf, int len)
{
if (username == NULL) {
if (mch_get_user_name(buf, len) == FAIL)
@@ -5053,16 +4944,12 @@ int (*cmp)__ARGS((const void *, const void *));
static int
sort_compare __ARGS((const void *s1, const void *s2));
-static int sort_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int sort_compare(const void *s1, const void *s2)
{
return STRCMP(*(char **)s1, *(char **)s2);
}
-void sort_strings(files, count)
-char_u **files;
-int count;
+void sort_strings(char_u **files, int count)
{
qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
}
@@ -5073,9 +4960,7 @@ int count;
* If "maxlen" >= 0 compare "p[maxlen]" to "q[maxlen]"
* Return value like strcmp(p, q), but consider path separators.
*/
-int pathcmp(p, q, maxlen)
-const char *p, *q;
-int maxlen;
+int pathcmp(const char *p, const char *q, int maxlen)
{
int i;
int c1, c2;
@@ -5174,8 +5059,7 @@ static int findenv __ARGS((char *name)); /* look for a name in the env. */
static int newenv __ARGS((void)); /* copy env. from stack to heap */
static int moreenv __ARGS((void)); /* incr. size of env. */
-int putenv(string)
-const char *string;
+int putenv(const char *string)
{
int i;
char *p;
@@ -5208,8 +5092,7 @@ const char *string;
return 0;
}
-static int findenv(name)
-char *name;
+static int findenv(char *name)
{
char *namechar, *envchar;
int i, found;
@@ -5227,7 +5110,7 @@ char *name;
return found ? i - 1 : -1;
}
-static int newenv() {
+static int newenv(void) {
char **env, *elem;
int i, esize;
@@ -5252,7 +5135,7 @@ static int newenv() {
return 0;
}
-static int moreenv() {
+static int moreenv(void) {
int esize;
char **env;
@@ -5266,8 +5149,7 @@ static int moreenv() {
}
# ifdef USE_VIMPTY_GETENV
-char_u * vimpty_getenv(string)
-const char_u *string;
+char_u *vimpty_getenv(const char_u *string)
{
int i;
char_u *p;
@@ -5291,8 +5173,7 @@ const char_u *string;
* Return 0 for not writable, 1 for writable file, 2 for a dir which we have
* rights to write into.
*/
-int filewritable(fname)
-char_u *fname;
+int filewritable(char_u *fname)
{
int retval = 0;
#if defined(UNIX) || defined(VMS)
@@ -5319,8 +5200,7 @@ char_u *fname;
* Print an error message with one or two "%s" and one or two string arguments.
* This is not in message.c to avoid a warning for prototypes.
*/
-int emsg3(s, a1, a2)
-char_u *s, *a1, *a2;
+int emsg3(char_u *s, char_u *a1, char_u *a2)
{
if (emsg_not_now())
return TRUE; /* no error messages at the moment */
@@ -5336,9 +5216,7 @@ char_u *s, *a1, *a2;
* Print an error message with one "%ld" and one long int argument.
* This is not in message.c to avoid a warning for prototypes.
*/
-int emsgn(s, n)
-char_u *s;
-long n;
+int emsgn(char_u *s, long n)
{
if (emsg_not_now())
return TRUE; /* no error messages at the moment */
@@ -5349,8 +5227,7 @@ long n;
/*
* Read 2 bytes from "fd" and turn them into an int, MSB first.
*/
-int get2c(fd)
-FILE *fd;
+int get2c(FILE *fd)
{
int n;
@@ -5362,8 +5239,7 @@ FILE *fd;
/*
* Read 3 bytes from "fd" and turn them into an int, MSB first.
*/
-int get3c(fd)
-FILE *fd;
+int get3c(FILE *fd)
{
int n;
@@ -5376,8 +5252,7 @@ FILE *fd;
/*
* Read 4 bytes from "fd" and turn them into an int, MSB first.
*/
-int get4c(fd)
-FILE *fd;
+int get4c(FILE *fd)
{
/* Use unsigned rather than int otherwise result is undefined
* when left-shift sets the MSB. */
@@ -5393,8 +5268,7 @@ FILE *fd;
/*
* Read 8 bytes from "fd" and turn them into a time_t, MSB first.
*/
-time_t get8ctime(fd)
-FILE *fd;
+time_t get8ctime(FILE *fd)
{
time_t n = 0;
int i;
@@ -5408,9 +5282,7 @@ FILE *fd;
* Read a string of length "cnt" from "fd" into allocated memory.
* Returns NULL when out of memory or unable to read that many bytes.
*/
-char_u * read_string(fd, cnt)
-FILE *fd;
-int cnt;
+char_u *read_string(FILE *fd, int cnt)
{
char_u *str;
int i;
@@ -5436,10 +5308,7 @@ int cnt;
/*
* Write a number to file "fd", MSB first, in "len" bytes.
*/
-int put_bytes(fd, nr, len)
-FILE *fd;
-long_u nr;
-int len;
+int put_bytes(FILE *fd, long_u nr, int len)
{
int i;
@@ -5453,9 +5322,7 @@ int len;
/*
* Write time_t to file "fd" in 8 bytes.
*/
-void put_time(fd, the_time)
-FILE *fd;
-time_t the_time;
+void put_time(FILE *fd, time_t the_time)
{
int c;
int i;
@@ -5491,8 +5358,7 @@ time_t the_time;
* Return TRUE if string "s" contains a non-ASCII character (128 or higher).
* When "s" is NULL FALSE is returned.
*/
-int has_non_ascii(s)
-char_u *s;
+int has_non_ascii(char_u *s)
{
char_u *p;
diff --git a/src/proto/misc2.pro b/src/misc2.h
index c0fd06ff77..7beb681661 100644
--- a/src/proto/misc2.pro
+++ b/src/misc2.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MISC2_H
+#define NEOVIM_MISC2_H
/* misc2.c */
int virtual_active __ARGS((void));
int getviscol __ARGS((void));
@@ -131,3 +133,4 @@ int put_bytes __ARGS((FILE *fd, long_u nr, int len));
void put_time __ARGS((FILE *fd, time_t the_time));
int has_non_ascii __ARGS((char_u *s));
/* vim: set ft=c : */
+#endif /* NEOVIM_MISC2_H */
diff --git a/src/move.c b/src/move.c
index ed63dd212b..d83cfc6b13 100644
--- a/src/move.c
+++ b/src/move.c
@@ -18,6 +18,17 @@
*/
#include "vim.h"
+#include "move.h"
+#include "charset.h"
+#include "diff.h"
+#include "edit.h"
+#include "fold.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "popupmnu.h"
+#include "screen.h"
static void comp_botline __ARGS((win_T *wp));
static int scrolljump_value __ARGS((void));
@@ -42,8 +53,7 @@ static void max_topfill __ARGS((void));
* Compute wp->w_botline for the current wp->w_topline. Can be called after
* wp->w_topline changed.
*/
-static void comp_botline(wp)
-win_T *wp;
+static void comp_botline(win_T *wp)
{
int n;
linenr_T lnum;
@@ -99,7 +109,7 @@ win_T *wp;
* Update curwin->w_topline and redraw if necessary.
* Used to update the screen before printing a message.
*/
-void update_topline_redraw() {
+void update_topline_redraw(void) {
update_topline();
if (must_redraw)
update_screen(0);
@@ -108,7 +118,7 @@ void update_topline_redraw() {
/*
* Update curwin->w_topline to move the cursor onto the screen.
*/
-void update_topline() {
+void update_topline(void) {
long line_count;
int halfheight;
int n;
@@ -296,7 +306,7 @@ void update_topline() {
* When 'scrolljump' is positive use it as-is.
* When 'scrolljump' is negative use it as a percentage of the window height.
*/
-static int scrolljump_value() {
+static int scrolljump_value(void) {
if (p_sj >= 0)
return (int)p_sj;
return (curwin->w_height * -p_sj) / 100;
@@ -306,7 +316,7 @@ static int scrolljump_value() {
* Return TRUE when there are not 'scrolloff' lines above the cursor for the
* current window.
*/
-static int check_top_offset() {
+static int check_top_offset(void) {
lineoff_T loff;
int n;
@@ -332,7 +342,7 @@ static int check_top_offset() {
return FALSE;
}
-void update_curswant() {
+void update_curswant(void) {
if (curwin->w_set_curswant) {
validate_virtcol();
curwin->w_curswant = curwin->w_virtcol;
@@ -343,8 +353,7 @@ void update_curswant() {
/*
* Check if the cursor has moved. Set the w_valid flag accordingly.
*/
-void check_cursor_moved(wp)
-win_T *wp;
+void check_cursor_moved(win_T *wp)
{
if (wp->w_cursor.lnum != wp->w_valid_cursor.lnum) {
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
@@ -367,12 +376,11 @@ win_T *wp;
* the cursor position, botline and topline to be recomputed and the window to
* be redrawn. E.g, when changing the 'wrap' option or folding.
*/
-void changed_window_setting() {
+void changed_window_setting(void) {
changed_window_setting_win(curwin);
}
-void changed_window_setting_win(wp)
-win_T *wp;
+void changed_window_setting_win(win_T *wp)
{
wp->w_lines_valid = 0;
changed_line_abv_curs_win(wp);
@@ -383,9 +391,7 @@ win_T *wp;
/*
* Set wp->w_topline to a certain number.
*/
-void set_topline(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+void set_topline(win_T *wp, linenr_T lnum)
{
/* go to first of folded lines */
(void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
@@ -404,13 +410,12 @@ linenr_T lnum;
* characters) has changed, and the change is before the cursor.
* Need to take care of w_botline separately!
*/
-void changed_cline_bef_curs() {
+void changed_cline_bef_curs(void) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
|VALID_CHEIGHT|VALID_TOPLINE);
}
-void changed_cline_bef_curs_win(wp)
-win_T *wp;
+void changed_cline_bef_curs_win(win_T *wp)
{
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL
|VALID_CHEIGHT|VALID_TOPLINE);
@@ -421,13 +426,12 @@ win_T *wp;
* the cursor have changed.
* Need to take care of w_botline separately!
*/
-void changed_line_abv_curs() {
+void changed_line_abv_curs(void) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|VALID_CHEIGHT|VALID_TOPLINE);
}
-void changed_line_abv_curs_win(wp)
-win_T *wp;
+void changed_line_abv_curs_win(win_T *wp)
{
wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL|VALID_CROW
|VALID_CHEIGHT|VALID_TOPLINE);
@@ -436,7 +440,7 @@ win_T *wp;
/*
* Make sure the value of curwin->w_botline is valid.
*/
-void validate_botline() {
+void validate_botline(void) {
if (!(curwin->w_valid & VALID_BOTLINE))
comp_botline(curwin);
}
@@ -444,8 +448,7 @@ void validate_botline() {
/*
* Make sure the value of wp->w_botline is valid.
*/
-static void validate_botline_win(wp)
-win_T *wp;
+static void validate_botline_win(win_T *wp)
{
if (!(wp->w_valid & VALID_BOTLINE))
comp_botline(wp);
@@ -454,18 +457,16 @@ win_T *wp;
/*
* Mark curwin->w_botline as invalid (because of some change in the buffer).
*/
-void invalidate_botline() {
+void invalidate_botline(void) {
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
}
-void invalidate_botline_win(wp)
-win_T *wp;
+void invalidate_botline_win(win_T *wp)
{
wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
}
-void approximate_botline_win(wp)
-win_T *wp;
+void approximate_botline_win(win_T *wp)
{
wp->w_valid &= ~VALID_BOTLINE;
}
@@ -473,7 +474,7 @@ win_T *wp;
/*
* Return TRUE if curwin->w_wrow and curwin->w_wcol are valid.
*/
-int cursor_valid() {
+int cursor_valid(void) {
check_cursor_moved(curwin);
return (curwin->w_valid & (VALID_WROW|VALID_WCOL)) ==
(VALID_WROW|VALID_WCOL);
@@ -483,7 +484,7 @@ int cursor_valid() {
* Validate cursor position. Makes sure w_wrow and w_wcol are valid.
* w_topline must be valid, you may need to call update_topline() first!
*/
-void validate_cursor() {
+void validate_cursor(void) {
check_cursor_moved(curwin);
if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW))
curs_columns(TRUE);
@@ -495,9 +496,11 @@ void validate_cursor() {
*
* Returns OK when cursor is in the window, FAIL when it isn't.
*/
-static void curs_rows(wp, do_botline)
-win_T *wp;
-int do_botline; /* also compute w_botline */
+static void
+curs_rows (
+ win_T *wp,
+ int do_botline /* also compute w_botline */
+)
{
linenr_T lnum;
int i;
@@ -585,15 +588,14 @@ int do_botline; /* also compute w_botline */
/*
* Validate curwin->w_virtcol only.
*/
-void validate_virtcol() {
+void validate_virtcol(void) {
validate_virtcol_win(curwin);
}
/*
* Validate wp->w_virtcol only.
*/
-void validate_virtcol_win(wp)
-win_T *wp;
+void validate_virtcol_win(win_T *wp)
{
check_cursor_moved(wp);
if (!(wp->w_valid & VALID_VIRTCOL)) {
@@ -609,7 +611,7 @@ win_T *wp;
/*
* Validate curwin->w_cline_height only.
*/
-static void validate_cheight() {
+static void validate_cheight(void) {
check_cursor_moved(curwin);
if (!(curwin->w_valid & VALID_CHEIGHT)) {
if (curwin->w_cursor.lnum == curwin->w_topline)
@@ -625,7 +627,7 @@ static void validate_cheight() {
/*
* Validate w_wcol and w_virtcol only.
*/
-void validate_cursor_col() {
+void validate_cursor_col(void) {
colnr_T off;
colnr_T col;
int width;
@@ -657,8 +659,7 @@ void validate_cursor_col() {
* Compute offset of a window, occupied by absolute or relative line number,
* fold column and sign column (these don't move when scrolling horizontally).
*/
-int win_col_off(wp)
-win_T *wp;
+int win_col_off(win_T *wp)
{
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ (cmdwin_type == 0 || wp != curwin ? 0 : 1)
@@ -666,7 +667,7 @@ win_T *wp;
;
}
-int curwin_col_off() {
+int curwin_col_off(void) {
return win_col_off(curwin);
}
@@ -675,15 +676,14 @@ int curwin_col_off() {
* wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in
* 'cpoptions'.
*/
-int win_col_off2(wp)
-win_T *wp;
+int win_col_off2(win_T *wp)
{
if ((wp->w_p_nu || wp->w_p_rnu) && vim_strchr(p_cpo, CPO_NUMCOL) != NULL)
return number_width(wp) + 1;
return 0;
}
-int curwin_col_off2() {
+int curwin_col_off2(void) {
return win_col_off2(curwin);
}
@@ -692,8 +692,10 @@ int curwin_col_off2() {
* Also updates curwin->w_wrow and curwin->w_cline_row.
* Also updates curwin->w_leftcol.
*/
-void curs_columns(may_scroll)
-int may_scroll; /* when TRUE, may scroll horizontally */
+void
+curs_columns (
+ int may_scroll /* when TRUE, may scroll horizontally */
+)
{
int diff;
int extra; /* offset for first screen line */
@@ -920,9 +922,11 @@ int may_scroll; /* when TRUE, may scroll horizontally */
/*
* Scroll the current window down by "line_count" logical lines. "CTRL-Y"
*/
-void scrolldown(line_count, byfold)
-long line_count;
-int byfold UNUSED; /* TRUE: count a closed fold as one line */
+void
+scrolldown (
+ long line_count,
+ int byfold /* TRUE: count a closed fold as one line */
+)
{
long done = 0; /* total # of physical lines done */
int wrow;
@@ -999,9 +1003,11 @@ int byfold UNUSED; /* TRUE: count a closed fold as one line */
/*
* Scroll the current window up by "line_count" logical lines. "CTRL-E"
*/
-void scrollup(line_count, byfold)
-long line_count;
-int byfold UNUSED; /* TRUE: count a closed fold as one line */
+void
+scrollup (
+ long line_count,
+ int byfold /* TRUE: count a closed fold as one line */
+)
{
linenr_T lnum;
@@ -1055,9 +1061,11 @@ int byfold UNUSED; /* TRUE: count a closed fold as one line */
/*
* Don't end up with too many filler lines in the window.
*/
-void check_topfill(wp, down)
-win_T *wp;
-int down; /* when TRUE scroll down when not enough space */
+void
+check_topfill (
+ win_T *wp,
+ int down /* when TRUE scroll down when not enough space */
+)
{
int n;
@@ -1080,7 +1088,7 @@ int down; /* when TRUE scroll down when not enough space */
* Use as many filler lines as possible for w_topline. Make sure w_topline
* is still visible.
*/
-static void max_topfill() {
+static void max_topfill(void) {
int n;
n = plines_nofill(curwin->w_topline);
@@ -1097,7 +1105,7 @@ static void max_topfill() {
* Scroll the screen one line down, but don't do it if it would move the
* cursor off the screen.
*/
-void scrolldown_clamp() {
+void scrolldown_clamp(void) {
int end_row;
int can_fill = (curwin->w_topfill
< diff_check_fill(curwin, curwin->w_topline));
@@ -1145,7 +1153,7 @@ void scrolldown_clamp() {
* Scroll the screen one line up, but don't do it if it would move the cursor
* off the screen.
*/
-void scrollup_clamp() {
+void scrollup_clamp(void) {
int start_row;
if (curwin->w_topline == curbuf->b_ml.ml_line_count
@@ -1186,8 +1194,7 @@ void scrollup_clamp() {
* Returns the height of the added line in "lp->height".
* Lines above the first one are incredibly high: MAXCOL.
*/
-static void topline_back(lp)
-lineoff_T *lp;
+static void topline_back(lineoff_T *lp)
{
if (lp->fill < diff_check_fill(curwin, lp->lnum)) {
/* Add a filler line. */
@@ -1213,8 +1220,7 @@ lineoff_T *lp;
* Returns the height of the added line in "lp->height".
* Lines below the last one are incredibly high.
*/
-static void botline_forw(lp)
-lineoff_T *lp;
+static void botline_forw(lineoff_T *lp)
{
if (lp->fill < diff_check_fill(curwin, lp->lnum + 1)) {
/* Add a filler line. */
@@ -1239,8 +1245,7 @@ lineoff_T *lp;
* lines above loff.lnum + 1. This keeps pointing to the same line.
* When there are no filler lines nothing changes.
*/
-static void botline_topline(lp)
-lineoff_T *lp;
+static void botline_topline(lineoff_T *lp)
{
if (lp->fill > 0) {
++lp->lnum;
@@ -1253,8 +1258,7 @@ lineoff_T *lp;
* lines below loff.lnum - 1. This keeps pointing to the same line.
* When there are no filler lines nothing changes.
*/
-static void topline_botline(lp)
-lineoff_T *lp;
+static void topline_botline(lineoff_T *lp)
{
if (lp->fill > 0) {
lp->fill = diff_check_fill(curwin, lp->lnum) - lp->fill + 1;
@@ -1267,9 +1271,7 @@ lineoff_T *lp;
* Scroll at least "min_scroll" lines.
* If "always" is TRUE, always set topline (for "zt").
*/
-void scroll_cursor_top(min_scroll, always)
-int min_scroll;
-int always;
+void scroll_cursor_top(int min_scroll, int always)
{
int scrolled = 0;
int extra = 0;
@@ -1383,9 +1385,7 @@ int always;
* Set w_empty_rows and w_filler_rows for window "wp", having used up "used"
* screen lines for text lines.
*/
-void set_empty_rows(wp, used)
-win_T *wp;
-int used;
+void set_empty_rows(win_T *wp, int used)
{
wp->w_filler_rows = 0;
if (used == 0)
@@ -1410,9 +1410,7 @@ int used;
* If "set_topbot" is TRUE, set topline and botline first (for "zb").
* This is messy stuff!!!
*/
-void scroll_cursor_bot(min_scroll, set_topbot)
-int min_scroll;
-int set_topbot;
+void scroll_cursor_bot(int min_scroll, int set_topbot)
{
int used;
int scrolled = 0;
@@ -1586,8 +1584,7 @@ int set_topbot;
* Recompute topline to put the cursor halfway the window
* If "atend" is TRUE, also put it halfway at the end of the file.
*/
-void scroll_cursor_halfway(atend)
-int atend;
+void scroll_cursor_halfway(int atend)
{
int above = 0;
linenr_T topline;
@@ -1645,7 +1642,7 @@ int atend;
* If not possible, put it at the same position as scroll_cursor_halfway().
* When called topline must be valid!
*/
-void cursor_correct() {
+void cursor_correct(void) {
int above = 0; /* screen lines above topline */
linenr_T topline;
int below = 0; /* screen lines below botline */
@@ -1748,9 +1745,7 @@ static void get_scroll_overlap __ARGS((lineoff_T *lp, int dir));
*
* return FAIL for failure, OK otherwise
*/
-int onepage(dir, count)
-int dir;
-long count;
+int onepage(int dir, long count)
{
long n;
int retval = OK;
@@ -1936,9 +1931,7 @@ long count;
* ------------- l3 second text line
* l3 etc.
*/
-static void get_scroll_overlap(lp, dir)
-lineoff_T *lp;
-int dir;
+static void get_scroll_overlap(lineoff_T *lp, int dir)
{
int h1, h2, h3, h4;
int min_height = curwin->w_height - 2;
@@ -1991,9 +1984,7 @@ int dir;
/*
* Scroll 'scroll' lines up or down.
*/
-void halfpage(flag, Prenum)
-int flag;
-linenr_T Prenum;
+void halfpage(int flag, linenr_T Prenum)
{
long scrolled = 0;
int i;
@@ -2153,7 +2144,7 @@ linenr_T Prenum;
redraw_later(VALID);
}
-void do_check_cursorbind() {
+void do_check_cursorbind(void) {
linenr_T line = curwin->w_cursor.lnum;
colnr_T col = curwin->w_cursor.col;
colnr_T coladd = curwin->w_cursor.coladd;
diff --git a/src/proto/move.pro b/src/move.h
index 595e3b8dd7..bf3371fa2d 100644
--- a/src/proto/move.pro
+++ b/src/move.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_MOVE_H
+#define NEOVIM_MOVE_H
/* move.c */
void update_topline_redraw __ARGS((void));
void update_topline __ARGS((void));
@@ -39,3 +41,4 @@ int onepage __ARGS((int dir, long count));
void halfpage __ARGS((int flag, linenr_T Prenum));
void do_check_cursorbind __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_MOVE_H */
diff --git a/src/normal.c b/src/normal.c
index c141f468b2..75b9319d95 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -13,6 +13,39 @@
*/
#include "vim.h"
+#include "normal.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "digraph.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mark.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "ops.h"
+#include "option.h"
+#include "quickfix.h"
+#include "screen.h"
+#include "search.h"
+#include "spell.h"
+#include "syntax.h"
+#include "tag.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
/*
* The Visual area is remembered for reselection.
@@ -384,9 +417,7 @@ static int nv_max_linear;
* Compare functions for qsort() below, that checks the command character
* through the index in nv_cmd_idx[].
*/
-static int nv_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int nv_compare(const void *s1, const void *s2)
{
int c1, c2;
@@ -403,7 +434,7 @@ const void *s2;
/*
* Initialize the nv_cmd_idx[] table.
*/
-void init_normal_cmds() {
+void init_normal_cmds(void) {
int i;
/* Fill the index table with a one to one relation. */
@@ -424,8 +455,7 @@ void init_normal_cmds() {
* Search for a command in the commands table.
* Returns -1 for invalid command.
*/
-static int find_command(cmdchar)
-int cmdchar;
+static int find_command(int cmdchar)
{
int i;
int idx;
@@ -470,9 +500,11 @@ int cmdchar;
/*
* Execute a command in Normal mode.
*/
-void normal_cmd(oap, toplevel)
-oparg_T *oap;
-int toplevel UNUSED; /* TRUE when called from main() */
+void
+normal_cmd (
+ oparg_T *oap,
+ int toplevel /* TRUE when called from main() */
+)
{
cmdarg_T ca; /* command arguments */
int c;
@@ -1140,9 +1172,7 @@ normal_end:
* Set v:count and v:count1 according to "cap".
* Set v:prevcount only when "set_prevcount" is TRUE.
*/
-static void set_vcount_ca(cap, set_prevcount)
-cmdarg_T *cap;
-int *set_prevcount;
+static void set_vcount_ca(cmdarg_T *cap, int *set_prevcount)
{
long count = cap->count0;
@@ -1156,10 +1186,7 @@ int *set_prevcount;
/*
* Handle an operator after visual mode or when the movement is finished
*/
-void do_pending_operator(cap, old_col, gui_yank)
-cmdarg_T *cap;
-int old_col;
-int gui_yank;
+void do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
{
oparg_T *oap = cap->oap;
pos_T old_cursor;
@@ -1782,8 +1809,7 @@ int gui_yank;
/*
* Handle indent and format operators and visual mode ":".
*/
-static void op_colon(oap)
-oparg_T *oap;
+static void op_colon(oparg_T *oap)
{
stuffcharReadbuff(':');
if (oap->is_VIsual)
@@ -1830,8 +1856,7 @@ oparg_T *oap;
/*
* Handle the "g@" operator: call 'operatorfunc'.
*/
-static void op_function(oap)
-oparg_T *oap UNUSED;
+static void op_function(oparg_T *oap)
{
char_u *(argv[1]);
int save_virtual_op = virtual_op;
@@ -1899,12 +1924,14 @@ oparg_T *oap UNUSED;
*
* Return TRUE if start_arrow() should be called for edit mode.
*/
-int do_mouse(oap, c, dir, count, fixindent)
-oparg_T *oap; /* operator argument, can be NULL */
-int c; /* K_LEFTMOUSE, etc */
-int dir; /* Direction to 'put' if necessary */
-long count;
-int fixindent; /* PUT_FIXINDENT if fixing indent necessary */
+int
+do_mouse (
+ oparg_T *oap, /* operator argument, can be NULL */
+ int c, /* K_LEFTMOUSE, etc */
+ int dir, /* Direction to 'put' if necessary */
+ long count,
+ int fixindent /* PUT_FIXINDENT if fixing indent necessary */
+)
{
static int do_always = FALSE; /* ignore 'mouse' setting next time */
static int got_click = FALSE; /* got a click some time back */
@@ -2574,8 +2601,7 @@ int fixindent; /* PUT_FIXINDENT if fixing indent necessary */
/*
* Move "pos" back to the start of the word it's in.
*/
-static void find_start_of_word(pos)
-pos_T *pos;
+static void find_start_of_word(pos_T *pos)
{
char_u *line;
int cclass;
@@ -2597,8 +2623,7 @@ pos_T *pos;
* Move "pos" forward to the end of the word it's in.
* When 'selection' is "exclusive", the position is just after the word.
*/
-static void find_end_of_word(pos)
-pos_T *pos;
+static void find_end_of_word(pos_T *pos)
{
char_u *line;
int cclass;
@@ -2628,8 +2653,7 @@ pos_T *pos;
* 2: normal word character
* >2: multi-byte word character.
*/
-static int get_mouse_class(p)
-char_u *p;
+static int get_mouse_class(char_u *p)
{
int c;
@@ -2658,7 +2682,7 @@ char_u *p;
* Check if highlighting for visual mode is possible, give a warning message
* if not.
*/
-void check_visual_highlight() {
+void check_visual_highlight(void) {
static int did_check = FALSE;
if (full_screen) {
@@ -2673,7 +2697,7 @@ void check_visual_highlight() {
* This function should ALWAYS be called to end Visual mode, except from
* do_pending_operator().
*/
-void end_visual_mode() {
+void end_visual_mode(void) {
VIsual_active = FALSE;
setmouse();
@@ -2699,7 +2723,7 @@ void end_visual_mode() {
/*
* Reset VIsual_active and VIsual_reselect.
*/
-void reset_VIsual_and_resel() {
+void reset_VIsual_and_resel(void) {
if (VIsual_active) {
end_visual_mode();
redraw_curbuf_later(INVERTED); /* delete the inversion later */
@@ -2710,7 +2734,7 @@ void reset_VIsual_and_resel() {
/*
* Reset VIsual_active and VIsual_reselect if it's set.
*/
-void reset_VIsual() {
+void reset_VIsual(void) {
if (VIsual_active) {
end_visual_mode();
redraw_curbuf_later(INVERTED); /* delete the inversion later */
@@ -2739,9 +2763,7 @@ void reset_VIsual() {
* If a string is found, a pointer to the string is put in "*string". This
* string is not always NUL terminated.
*/
-int find_ident_under_cursor(string, find_type)
-char_u **string;
-int find_type;
+int find_ident_under_cursor(char_u **string, int find_type)
{
return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
curwin->w_cursor.col, string, find_type);
@@ -2751,12 +2773,7 @@ int find_type;
* Like find_ident_under_cursor(), but for any window and any position.
* However: Uses 'iskeyword' from the current window!.
*/
-int find_ident_at_pos(wp, lnum, startcol, string, find_type)
-win_T *wp;
-linenr_T lnum;
-colnr_T startcol;
-char_u **string;
-int find_type;
+int find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char_u **string, int find_type)
{
char_u *ptr;
int col = 0; /* init to shut up GCC */
@@ -2870,8 +2887,7 @@ int find_type;
/*
* Prepare for redo of a normal command.
*/
-static void prep_redo_cmd(cap)
-cmdarg_T *cap;
+static void prep_redo_cmd(cmdarg_T *cap)
{
prep_redo(cap->oap->regname, cap->count0,
NUL, cap->cmdchar, NUL, NUL, cap->nchar);
@@ -2881,14 +2897,7 @@ cmdarg_T *cap;
* Prepare for redo of any command.
* Note that only the last argument can be a multi-byte char.
*/
-static void prep_redo(regname, num, cmd1, cmd2, cmd3, cmd4, cmd5)
-int regname;
-long num;
-int cmd1;
-int cmd2;
-int cmd3;
-int cmd4;
-int cmd5;
+static void prep_redo(int regname, long num, int cmd1, int cmd2, int cmd3, int cmd4, int cmd5)
{
ResetRedobuff();
if (regname != 0) { /* yank from specified buffer */
@@ -2915,8 +2924,7 @@ int cmd5;
*
* return TRUE if operator was active
*/
-static int checkclearop(oap)
-oparg_T *oap;
+static int checkclearop(oparg_T *oap)
{
if (oap->op_type == OP_NOP)
return FALSE;
@@ -2929,8 +2937,7 @@ oparg_T *oap;
*
* Return TRUE if operator or Visual was active.
*/
-static int checkclearopq(oap)
-oparg_T *oap;
+static int checkclearopq(oparg_T *oap)
{
if (oap->op_type == OP_NOP
&& !VIsual_active
@@ -2940,8 +2947,7 @@ oparg_T *oap;
return TRUE;
}
-static void clearop(oap)
-oparg_T *oap;
+static void clearop(oparg_T *oap)
{
oap->op_type = OP_NOP;
oap->regname = 0;
@@ -2949,8 +2955,7 @@ oparg_T *oap;
oap->use_reg_one = FALSE;
}
-static void clearopbeep(oap)
-oparg_T *oap;
+static void clearopbeep(oparg_T *oap)
{
clearop(oap);
beep_flush();
@@ -2959,8 +2964,7 @@ oparg_T *oap;
/*
* Remove the shift modifier from a special key.
*/
-static void unshift_special(cap)
-cmdarg_T *cap;
+static void unshift_special(cmdarg_T *cap)
{
switch (cap->cmdchar) {
case K_S_RIGHT: cap->cmdchar = K_RIGHT; break;
@@ -2985,7 +2989,7 @@ static int showcmd_visual = FALSE;
static void display_showcmd __ARGS((void));
-void clear_showcmd() {
+void clear_showcmd(void) {
if (!p_sc)
return;
@@ -3066,8 +3070,7 @@ void clear_showcmd() {
* Add 'c' to string of shown command chars.
* Return TRUE if output has been written (and setcursor() has been called).
*/
-int add_to_showcmd(c)
-int c;
+int add_to_showcmd(int c)
{
char_u *p;
int old_len;
@@ -3119,8 +3122,7 @@ int c;
return TRUE;
}
-void add_to_showcmd_c(c)
-int c;
+void add_to_showcmd_c(int c)
{
if (!add_to_showcmd(c))
setcursor();
@@ -3129,8 +3131,7 @@ int c;
/*
* Delete 'len' characters from the end of the shown command.
*/
-static void del_from_showcmd(len)
-int len;
+static void del_from_showcmd(int len)
{
int old_len;
@@ -3150,12 +3151,12 @@ int len;
* push_showcmd() and pop_showcmd() are used when waiting for the user to type
* something and there is a partial mapping.
*/
-void push_showcmd() {
+void push_showcmd(void) {
if (p_sc)
STRCPY(old_showcmd_buf, showcmd_buf);
}
-void pop_showcmd() {
+void pop_showcmd(void) {
if (!p_sc)
return;
@@ -3164,7 +3165,7 @@ void pop_showcmd() {
display_showcmd();
}
-static void display_showcmd() {
+static void display_showcmd(void) {
int len;
cursor_off();
@@ -3191,8 +3192,7 @@ static void display_showcmd() {
* When "check" is TRUE, take care of scroll-binding after the window has
* scrolled. Called from normal_cmd() and edit().
*/
-void do_check_scrollbind(check)
-int check;
+void do_check_scrollbind(int check)
{
static win_T *old_curwin = NULL;
static linenr_T old_topline = 0;
@@ -3248,9 +3248,7 @@ int check;
* number of rows by which the current window has changed
* (1998-11-02 16:21:01 R. Edward Ralston <eralston@computer.org>)
*/
-void check_scrollbind(topline_diff, leftcol_diff)
-linenr_T topline_diff;
-long leftcol_diff;
+void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
{
int want_ver;
int want_hor;
@@ -3327,8 +3325,7 @@ long leftcol_diff;
* Used for CTRL-Q and CTRL-S to avoid problems with terminals that use
* xon/xoff.
*/
-static void nv_ignore(cap)
-cmdarg_T *cap;
+static void nv_ignore(cmdarg_T *cap)
{
cap->retval |= CA_COMMAND_BUSY; /* don't call edit() now */
}
@@ -3337,16 +3334,14 @@ cmdarg_T *cap;
* Command character that doesn't do anything, but unlike nv_ignore() does
* start edit(). Used for "startinsert" executed while starting up.
*/
-static void nv_nop(cap)
-cmdarg_T *cap UNUSED;
+static void nv_nop(cmdarg_T *cap)
{
}
/*
* Command character doesn't exist.
*/
-static void nv_error(cap)
-cmdarg_T *cap;
+static void nv_error(cmdarg_T *cap)
{
clearopbeep(cap->oap);
}
@@ -3354,8 +3349,7 @@ cmdarg_T *cap;
/*
* <Help> and <F1> commands.
*/
-static void nv_help(cap)
-cmdarg_T *cap;
+static void nv_help(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap))
ex_help(NULL);
@@ -3364,8 +3358,7 @@ cmdarg_T *cap;
/*
* CTRL-A and CTRL-X: Add or subtract from letter or number under cursor.
*/
-static void nv_addsub(cap)
-cmdarg_T *cap;
+static void nv_addsub(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)
&& do_addsub((int)cap->cmdchar, cap->count1) == OK)
@@ -3375,8 +3368,7 @@ cmdarg_T *cap;
/*
* CTRL-F, CTRL-B, etc: Scroll page up or down.
*/
-static void nv_page(cap)
-cmdarg_T *cap;
+static void nv_page(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
if (mod_mask & MOD_MASK_CTRL) {
@@ -3393,10 +3385,12 @@ cmdarg_T *cap;
/*
* Implementation of "gd" and "gD" command.
*/
-static void nv_gd(oap, nchar, thisblock)
-oparg_T *oap;
-int nchar;
-int thisblock; /* 1 for "1gd" and "1gD" */
+static void
+nv_gd (
+ oparg_T *oap,
+ int nchar,
+ int thisblock /* 1 for "1gd" and "1gD" */
+)
{
int len;
char_u *ptr;
@@ -3415,12 +3409,14 @@ int thisblock; /* 1 for "1gd" and "1gD" */
* When "thisblock" is TRUE check the {} block scope.
* Return FAIL when not found.
*/
-int find_decl(ptr, len, locally, thisblock, searchflags)
-char_u *ptr;
-int len;
-int locally;
-int thisblock;
-int searchflags; /* flags passed to searchit() */
+int
+find_decl (
+ char_u *ptr,
+ int len,
+ int locally,
+ int thisblock,
+ int searchflags /* flags passed to searchit() */
+)
{
char_u *pat;
pos_T old_pos;
@@ -3532,10 +3528,7 @@ int searchflags; /* flags passed to searchit() */
*
* Return OK if able to move cursor, FAIL otherwise.
*/
-static int nv_screengo(oap, dir, dist)
-oparg_T *oap;
-int dir;
-long dist;
+static int nv_screengo(oparg_T *oap, int dir, long dist)
{
int linelen = linetabsize(ml_get_curline());
int retval = OK;
@@ -3660,8 +3653,7 @@ long dist;
* K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or
* K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2)
*/
-static void nv_mousescroll(cap)
-cmdarg_T *cap;
+static void nv_mousescroll(cmdarg_T *cap)
{
win_T *old_curwin = curwin;
@@ -3695,8 +3687,7 @@ cmdarg_T *cap;
/*
* Mouse clicks and drags.
*/
-static void nv_mouse(cap)
-cmdarg_T *cap;
+static void nv_mouse(cmdarg_T *cap)
{
(void)do_mouse(cap->oap, cap->cmdchar, BACKWARD, cap->count1, 0);
}
@@ -3705,8 +3696,7 @@ cmdarg_T *cap;
* Handle CTRL-E and CTRL-Y commands: scroll a line up or down.
* cap->arg must be TRUE for CTRL-E.
*/
-static void nv_scroll_line(cap)
-cmdarg_T *cap;
+static void nv_scroll_line(cmdarg_T *cap)
{
if (!checkclearop(cap->oap))
scroll_redraw(cap->arg, cap->count1);
@@ -3715,9 +3705,7 @@ cmdarg_T *cap;
/*
* Scroll "count" lines up or down, and redraw.
*/
-void scroll_redraw(up, count)
-int up;
-long count;
+void scroll_redraw(int up, long count)
{
linenr_T prev_topline = curwin->w_topline;
int prev_topfill = curwin->w_topfill;
@@ -3764,8 +3752,7 @@ long count;
/*
* Commands that start with "z".
*/
-static void nv_zet(cap)
-cmdarg_T *cap;
+static void nv_zet(cmdarg_T *cap)
{
long n;
colnr_T col;
@@ -4191,8 +4178,7 @@ dozet:
/*
* "Q" command.
*/
-static void nv_exmode(cap)
-cmdarg_T *cap;
+static void nv_exmode(cmdarg_T *cap)
{
/*
* Ignore 'Q' in Visual mode, just give a beep.
@@ -4206,8 +4192,7 @@ cmdarg_T *cap;
/*
* Handle a ":" command.
*/
-static void nv_colon(cap)
-cmdarg_T *cap;
+static void nv_colon(cmdarg_T *cap)
{
int old_p_im;
int cmd_result;
@@ -4264,8 +4249,7 @@ cmdarg_T *cap;
/*
* Handle CTRL-G command.
*/
-static void nv_ctrlg(cap)
-cmdarg_T *cap;
+static void nv_ctrlg(cmdarg_T *cap)
{
if (VIsual_active) { /* toggle Selection/Visual mode */
VIsual_select = !VIsual_select;
@@ -4278,8 +4262,7 @@ cmdarg_T *cap;
/*
* Handle CTRL-H <Backspace> command.
*/
-static void nv_ctrlh(cap)
-cmdarg_T *cap;
+static void nv_ctrlh(cmdarg_T *cap)
{
if (VIsual_active && VIsual_select) {
cap->cmdchar = 'x'; /* BS key behaves like 'x' in Select mode */
@@ -4291,8 +4274,7 @@ cmdarg_T *cap;
/*
* CTRL-L: clear screen and redraw.
*/
-static void nv_clear(cap)
-cmdarg_T *cap;
+static void nv_clear(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
/* Clear all syntax states to force resyncing. */
@@ -4305,8 +4287,7 @@ cmdarg_T *cap;
* CTRL-O: In Select mode: switch to Visual mode for one command.
* Otherwise: Go to older pcmark.
*/
-static void nv_ctrlo(cap)
-cmdarg_T *cap;
+static void nv_ctrlo(cmdarg_T *cap)
{
if (VIsual_active && VIsual_select) {
VIsual_select = FALSE;
@@ -4321,8 +4302,7 @@ cmdarg_T *cap;
/*
* CTRL-^ command, short for ":e #"
*/
-static void nv_hat(cap)
-cmdarg_T *cap;
+static void nv_hat(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap))
(void)buflist_getfile((int)cap->count0, (linenr_T)0,
@@ -4332,8 +4312,7 @@ cmdarg_T *cap;
/*
* "Z" commands.
*/
-static void nv_Zet(cap)
-cmdarg_T *cap;
+static void nv_Zet(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
switch (cap->nchar) {
@@ -4353,9 +4332,7 @@ cmdarg_T *cap;
/*
* Call nv_ident() as if "c1" was used, with "c2" as next character.
*/
-void do_nv_ident(c1, c2)
-int c1;
-int c2;
+void do_nv_ident(int c1, int c2)
{
oparg_T oa;
cmdarg_T ca;
@@ -4376,8 +4353,7 @@ int c2;
* [g] '#' ? to current identifier or string
* g ']' :tselect for current identifier
*/
-static void nv_ident(cap)
-cmdarg_T *cap;
+static void nv_ident(cmdarg_T *cap)
{
char_u *ptr = NULL;
char_u *buf;
@@ -4581,10 +4557,12 @@ cmdarg_T *cap;
* Get visually selected text, within one line only.
* Returns FAIL if more than one line selected.
*/
-int get_visual_text(cap, pp, lenp)
-cmdarg_T *cap;
-char_u **pp; /* return: start of selected text */
-int *lenp; /* return: length of selected text */
+int
+get_visual_text (
+ cmdarg_T *cap,
+ char_u **pp, /* return: start of selected text */
+ int *lenp /* return: length of selected text */
+)
{
if (VIsual_mode != 'V')
unadjust_for_sel();
@@ -4615,8 +4593,7 @@ int *lenp; /* return: length of selected text */
/*
* CTRL-T: backwards in tag stack
*/
-static void nv_tagpop(cap)
-cmdarg_T *cap;
+static void nv_tagpop(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap))
do_tag((char_u *)"", DT_POP, (int)cap->count1, FALSE, TRUE);
@@ -4625,8 +4602,7 @@ cmdarg_T *cap;
/*
* Handle scrolling command 'H', 'L' and 'M'.
*/
-static void nv_scroll(cap)
-cmdarg_T *cap;
+static void nv_scroll(cmdarg_T *cap)
{
int used = 0;
long n;
@@ -4700,8 +4676,7 @@ cmdarg_T *cap;
/*
* Cursor right commands.
*/
-static void nv_right(cap)
-cmdarg_T *cap;
+static void nv_right(cmdarg_T *cap)
{
long n;
int PAST_LINE;
@@ -4789,8 +4764,7 @@ cmdarg_T *cap;
*
* Returns TRUE when operator end should not be adjusted.
*/
-static void nv_left(cap)
-cmdarg_T *cap;
+static void nv_left(cmdarg_T *cap)
{
long n;
@@ -4850,8 +4824,7 @@ cmdarg_T *cap;
* Cursor up commands.
* cap->arg is TRUE for "-": Move cursor to first non-blank.
*/
-static void nv_up(cap)
-cmdarg_T *cap;
+static void nv_up(cmdarg_T *cap)
{
if (mod_mask & MOD_MASK_SHIFT) {
/* <S-Up> is page up */
@@ -4870,8 +4843,7 @@ cmdarg_T *cap;
* Cursor down commands.
* cap->arg is TRUE for CR and "+": Move cursor to first non-blank.
*/
-static void nv_down(cap)
-cmdarg_T *cap;
+static void nv_down(cmdarg_T *cap)
{
if (mod_mask & MOD_MASK_SHIFT) {
/* <S-Down> is page down */
@@ -4901,8 +4873,7 @@ cmdarg_T *cap;
/*
* Grab the file name under the cursor and edit it.
*/
-static void nv_gotofile(cap)
-cmdarg_T *cap;
+static void nv_gotofile(cmdarg_T *cap)
{
char_u *ptr;
linenr_T lnum = -1;
@@ -4939,8 +4910,7 @@ cmdarg_T *cap;
/*
* <End> command: to end of current line or last line.
*/
-static void nv_end(cap)
-cmdarg_T *cap;
+static void nv_end(cmdarg_T *cap)
{
if (cap->arg || (mod_mask & MOD_MASK_CTRL)) { /* CTRL-END = goto last line */
cap->arg = TRUE;
@@ -4953,8 +4923,7 @@ cmdarg_T *cap;
/*
* Handle the "$" command.
*/
-static void nv_dollar(cap)
-cmdarg_T *cap;
+static void nv_dollar(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = TRUE;
@@ -4975,8 +4944,7 @@ cmdarg_T *cap;
* Implementation of '?' and '/' commands.
* If cap->arg is TRUE don't set PC mark.
*/
-static void nv_search(cap)
-cmdarg_T *cap;
+static void nv_search(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
@@ -5003,8 +4971,7 @@ cmdarg_T *cap;
* Handle "N" and "n" commands.
* cap->arg is SEARCH_REV for "N", 0 for "n".
*/
-static void nv_next(cap)
-cmdarg_T *cap;
+static void nv_next(cmdarg_T *cap)
{
normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
}
@@ -5013,11 +4980,13 @@ cmdarg_T *cap;
* Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
* Uses only cap->count1 and cap->oap from "cap".
*/
-static void normal_search(cap, dir, pat, opt)
-cmdarg_T *cap;
-int dir;
-char_u *pat;
-int opt; /* extra flags for do_search() */
+static void
+normal_search (
+ cmdarg_T *cap,
+ int dir,
+ char_u *pat,
+ int opt /* extra flags for do_search() */
+)
{
int i;
@@ -5049,8 +5018,7 @@ int opt; /* extra flags for do_search() */
* ',' and FALSE for ';'.
* cap->nchar is NUL for ',' and ';' (repeat the search)
*/
-static void nv_csearch(cap)
-cmdarg_T *cap;
+static void nv_csearch(cmdarg_T *cap)
{
int t_cmd;
@@ -5083,8 +5051,7 @@ cmdarg_T *cap;
* "[" and "]" commands.
* cap->arg is BACKWARD for "[" and FORWARD for "]".
*/
-static void nv_brackets(cap)
-cmdarg_T *cap;
+static void nv_brackets(cmdarg_T *cap)
{
pos_T new_pos = INIT_POS_T(0, 0, 0);
pos_T prev_pos;
@@ -5342,8 +5309,7 @@ cmdarg_T *cap;
/*
* Handle Normal mode "%" command.
*/
-static void nv_percent(cap)
-cmdarg_T *cap;
+static void nv_percent(cmdarg_T *cap)
{
pos_T *pos;
linenr_T lnum = curwin->w_cursor.lnum;
@@ -5391,8 +5357,7 @@ cmdarg_T *cap;
* Handle "(" and ")" commands.
* cap->arg is BACKWARD for "(" and FORWARD for ")".
*/
-static void nv_brace(cap)
-cmdarg_T *cap;
+static void nv_brace(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->use_reg_one = TRUE;
@@ -5414,8 +5379,7 @@ cmdarg_T *cap;
/*
* "m" command: Mark a position.
*/
-static void nv_mark(cap)
-cmdarg_T *cap;
+static void nv_mark(cmdarg_T *cap)
{
if (!checkclearop(cap->oap)) {
if (setmark(cap->nchar) == FAIL)
@@ -5427,8 +5391,7 @@ cmdarg_T *cap;
* "{" and "}" commands.
* cmd->arg is BACKWARD for "{" and FORWARD for "}".
*/
-static void nv_findpar(cap)
-cmdarg_T *cap;
+static void nv_findpar(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = FALSE;
@@ -5446,8 +5409,7 @@ cmdarg_T *cap;
/*
* "u" command: Undo or make lower case.
*/
-static void nv_undo(cap)
-cmdarg_T *cap;
+static void nv_undo(cmdarg_T *cap)
{
if (cap->oap->op_type == OP_LOWER
|| VIsual_active
@@ -5463,8 +5425,7 @@ cmdarg_T *cap;
/*
* <Undo> command.
*/
-static void nv_kundo(cap)
-cmdarg_T *cap;
+static void nv_kundo(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
u_undo((int)cap->count1);
@@ -5475,8 +5436,7 @@ cmdarg_T *cap;
/*
* Handle the "r" command.
*/
-static void nv_replace(cap)
-cmdarg_T *cap;
+static void nv_replace(cmdarg_T *cap)
{
char_u *ptr;
int had_ctrl_v;
@@ -5646,8 +5606,7 @@ cmdarg_T *cap;
* 'o': Exchange start and end of Visual area.
* 'O': same, but in block mode exchange left and right corners.
*/
-static void v_swap_corners(cmdchar)
-int cmdchar;
+static void v_swap_corners(int cmdchar)
{
pos_T old_cursor;
colnr_T left, right;
@@ -5691,8 +5650,7 @@ int cmdchar;
/*
* "R" (cap->arg is FALSE) and "gR" (cap->arg is TRUE).
*/
-static void nv_Replace(cap)
-cmdarg_T *cap;
+static void nv_Replace(cmdarg_T *cap)
{
if (VIsual_active) { /* "R" is replace lines */
cap->cmdchar = 'c';
@@ -5714,8 +5672,7 @@ cmdarg_T *cap;
/*
* "gr".
*/
-static void nv_vreplace(cap)
-cmdarg_T *cap;
+static void nv_vreplace(cmdarg_T *cap)
{
if (VIsual_active) {
cap->cmdchar = 'r';
@@ -5739,8 +5696,7 @@ cmdarg_T *cap;
/*
* Swap case for "~" command, when it does not work like an operator.
*/
-static void n_swapchar(cap)
-cmdarg_T *cap;
+static void n_swapchar(cmdarg_T *cap)
{
long n;
pos_T startpos;
@@ -5794,10 +5750,7 @@ cmdarg_T *cap;
/*
* Move cursor to mark.
*/
-static void nv_cursormark(cap, flag, pos)
-cmdarg_T *cap;
-int flag;
-pos_T *pos;
+static void nv_cursormark(cmdarg_T *cap, int flag, pos_T *pos)
{
if (check_mark(pos) == FAIL)
clearop(cap->oap);
@@ -5823,8 +5776,7 @@ pos_T *pos;
/*
* Handle commands that are operators in Visual mode.
*/
-static void v_visop(cap)
-cmdarg_T *cap;
+static void v_visop(cmdarg_T *cap)
{
static char_u trans[] = "YyDdCcxdXdAAIIrr";
@@ -5844,8 +5796,7 @@ cmdarg_T *cap;
/*
* "s" and "S" commands.
*/
-static void nv_subst(cap)
-cmdarg_T *cap;
+static void nv_subst(cmdarg_T *cap)
{
if (VIsual_active) { /* "vs" and "vS" are the same as "vc" */
if (cap->cmdchar == 'S') {
@@ -5861,8 +5812,7 @@ cmdarg_T *cap;
/*
* Abbreviated commands.
*/
-static void nv_abbrev(cap)
-cmdarg_T *cap;
+static void nv_abbrev(cmdarg_T *cap)
{
if (cap->cmdchar == K_DEL || cap->cmdchar == K_KDEL)
cap->cmdchar = 'x'; /* DEL key behaves like 'x' */
@@ -5877,8 +5827,7 @@ cmdarg_T *cap;
/*
* Translate a command into another command.
*/
-static void nv_optrans(cap)
-cmdarg_T *cap;
+static void nv_optrans(cmdarg_T *cap)
{
static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh",
(char_u *)"d$", (char_u *)"c$",
@@ -5911,8 +5860,7 @@ cmdarg_T *cap;
* "'" and "`" commands. Also for "g'" and "g`".
* cap->arg is TRUE for "'" and "g'".
*/
-static void nv_gomark(cap)
-cmdarg_T *cap;
+static void nv_gomark(cmdarg_T *cap)
{
pos_T *pos;
int c;
@@ -5947,8 +5895,7 @@ cmdarg_T *cap;
/*
* Handle CTRL-O, CTRL-I, "g;" and "g," commands.
*/
-static void nv_pcmark(cap)
-cmdarg_T *cap;
+static void nv_pcmark(cmdarg_T *cap)
{
pos_T *pos;
linenr_T lnum = curwin->w_cursor.lnum;
@@ -5984,8 +5931,7 @@ cmdarg_T *cap;
/*
* Handle '"' command.
*/
-static void nv_regname(cap)
-cmdarg_T *cap;
+static void nv_regname(cmdarg_T *cap)
{
if (checkclearop(cap->oap))
return;
@@ -6005,8 +5951,7 @@ cmdarg_T *cap;
* is TRUE.
* Handle CTRL-Q just like CTRL-V.
*/
-static void nv_visual(cap)
-cmdarg_T *cap;
+static void nv_visual(cmdarg_T *cap)
{
if (cap->cmdchar == Ctrl_Q)
cap->cmdchar = Ctrl_V;
@@ -6095,7 +6040,7 @@ cmdarg_T *cap;
/*
* Start selection for Shift-movement keys.
*/
-void start_selection() {
+void start_selection(void) {
/* if 'selectmode' contains "key", start Select mode */
may_start_select('k');
n_start_visual_mode('v');
@@ -6104,8 +6049,7 @@ void start_selection() {
/*
* Start Select mode, if "c" is in 'selectmode' and not in a mapping or menu.
*/
-void may_start_select(c)
-int c;
+void may_start_select(int c)
{
VIsual_select = (stuff_empty() && typebuf_typed()
&& (vim_strchr(p_slm, c) != NULL));
@@ -6115,8 +6059,7 @@ int c;
* Start Visual mode "c".
* Should set VIsual_select before calling this.
*/
-static void n_start_visual_mode(c)
-int c;
+static void n_start_visual_mode(int c)
{
/* Check for redraw before changing the state. */
conceal_check_cursur_line();
@@ -6154,8 +6097,7 @@ int c;
/*
* CTRL-W: Window commands
*/
-static void nv_window(cap)
-cmdarg_T *cap;
+static void nv_window(cmdarg_T *cap)
{
if (!checkclearop(cap->oap))
do_window(cap->nchar, cap->count0, NUL); /* everything is in window.c */
@@ -6164,8 +6106,7 @@ cmdarg_T *cap;
/*
* CTRL-Z: Suspend
*/
-static void nv_suspend(cap)
-cmdarg_T *cap;
+static void nv_suspend(cmdarg_T *cap)
{
clearop(cap->oap);
if (VIsual_active)
@@ -6176,8 +6117,7 @@ cmdarg_T *cap;
/*
* Commands starting with "g".
*/
-static void nv_g_cmd(cap)
-cmdarg_T *cap;
+static void nv_g_cmd(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
pos_T tpos;
@@ -6692,8 +6632,7 @@ cmdarg_T *cap;
/*
* Handle "o" and "O" commands.
*/
-static void n_opencmd(cap)
-cmdarg_T *cap;
+static void n_opencmd(cmdarg_T *cap)
{
linenr_T oldline = curwin->w_cursor.lnum;
@@ -6727,8 +6666,7 @@ cmdarg_T *cap;
/*
* "." command: redo last change.
*/
-static void nv_dot(cap)
-cmdarg_T *cap;
+static void nv_dot(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
/*
@@ -6744,8 +6682,7 @@ cmdarg_T *cap;
/*
* CTRL-R: undo undo
*/
-static void nv_redo(cap)
-cmdarg_T *cap;
+static void nv_redo(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
u_redo((int)cap->count1);
@@ -6756,8 +6693,7 @@ cmdarg_T *cap;
/*
* Handle "U" command.
*/
-static void nv_Undo(cap)
-cmdarg_T *cap;
+static void nv_Undo(cmdarg_T *cap)
{
/* In Visual mode and typing "gUU" triggers an operator */
if (cap->oap->op_type == OP_UPPER
@@ -6777,8 +6713,7 @@ cmdarg_T *cap;
* '~' command: If tilde is not an operator and Visual is off: swap case of a
* single character.
*/
-static void nv_tilde(cap)
-cmdarg_T *cap;
+static void nv_tilde(cmdarg_T *cap)
{
if (!p_to
&& !VIsual_active
@@ -6792,8 +6727,7 @@ cmdarg_T *cap;
* Handle an operator command.
* The actual work is done by do_pending_operator().
*/
-static void nv_operator(cap)
-cmdarg_T *cap;
+static void nv_operator(cmdarg_T *cap)
{
int op_type;
@@ -6811,8 +6745,7 @@ cmdarg_T *cap;
/*
* Set v:operator to the characters for "optype".
*/
-static void set_op_var(optype)
-int optype;
+static void set_op_var(int optype)
{
char_u opchars[3];
@@ -6835,8 +6768,7 @@ int optype;
* are really an alternate form of "d_" and "y_". It does accept a count, so
* "d3_" works to delete 3 lines.
*/
-static void nv_lineop(cap)
-cmdarg_T *cap;
+static void nv_lineop(cmdarg_T *cap)
{
cap->oap->motion_type = MLINE;
if (cursor_down(cap->count1 - 1L, cap->oap->op_type == OP_NOP) == FAIL)
@@ -6854,8 +6786,7 @@ cmdarg_T *cap;
/*
* <Home> command.
*/
-static void nv_home(cap)
-cmdarg_T *cap;
+static void nv_home(cmdarg_T *cap)
{
/* CTRL-HOME is like "gg" */
if (mod_mask & MOD_MASK_CTRL)
@@ -6871,8 +6802,7 @@ cmdarg_T *cap;
/*
* "|" command.
*/
-static void nv_pipe(cap)
-cmdarg_T *cap;
+static void nv_pipe(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = FALSE;
@@ -6891,8 +6821,7 @@ cmdarg_T *cap;
* Handle back-word command "b" and "B".
* cap->arg is 1 for "B"
*/
-static void nv_bck_word(cap)
-cmdarg_T *cap;
+static void nv_bck_word(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = FALSE;
@@ -6907,8 +6836,7 @@ cmdarg_T *cap;
* Handle word motion commands "e", "E", "w" and "W".
* cap->arg is TRUE for "E" and "W".
*/
-static void nv_wordcmd(cap)
-cmdarg_T *cap;
+static void nv_wordcmd(cmdarg_T *cap)
{
int n;
int word_end;
@@ -6987,8 +6915,7 @@ cmdarg_T *cap;
* end of the line, may move it back to the last character and make the motion
* inclusive.
*/
-static void adjust_cursor(oap)
-oparg_T *oap;
+static void adjust_cursor(oparg_T *oap)
{
/* The cursor cannot remain on the NUL when:
* - the column is > 0
@@ -7011,8 +6938,7 @@ oparg_T *oap;
* "0" and "^" commands.
* cap->arg is the argument for beginline().
*/
-static void nv_beginline(cap)
-cmdarg_T *cap;
+static void nv_beginline(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = FALSE;
@@ -7026,8 +6952,7 @@ cmdarg_T *cap;
/*
* In exclusive Visual mode, may include the last character.
*/
-static void adjust_for_sel(cap)
-cmdarg_T *cap;
+static void adjust_for_sel(cmdarg_T *cap)
{
if (VIsual_active && cap->oap->inclusive && *p_sel == 'e'
&& gchar_cursor() != NUL && lt(VIsual, curwin->w_cursor)) {
@@ -7044,7 +6969,7 @@ cmdarg_T *cap;
* Should check VIsual_mode before calling this.
* Returns TRUE when backed up to the previous line.
*/
-static int unadjust_for_sel() {
+static int unadjust_for_sel(void) {
pos_T *pp;
if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor)) {
@@ -7069,8 +6994,7 @@ static int unadjust_for_sel() {
/*
* SELECT key in Normal or Visual mode: end of Select mode mapping.
*/
-static void nv_select(cap)
-cmdarg_T *cap;
+static void nv_select(cmdarg_T *cap)
{
if (VIsual_active)
VIsual_select = TRUE;
@@ -7086,8 +7010,7 @@ cmdarg_T *cap;
* "G", "gg", CTRL-END, CTRL-HOME.
* cap->arg is TRUE for "G".
*/
-static void nv_goto(cap)
-cmdarg_T *cap;
+static void nv_goto(cmdarg_T *cap)
{
linenr_T lnum;
@@ -7114,8 +7037,7 @@ cmdarg_T *cap;
/*
* CTRL-\ in Normal mode.
*/
-static void nv_normal(cap)
-cmdarg_T *cap;
+static void nv_normal(cmdarg_T *cap)
{
if (cap->nchar == Ctrl_N || cap->nchar == Ctrl_G) {
clearop(cap->oap);
@@ -7139,8 +7061,7 @@ cmdarg_T *cap;
* ESC in Normal mode: beep, but don't flush buffers.
* Don't even beep if we are canceling a command.
*/
-static void nv_esc(cap)
-cmdarg_T *cap;
+static void nv_esc(cmdarg_T *cap)
{
int no_reason;
@@ -7188,8 +7109,7 @@ cmdarg_T *cap;
/*
* Handle "A", "a", "I", "i" and <Insert> commands.
*/
-static void nv_edit(cap)
-cmdarg_T *cap;
+static void nv_edit(cmdarg_T *cap)
{
/* <Insert> is equal to "i" */
if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS)
@@ -7262,11 +7182,13 @@ cmdarg_T *cap;
/*
* Invoke edit() and take care of "restart_edit" and the return value.
*/
-static void invoke_edit(cap, repl, cmd, startln)
-cmdarg_T *cap;
-int repl; /* "r" or "gr" command */
-int cmd;
-int startln;
+static void
+invoke_edit (
+ cmdarg_T *cap,
+ int repl, /* "r" or "gr" command */
+ int cmd,
+ int startln
+)
{
int restart_edit_save = 0;
@@ -7291,8 +7213,7 @@ int startln;
/*
* "a" or "i" while an operator is pending or in Visual mode: object motion.
*/
-static void nv_object(cap)
-cmdarg_T *cap;
+static void nv_object(cmdarg_T *cap)
{
int flag;
int include;
@@ -7363,8 +7284,7 @@ cmdarg_T *cap;
* "q" command: Start/stop recording.
* "q:", "q/", "q?": edit command-line in command-line window.
*/
-static void nv_record(cap)
-cmdarg_T *cap;
+static void nv_record(cmdarg_T *cap)
{
if (cap->oap->op_type == OP_FORMAT) {
/* "gqq" is the same as "gqgq": format line */
@@ -7386,8 +7306,7 @@ cmdarg_T *cap;
/*
* Handle the "@r" command.
*/
-static void nv_at(cap)
-cmdarg_T *cap;
+static void nv_at(cmdarg_T *cap)
{
if (checkclearop(cap->oap))
return;
@@ -7407,8 +7326,7 @@ cmdarg_T *cap;
/*
* Handle the CTRL-U and CTRL-D commands.
*/
-static void nv_halfpage(cap)
-cmdarg_T *cap;
+static void nv_halfpage(cmdarg_T *cap)
{
if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1)
|| (cap->cmdchar == Ctrl_D
@@ -7421,8 +7339,7 @@ cmdarg_T *cap;
/*
* Handle "J" or "gJ" command.
*/
-static void nv_join(cap)
-cmdarg_T *cap;
+static void nv_join(cmdarg_T *cap)
{
if (VIsual_active) /* join the visual lines */
nv_operator(cap);
@@ -7443,8 +7360,7 @@ cmdarg_T *cap;
/*
* "P", "gP", "p" and "gp" commands.
*/
-static void nv_put(cap)
-cmdarg_T *cap;
+static void nv_put(cmdarg_T *cap)
{
int regname = 0;
void *reg1 = NULL, *reg2 = NULL;
@@ -7555,8 +7471,7 @@ cmdarg_T *cap;
/*
* "o" and "O" commands.
*/
-static void nv_open(cap)
-cmdarg_T *cap;
+static void nv_open(cmdarg_T *cap)
{
/* "do" is ":diffget" */
if (cap->oap->op_type == OP_DELETE && cap->cmdchar == 'o') {
@@ -7576,8 +7491,7 @@ cmdarg_T *cap;
* When waiting for a character for 'updatetime' K_CURSORHOLD is put in the
* input buffer. "did_cursorhold" is set to avoid retriggering.
*/
-static void nv_cursorhold(cap)
-cmdarg_T *cap;
+static void nv_cursorhold(cmdarg_T *cap)
{
apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf);
did_cursorhold = TRUE;
diff --git a/src/proto/normal.pro b/src/normal.h
index a178751474..171c4c928d 100644
--- a/src/proto/normal.pro
+++ b/src/normal.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_NORMAL_H
+#define NEOVIM_NORMAL_H
/* normal.c */
void init_normal_cmds __ARGS((void));
void normal_cmd __ARGS((oparg_T *oap, int toplevel));
@@ -27,3 +29,4 @@ int get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
void start_selection __ARGS((void));
void may_start_select __ARGS((int c));
/* vim: set ft=c : */
+#endif /* NEOVIM_NORMAL_H */
diff --git a/src/ops.c b/src/ops.c
index 3acb297134..5fb256e30d 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -13,6 +13,31 @@
*/
#include "vim.h"
+#include "ops.h"
+#include "buffer.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_getln.h"
+#include "fold.h"
+#include "getchar.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "screen.h"
+#include "search.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
/*
* Number of registers.
@@ -130,9 +155,7 @@ static char opchars[][3] =
* Translate a command name into an operator type.
* Must only be called with a valid operator name!
*/
-int get_op_type(char1, char2)
-int char1;
-int char2;
+int get_op_type(int char1, int char2)
{
int i;
@@ -149,8 +172,7 @@ int char2;
/*
* Return TRUE if operator "op" always works on whole lines.
*/
-int op_on_lines(op)
-int op;
+int op_on_lines(int op)
{
return opchars[op][2];
}
@@ -159,8 +181,7 @@ int op;
* Get first operator command character.
* Returns 'g' or 'z' if there is another command character.
*/
-int get_op_char(optype)
-int optype;
+int get_op_char(int optype)
{
return opchars[optype][0];
}
@@ -168,8 +189,7 @@ int optype;
/*
* Get second operator command character.
*/
-int get_extra_op_char(optype)
-int optype;
+int get_extra_op_char(int optype)
{
return opchars[optype][1];
}
@@ -177,10 +197,7 @@ int optype;
/*
* op_shift - handle a shift operation
*/
-void op_shift(oap, curs_top, amount)
-oparg_T *oap;
-int curs_top;
-int amount;
+void op_shift(oparg_T *oap, int curs_top, int amount)
{
long i;
int first_char;
@@ -257,11 +274,13 @@ int amount;
* shift the current line one shiftwidth left (if left != 0) or right
* leaves cursor on first blank in the line
*/
-void shift_line(left, round, amount, call_changed_bytes)
-int left;
-int round;
-int amount;
-int call_changed_bytes; /* call changed_bytes() */
+void
+shift_line (
+ int left,
+ int round,
+ int amount,
+ int call_changed_bytes /* call changed_bytes() */
+)
{
int count;
int i, j;
@@ -301,9 +320,7 @@ int call_changed_bytes; /* call changed_bytes() */
* Shift one line of the current block one shiftwidth right or left.
* Leaves cursor on first character in block.
*/
-static void shift_block(oap, amount)
-oparg_T *oap;
-int amount;
+static void shift_block(oparg_T *oap, int amount)
{
int left = (oap->op_type == OP_LSHIFT);
int oldstate = State;
@@ -466,11 +483,7 @@ int amount;
* Insert string "s" (b_insert ? before : after) block :AKelly
* Caller must prepare for undo.
*/
-static void block_insert(oap, s, b_insert, bdp)
-oparg_T *oap;
-char_u *s;
-int b_insert;
-struct block_def *bdp;
+static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def *bdp)
{
int p_ts;
int count = 0; /* extra spaces to replace a cut TAB */
@@ -643,7 +656,7 @@ static char_u *expr_line = NULL;
* Get an expression for the "\"=expr1" or "CTRL-R =expr1"
* Returns '=' when OK, NUL otherwise.
*/
-int get_expr_register() {
+int get_expr_register(void) {
char_u *new_line;
new_line = getcmdline('=', 0L, 0);
@@ -660,8 +673,7 @@ int get_expr_register() {
* Set the expression for the '=' register.
* Argument must be an allocated string.
*/
-void set_expr_line(new_line)
-char_u *new_line;
+void set_expr_line(char_u *new_line)
{
vim_free(expr_line);
expr_line = new_line;
@@ -671,7 +683,7 @@ char_u *new_line;
* Get the result of the '=' register expression.
* Returns a pointer to allocated memory, or NULL for failure.
*/
-char_u * get_expr_line() {
+char_u *get_expr_line(void) {
char_u *expr_copy;
char_u *rv;
static int nested = 0;
@@ -700,7 +712,7 @@ char_u * get_expr_line() {
/*
* Get the '=' register expression itself, without evaluating it.
*/
-char_u * get_expr_line_src() {
+char_u *get_expr_line_src(void) {
if (expr_line == NULL)
return NULL;
return vim_strsave(expr_line);
@@ -710,9 +722,11 @@ char_u * get_expr_line_src() {
* Check if 'regname' is a valid name of a yank register.
* Note: There is no check for 0 (default register), caller should do this
*/
-int valid_yank_reg(regname, writing)
-int regname;
-int writing; /* if TRUE check for writable registers */
+int
+valid_yank_reg (
+ int regname,
+ int writing /* if TRUE check for writable registers */
+)
{
if ( (regname > 0 && ASCII_ISALNUM(regname))
|| (!writing && vim_strchr((char_u *)
@@ -734,9 +748,7 @@ int writing; /* if TRUE check for writable registers */
* If regname is 0 and writing, use register 0
* If regname is 0 and reading, use previous register
*/
-void get_yank_register(regname, writing)
-int regname;
-int writing;
+void get_yank_register(int regname, int writing)
{
int i;
@@ -767,9 +779,11 @@ int writing;
* Obtain the contents of a "normal" register. The register is made empty.
* The returned pointer has allocated memory, use put_register() later.
*/
-void * get_register(name, copy)
-int name;
-int copy; /* make a copy, if FALSE make register empty. */
+void *
+get_register (
+ int name,
+ int copy /* make a copy, if FALSE make register empty. */
+)
{
struct yankreg *reg;
int i;
@@ -799,9 +813,7 @@ int copy; /* make a copy, if FALSE make register empty. */
/*
* Put "reg" into register "name". Free any previous contents and "reg".
*/
-void put_register(name, reg)
-int name;
-void *reg;
+void put_register(int name, void *reg)
{
get_yank_register(name, 0);
free_yank_all();
@@ -810,8 +822,7 @@ void *reg;
}
-void free_register(reg)
-void *reg;
+void free_register(void *reg)
{
struct yankreg tmp;
@@ -825,8 +836,7 @@ void *reg;
/*
* return TRUE if the current yank register has type MLINE
*/
-int yank_register_mline(regname)
-int regname;
+int yank_register_mline(int regname)
{
if (regname != 0 && !valid_yank_reg(regname, FALSE))
return FALSE;
@@ -841,8 +851,7 @@ int regname;
*
* Return FAIL for failure, OK otherwise.
*/
-int do_record(c)
-int c;
+int do_record(int c)
{
char_u *p;
static int regname;
@@ -896,9 +905,7 @@ int c;
*
* return FAIL for failure, OK otherwise
*/
-static int stuff_yank(regname, p)
-int regname;
-char_u *p;
+static int stuff_yank(int regname, char_u *p)
{
char_u *lp;
char_u **pp;
@@ -946,11 +953,13 @@ static int execreg_lastc = NUL;
*
* return FAIL for failure, OK otherwise
*/
-int do_execreg(regname, colon, addcr, silent)
-int regname;
-int colon; /* insert ':' before each line */
-int addcr; /* always add '\n' to end of line */
-int silent; /* set "silent" flag in typeahead buffer */
+int
+do_execreg (
+ int regname,
+ int colon, /* insert ':' before each line */
+ int addcr, /* always add '\n' to end of line */
+ int silent /* set "silent" flag in typeahead buffer */
+)
{
long i;
char_u *p;
@@ -1052,8 +1061,7 @@ int silent; /* set "silent" flag in typeahead buffer */
* If "restart_edit" is not zero, put it in the typeahead buffer, so that it's
* used only after other typeahead has been processed.
*/
-static void put_reedit_in_typebuf(silent)
-int silent;
+static void put_reedit_in_typebuf(int silent)
{
char_u buf[3];
@@ -1077,11 +1085,13 @@ int silent;
* When "esc" is TRUE it is to be taken literally: Escape CSI characters and
* no remapping.
*/
-static int put_in_typebuf(s, esc, colon, silent)
-char_u *s;
-int esc;
-int colon; /* add ':' before the line */
-int silent;
+static int
+put_in_typebuf (
+ char_u *s,
+ int esc,
+ int colon, /* add ':' before the line */
+ int silent
+)
{
int retval = OK;
@@ -1114,9 +1124,11 @@ int silent;
*
* return FAIL for failure, OK otherwise
*/
-int insert_reg(regname, literally)
-int regname;
-int literally; /* insert literally, not as if typed */
+int
+insert_reg (
+ int regname,
+ int literally /* insert literally, not as if typed */
+)
{
long i;
int retval = OK;
@@ -1169,9 +1181,7 @@ int literally; /* insert literally, not as if typed */
* Stuff a string into the typeahead buffer, such that edit() will insert it
* literally ("literally" TRUE) or interpret is as typed characters.
*/
-static void stuffescaped(arg, literally)
-char_u *arg;
-int literally;
+static void stuffescaped(char_u *arg, int literally)
{
int c;
char_u *start;
@@ -1206,11 +1216,13 @@ int literally;
* If "regname" is a special register, return TRUE and store a pointer to its
* value in "argp".
*/
-int get_spec_reg(regname, argp, allocated, errmsg)
-int regname;
-char_u **argp;
-int *allocated; /* return: TRUE when value was allocated */
-int errmsg; /* give error message when failing */
+int
+get_spec_reg (
+ int regname,
+ char_u **argp,
+ int *allocated, /* return: TRUE when value was allocated */
+ int errmsg /* give error message when failing */
+)
{
int cnt;
@@ -1287,10 +1299,12 @@ int errmsg; /* give error message when failing */
*
* return FAIL for failure, OK otherwise
*/
-int cmdline_paste_reg(regname, literally, remcr)
-int regname;
-int literally; /* Insert text literally instead of "as typed" */
-int remcr; /* don't add trailing CR */
+int
+cmdline_paste_reg (
+ int regname,
+ int literally, /* Insert text literally instead of "as typed" */
+ int remcr /* don't add trailing CR */
+)
{
long i;
@@ -1325,8 +1339,7 @@ int remcr; /* don't add trailing CR */
*
* Return FAIL if undo failed, OK otherwise.
*/
-int op_delete(oap)
-oparg_T *oap;
+int op_delete(oparg_T *oap)
{
int n;
linenr_T lnum;
@@ -1667,8 +1680,7 @@ setmarks:
* Adjust end of operating area for ending on a multi-byte character.
* Used for deletion.
*/
-static void mb_adjust_opend(oap)
-oparg_T *oap;
+static void mb_adjust_opend(oparg_T *oap)
{
char_u *p;
@@ -1681,9 +1693,7 @@ oparg_T *oap;
/*
* Replace a whole area with one character.
*/
-int op_replace(oap, c)
-oparg_T *oap;
-int c;
+int op_replace(oparg_T *oap, int c)
{
int n, numc;
int num_chars;
@@ -1885,8 +1895,7 @@ static int swapchars __ARGS((int op_type, pos_T *pos, int length));
/*
* Handle the (non-standard vi) tilde operator. Also for "gu", "gU" and "g?".
*/
-void op_tilde(oap)
-oparg_T *oap;
+void op_tilde(oparg_T *oap)
{
pos_T pos;
struct block_def bd;
@@ -1961,10 +1970,7 @@ oparg_T *oap;
* Also works correctly when the number of bytes changes.
* Returns TRUE if some character was changed.
*/
-static int swapchars(op_type, pos, length)
-int op_type;
-pos_T *pos;
-int length;
+static int swapchars(int op_type, pos_T *pos, int length)
{
int todo;
int did_change = 0;
@@ -1991,9 +1997,7 @@ int length;
* else swap case of character at 'pos'
* returns TRUE when something actually changed.
*/
-int swapchar(op_type, pos)
-int op_type;
-pos_T *pos;
+int swapchar(int op_type, pos_T *pos)
{
int c;
int nc;
@@ -2050,9 +2054,7 @@ pos_T *pos;
/*
* op_insert - Insert and append operators for Visual mode.
*/
-void op_insert(oap, count1)
-oparg_T *oap;
-long count1;
+void op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
@@ -2198,8 +2200,7 @@ long count1;
*
* return TRUE if edit() returns because of a CTRL-O command
*/
-int op_change(oap)
-oparg_T *oap;
+int op_change(oparg_T *oap)
{
colnr_T l;
int retval;
@@ -2318,7 +2319,7 @@ oparg_T *oap;
/*
* set all the yank registers to empty (called from main())
*/
-void init_yank() {
+void init_yank(void) {
int i;
for (i = 0; i < NUM_REGISTERS; ++i)
@@ -2326,7 +2327,7 @@ void init_yank() {
}
#if defined(EXITFREE) || defined(PROTO)
-void clear_registers() {
+void clear_registers(void) {
int i;
for (i = 0; i < NUM_REGISTERS; ++i) {
@@ -2342,8 +2343,7 @@ void clear_registers() {
* Free "n" lines from the current yank register.
* Called for normal freeing and in case of error.
*/
-static void free_yank(n)
-long n;
+static void free_yank(long n)
{
if (y_current->y_array != NULL) {
long i;
@@ -2356,7 +2356,7 @@ long n;
}
}
-static void free_yank_all() {
+static void free_yank_all(void) {
free_yank(y_current->y_size);
}
@@ -2368,10 +2368,7 @@ static void free_yank_all() {
*
* Return FAIL for failure, OK otherwise.
*/
-int op_yank(oap, deleting, mess)
-oparg_T *oap;
-int deleting;
-int mess;
+int op_yank(oparg_T *oap, int deleting, int mess)
{
long y_idx; /* index in y_array[] */
struct yankreg *curr; /* copy of y_current */
@@ -2604,9 +2601,7 @@ fail: /* free the allocated lines */
return FAIL;
}
-static int yank_copy_line(bd, y_idx)
-struct block_def *bd;
-long y_idx;
+static int yank_copy_line(struct block_def *bd, long y_idx)
{
char_u *pnew;
@@ -2632,11 +2627,13 @@ long y_idx;
* PUT_CURSEND leave cursor after end of new text
* PUT_LINE force linewise put (":put")
*/
-void do_put(regname, dir, count, flags)
-int regname;
-int dir; /* BACKWARD for 'P', FORWARD for 'p' */
-long count;
-int flags;
+void
+do_put (
+ int regname,
+ int dir, /* BACKWARD for 'P', FORWARD for 'p' */
+ long count,
+ int flags
+)
{
char_u *ptr;
char_u *newp, *oldp;
@@ -3197,7 +3194,7 @@ end:
* When the cursor is on the NUL past the end of the line and it should not be
* there move it left.
*/
-void adjust_cursor_eol() {
+void adjust_cursor_eol(void) {
if (curwin->w_cursor.col > 0
&& gchar_cursor() == NUL
&& (ve_flags & VE_ONEMORE) == 0
@@ -3218,7 +3215,7 @@ void adjust_cursor_eol() {
/*
* Return TRUE if lines starting with '#' should be left aligned.
*/
-int preprocs_left() {
+int preprocs_left(void) {
return
(curbuf->b_p_si && !curbuf->b_p_cin) ||
(curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE)
@@ -3227,8 +3224,7 @@ int preprocs_left() {
}
/* Return the character name of the register with the given number */
-int get_register_name(num)
-int num;
+int get_register_name(int num)
{
if (num == -1)
return '"';
@@ -3244,8 +3240,7 @@ int num;
/*
* ":dis" and ":registers": Display the contents of the yank registers.
*/
-void ex_display(eap)
-exarg_T *eap;
+void ex_display(exarg_T *eap)
{
int i, n;
long j;
@@ -3374,9 +3369,11 @@ exarg_T *eap;
* display a string for do_dis()
* truncate at end of screen line
*/
-static void dis_msg(p, skip_esc)
-char_u *p;
-int skip_esc; /* if TRUE, ignore trailing ESC */
+static void
+dis_msg (
+ char_u *p,
+ int skip_esc /* if TRUE, ignore trailing ESC */
+)
{
int n;
int l;
@@ -3406,11 +3403,7 @@ int skip_esc; /* if TRUE, ignore trailing ESC */
* is_comment - will indicate whether the current line ends with an unclosed
* comment.
*/
-static char_u * skip_comment(line, process, include_space, is_comment)
-char_u *line;
-int process;
-int include_space;
-int *is_comment;
+static char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment)
{
char_u *comment_flags = NULL;
int lead_len;
@@ -3470,11 +3463,7 @@ int *is_comment;
*
* return FAIL for failure, OK otherwise
*/
-int do_join(count, insert_space, save_undo, use_formatoptions)
-long count;
-int insert_space;
-int save_undo;
-int use_formatoptions UNUSED;
+int do_join(long count, int insert_space, int save_undo, int use_formatoptions)
{
char_u *curr = NULL;
char_u *curr_start = NULL;
@@ -3652,13 +3641,7 @@ theend:
* the first line. White-space is ignored. Note that the whole of
* 'leader1' must match 'leader2_len' characters from 'leader2' -- webb
*/
-static int same_leader(lnum, leader1_len, leader1_flags, leader2_len,
- leader2_flags)
-linenr_T lnum;
-int leader1_len;
-char_u *leader1_flags;
-int leader2_len;
-char_u *leader2_flags;
+static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, int leader2_len, char_u *leader2_flags)
{
int idx1 = 0, idx2 = 0;
char_u *p;
@@ -3719,9 +3702,11 @@ char_u *leader2_flags;
/*
* Implementation of the format operator 'gq'.
*/
-void op_format(oap, keep_cursor)
-oparg_T *oap;
-int keep_cursor; /* keep cursor on same text char */
+void
+op_format (
+ oparg_T *oap,
+ int keep_cursor /* keep cursor on same text char */
+)
{
long old_line_count = curbuf->b_ml.ml_line_count;
@@ -3787,8 +3772,7 @@ int keep_cursor; /* keep cursor on same text char */
/*
* Implementation of the format operator 'gq' for when using 'formatexpr'.
*/
-void op_formatexpr(oap)
-oparg_T *oap;
+void op_formatexpr(oparg_T *oap)
{
if (oap->is_VIsual)
/* When there is no change: need to remove the Visual selection */
@@ -3800,10 +3784,12 @@ oparg_T *oap;
op_format(oap, FALSE);
}
-int fex_format(lnum, count, c)
-linenr_T lnum;
-long count;
-int c; /* character to be inserted */
+int
+fex_format (
+ linenr_T lnum,
+ long count,
+ int c /* character to be inserted */
+)
{
int use_sandbox = was_set_insecurely((char_u *)"formatexpr",
OPT_LOCAL);
@@ -3837,9 +3823,11 @@ int c; /* character to be inserted */
* Lines after the cursor line are saved for undo, caller must have saved the
* first line.
*/
-void format_lines(line_count, avoid_fex)
-linenr_T line_count;
-int avoid_fex; /* don't use 'formatexpr' */
+void
+format_lines (
+ linenr_T line_count,
+ int avoid_fex /* don't use 'formatexpr' */
+)
{
int max_len;
int is_not_par; /* current line not part of parag. */
@@ -4056,8 +4044,7 @@ int avoid_fex; /* don't use 'formatexpr' */
/*
* Return TRUE if line "lnum" ends in a white character.
*/
-static int ends_in_white(lnum)
-linenr_T lnum;
+static int ends_in_white(linenr_T lnum)
{
char_u *s = ml_get(lnum);
size_t l;
@@ -4078,11 +4065,7 @@ linenr_T lnum;
* previous line. A new paragraph starts after a blank line, or when the
* comment leader changes -- webb.
*/
-static int fmt_check_par(lnum, leader_len, leader_flags, do_comments)
-linenr_T lnum;
-int *leader_len;
-char_u **leader_flags;
-int do_comments;
+static int fmt_check_par(linenr_T lnum, int *leader_len, char_u **leader_flags, int do_comments)
{
char_u *flags = NULL; /* init for GCC */
char_u *ptr;
@@ -4111,8 +4094,7 @@ int do_comments;
* Return TRUE when a paragraph starts in line "lnum". Return FALSE when the
* previous line is in the same paragraph. Used for auto-formatting.
*/
-int paragraph_start(lnum)
-linenr_T lnum;
+int paragraph_start(linenr_T lnum)
{
char_u *p;
int leader_len = 0; /* leader len of current line */
@@ -4165,11 +4147,7 @@ linenr_T lnum;
* - start/endspaces is the number of columns of the first/last yanked char
* that are to be yanked.
*/
-static void block_prep(oap, bdp, lnum, is_del)
-oparg_T *oap;
-struct block_def *bdp;
-linenr_T lnum;
-int is_del;
+static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int is_del)
{
int incr = 0;
char_u *pend;
@@ -4281,8 +4259,7 @@ int is_del;
static void reverse_line __ARGS((char_u *s));
-static void reverse_line(s)
-char_u *s;
+static void reverse_line(char_u *s)
{
int i, j;
char_u c;
@@ -4304,9 +4281,7 @@ char_u *s;
*
* return FAIL for failure, OK otherwise
*/
-int do_addsub(command, Prenum1)
-int command;
-linenr_T Prenum1;
+int do_addsub(int command, linenr_T Prenum1)
{
int col;
char_u *buf1;
@@ -4530,9 +4505,7 @@ linenr_T Prenum1;
return OK;
}
-int read_viminfo_register(virp, force)
-vir_T *virp;
-int force;
+int read_viminfo_register(vir_T *virp, int force)
{
int eof;
int do_it = TRUE;
@@ -4622,8 +4595,7 @@ int force;
return eof;
}
-void write_viminfo_registers(fp)
-FILE *fp;
+void write_viminfo_registers(FILE *fp)
{
int i, j;
char_u *type;
@@ -4710,9 +4682,7 @@ FILE *fp;
* Used for getregtype()
* Returns MAUTO for error.
*/
-char_u get_reg_type(regname, reglen)
-int regname;
-long *reglen;
+char_u get_reg_type(int regname, long *reglen)
{
switch (regname) {
case '%': /* file name */
@@ -4748,10 +4718,12 @@ long *reglen;
* Used for "@r" in expressions and for getreg().
* Returns NULL for error.
*/
-char_u * get_reg_contents(regname, allowexpr, expr_src)
-int regname;
-int allowexpr; /* allow "=" register */
-int expr_src; /* get expression for "=" register */
+char_u *
+get_reg_contents (
+ int regname,
+ int allowexpr, /* allow "=" register */
+ int expr_src /* get expression for "=" register */
+)
{
long i;
char_u *retval;
@@ -4835,22 +4807,12 @@ int expr_src; /* get expression for "=" register */
* Careful: 'str' is modified, you may have to use a copy!
* If "str" ends in '\n' or '\r', use linewise, otherwise use characterwise.
*/
-void write_reg_contents(name, str, maxlen, must_append)
-int name;
-char_u *str;
-int maxlen;
-int must_append;
+void write_reg_contents(int name, char_u *str, int maxlen, int must_append)
{
write_reg_contents_ex(name, str, maxlen, must_append, MAUTO, 0L);
}
-void write_reg_contents_ex(name, str, maxlen, must_append, yank_type, block_len)
-int name;
-char_u *str;
-int maxlen;
-int must_append;
-int yank_type;
-long block_len;
+void write_reg_contents_ex(int name, char_u *str, int maxlen, int must_append, int yank_type, long block_len)
{
struct yankreg *old_y_previous, *old_y_current;
long len;
@@ -4910,12 +4872,14 @@ long block_len;
* Put a string into a register. When the register is not empty, the string
* is appended.
*/
-static void str_to_reg(y_ptr, yank_type, str, len, blocklen)
-struct yankreg *y_ptr; /* pointer to yank register */
-int yank_type; /* MCHAR, MLINE, MBLOCK, MAUTO */
-char_u *str; /* string to put in register */
-long len; /* length of string */
-long blocklen; /* width of Visual block */
+static void
+str_to_reg (
+ struct yankreg *y_ptr, /* pointer to yank register */
+ int yank_type, /* MCHAR, MLINE, MBLOCK, MAUTO */
+ char_u *str, /* string to put in register */
+ long len, /* length of string */
+ long blocklen /* width of Visual block */
+)
{
int type; /* MCHAR, MLINE or MBLOCK */
int lnum;
@@ -5010,8 +4974,7 @@ long blocklen; /* width of Visual block */
y_ptr->y_width = 0;
}
-void clear_oparg(oap)
-oparg_T *oap;
+void clear_oparg(oparg_T *oap)
{
vim_memset(oap, 0, sizeof(oparg_T));
}
@@ -5034,12 +4997,7 @@ static long line_count_info __ARGS((char_u *line, long *wc, long *cc,
* case, eol_size will be added to the character count to account for
* the size of the EOL character.
*/
-static long line_count_info(line, wc, cc, limit, eol_size)
-char_u *line;
-long *wc;
-long *cc;
-long limit;
-int eol_size;
+static long line_count_info(char_u *line, long *wc, long *cc, long limit, int eol_size)
{
long i;
long words = 0;
@@ -5076,7 +5034,7 @@ int eol_size;
* In Visual mode, give some info about the selected region. (In this case,
* the *_count_cursor variables store running totals for the selection.)
*/
-void cursor_pos_info() {
+void cursor_pos_info(void) {
char_u *p;
char_u buf1[50];
char_u buf2[40];
diff --git a/src/proto/ops.pro b/src/ops.h
index f69f71ae25..f9fcbb2656 100644
--- a/src/proto/ops.pro
+++ b/src/ops.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_OPS_H
+#define NEOVIM_OPS_H
/* ops.c */
int get_op_type __ARGS((int char1, int char2));
int op_on_lines __ARGS((int op));
@@ -64,3 +66,4 @@ void write_reg_contents_ex __ARGS((int name, char_u *str, int maxlen,
void clear_oparg __ARGS((oparg_T *oap));
void cursor_pos_info __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_OPS_H */
diff --git a/src/option.c b/src/option.c
index 9dc432a1d4..ded6fc1314 100644
--- a/src/option.c
+++ b/src/option.c
@@ -11,7 +11,7 @@
* Code to handle user-settable options. This is all pretty much table-
* driven. Checklist for adding a new option:
* - Put it in the options array below (copy an existing entry).
- * - For a global option: Add a variable for it in option.h.
+ * - For a global option: Add a variable for it in option_defs.h.
* - For a buffer or window local option:
* - Add a PV_XX entry to the enum below.
* - Add a variable to the window or buffer struct in structs.h.
@@ -33,6 +33,37 @@
#define IN_OPTION_C
#include "vim.h"
+#include "option.h"
+#include "blowfish.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "digraph.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hardcopy.h"
+#include "mbyte.h"
+#include "memfile.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "os_unix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "spell.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "window.h"
/*
* The options that are local to a window or buffer have "indir" set to one of
@@ -52,7 +83,7 @@
/*
* Definition of the PV_ values for buffer-local options.
- * The BV_ values are defined in option.h.
+ * The BV_ values are defined in option_defs.h.
*/
#define PV_AI OPT_BUF(BV_AI)
#define PV_AR OPT_BOTH(OPT_BUF(BV_AR))
@@ -130,7 +161,7 @@
/*
* Definition of the PV_ values for window-local options.
- * The WV_ values are defined in option.h.
+ * The WV_ values are defined in option_defs.h.
*/
#define PV_LIST OPT_WIN(WV_LIST)
# define PV_ARAB OPT_WIN(WV_ARAB)
@@ -1921,7 +1952,7 @@ static int check_opt_wim __ARGS((void));
*
* Called only once from main(), just after creating the first buffer.
*/
-void set_init_1() {
+void set_init_1(void) {
char_u *p;
int opt_idx;
long_u n;
@@ -2212,10 +2243,12 @@ void set_init_1() {
* Set an option to its default value.
* This does not take care of side effects!
*/
-static void set_option_default(opt_idx, opt_flags, compatible)
-int opt_idx;
-int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
-int compatible; /* use Vi default value */
+static void
+set_option_default (
+ int opt_idx,
+ int opt_flags, /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+ int compatible /* use Vi default value */
+)
{
char_u *varp; /* pointer to variable for current option */
int dvi; /* index in def_val[] */
@@ -2275,8 +2308,10 @@ int compatible; /* use Vi default value */
/*
* Set all options (except terminal options) to their default value.
*/
-static void set_options_default(opt_flags)
-int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+static void
+set_options_default (
+ int opt_flags /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+)
{
int i;
win_T *wp;
@@ -2295,9 +2330,7 @@ int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
* Set the Vi-default value of a string option.
* Used for 'sh', 'backupskip' and 'term'.
*/
-void set_string_default(name, val)
-char *name;
-char_u *val;
+void set_string_default(char *name, char_u *val)
{
char_u *p;
int opt_idx;
@@ -2318,9 +2351,7 @@ char_u *val;
* Set the Vi-default value of a number option.
* Used for 'lines' and 'columns'.
*/
-void set_number_default(name, val)
-char *name;
-long val;
+void set_number_default(char *name, long val)
{
int opt_idx;
@@ -2333,7 +2364,7 @@ long val;
/*
* Free all options.
*/
-void free_all_options() {
+void free_all_options(void) {
int i;
for (i = 0; !istermoption(&options[i]); i++) {
@@ -2357,7 +2388,7 @@ void free_all_options() {
* Initialize the options, part two: After getting Rows and Columns and
* setting 'term'.
*/
-void set_init_2() {
+void set_init_2(void) {
int idx;
/*
@@ -2411,7 +2442,7 @@ void set_init_2() {
* values separated by semicolons; we want the last value in either
* case. If this value is 0-6 or 8, our background is dark.
*/
-static char_u * term_bg_default() {
+static char_u *term_bg_default(void) {
char_u *p;
if (STRCMP(T_NAME, "linux") == 0
@@ -2429,7 +2460,7 @@ static char_u * term_bg_default() {
/*
* Initialize the options, part three: After reading the .vimrc
*/
-void set_init_3() {
+void set_init_3(void) {
#if defined(UNIX) || defined(OS2) || defined(WIN3264)
/*
* Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
@@ -2520,8 +2551,7 @@ void set_init_3() {
* When 'helplang' is still at its default value, set it to "lang".
* Only the first two characters of "lang" are used.
*/
-void set_helplang_default(lang)
-char_u *lang;
+void set_helplang_default(char_u *lang)
{
int idx;
@@ -2554,7 +2584,7 @@ char_u *lang;
* they can be reset. This reduces startup time when using X on a remote
* machine.
*/
-void set_title_defaults() {
+void set_title_defaults(void) {
int idx1;
long val;
@@ -2592,9 +2622,11 @@ void set_title_defaults() {
*
* returns FAIL if an error is detected, OK otherwise
*/
-int do_set(arg, opt_flags)
-char_u *arg; /* option string (may be written to!) */
-int opt_flags;
+int
+do_set (
+ char_u *arg, /* option string (may be written to!) */
+ int opt_flags
+)
{
int opt_idx;
char_u *errmsg;
@@ -3339,10 +3371,12 @@ theend:
* Call this when an option has been given a new value through a user command.
* Sets the P_WAS_SET flag and takes care of the P_INSECURE flag.
*/
-static void did_set_option(opt_idx, opt_flags, new_value)
-int opt_idx;
-int opt_flags; /* possibly with OPT_MODELINE */
-int new_value; /* value was replaced completely */
+static void
+did_set_option (
+ int opt_idx,
+ int opt_flags, /* possibly with OPT_MODELINE */
+ int new_value /* value was replaced completely */
+)
{
long_u *p;
@@ -3362,9 +3396,7 @@ int new_value; /* value was replaced completely */
*p = *p & ~P_INSECURE;
}
-static char_u * illegal_char(errbuf, c)
-char_u *errbuf;
-int c;
+static char_u *illegal_char(char_u *errbuf, int c)
{
if (errbuf == NULL)
return (char_u *)"";
@@ -3377,8 +3409,7 @@ int c;
* Convert a key name or string into a key value.
* Used for 'wildchar' and 'cedit' options.
*/
-static int string_to_key(arg)
-char_u *arg;
+static int string_to_key(char_u *arg)
{
if (*arg == '<')
return find_key_option(arg + 1);
@@ -3391,7 +3422,7 @@ char_u *arg;
* Check value of 'cedit' and set cedit_key.
* Returns NULL if value is OK, error message otherwise.
*/
-static char_u * check_cedit() {
+static char_u *check_cedit(void) {
int n;
if (*p_cedit == NUL)
@@ -3411,8 +3442,10 @@ static char_u * check_cedit() {
* When switching the title or icon off, call mch_restore_title() to get
* the old value back.
*/
-static void did_set_title(icon)
-int icon; /* Did set icon instead of title */
+static void
+did_set_title (
+ int icon /* Did set icon instead of title */
+)
{
if (starting != NO_SCREEN
) {
@@ -3430,10 +3463,12 @@ int icon; /* Did set icon instead of title */
/*
* set_options_bin - called when 'bin' changes value.
*/
-void set_options_bin(oldval, newval, opt_flags)
-int oldval;
-int newval;
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+void
+set_options_bin (
+ int oldval,
+ int newval,
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
/*
* The option values that are changed when 'bin' changes are
@@ -3491,8 +3526,7 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
* If the parameter is not specified in the string or there is no following
* number, return -1.
*/
-int get_viminfo_parameter(type)
-int type;
+int get_viminfo_parameter(int type)
{
char_u *p;
@@ -3507,8 +3541,7 @@ int type;
* '/') in the 'viminfo' option and return a pointer to the string after it.
* Return NULL if the parameter is not specified in the string.
*/
-char_u * find_viminfo_parameter(type)
-int type;
+char_u *find_viminfo_parameter(int type)
{
char_u *p;
@@ -3530,9 +3563,7 @@ int type;
* If "val" is NULL expand the current value of the option.
* Return pointer to NameBuff, or NULL when not expanded.
*/
-static char_u * option_expand(opt_idx, val)
-int opt_idx;
-char_u *val;
+static char_u *option_expand(int opt_idx, char_u *val)
{
/* if option doesn't need expansion nothing to do */
if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
@@ -3566,7 +3597,7 @@ char_u *val;
* After setting various option values: recompute variables that depend on
* option values.
*/
-static void didset_options() {
+static void didset_options(void) {
/* initialize the table for 'iskeyword' et.al. */
(void)init_chartab();
@@ -3590,7 +3621,7 @@ static void didset_options() {
/*
* Check for string options that are NULL (normally only termcap options).
*/
-void check_options() {
+void check_options(void) {
int opt_idx;
for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++)
@@ -3601,8 +3632,7 @@ void check_options() {
/*
* Check string options in a buffer for NULL value.
*/
-void check_buf_options(buf)
-buf_T *buf;
+void check_buf_options(buf_T *buf)
{
check_string_option(&buf->b_p_bh);
check_string_option(&buf->b_p_bt);
@@ -3656,23 +3686,20 @@ buf_T *buf;
* check_options().
* Does NOT check for P_ALLOCED flag!
*/
-void free_string_option(p)
-char_u *p;
+void free_string_option(char_u *p)
{
if (p != empty_option)
vim_free(p);
}
-void clear_string_option(pp)
-char_u **pp;
+void clear_string_option(char_u **pp)
{
if (*pp != empty_option)
vim_free(*pp);
*pp = empty_option;
}
-static void check_string_option(pp)
-char_u **pp;
+static void check_string_option(char_u **pp)
{
if (*pp == NULL)
*pp = empty_option;
@@ -3681,8 +3708,7 @@ char_u **pp;
/*
* Mark a terminal option as allocated, found by a pointer into term_strings[].
*/
-void set_term_option_alloced(p)
-char_u **p;
+void set_term_option_alloced(char_u **p)
{
int opt_idx;
@@ -3699,9 +3725,7 @@ char_u **p;
* Return FALSE when it wasn't.
* Return -1 for an unknown option.
*/
-int was_set_insecurely(opt, opt_flags)
-char_u *opt;
-int opt_flags;
+int was_set_insecurely(char_u *opt, int opt_flags)
{
int idx = findoption(opt);
long_u *flagp;
@@ -3718,9 +3742,7 @@ int opt_flags;
* Get a pointer to the flags used for the P_INSECURE flag of option
* "opt_idx". For some local options a local flags field is used.
*/
-static long_u * insecure_flag(opt_idx, opt_flags)
-int opt_idx;
-int opt_flags;
+static long_u *insecure_flag(int opt_idx, int opt_flags)
{
if (opt_flags & OPT_LOCAL)
switch ((int)options[opt_idx].indir) {
@@ -3741,7 +3763,7 @@ static void redraw_titles __ARGS((void));
/*
* Redraw the window title and/or tab page text later.
*/
-static void redraw_titles() {
+static void redraw_titles(void) {
need_maketitle = TRUE;
redraw_tabline = TRUE;
}
@@ -3753,12 +3775,14 @@ static void redraw_titles() {
* When "set_sid" is zero set the scriptID to current_SID. When "set_sid" is
* SID_NONE don't set the scriptID. Otherwise set the scriptID to "set_sid".
*/
-void set_string_option_direct(name, opt_idx, val, opt_flags, set_sid)
-char_u *name;
-int opt_idx;
-char_u *val;
-int opt_flags; /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
-int set_sid UNUSED;
+void
+set_string_option_direct (
+ char_u *name,
+ int opt_idx,
+ char_u *val,
+ int opt_flags, /* OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL */
+ int set_sid
+)
{
char_u *s;
char_u **varp;
@@ -3805,9 +3829,11 @@ int set_sid UNUSED;
/*
* Set global value for string option when it's a local option.
*/
-static void set_string_option_global(opt_idx, varp)
-int opt_idx; /* option index */
-char_u **varp; /* pointer to option variable */
+static void
+set_string_option_global (
+ int opt_idx, /* option index */
+ char_u **varp /* pointer to option variable */
+)
{
char_u **p, *s;
@@ -3829,10 +3855,12 @@ char_u **varp; /* pointer to option variable */
*
* Returns NULL on success or error message on error.
*/
-static char_u * set_string_option(opt_idx, value, opt_flags)
-int opt_idx;
-char_u *value;
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+static char_u *
+set_string_option (
+ int opt_idx,
+ char_u *value,
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
char_u *s;
char_u **varp;
@@ -3862,15 +3890,15 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
* Handle string options that need some action to perform when changed.
* Returns NULL for success, or an error message for an error.
*/
-static char_u * did_set_string_option(opt_idx, varp, new_value_alloced, oldval,
- errbuf,
- opt_flags)
-int opt_idx; /* index in options[] table */
-char_u **varp; /* pointer to the option variable */
-int new_value_alloced; /* new value was allocated */
-char_u *oldval; /* previous value of the option */
-char_u *errbuf; /* buffer for errors, or NULL */
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+static char_u *
+did_set_string_option (
+ int opt_idx, /* index in options[] table */
+ char_u **varp, /* pointer to the option variable */
+ int new_value_alloced, /* new value was allocated */
+ char_u *oldval, /* previous value of the option */
+ char_u *errbuf, /* buffer for errors, or NULL */
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
char_u *errmsg = NULL;
char_u *s, *p;
@@ -4817,9 +4845,7 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
/*
* Simple int comparison function for use with qsort()
*/
-static int int_cmp(a, b)
-const void *a;
-const void *b;
+static int int_cmp(const void *a, const void *b)
{
return *(const int *)a - *(const int *)b;
}
@@ -4828,8 +4854,7 @@ const void *b;
* Handle setting 'colorcolumn' or 'textwidth' in window "wp".
* Returns error message, NULL if it's OK.
*/
-char_u * check_colorcolumn(wp)
-win_T *wp;
+char_u *check_colorcolumn(win_T *wp)
{
char_u *s;
int col;
@@ -4893,8 +4918,7 @@ skip:
* Handle setting 'listchars' or 'fillchars'.
* Returns error message, NULL if it's OK.
*/
-static char_u * set_chars_option(varp)
-char_u **varp;
+static char_u *set_chars_option(char_u **varp)
{
int round, i, len, entries;
char_u *p, *s;
@@ -4991,8 +5015,7 @@ char_u **varp;
* Check validity of options with the 'statusline' format.
* Return error message or NULL.
*/
-char_u * check_stl_option(s)
-char_u *s;
+char_u *check_stl_option(char_u *s)
{
int itemcnt = 0;
int groupdepth = 0;
@@ -5055,8 +5078,7 @@ char_u *s;
* Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
* Return error message when failed, NULL when OK.
*/
-static char_u * compile_cap_prog(synblock)
-synblock_T *synblock;
+static char_u *compile_cap_prog(synblock_T *synblock)
{
regprog_T *rp = synblock->b_cap_prog;
char_u *re;
@@ -5084,10 +5106,7 @@ synblock_T *synblock;
* Set the scriptID for an option, taking care of setting the buffer- or
* window-local value.
*/
-static void set_option_scriptID_idx(opt_idx, opt_flags, id)
-int opt_idx;
-int opt_flags;
-int id;
+static void set_option_scriptID_idx(int opt_idx, int opt_flags, int id)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
@@ -5108,11 +5127,13 @@ int id;
* Set the value of a boolean option, and take care of side effects.
* Returns NULL for success, or an error message for an error.
*/
-static char_u * set_bool_option(opt_idx, varp, value, opt_flags)
-int opt_idx; /* index in options[] table */
-char_u *varp; /* pointer to the option variable */
-int value; /* new value */
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+static char_u *
+set_bool_option (
+ int opt_idx, /* index in options[] table */
+ char_u *varp, /* pointer to the option variable */
+ int value, /* new value */
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
int old_value = *(int *)varp;
@@ -5496,15 +5517,16 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
* Set the value of a number option, and take care of side effects.
* Returns NULL for success, or an error message for an error.
*/
-static char_u * set_num_option(opt_idx, varp, value, errbuf, errbuflen,
- opt_flags)
-int opt_idx; /* index in options[] table */
-char_u *varp; /* pointer to the option variable */
-long value; /* new value */
-char_u *errbuf; /* buffer for error messages */
-size_t errbuflen; /* length of "errbuf" */
-int opt_flags; /* OPT_LOCAL, OPT_GLOBAL and
+static char_u *
+set_num_option (
+ int opt_idx, /* index in options[] table */
+ char_u *varp, /* pointer to the option variable */
+ long value, /* new value */
+ char_u *errbuf, /* buffer for error messages */
+ size_t errbuflen, /* length of "errbuf" */
+ int opt_flags /* OPT_LOCAL, OPT_GLOBAL and
OPT_MODELINE */
+)
{
char_u *errmsg = NULL;
long old_value = *(long *)varp;
@@ -5867,8 +5889,7 @@ int opt_flags; /* OPT_LOCAL, OPT_GLOBAL and
/*
* Called after an option changed: check if something needs to be redrawn.
*/
-static void check_redraw(flags)
-long_u flags;
+static void check_redraw(long_u flags)
{
/* Careful: P_RCLR and P_RALL are a combination of other P_ flags */
int doclear = (flags & P_RCLR) == P_RCLR;
@@ -5891,8 +5912,7 @@ long_u flags;
* Find index for option 'arg'.
* Return -1 if not found.
*/
-static int findoption(arg)
-char_u *arg;
+static int findoption(char_u *arg)
{
int opt_idx;
char *s, *p;
@@ -5956,11 +5976,13 @@ char_u *arg;
* hidden String option: -2.
* unknown option: -3.
*/
-int get_option_value(name, numval, stringval, opt_flags)
-char_u *name;
-long *numval;
-char_u **stringval; /* NULL when only checking existence */
-int opt_flags;
+int
+get_option_value (
+ char_u *name,
+ long *numval,
+ char_u **stringval, /* NULL when only checking existence */
+ int opt_flags
+)
{
int opt_idx;
char_u *varp;
@@ -6007,11 +6029,13 @@ int opt_flags;
*
* Returns NULL on success or error message on error.
*/
-char_u * set_option_value(name, number, string, opt_flags)
-char_u *name;
-long number;
-char_u *string;
-int opt_flags; /* OPT_LOCAL or 0 (both) */
+char_u *
+set_option_value (
+ char_u *name,
+ long number,
+ char_u *string,
+ int opt_flags /* OPT_LOCAL or 0 (both) */
+)
{
int opt_idx;
char_u *varp;
@@ -6067,8 +6091,7 @@ int opt_flags; /* OPT_LOCAL or 0 (both) */
* Get the terminal code for a terminal option.
* Returns NULL when not found.
*/
-char_u * get_term_code(tname)
-char_u *tname;
+char_u *get_term_code(char_u *tname)
{
int opt_idx;
char_u *varp;
@@ -6085,7 +6108,7 @@ char_u *tname;
return find_termcode(tname + 2);
}
-char_u * get_highlight_default() {
+char_u *get_highlight_default(void) {
int i;
i = findoption((char_u *)"hl");
@@ -6094,7 +6117,7 @@ char_u * get_highlight_default() {
return (char_u *)NULL;
}
-char_u * get_encoding_default() {
+char_u *get_encoding_default(void) {
int i;
i = findoption((char_u *)"enc");
@@ -6106,8 +6129,7 @@ char_u * get_encoding_default() {
/*
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
*/
-static int find_key_option(arg)
-char_u *arg;
+static int find_key_option(char_u *arg)
{
int key;
int modifiers;
@@ -6133,9 +6155,11 @@ char_u *arg;
* if 'all' == 1: show all normal options
* if 'all' == 2: show all terminal options
*/
-static void showoptions(all, opt_flags)
-int all;
-int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
+static void
+showoptions (
+ int all,
+ int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
+)
{
struct vimoption *p;
int col;
@@ -6231,9 +6255,7 @@ int opt_flags; /* OPT_LOCAL and/or OPT_GLOBAL */
/*
* Return TRUE if option "p" has its default value.
*/
-static int optval_default(p, varp)
-struct vimoption *p;
-char_u *varp;
+static int optval_default(struct vimoption *p, char_u *varp)
{
int dvi;
@@ -6254,9 +6276,11 @@ char_u *varp;
* showoneopt: show the value of one option
* must not be called with a hidden option!
*/
-static void showoneopt(p, opt_flags)
-struct vimoption *p;
-int opt_flags; /* OPT_LOCAL or OPT_GLOBAL */
+static void
+showoneopt (
+ struct vimoption *p,
+ int opt_flags /* OPT_LOCAL or OPT_GLOBAL */
+)
{
char_u *varp;
int save_silent = silent_mode;
@@ -6308,10 +6332,7 @@ int opt_flags; /* OPT_LOCAL or OPT_GLOBAL */
*
* Return FAIL on error, OK otherwise.
*/
-int makeset(fd, opt_flags, local_only)
-FILE *fd;
-int opt_flags;
-int local_only;
+int makeset(FILE *fd, int opt_flags, int local_only)
{
struct vimoption *p;
char_u *varp; /* currently used value */
@@ -6413,8 +6434,7 @@ int local_only;
* Generate set commands for the local fold options only. Used when
* 'sessionoptions' or 'viewoptions' contains "folds" but not "options".
*/
-int makefoldset(fd)
-FILE *fd;
+int makefoldset(FILE *fd)
{
if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, FALSE) == FAIL
|| put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, FALSE)
@@ -6433,12 +6453,7 @@ FILE *fd;
return OK;
}
-static int put_setstring(fd, cmd, name, valuep, expand)
-FILE *fd;
-char *cmd;
-char *name;
-char_u **valuep;
-int expand;
+static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, int expand)
{
char_u *s;
char_u *buf;
@@ -6472,11 +6487,7 @@ int expand;
return OK;
}
-static int put_setnum(fd, cmd, name, valuep)
-FILE *fd;
-char *cmd;
-char *name;
-long *valuep;
+static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep)
{
long wc;
@@ -6493,11 +6504,7 @@ long *valuep;
return OK;
}
-static int put_setbool(fd, cmd, name, value)
-FILE *fd;
-char *cmd;
-char *name;
-int value;
+static int put_setbool(FILE *fd, char *cmd, char *name, int value)
{
if (value < 0) /* global/local option using global value */
return OK;
@@ -6512,7 +6519,7 @@ int value;
* If the option has been allocated, free the memory.
* Terminal options are never hidden or indirect.
*/
-void clear_termoptions() {
+void clear_termoptions(void) {
/*
* Reset a few things before clearing the old options. This may cause
* outputting a few things that the terminal doesn't understand, but the
@@ -6525,7 +6532,7 @@ void clear_termoptions() {
free_termoptions();
}
-void free_termoptions() {
+void free_termoptions(void) {
struct vimoption *p;
for (p = &options[0]; p->fullname != NULL; p++)
@@ -6546,8 +6553,7 @@ void free_termoptions() {
* Set the string to empty_option and clear allocated flag.
* "var" points to the option value.
*/
-void free_one_termoption(var)
-char_u *var;
+void free_one_termoption(char_u *var)
{
struct vimoption *p;
@@ -6565,7 +6571,7 @@ char_u *var;
* Set the terminal option defaults to the current value.
* Used after setting the terminal name.
*/
-void set_term_defaults() {
+void set_term_defaults(void) {
struct vimoption *p;
for (p = &options[0]; p->fullname != NULL; p++) {
@@ -6586,8 +6592,7 @@ void set_term_defaults() {
/*
* return TRUE if 'p' starts with 't_'
*/
-static int istermoption(p)
-struct vimoption *p;
+static int istermoption(struct vimoption *p)
{
return p->fullname[0] == 't' && p->fullname[1] == '_';
}
@@ -6601,7 +6606,7 @@ struct vimoption *p;
#define COL_RULER 17 /* columns needed by standard ruler */
-void comp_col() {
+void comp_col(void) {
int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
sc_col = 0;
@@ -6628,9 +6633,7 @@ void comp_col() {
/*
* Unset local option value, similar to ":set opt<".
*/
-void unset_global_local_option(name, from)
-char_u *name;
-void *from;
+void unset_global_local_option(char_u *name, void *from)
{
struct vimoption *p;
int opt_idx;
@@ -6692,9 +6695,7 @@ void *from;
/*
* Get pointer to option variable, depending on local or global scope.
*/
-static char_u * get_varp_scope(p, opt_flags)
-struct vimoption *p;
-int opt_flags;
+static char_u *get_varp_scope(struct vimoption *p, int opt_flags)
{
if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
if (p->var == VAR_WIN)
@@ -6727,8 +6728,7 @@ int opt_flags;
/*
* Get pointer to option variable.
*/
-static char_u * get_varp(p)
-struct vimoption *p;
+static char_u *get_varp(struct vimoption *p)
{
/* hidden option, always return NULL */
if (p->var == NULL)
@@ -6871,7 +6871,7 @@ struct vimoption *p;
/*
* Get the value of 'equalprg', either the buffer-local one or the global one.
*/
-char_u * get_equalprg() {
+char_u *get_equalprg(void) {
if (*curbuf->b_p_ep == NUL)
return p_ep;
return curbuf->b_p_ep;
@@ -6881,9 +6881,7 @@ char_u * get_equalprg() {
* Copy options from one window to another.
* Used when splitting a window.
*/
-void win_copy_options(wp_from, wp_to)
-win_T *wp_from;
-win_T *wp_to;
+void win_copy_options(win_T *wp_from, win_T *wp_to)
{
copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
@@ -6897,9 +6895,7 @@ win_T *wp_to;
* The 'scroll' option is not copied, because it depends on the window height.
* The 'previewwindow' option is reset, there can be only one preview window.
*/
-void copy_winopt(from, to)
-winopt_T *from;
-winopt_T *to;
+void copy_winopt(winopt_T *from, winopt_T *to)
{
to->wo_arab = from->wo_arab;
to->wo_list = from->wo_list;
@@ -6945,8 +6941,7 @@ winopt_T *to;
/*
* Check string options in a window for a NULL value.
*/
-void check_win_options(win)
-win_T *win;
+void check_win_options(win_T *win)
{
check_winopt(&win->w_onebuf_opt);
check_winopt(&win->w_allbuf_opt);
@@ -6955,8 +6950,7 @@ win_T *win;
/*
* Check for NULL pointers in a winopt_T and replace them with empty_option.
*/
-void check_winopt(wop)
-winopt_T *wop UNUSED;
+void check_winopt(winopt_T *wop)
{
check_string_option(&wop->wo_fdi);
check_string_option(&wop->wo_fdm);
@@ -6973,8 +6967,7 @@ winopt_T *wop UNUSED;
/*
* Free the allocated memory inside a winopt_T.
*/
-void clear_winopt(wop)
-winopt_T *wop UNUSED;
+void clear_winopt(winopt_T *wop)
{
clear_string_option(&wop->wo_fdi);
clear_string_option(&wop->wo_fdm);
@@ -6997,9 +6990,7 @@ winopt_T *wop UNUSED;
* appropriate.
* BCO_NOHELP Don't copy the values to a help buffer.
*/
-void buf_copy_options(buf, flags)
-buf_T *buf;
-int flags;
+void buf_copy_options(buf_T *buf, int flags)
{
int should_copy = TRUE;
char_u *save_p_isk = NULL; /* init for GCC */
@@ -7175,7 +7166,7 @@ int flags;
/*
* Reset the 'modifiable' option and its default value.
*/
-void reset_modifiable() {
+void reset_modifiable(void) {
int opt_idx;
curbuf->b_p_ma = FALSE;
@@ -7188,14 +7179,14 @@ void reset_modifiable() {
/*
* Set the global value for 'iminsert' to the local value.
*/
-void set_iminsert_global() {
+void set_iminsert_global(void) {
p_iminsert = curbuf->b_p_iminsert;
}
/*
* Set the global value for 'imsearch' to the local value.
*/
-void set_imsearch_global() {
+void set_imsearch_global(void) {
p_imsearch = curbuf->b_p_imsearch;
}
@@ -7203,10 +7194,12 @@ static int expand_option_idx = -1;
static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL};
static int expand_option_flags = 0;
-void set_context_in_set_cmd(xp, arg, opt_flags)
-expand_T *xp;
-char_u *arg;
-int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
+void
+set_context_in_set_cmd (
+ expand_T *xp,
+ char_u *arg,
+ int opt_flags /* OPT_GLOBAL and/or OPT_LOCAL */
+)
{
int nextchar;
long_u flags = 0; /* init for GCC */
@@ -7373,11 +7366,7 @@ int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
return;
}
-int ExpandSettings(xp, regmatch, num_file, file)
-expand_T *xp;
-regmatch_T *regmatch;
-int *num_file;
-char_u ***file;
+int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
int num_normal = 0; /* Nr of matching non-term-code settings */
int num_term = 0; /* Nr of matching terminal code settings */
@@ -7517,9 +7506,7 @@ char_u ***file;
return OK;
}
-int ExpandOldSetting(num_file, file)
-int *num_file;
-char_u ***file;
+int ExpandOldSetting(int *num_file, char_u ***file)
{
char_u *var = NULL; /* init for GCC */
char_u *buf;
@@ -7576,9 +7563,11 @@ char_u ***file;
* Get the value for the numeric or string option *opp in a nice format into
* NameBuff[]. Must not be called with a hidden option!
*/
-static void option_value2string(opp, opt_flags)
-struct vimoption *opp;
-int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
+static void
+option_value2string (
+ struct vimoption *opp,
+ int opt_flags /* OPT_GLOBAL and/or OPT_LOCAL */
+)
{
char_u *varp;
@@ -7615,9 +7604,7 @@ int opt_flags; /* OPT_GLOBAL and/or OPT_LOCAL */
* printed as a keyname.
* "*wcp" is set to the value of the option if it's 'wildchar' or 'wildcharm'.
*/
-static int wc_use_keyname(varp, wcp)
-char_u *varp;
-long *wcp;
+static int wc_use_keyname(char_u *varp, long *wcp)
{
if (((long *)varp == &p_wc) || ((long *)varp == &p_wcm)) {
*wcp = *(long *)varp;
@@ -7655,9 +7642,7 @@ static void langmap_set_entry __ARGS((int from, int to));
* Search for an entry in "langmap_mapga" for "from". If found set the "to"
* field. If not found insert a new entry at the appropriate location.
*/
-static void langmap_set_entry(from, to)
-int from;
-int to;
+static void langmap_set_entry(int from, int to)
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
int a = 0;
@@ -7693,8 +7678,7 @@ int to;
/*
* Apply 'langmap' to multi-byte character "c" and return the result.
*/
-int langmap_adjust_mb(c)
-int c;
+int langmap_adjust_mb(int c)
{
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
int a = 0;
@@ -7714,7 +7698,7 @@ int c;
return c; /* no entry found, return "c" unmodified */
}
-static void langmap_init() {
+static void langmap_init(void) {
int i;
for (i = 0; i < 256; i++)
@@ -7726,7 +7710,7 @@ static void langmap_init() {
* Called when langmap option is set; the language map can be
* changed at any time!
*/
-static void langmap_set() {
+static void langmap_set(void) {
char_u *p;
char_u *p2;
int from, to;
@@ -7804,8 +7788,7 @@ static void langmap_set() {
* Return TRUE if format option 'x' is in effect.
* Take care of no formatting when 'paste' is set.
*/
-int has_format_option(x)
-int x;
+int has_format_option(int x)
{
if (p_paste)
return FALSE;
@@ -7816,8 +7799,7 @@ int x;
* Return TRUE if "x" is present in 'shortmess' option, or
* 'shortmess' contains 'a' and "x" is present in SHM_A.
*/
-int shortmess(x)
-int x;
+int shortmess(int x)
{
return p_shm != NULL &&
( vim_strchr(p_shm, x) != NULL
@@ -7828,7 +7810,7 @@ int x;
/*
* paste_option_changed() - Called after p_paste was set or reset.
*/
-static void paste_option_changed() {
+static void paste_option_changed(void) {
static int old_p_paste = FALSE;
static int save_sm = 0;
static int save_ru = 0;
@@ -7924,9 +7906,7 @@ static void paste_option_changed() {
* Don't do this if the 'compatible' option has been set or reset before.
* When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
*/
-void vimrc_found(fname, envname)
-char_u *fname;
-char_u *envname;
+void vimrc_found(char_u *fname, char_u *envname)
{
int opt_idx;
int dofree = FALSE;
@@ -7957,8 +7937,7 @@ char_u *envname;
/*
* Set 'compatible' on or off. Called for "-C" and "-N" command line arg.
*/
-void change_compatible(on)
-int on;
+void change_compatible(int on)
{
int opt_idx;
@@ -7975,8 +7954,7 @@ int on;
* Return TRUE when option "name" has been set.
* Only works correctly for global options.
*/
-int option_was_set(name)
-char_u *name;
+int option_was_set(char_u *name)
{
int idx;
@@ -7991,8 +7969,7 @@ char_u *name;
/*
* Reset the flag indicating option "name" was set.
*/
-void reset_option_was_set(name)
-char_u *name;
+void reset_option_was_set(char_u *name)
{
int idx = findoption(name);
@@ -8008,7 +7985,7 @@ char_u *name;
* When 'compatible' is unset: Set all options that have a different default
* for Vim (without the P_VI_DEF flag) to that default.
*/
-static void compatible_set() {
+static void compatible_set(void) {
int opt_idx;
for (opt_idx = 0; !istermoption(&options[opt_idx]); opt_idx++)
@@ -8021,7 +7998,7 @@ static void compatible_set() {
/*
* fill_breakat_flags() -- called when 'breakat' changes value.
*/
-static void fill_breakat_flags() {
+static void fill_breakat_flags(void) {
char_u *p;
int i;
@@ -8039,10 +8016,12 @@ static void fill_breakat_flags() {
* Return OK for correct value, FAIL otherwise.
* Empty is always OK.
*/
-static int check_opt_strings(val, values, list)
-char_u *val;
-char **values;
-int list; /* when TRUE: accept a list of values */
+static int
+check_opt_strings (
+ char_u *val,
+ char **values,
+ int list /* when TRUE: accept a list of values */
+)
{
return opt_strings_flags(val, values, NULL, list);
}
@@ -8054,11 +8033,13 @@ int list; /* when TRUE: accept a list of values */
* Return OK for correct value, FAIL otherwise.
* Empty is always OK.
*/
-static int opt_strings_flags(val, values, flagp, list)
-char_u *val; /* new value */
-char **values; /* array of valid string values */
-unsigned *flagp;
-int list; /* when TRUE: accept a list of values */
+static int
+opt_strings_flags (
+ char_u *val, /* new value */
+ char **values, /* array of valid string values */
+ unsigned *flagp,
+ int list /* when TRUE: accept a list of values */
+)
{
int i;
int len;
@@ -8087,7 +8068,7 @@ int list; /* when TRUE: accept a list of values */
/*
* Read the 'wildmode' option, fill wim_flags[].
*/
-static int check_opt_wim() {
+static int check_opt_wim(void) {
char_u new_wim_flags[4];
char_u *p;
int i;
@@ -8134,8 +8115,10 @@ static int check_opt_wim() {
/*
* Check if backspacing over something is allowed.
*/
-int can_bs(what)
-int what; /* BS_INDENT, BS_EOL or BS_START */
+int
+can_bs (
+ int what /* BS_INDENT, BS_EOL or BS_START */
+)
{
switch (*p_bs) {
case '2': return TRUE;
@@ -8149,8 +8132,7 @@ int what; /* BS_INDENT, BS_EOL or BS_START */
* Save the current values of 'fileformat' and 'fileencoding', so that we know
* the file must be considered changed when the value is different.
*/
-void save_file_ff(buf)
-buf_T *buf;
+void save_file_ff(buf_T *buf)
{
buf->b_start_ffc = *buf->b_p_ff;
buf->b_start_eol = buf->b_p_eol;
@@ -8172,9 +8154,7 @@ buf_T *buf;
* When "ignore_empty" is true don't consider a new, empty buffer to be
* changed.
*/
-int file_ff_differs(buf, ignore_empty)
-buf_T *buf;
-int ignore_empty;
+int file_ff_differs(buf_T *buf, int ignore_empty)
{
/* In a buffer that was never loaded the options are not valid. */
if (buf->b_flags & BF_NEVERLOADED)
@@ -8198,8 +8178,7 @@ int ignore_empty;
/*
* return OK if "p" is a valid fileformat name, FAIL otherwise.
*/
-int check_ff_value(p)
-char_u *p;
+int check_ff_value(char_u *p)
{
return check_opt_strings(p, p_ff_values, FALSE);
}
@@ -8208,8 +8187,7 @@ char_u *p;
* Return the effective shiftwidth value for current buffer, using the
* 'tabstop' value when 'shiftwidth' is zero.
*/
-long get_sw_value(buf)
-buf_T *buf;
+long get_sw_value(buf_T *buf)
{
return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
}
@@ -8218,7 +8196,7 @@ buf_T *buf;
* Return the effective softtabstop value for the current buffer, using the
* 'tabstop' value when 'softtabstop' is negative.
*/
-long get_sts_value() {
+long get_sts_value(void) {
return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
}
@@ -8228,11 +8206,7 @@ long get_sts_value() {
* the opposite character. Set "*backwards" to the direction.
* When "switchit" is TRUE swap the direction.
*/
-void find_mps_values(initc, findc, backwards, switchit)
-int *initc;
-int *findc;
-int *backwards;
-int switchit;
+void find_mps_values(int *initc, int *findc, int *backwards, int switchit)
{
char_u *ptr;
diff --git a/src/option.h b/src/option.h
index 6cc0cce362..e8332cd2aa 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1,768 +1,77 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * option.h: definition of global variables for settable options
- */
-
-/*
- * Default values for 'errorformat'.
- * The "%f|%l| %m" one is used for when the contents of the quickfix window is
- * written to a file.
- */
-#define DFLT_EFM \
- "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m"
-
-#define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m"
-
-/* default values for b_p_ff 'fileformat' and p_ffs 'fileformats' */
-#define FF_DOS "dos"
-#define FF_MAC "mac"
-#define FF_UNIX "unix"
-
-#ifdef USE_CRNL
-# define DFLT_FF "dos"
-# define DFLT_FFS_VIM "dos,unix"
-# define DFLT_FFS_VI "dos,unix" /* also autodetect in compatible mode */
-# define DFLT_TEXTAUTO TRUE
-#else
-# ifdef USE_CR
-# define DFLT_FF "mac"
-# define DFLT_FFS_VIM "mac,unix,dos"
-# define DFLT_FFS_VI "mac,unix,dos"
-# define DFLT_TEXTAUTO TRUE
-# else
-# define DFLT_FF "unix"
-# define DFLT_FFS_VIM "unix,dos"
-# define DFLT_FFS_VI ""
-# define DFLT_TEXTAUTO FALSE
-# endif
-#endif
-
-
-/* Possible values for 'encoding' */
-# define ENC_UCSBOM "ucs-bom" /* check for BOM at start of file */
-
-/* default value for 'encoding' */
-# define ENC_DFLT "latin1"
-
-/* end-of-line style */
-#define EOL_UNKNOWN -1 /* not defined yet */
-#define EOL_UNIX 0 /* NL */
-#define EOL_DOS 1 /* CR NL */
-#define EOL_MAC 2 /* CR */
-
-/* Formatting options for p_fo 'formatoptions' */
-#define FO_WRAP 't'
-#define FO_WRAP_COMS 'c'
-#define FO_RET_COMS 'r'
-#define FO_OPEN_COMS 'o'
-#define FO_Q_COMS 'q'
-#define FO_Q_NUMBER 'n'
-#define FO_Q_SECOND '2'
-#define FO_INS_VI 'v'
-#define FO_INS_LONG 'l'
-#define FO_INS_BLANK 'b'
-#define FO_MBYTE_BREAK 'm' /* break before/after multi-byte char */
-#define FO_MBYTE_JOIN 'M' /* no space before/after multi-byte char */
-#define FO_MBYTE_JOIN2 'B' /* no space between multi-byte chars */
-#define FO_ONE_LETTER '1'
-#define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */
-#define FO_AUTO 'a' /* automatic formatting */
-#define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */
-
-#define DFLT_FO_VI "vt"
-#define DFLT_FO_VIM "tcq"
-#define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */
-
-/* characters for the p_cpo option: */
-#define CPO_ALTREAD 'a' /* ":read" sets alternate file name */
-#define CPO_ALTWRITE 'A' /* ":write" sets alternate file name */
-#define CPO_BAR 'b' /* "\|" ends a mapping */
-#define CPO_BSLASH 'B' /* backslash in mapping is not special */
-#define CPO_SEARCH 'c'
-#define CPO_CONCAT 'C' /* Don't concatenate sourced lines */
-#define CPO_DOTTAG 'd' /* "./tags" in 'tags' is in current dir */
-#define CPO_DIGRAPH 'D' /* No digraph after "r", "f", etc. */
-#define CPO_EXECBUF 'e'
-#define CPO_EMPTYREGION 'E' /* operating on empty region is an error */
-#define CPO_FNAMER 'f' /* set file name for ":r file" */
-#define CPO_FNAMEW 'F' /* set file name for ":w file" */
-#define CPO_GOTO1 'g' /* goto line 1 for ":edit" */
-#define CPO_INSEND 'H' /* "I" inserts before last blank in line */
-#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */
-#define CPO_INDENT 'I' /* remove auto-indent more often */
-#define CPO_JOINSP 'j' /* only use two spaces for join after '.' */
-#define CPO_ENDOFSENT 'J' /* need two spaces to detect end of sentence */
-#define CPO_KEYCODE 'k' /* don't recognize raw key code in mappings */
-#define CPO_KOFFSET 'K' /* don't wait for key code in mappings */
-#define CPO_LITERAL 'l' /* take char after backslash in [] literal */
-#define CPO_LISTWM 'L' /* 'list' changes wrapmargin */
-#define CPO_SHOWMATCH 'm'
-#define CPO_MATCHBSL 'M' /* "%" ignores use of backslashes */
-#define CPO_NUMCOL 'n' /* 'number' column also used for text */
-#define CPO_LINEOFF 'o'
-#define CPO_OVERNEW 'O' /* silently overwrite new file */
-#define CPO_LISP 'p' /* 'lisp' indenting */
-#define CPO_FNAMEAPP 'P' /* set file name for ":w >>file" */
-#define CPO_JOINCOL 'q' /* with "3J" use column after first join */
-#define CPO_REDO 'r'
-#define CPO_REMMARK 'R' /* remove marks when filtering */
-#define CPO_BUFOPT 's'
-#define CPO_BUFOPTGLOB 'S'
-#define CPO_TAGPAT 't'
-#define CPO_UNDO 'u' /* "u" undoes itself */
-#define CPO_BACKSPACE 'v' /* "v" keep deleted text */
-#define CPO_CW 'w' /* "cw" only changes one blank */
-#define CPO_FWRITE 'W' /* "w!" doesn't overwrite readonly files */
-#define CPO_ESC 'x'
-#define CPO_REPLCNT 'X' /* "R" with a count only deletes chars once */
-#define CPO_YANK 'y'
-#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */
-#define CPO_DOLLAR '$'
-#define CPO_FILTER '!'
-#define CPO_MATCH '%'
-#define CPO_STAR '*' /* ":*" means ":@" */
-#define CPO_PLUS '+' /* ":write file" resets 'modified' */
-#define CPO_MINUS '-' /* "9-" fails at and before line 9 */
-#define CPO_SPECI '<' /* don't recognize <> in mappings */
-#define CPO_REGAPPEND '>' /* insert NL when appending to a register */
-/* POSIX flags */
-#define CPO_HASH '#' /* "D", "o" and "O" do not use a count */
-#define CPO_PARA '{' /* "{" is also a paragraph boundary */
-#define CPO_TSIZE '|' /* $LINES and $COLUMNS overrule term size */
-#define CPO_PRESERVE '&' /* keep swap file after :preserve */
-#define CPO_SUBPERCENT '/' /* % in :s string uses previous one */
-#define CPO_BACKSL '\\' /* \ is not special in [] */
-#define CPO_CHDIR '.' /* don't chdir if buffer is modified */
-#define CPO_SCOLON ';' /* using "," and ";" will skip over char if
- * cursor would not move */
-/* default values for Vim, Vi and POSIX */
-#define CPO_VIM "aABceFs"
-#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;"
-#define CPO_ALL \
- "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;"
-
-/* characters for p_ww option: */
-#define WW_ALL "bshl<>[],~"
-
-/* characters for p_mouse option: */
-#define MOUSE_NORMAL 'n' /* use mouse in Normal mode */
-#define MOUSE_VISUAL 'v' /* use mouse in Visual/Select mode */
-#define MOUSE_INSERT 'i' /* use mouse in Insert mode */
-#define MOUSE_COMMAND 'c' /* use mouse in Command-line mode */
-#define MOUSE_HELP 'h' /* use mouse in help buffers */
-#define MOUSE_RETURN 'r' /* use mouse for hit-return message */
-#define MOUSE_A "nvich" /* used for 'a' flag */
-#define MOUSE_ALL "anvichr" /* all possible characters */
-#define MOUSE_NONE ' ' /* don't use Visual selection */
-#define MOUSE_NONEF 'x' /* forced modeless selection */
-
-#define COCU_ALL "nvic" /* flags for 'concealcursor' */
-
-/* characters for p_shm option: */
-#define SHM_RO 'r' /* readonly */
-#define SHM_MOD 'm' /* modified */
-#define SHM_FILE 'f' /* (file 1 of 2) */
-#define SHM_LAST 'i' /* last line incomplete */
-#define SHM_TEXT 'x' /* tx instead of textmode */
-#define SHM_LINES 'l' /* "L" instead of "lines" */
-#define SHM_NEW 'n' /* "[New]" instead of "[New file]" */
-#define SHM_WRI 'w' /* "[w]" instead of "written" */
-#define SHM_A "rmfixlnw" /* represented by 'a' flag */
-#define SHM_WRITE 'W' /* don't use "written" at all */
-#define SHM_TRUNC 't' /* trunctate file messages */
-#define SHM_TRUNCALL 'T' /* trunctate all messages */
-#define SHM_OVER 'o' /* overwrite file messages */
-#define SHM_OVERALL 'O' /* overwrite more messages */
-#define SHM_SEARCH 's' /* no search hit bottom messages */
-#define SHM_ATTENTION 'A' /* no ATTENTION messages */
-#define SHM_INTRO 'I' /* intro messages */
-#define SHM_ALL "rmfixlnwaWtToOsAI" /* all possible flags for 'shm' */
-
-/* characters for p_go: */
-#define GO_ASEL 'a' /* autoselect */
-#define GO_ASELML 'A' /* autoselect modeless selection */
-#define GO_BOT 'b' /* use bottom scrollbar */
-#define GO_CONDIALOG 'c' /* use console dialog */
-#define GO_TABLINE 'e' /* may show tabline */
-#define GO_FORG 'f' /* start GUI in foreground */
-#define GO_GREY 'g' /* use grey menu items */
-#define GO_HORSCROLL 'h' /* flexible horizontal scrolling */
-#define GO_ICON 'i' /* use Vim icon */
-#define GO_LEFT 'l' /* use left scrollbar */
-#define GO_VLEFT 'L' /* left scrollbar with vert split */
-#define GO_MENUS 'm' /* use menu bar */
-#define GO_NOSYSMENU 'M' /* don't source system menu */
-#define GO_POINTER 'p' /* pointer enter/leave callbacks */
-#define GO_ASELPLUS 'P' /* autoselectPlus */
-#define GO_RIGHT 'r' /* use right scrollbar */
-#define GO_VRIGHT 'R' /* right scrollbar with vert split */
-#define GO_TEAROFF 't' /* add tear-off menu items */
-#define GO_TOOLBAR 'T' /* add toolbar */
-#define GO_FOOTER 'F' /* add footer */
-#define GO_VERTICAL 'v' /* arrange dialog buttons vertically */
-#define GO_ALL "aAbcefFghilmMprtTv" /* all possible flags for 'go' */
-
-/* flags for 'comments' option */
-#define COM_NEST 'n' /* comments strings nest */
-#define COM_BLANK 'b' /* needs blank after string */
-#define COM_START 's' /* start of comment */
-#define COM_MIDDLE 'm' /* middle of comment */
-#define COM_END 'e' /* end of comment */
-#define COM_AUTO_END 'x' /* last char of end closes comment */
-#define COM_FIRST 'f' /* first line comment only */
-#define COM_LEFT 'l' /* left adjusted */
-#define COM_RIGHT 'r' /* right adjusted */
-#define COM_NOBACK 'O' /* don't use for "O" command */
-#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */
-#define COM_MAX_LEN 50 /* maximum length of a part */
-
-/* flags for 'statusline' option */
-#define STL_FILEPATH 'f' /* path of file in buffer */
-#define STL_FULLPATH 'F' /* full path of file in buffer */
-#define STL_FILENAME 't' /* last part (tail) of file path */
-#define STL_COLUMN 'c' /* column og cursor*/
-#define STL_VIRTCOL 'v' /* virtual column */
-#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */
-#define STL_LINE 'l' /* line number of cursor */
-#define STL_NUMLINES 'L' /* number of lines in buffer */
-#define STL_BUFNO 'n' /* current buffer number */
-#define STL_KEYMAP 'k' /* 'keymap' when active */
-#define STL_OFFSET 'o' /* offset of character under cursor*/
-#define STL_OFFSET_X 'O' /* - in hexadecimal */
-#define STL_BYTEVAL 'b' /* byte value of character */
-#define STL_BYTEVAL_X 'B' /* - in hexadecimal */
-#define STL_ROFLAG 'r' /* readonly flag */
-#define STL_ROFLAG_ALT 'R' /* - other display */
-#define STL_HELPFLAG 'h' /* window is showing a help file */
-#define STL_HELPFLAG_ALT 'H' /* - other display */
-#define STL_FILETYPE 'y' /* 'filetype' */
-#define STL_FILETYPE_ALT 'Y' /* - other display */
-#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */
-#define STL_PREVIEWFLAG_ALT 'W' /* - other display */
-#define STL_MODIFIED 'm' /* modified flag */
-#define STL_MODIFIED_ALT 'M' /* - other display */
-#define STL_QUICKFIX 'q' /* quickfix window description */
-#define STL_PERCENTAGE 'p' /* percentage through file */
-#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */
-#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */
-#define STL_PAGENUM 'N' /* page number (when printing)*/
-#define STL_VIM_EXPR '{' /* start of expression to substitute */
-#define STL_MIDDLEMARK '=' /* separation between left and right */
-#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/
-#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */
-#define STL_HIGHLIGHT '#' /* highlight name */
-#define STL_TABPAGENR 'T' /* tab page label nr */
-#define STL_TABCLOSENR 'X' /* tab page close nr */
-#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
-
-/* flags used for parsed 'wildmode' */
-#define WIM_FULL 1
-#define WIM_LONGEST 2
-#define WIM_LIST 4
-
-/* arguments for can_bs() */
-#define BS_INDENT 'i' /* "Indent" */
-#define BS_EOL 'o' /* "eOl" */
-#define BS_START 's' /* "Start" */
-
-#define LISPWORD_VALUE \
- "defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
-
-/*
- * The following are actual variables for the options
- */
-
-EXTERN long p_aleph; /* 'aleph' */
-EXTERN int p_acd; /* 'autochdir' */
-EXTERN char_u *p_ambw; /* 'ambiwidth' */
-EXTERN int p_ar; /* 'autoread' */
-EXTERN int p_aw; /* 'autowrite' */
-EXTERN int p_awa; /* 'autowriteall' */
-EXTERN char_u *p_bs; /* 'backspace' */
-EXTERN char_u *p_bg; /* 'background' */
-EXTERN int p_bk; /* 'backup' */
-EXTERN char_u *p_bkc; /* 'backupcopy' */
-EXTERN unsigned bkc_flags;
-#ifdef IN_OPTION_C
-static char *(p_bkc_values[]) =
-{"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
-#endif
-# define BKC_YES 0x001
-# define BKC_AUTO 0x002
-# define BKC_NO 0x004
-# define BKC_BREAKSYMLINK 0x008
-# define BKC_BREAKHARDLINK 0x010
-EXTERN char_u *p_bdir; /* 'backupdir' */
-EXTERN char_u *p_bex; /* 'backupext' */
-EXTERN char_u *p_bsk; /* 'backupskip' */
-EXTERN char_u *p_cm; /* 'cryptmethod' */
-EXTERN char_u *p_breakat; /* 'breakat' */
-EXTERN char_u *p_cmp; /* 'casemap' */
-EXTERN unsigned cmp_flags;
-# ifdef IN_OPTION_C
-static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
-# endif
-# define CMP_INTERNAL 0x001
-# define CMP_KEEPASCII 0x002
-EXTERN char_u *p_enc; /* 'encoding' */
-EXTERN int p_deco; /* 'delcombine' */
-EXTERN char_u *p_ccv; /* 'charconvert' */
-EXTERN char_u *p_cedit; /* 'cedit' */
-EXTERN long p_cwh; /* 'cmdwinheight' */
-EXTERN long p_ch; /* 'cmdheight' */
-EXTERN int p_confirm; /* 'confirm' */
-EXTERN int p_cp; /* 'compatible' */
-EXTERN char_u *p_cot; /* 'completeopt' */
-EXTERN long p_ph; /* 'pumheight' */
-EXTERN char_u *p_cpo; /* 'cpoptions' */
-EXTERN char_u *p_csprg; /* 'cscopeprg' */
-EXTERN int p_csre; /* 'cscoperelative' */
-EXTERN char_u *p_csqf; /* 'cscopequickfix' */
-# define CSQF_CMDS "sgdctefi"
-# define CSQF_FLAGS "+-0"
-EXTERN int p_cst; /* 'cscopetag' */
-EXTERN long p_csto; /* 'cscopetagorder' */
-EXTERN long p_cspc; /* 'cscopepathcomp' */
-EXTERN int p_csverbose; /* 'cscopeverbose' */
-EXTERN char_u *p_debug; /* 'debug' */
-EXTERN char_u *p_def; /* 'define' */
-EXTERN char_u *p_inc;
-EXTERN char_u *p_dip; /* 'diffopt' */
-EXTERN char_u *p_dex; /* 'diffexpr' */
-EXTERN char_u *p_dict; /* 'dictionary' */
-EXTERN int p_dg; /* 'digraph' */
-EXTERN char_u *p_dir; /* 'directory' */
-EXTERN char_u *p_dy; /* 'display' */
-EXTERN unsigned dy_flags;
-#ifdef IN_OPTION_C
-static char *(p_dy_values[]) = {"lastline", "uhex", NULL};
-#endif
-#define DY_LASTLINE 0x001
-#define DY_UHEX 0x002
-EXTERN int p_ed; /* 'edcompatible' */
-EXTERN char_u *p_ead; /* 'eadirection' */
-EXTERN int p_ea; /* 'equalalways' */
-EXTERN char_u *p_ep; /* 'equalprg' */
-EXTERN int p_eb; /* 'errorbells' */
-EXTERN char_u *p_ef; /* 'errorfile' */
-EXTERN char_u *p_efm; /* 'errorformat' */
-EXTERN char_u *p_gefm; /* 'grepformat' */
-EXTERN char_u *p_gp; /* 'grepprg' */
-EXTERN char_u *p_ei; /* 'eventignore' */
-EXTERN int p_ek; /* 'esckeys' */
-EXTERN int p_exrc; /* 'exrc' */
-EXTERN char_u *p_fencs; /* 'fileencodings' */
-EXTERN char_u *p_ffs; /* 'fileformats' */
-EXTERN long p_fic; /* 'fileignorecase' */
-EXTERN char_u *p_fcl; /* 'foldclose' */
-EXTERN long p_fdls; /* 'foldlevelstart' */
-EXTERN char_u *p_fdo; /* 'foldopen' */
-EXTERN unsigned fdo_flags;
-# ifdef IN_OPTION_C
-static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
- "quickfix", "search", "tag", "insert",
- "undo", "jump", NULL};
-# endif
-# define FDO_ALL 0x001
-# define FDO_BLOCK 0x002
-# define FDO_HOR 0x004
-# define FDO_MARK 0x008
-# define FDO_PERCENT 0x010
-# define FDO_QUICKFIX 0x020
-# define FDO_SEARCH 0x040
-# define FDO_TAG 0x080
-# define FDO_INSERT 0x100
-# define FDO_UNDO 0x200
-# define FDO_JUMP 0x400
-EXTERN char_u *p_fp; /* 'formatprg' */
-#ifdef HAVE_FSYNC
-EXTERN int p_fs; /* 'fsync' */
-#endif
-EXTERN int p_gd; /* 'gdefault' */
-EXTERN char_u *p_pdev; /* 'printdevice' */
-EXTERN char_u *p_penc; /* 'printencoding' */
-EXTERN char_u *p_pexpr; /* 'printexpr' */
-EXTERN char_u *p_pmfn; /* 'printmbfont' */
-EXTERN char_u *p_pmcs; /* 'printmbcharset' */
-EXTERN char_u *p_pfn; /* 'printfont' */
-EXTERN char_u *p_popt; /* 'printoptions' */
-EXTERN char_u *p_header; /* 'printheader' */
-EXTERN int p_prompt; /* 'prompt' */
-#ifdef CURSOR_SHAPE
-EXTERN char_u *p_guicursor; /* 'guicursor' */
-#endif
-EXTERN char_u *p_hf; /* 'helpfile' */
-EXTERN long p_hh; /* 'helpheight' */
-EXTERN char_u *p_hlg; /* 'helplang' */
-EXTERN int p_hid; /* 'hidden' */
-/* Use P_HID to check if a buffer is to be hidden when it is no longer
- * visible in a window. */
-# define P_HID(buf) (buf_hide(buf))
-EXTERN char_u *p_hl; /* 'highlight' */
-EXTERN int p_hls; /* 'hlsearch' */
-EXTERN long p_hi; /* 'history' */
-EXTERN int p_hkmap; /* 'hkmap' */
-EXTERN int p_hkmapp; /* 'hkmapp' */
-EXTERN int p_fkmap; /* 'fkmap' */
-EXTERN int p_altkeymap; /* 'altkeymap' */
-EXTERN int p_arshape; /* 'arabicshape' */
-EXTERN int p_icon; /* 'icon' */
-EXTERN char_u *p_iconstring; /* 'iconstring' */
-EXTERN int p_ic; /* 'ignorecase' */
-#ifdef USE_IM_CONTROL
-EXTERN int p_imcmdline; /* 'imcmdline' */
-EXTERN int p_imdisable; /* 'imdisable' */
-#endif
-EXTERN int p_is; /* 'incsearch' */
-EXTERN int p_im; /* 'insertmode' */
-EXTERN char_u *p_isf; /* 'isfname' */
-EXTERN char_u *p_isi; /* 'isident' */
-EXTERN char_u *p_isp; /* 'isprint' */
-EXTERN int p_js; /* 'joinspaces' */
-EXTERN char_u *p_kp; /* 'keywordprg' */
-EXTERN char_u *p_km; /* 'keymodel' */
-EXTERN char_u *p_langmap; /* 'langmap'*/
-EXTERN char_u *p_lm; /* 'langmenu' */
-EXTERN char_u *p_lispwords; /* 'lispwords' */
-EXTERN long p_ls; /* 'laststatus' */
-EXTERN long p_stal; /* 'showtabline' */
-EXTERN char_u *p_lcs; /* 'listchars' */
-
-EXTERN int p_lz; /* 'lazyredraw' */
-EXTERN int p_lpl; /* 'loadplugins' */
-EXTERN int p_magic; /* 'magic' */
-EXTERN char_u *p_mef; /* 'makeef' */
-EXTERN char_u *p_mp; /* 'makeprg' */
-EXTERN char_u *p_cc; /* 'colorcolumn' */
-EXTERN int p_cc_cols[256]; /* array for 'colorcolumn' columns */
-EXTERN long p_mat; /* 'matchtime' */
-EXTERN long p_mco; /* 'maxcombine' */
-EXTERN long p_mfd; /* 'maxfuncdepth' */
-EXTERN long p_mmd; /* 'maxmapdepth' */
-EXTERN long p_mm; /* 'maxmem' */
-EXTERN long p_mmp; /* 'maxmempattern' */
-EXTERN long p_mmt; /* 'maxmemtot' */
-EXTERN long p_mis; /* 'menuitems' */
-EXTERN char_u *p_msm; /* 'mkspellmem' */
-EXTERN long p_mls; /* 'modelines' */
-EXTERN char_u *p_mouse; /* 'mouse' */
-EXTERN char_u *p_mousem; /* 'mousemodel' */
-EXTERN long p_mouset; /* 'mousetime' */
-EXTERN int p_more; /* 'more' */
-EXTERN char_u *p_opfunc; /* 'operatorfunc' */
-EXTERN char_u *p_para; /* 'paragraphs' */
-EXTERN int p_paste; /* 'paste' */
-EXTERN char_u *p_pt; /* 'pastetoggle' */
-EXTERN char_u *p_pex; /* 'patchexpr' */
-EXTERN char_u *p_pm; /* 'patchmode' */
-EXTERN char_u *p_path; /* 'path' */
-EXTERN char_u *p_cdpath; /* 'cdpath' */
-EXTERN long p_rdt; /* 'redrawtime' */
-EXTERN int p_remap; /* 'remap' */
-EXTERN long p_re; /* 'regexpengine' */
-EXTERN long p_report; /* 'report' */
-EXTERN long p_pvh; /* 'previewheight' */
-EXTERN int p_ari; /* 'allowrevins' */
-EXTERN int p_ri; /* 'revins' */
-EXTERN int p_ru; /* 'ruler' */
-EXTERN char_u *p_ruf; /* 'rulerformat' */
-EXTERN char_u *p_rtp; /* 'runtimepath' */
-EXTERN long p_sj; /* 'scrolljump' */
-EXTERN long p_so; /* 'scrolloff' */
-EXTERN char_u *p_sbo; /* 'scrollopt' */
-EXTERN char_u *p_sections; /* 'sections' */
-EXTERN int p_secure; /* 'secure' */
-EXTERN char_u *p_sel; /* 'selection' */
-EXTERN char_u *p_slm; /* 'selectmode' */
-EXTERN char_u *p_ssop; /* 'sessionoptions' */
-EXTERN unsigned ssop_flags;
-# ifdef IN_OPTION_C
-/* Also used for 'viewoptions'! */
-static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
- "localoptions", "options", "help", "blank",
- "globals", "slash", "unix",
- "sesdir", "curdir", "folds", "cursor",
- "tabpages", NULL};
-# endif
-# define SSOP_BUFFERS 0x001
-# define SSOP_WINPOS 0x002
-# define SSOP_RESIZE 0x004
-# define SSOP_WINSIZE 0x008
-# define SSOP_LOCALOPTIONS 0x010
-# define SSOP_OPTIONS 0x020
-# define SSOP_HELP 0x040
-# define SSOP_BLANK 0x080
-# define SSOP_GLOBALS 0x100
-# define SSOP_SLASH 0x200
-# define SSOP_UNIX 0x400
-# define SSOP_SESDIR 0x800
-# define SSOP_CURDIR 0x1000
-# define SSOP_FOLDS 0x2000
-# define SSOP_CURSOR 0x4000
-# define SSOP_TABPAGES 0x8000
-EXTERN char_u *p_sh; /* 'shell' */
-EXTERN char_u *p_shcf; /* 'shellcmdflag' */
-EXTERN char_u *p_sp; /* 'shellpipe' */
-EXTERN char_u *p_shq; /* 'shellquote' */
-EXTERN char_u *p_sxq; /* 'shellxquote' */
-EXTERN char_u *p_sxe; /* 'shellxescape' */
-EXTERN char_u *p_srr; /* 'shellredir' */
-EXTERN int p_stmp; /* 'shelltemp' */
-#ifdef BACKSLASH_IN_FILENAME
-EXTERN int p_ssl; /* 'shellslash' */
-#endif
-EXTERN char_u *p_stl; /* 'statusline' */
-EXTERN int p_sr; /* 'shiftround' */
-EXTERN char_u *p_shm; /* 'shortmess' */
-EXTERN char_u *p_sbr; /* 'showbreak' */
-EXTERN int p_sc; /* 'showcmd' */
-EXTERN int p_sft; /* 'showfulltag' */
-EXTERN int p_sm; /* 'showmatch' */
-EXTERN int p_smd; /* 'showmode' */
-EXTERN long p_ss; /* 'sidescroll' */
-EXTERN long p_siso; /* 'sidescrolloff' */
-EXTERN int p_scs; /* 'smartcase' */
-EXTERN int p_sta; /* 'smarttab' */
-EXTERN int p_sb; /* 'splitbelow' */
-EXTERN long p_tpm; /* 'tabpagemax' */
-EXTERN char_u *p_tal; /* 'tabline' */
-EXTERN char_u *p_sps; /* 'spellsuggest' */
-EXTERN int p_spr; /* 'splitright' */
-EXTERN int p_sol; /* 'startofline' */
-EXTERN char_u *p_su; /* 'suffixes' */
-EXTERN char_u *p_sws; /* 'swapsync' */
-EXTERN char_u *p_swb; /* 'switchbuf' */
-EXTERN unsigned swb_flags;
-#ifdef IN_OPTION_C
-static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", NULL};
-#endif
-#define SWB_USEOPEN 0x001
-#define SWB_USETAB 0x002
-#define SWB_SPLIT 0x004
-#define SWB_NEWTAB 0x008
-EXTERN int p_tbs; /* 'tagbsearch' */
-EXTERN long p_tl; /* 'taglength' */
-EXTERN int p_tr; /* 'tagrelative' */
-EXTERN char_u *p_tags; /* 'tags' */
-EXTERN int p_tgst; /* 'tagstack' */
-EXTERN int p_tbidi; /* 'termbidi' */
-EXTERN char_u *p_tenc; /* 'termencoding' */
-EXTERN int p_terse; /* 'terse' */
-EXTERN int p_ta; /* 'textauto' */
-EXTERN int p_to; /* 'tildeop' */
-EXTERN int p_timeout; /* 'timeout' */
-EXTERN long p_tm; /* 'timeoutlen' */
-EXTERN int p_title; /* 'title' */
-EXTERN long p_titlelen; /* 'titlelen' */
-EXTERN char_u *p_titleold; /* 'titleold' */
-EXTERN char_u *p_titlestring; /* 'titlestring' */
-EXTERN char_u *p_tsr; /* 'thesaurus' */
-EXTERN int p_ttimeout; /* 'ttimeout' */
-EXTERN long p_ttm; /* 'ttimeoutlen' */
-EXTERN int p_tbi; /* 'ttybuiltin' */
-EXTERN int p_tf; /* 'ttyfast' */
-EXTERN long p_ttyscroll; /* 'ttyscroll' */
-#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
-EXTERN char_u *p_ttym; /* 'ttymouse' */
-EXTERN unsigned ttym_flags;
-# ifdef IN_OPTION_C
-static char *(p_ttym_values[]) =
-{"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
-# endif
-# define TTYM_XTERM 0x01
-# define TTYM_XTERM2 0x02
-# define TTYM_DEC 0x04
-# define TTYM_NETTERM 0x08
-# define TTYM_JSBTERM 0x10
-# define TTYM_PTERM 0x20
-# define TTYM_URXVT 0x40
-# define TTYM_SGR 0x80
-#endif
-EXTERN char_u *p_udir; /* 'undodir' */
-EXTERN long p_ul; /* 'undolevels' */
-EXTERN long p_ur; /* 'undoreload' */
-EXTERN long p_uc; /* 'updatecount' */
-EXTERN long p_ut; /* 'updatetime' */
-EXTERN char_u *p_fcs; /* 'fillchar' */
-EXTERN char_u *p_viminfo; /* 'viminfo' */
-EXTERN char_u *p_vdir; /* 'viewdir' */
-EXTERN char_u *p_vop; /* 'viewoptions' */
-EXTERN unsigned vop_flags; /* uses SSOP_ flags */
-EXTERN int p_vb; /* 'visualbell' */
-EXTERN char_u *p_ve; /* 'virtualedit' */
-EXTERN unsigned ve_flags;
-# ifdef IN_OPTION_C
-static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
-# endif
-# define VE_BLOCK 5 /* includes "all" */
-# define VE_INSERT 6 /* includes "all" */
-# define VE_ALL 4
-# define VE_ONEMORE 8
-EXTERN long p_verbose; /* 'verbose' */
-#ifdef IN_OPTION_C
-char_u *p_vfile = (char_u *)""; /* used before options are initialized */
-#else
-extern char_u *p_vfile; /* 'verbosefile' */
-#endif
-EXTERN int p_warn; /* 'warn' */
-EXTERN char_u *p_wop; /* 'wildoptions' */
-EXTERN long p_window; /* 'window' */
-#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(LINT) \
- || defined (FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)
-#define FEAT_WAK
-EXTERN char_u *p_wak; /* 'winaltkeys' */
-#endif
-EXTERN char_u *p_wak;
-EXTERN char_u *p_wig; /* 'wildignore' */
-EXTERN int p_wiv; /* 'weirdinvert' */
-EXTERN char_u *p_ww; /* 'whichwrap' */
-EXTERN long p_wc; /* 'wildchar' */
-EXTERN long p_wcm; /* 'wildcharm' */
-EXTERN long p_wic; /* 'wildignorecase' */
-EXTERN char_u *p_wim; /* 'wildmode' */
-EXTERN int p_wmnu; /* 'wildmenu' */
-EXTERN long p_wh; /* 'winheight' */
-EXTERN long p_wmh; /* 'winminheight' */
-EXTERN long p_wmw; /* 'winminwidth' */
-EXTERN long p_wiw; /* 'winwidth' */
-EXTERN int p_ws; /* 'wrapscan' */
-EXTERN int p_write; /* 'write' */
-EXTERN int p_wa; /* 'writeany' */
-EXTERN int p_wb; /* 'writebackup' */
-EXTERN long p_wd; /* 'writedelay' */
-
-/*
- * "indir" values for buffer-local opions.
- * These need to be defined globally, so that the BV_COUNT can be used with
- * b_p_scriptID[].
- */
-enum {
- BV_AI = 0
- , BV_AR
- , BV_BH
- , BV_BT
- , BV_EFM
- , BV_GP
- , BV_MP
- , BV_BIN
- , BV_BL
- , BV_BOMB
- , BV_CI
- , BV_CIN
- , BV_CINK
- , BV_CINO
- , BV_CINW
- , BV_CM
- , BV_CMS
- , BV_COM
- , BV_CPT
- , BV_DICT
- , BV_TSR
- , BV_CFU
- , BV_DEF
- , BV_INC
- , BV_EOL
- , BV_EP
- , BV_ET
- , BV_FENC
- , BV_BEXPR
- , BV_FEX
- , BV_FF
- , BV_FLP
- , BV_FO
- , BV_FT
- , BV_IMI
- , BV_IMS
- , BV_INDE
- , BV_INDK
- , BV_INEX
- , BV_INF
- , BV_ISK
- , BV_KEY
- , BV_KMAP
- , BV_KP
- , BV_LISP
- , BV_MA
- , BV_ML
- , BV_MOD
- , BV_MPS
- , BV_NF
- , BV_OFU
- , BV_PATH
- , BV_PI
- , BV_QE
- , BV_RO
- , BV_SI
-#ifndef SHORT_FNAME
- , BV_SN
-#endif
- , BV_SMC
- , BV_SYN
- , BV_SPC
- , BV_SPF
- , BV_SPL
- , BV_STS
- , BV_SUA
- , BV_SW
- , BV_SWF
- , BV_TAGS
- , BV_TS
- , BV_TW
- , BV_TX
- , BV_UDF
- , BV_UL
- , BV_WM
- , BV_COUNT /* must be the last one */
-};
-
-/*
- * "indir" values for window-local options.
- * These need to be defined globally, so that the WV_COUNT can be used in the
- * window structure.
- */
-enum {
- WV_LIST = 0
- , WV_ARAB
- , WV_COCU
- , WV_COLE
- , WV_CRBIND
- , WV_DIFF
- , WV_FDC
- , WV_FEN
- , WV_FDI
- , WV_FDL
- , WV_FDM
- , WV_FML
- , WV_FDN
- , WV_FDE
- , WV_FDT
- , WV_FMR
- , WV_LBR
- , WV_NU
- , WV_RNU
- , WV_NUW
- , WV_PVW
- , WV_RL
- , WV_RLC
- , WV_SCBIND
- , WV_SCROLL
- , WV_SPELL
- , WV_CUC
- , WV_CUL
- , WV_CC
- , WV_STL
- , WV_WFH
- , WV_WFW
- , WV_WRAP
- , WV_COUNT /* must be the last one */
-};
-
-/* Value for b_p_ul indicating the global value must be used. */
-#define NO_LOCAL_UNDOLEVEL -123456
+#ifndef NEOVIM_OPTION_H
+#define NEOVIM_OPTION_H
+/* option.c */
+void set_init_1 __ARGS((void));
+void set_string_default __ARGS((char *name, char_u *val));
+void set_number_default __ARGS((char *name, long val));
+void free_all_options __ARGS((void));
+void set_init_2 __ARGS((void));
+void set_init_3 __ARGS((void));
+void set_helplang_default __ARGS((char_u *lang));
+void init_gui_options __ARGS((void));
+void set_title_defaults __ARGS((void));
+int do_set __ARGS((char_u *arg, int opt_flags));
+void set_options_bin __ARGS((int oldval, int newval, int opt_flags));
+int get_viminfo_parameter __ARGS((int type));
+char_u *find_viminfo_parameter __ARGS((int type));
+void check_options __ARGS((void));
+void check_buf_options __ARGS((buf_T *buf));
+void free_string_option __ARGS((char_u *p));
+void clear_string_option __ARGS((char_u **pp));
+void set_term_option_alloced __ARGS((char_u **p));
+int was_set_insecurely __ARGS((char_u *opt, int opt_flags));
+void set_string_option_direct __ARGS((char_u *name, int opt_idx, char_u *val,
+ int opt_flags,
+ int set_sid));
+char_u *check_colorcolumn __ARGS((win_T *wp));
+char_u *check_stl_option __ARGS((char_u *s));
+int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval,
+ int opt_flags));
+int get_option_value_strict __ARGS((char_u *name, long *numval, char_u *
+ *stringval, int opt_type,
+ void *from));
+char_u *option_iter_next __ARGS((void **option, int opt_type));
+char_u *set_option_value __ARGS((char_u *name, long number, char_u *string,
+ int opt_flags));
+char_u *get_term_code __ARGS((char_u *tname));
+char_u *get_highlight_default __ARGS((void));
+char_u *get_encoding_default __ARGS((void));
+int makeset __ARGS((FILE *fd, int opt_flags, int local_only));
+int makefoldset __ARGS((FILE *fd));
+void clear_termoptions __ARGS((void));
+void free_termoptions __ARGS((void));
+void free_one_termoption __ARGS((char_u *var));
+void set_term_defaults __ARGS((void));
+void comp_col __ARGS((void));
+void unset_global_local_option __ARGS((char_u *name, void *from));
+char_u *get_equalprg __ARGS((void));
+void win_copy_options __ARGS((win_T *wp_from, win_T *wp_to));
+void copy_winopt __ARGS((winopt_T *from, winopt_T *to));
+void check_win_options __ARGS((win_T *win));
+void check_winopt __ARGS((winopt_T *wop));
+void clear_winopt __ARGS((winopt_T *wop));
+void buf_copy_options __ARGS((buf_T *buf, int flags));
+void reset_modifiable __ARGS((void));
+void set_iminsert_global __ARGS((void));
+void set_imsearch_global __ARGS((void));
+void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
+int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file,
+ char_u ***file));
+int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
+int langmap_adjust_mb __ARGS((int c));
+int has_format_option __ARGS((int x));
+int shortmess __ARGS((int x));
+void vimrc_found __ARGS((char_u *fname, char_u *envname));
+void change_compatible __ARGS((int on));
+int option_was_set __ARGS((char_u *name));
+void reset_option_was_set __ARGS((char_u *name));
+int can_bs __ARGS((int what));
+void save_file_ff __ARGS((buf_T *buf));
+int file_ff_differs __ARGS((buf_T *buf, int ignore_empty));
+int check_ff_value __ARGS((char_u *p));
+long get_sw_value __ARGS((buf_T *buf));
+long get_sts_value __ARGS((void));
+void find_mps_values __ARGS((int *initc, int *findc, int *backwards,
+ int switchit));
+/* vim: set ft=c : */
+#endif /* NEOVIM_OPTION_H */
diff --git a/src/option_defs.h b/src/option_defs.h
new file mode 100644
index 0000000000..6dc232d03d
--- /dev/null
+++ b/src/option_defs.h
@@ -0,0 +1,768 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * option_defs.h: definition of global variables for settable options
+ */
+
+/*
+ * Default values for 'errorformat'.
+ * The "%f|%l| %m" one is used for when the contents of the quickfix window is
+ * written to a file.
+ */
+#define DFLT_EFM \
+ "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m"
+
+#define DFLT_GREPFORMAT "%f:%l:%m,%f:%l%m,%f %l%m"
+
+/* default values for b_p_ff 'fileformat' and p_ffs 'fileformats' */
+#define FF_DOS "dos"
+#define FF_MAC "mac"
+#define FF_UNIX "unix"
+
+#ifdef USE_CRNL
+# define DFLT_FF "dos"
+# define DFLT_FFS_VIM "dos,unix"
+# define DFLT_FFS_VI "dos,unix" /* also autodetect in compatible mode */
+# define DFLT_TEXTAUTO TRUE
+#else
+# ifdef USE_CR
+# define DFLT_FF "mac"
+# define DFLT_FFS_VIM "mac,unix,dos"
+# define DFLT_FFS_VI "mac,unix,dos"
+# define DFLT_TEXTAUTO TRUE
+# else
+# define DFLT_FF "unix"
+# define DFLT_FFS_VIM "unix,dos"
+# define DFLT_FFS_VI ""
+# define DFLT_TEXTAUTO FALSE
+# endif
+#endif
+
+
+/* Possible values for 'encoding' */
+# define ENC_UCSBOM "ucs-bom" /* check for BOM at start of file */
+
+/* default value for 'encoding' */
+# define ENC_DFLT "latin1"
+
+/* end-of-line style */
+#define EOL_UNKNOWN -1 /* not defined yet */
+#define EOL_UNIX 0 /* NL */
+#define EOL_DOS 1 /* CR NL */
+#define EOL_MAC 2 /* CR */
+
+/* Formatting options for p_fo 'formatoptions' */
+#define FO_WRAP 't'
+#define FO_WRAP_COMS 'c'
+#define FO_RET_COMS 'r'
+#define FO_OPEN_COMS 'o'
+#define FO_Q_COMS 'q'
+#define FO_Q_NUMBER 'n'
+#define FO_Q_SECOND '2'
+#define FO_INS_VI 'v'
+#define FO_INS_LONG 'l'
+#define FO_INS_BLANK 'b'
+#define FO_MBYTE_BREAK 'm' /* break before/after multi-byte char */
+#define FO_MBYTE_JOIN 'M' /* no space before/after multi-byte char */
+#define FO_MBYTE_JOIN2 'B' /* no space between multi-byte chars */
+#define FO_ONE_LETTER '1'
+#define FO_WHITE_PAR 'w' /* trailing white space continues paragr. */
+#define FO_AUTO 'a' /* automatic formatting */
+#define FO_REMOVE_COMS 'j' /* remove comment leaders when joining lines */
+
+#define DFLT_FO_VI "vt"
+#define DFLT_FO_VIM "tcq"
+#define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */
+
+/* characters for the p_cpo option: */
+#define CPO_ALTREAD 'a' /* ":read" sets alternate file name */
+#define CPO_ALTWRITE 'A' /* ":write" sets alternate file name */
+#define CPO_BAR 'b' /* "\|" ends a mapping */
+#define CPO_BSLASH 'B' /* backslash in mapping is not special */
+#define CPO_SEARCH 'c'
+#define CPO_CONCAT 'C' /* Don't concatenate sourced lines */
+#define CPO_DOTTAG 'd' /* "./tags" in 'tags' is in current dir */
+#define CPO_DIGRAPH 'D' /* No digraph after "r", "f", etc. */
+#define CPO_EXECBUF 'e'
+#define CPO_EMPTYREGION 'E' /* operating on empty region is an error */
+#define CPO_FNAMER 'f' /* set file name for ":r file" */
+#define CPO_FNAMEW 'F' /* set file name for ":w file" */
+#define CPO_GOTO1 'g' /* goto line 1 for ":edit" */
+#define CPO_INSEND 'H' /* "I" inserts before last blank in line */
+#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */
+#define CPO_INDENT 'I' /* remove auto-indent more often */
+#define CPO_JOINSP 'j' /* only use two spaces for join after '.' */
+#define CPO_ENDOFSENT 'J' /* need two spaces to detect end of sentence */
+#define CPO_KEYCODE 'k' /* don't recognize raw key code in mappings */
+#define CPO_KOFFSET 'K' /* don't wait for key code in mappings */
+#define CPO_LITERAL 'l' /* take char after backslash in [] literal */
+#define CPO_LISTWM 'L' /* 'list' changes wrapmargin */
+#define CPO_SHOWMATCH 'm'
+#define CPO_MATCHBSL 'M' /* "%" ignores use of backslashes */
+#define CPO_NUMCOL 'n' /* 'number' column also used for text */
+#define CPO_LINEOFF 'o'
+#define CPO_OVERNEW 'O' /* silently overwrite new file */
+#define CPO_LISP 'p' /* 'lisp' indenting */
+#define CPO_FNAMEAPP 'P' /* set file name for ":w >>file" */
+#define CPO_JOINCOL 'q' /* with "3J" use column after first join */
+#define CPO_REDO 'r'
+#define CPO_REMMARK 'R' /* remove marks when filtering */
+#define CPO_BUFOPT 's'
+#define CPO_BUFOPTGLOB 'S'
+#define CPO_TAGPAT 't'
+#define CPO_UNDO 'u' /* "u" undoes itself */
+#define CPO_BACKSPACE 'v' /* "v" keep deleted text */
+#define CPO_CW 'w' /* "cw" only changes one blank */
+#define CPO_FWRITE 'W' /* "w!" doesn't overwrite readonly files */
+#define CPO_ESC 'x'
+#define CPO_REPLCNT 'X' /* "R" with a count only deletes chars once */
+#define CPO_YANK 'y'
+#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */
+#define CPO_DOLLAR '$'
+#define CPO_FILTER '!'
+#define CPO_MATCH '%'
+#define CPO_STAR '*' /* ":*" means ":@" */
+#define CPO_PLUS '+' /* ":write file" resets 'modified' */
+#define CPO_MINUS '-' /* "9-" fails at and before line 9 */
+#define CPO_SPECI '<' /* don't recognize <> in mappings */
+#define CPO_REGAPPEND '>' /* insert NL when appending to a register */
+/* POSIX flags */
+#define CPO_HASH '#' /* "D", "o" and "O" do not use a count */
+#define CPO_PARA '{' /* "{" is also a paragraph boundary */
+#define CPO_TSIZE '|' /* $LINES and $COLUMNS overrule term size */
+#define CPO_PRESERVE '&' /* keep swap file after :preserve */
+#define CPO_SUBPERCENT '/' /* % in :s string uses previous one */
+#define CPO_BACKSL '\\' /* \ is not special in [] */
+#define CPO_CHDIR '.' /* don't chdir if buffer is modified */
+#define CPO_SCOLON ';' /* using "," and ";" will skip over char if
+ * cursor would not move */
+/* default values for Vim, Vi and POSIX */
+#define CPO_VIM "aABceFs"
+#define CPO_VI "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>;"
+#define CPO_ALL \
+ "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;"
+
+/* characters for p_ww option: */
+#define WW_ALL "bshl<>[],~"
+
+/* characters for p_mouse option: */
+#define MOUSE_NORMAL 'n' /* use mouse in Normal mode */
+#define MOUSE_VISUAL 'v' /* use mouse in Visual/Select mode */
+#define MOUSE_INSERT 'i' /* use mouse in Insert mode */
+#define MOUSE_COMMAND 'c' /* use mouse in Command-line mode */
+#define MOUSE_HELP 'h' /* use mouse in help buffers */
+#define MOUSE_RETURN 'r' /* use mouse for hit-return message */
+#define MOUSE_A "nvich" /* used for 'a' flag */
+#define MOUSE_ALL "anvichr" /* all possible characters */
+#define MOUSE_NONE ' ' /* don't use Visual selection */
+#define MOUSE_NONEF 'x' /* forced modeless selection */
+
+#define COCU_ALL "nvic" /* flags for 'concealcursor' */
+
+/* characters for p_shm option: */
+#define SHM_RO 'r' /* readonly */
+#define SHM_MOD 'm' /* modified */
+#define SHM_FILE 'f' /* (file 1 of 2) */
+#define SHM_LAST 'i' /* last line incomplete */
+#define SHM_TEXT 'x' /* tx instead of textmode */
+#define SHM_LINES 'l' /* "L" instead of "lines" */
+#define SHM_NEW 'n' /* "[New]" instead of "[New file]" */
+#define SHM_WRI 'w' /* "[w]" instead of "written" */
+#define SHM_A "rmfixlnw" /* represented by 'a' flag */
+#define SHM_WRITE 'W' /* don't use "written" at all */
+#define SHM_TRUNC 't' /* trunctate file messages */
+#define SHM_TRUNCALL 'T' /* trunctate all messages */
+#define SHM_OVER 'o' /* overwrite file messages */
+#define SHM_OVERALL 'O' /* overwrite more messages */
+#define SHM_SEARCH 's' /* no search hit bottom messages */
+#define SHM_ATTENTION 'A' /* no ATTENTION messages */
+#define SHM_INTRO 'I' /* intro messages */
+#define SHM_ALL "rmfixlnwaWtToOsAI" /* all possible flags for 'shm' */
+
+/* characters for p_go: */
+#define GO_ASEL 'a' /* autoselect */
+#define GO_ASELML 'A' /* autoselect modeless selection */
+#define GO_BOT 'b' /* use bottom scrollbar */
+#define GO_CONDIALOG 'c' /* use console dialog */
+#define GO_TABLINE 'e' /* may show tabline */
+#define GO_FORG 'f' /* start GUI in foreground */
+#define GO_GREY 'g' /* use grey menu items */
+#define GO_HORSCROLL 'h' /* flexible horizontal scrolling */
+#define GO_ICON 'i' /* use Vim icon */
+#define GO_LEFT 'l' /* use left scrollbar */
+#define GO_VLEFT 'L' /* left scrollbar with vert split */
+#define GO_MENUS 'm' /* use menu bar */
+#define GO_NOSYSMENU 'M' /* don't source system menu */
+#define GO_POINTER 'p' /* pointer enter/leave callbacks */
+#define GO_ASELPLUS 'P' /* autoselectPlus */
+#define GO_RIGHT 'r' /* use right scrollbar */
+#define GO_VRIGHT 'R' /* right scrollbar with vert split */
+#define GO_TEAROFF 't' /* add tear-off menu items */
+#define GO_TOOLBAR 'T' /* add toolbar */
+#define GO_FOOTER 'F' /* add footer */
+#define GO_VERTICAL 'v' /* arrange dialog buttons vertically */
+#define GO_ALL "aAbcefFghilmMprtTv" /* all possible flags for 'go' */
+
+/* flags for 'comments' option */
+#define COM_NEST 'n' /* comments strings nest */
+#define COM_BLANK 'b' /* needs blank after string */
+#define COM_START 's' /* start of comment */
+#define COM_MIDDLE 'm' /* middle of comment */
+#define COM_END 'e' /* end of comment */
+#define COM_AUTO_END 'x' /* last char of end closes comment */
+#define COM_FIRST 'f' /* first line comment only */
+#define COM_LEFT 'l' /* left adjusted */
+#define COM_RIGHT 'r' /* right adjusted */
+#define COM_NOBACK 'O' /* don't use for "O" command */
+#define COM_ALL "nbsmexflrO" /* all flags for 'comments' option */
+#define COM_MAX_LEN 50 /* maximum length of a part */
+
+/* flags for 'statusline' option */
+#define STL_FILEPATH 'f' /* path of file in buffer */
+#define STL_FULLPATH 'F' /* full path of file in buffer */
+#define STL_FILENAME 't' /* last part (tail) of file path */
+#define STL_COLUMN 'c' /* column og cursor*/
+#define STL_VIRTCOL 'v' /* virtual column */
+#define STL_VIRTCOL_ALT 'V' /* - with 'if different' display */
+#define STL_LINE 'l' /* line number of cursor */
+#define STL_NUMLINES 'L' /* number of lines in buffer */
+#define STL_BUFNO 'n' /* current buffer number */
+#define STL_KEYMAP 'k' /* 'keymap' when active */
+#define STL_OFFSET 'o' /* offset of character under cursor*/
+#define STL_OFFSET_X 'O' /* - in hexadecimal */
+#define STL_BYTEVAL 'b' /* byte value of character */
+#define STL_BYTEVAL_X 'B' /* - in hexadecimal */
+#define STL_ROFLAG 'r' /* readonly flag */
+#define STL_ROFLAG_ALT 'R' /* - other display */
+#define STL_HELPFLAG 'h' /* window is showing a help file */
+#define STL_HELPFLAG_ALT 'H' /* - other display */
+#define STL_FILETYPE 'y' /* 'filetype' */
+#define STL_FILETYPE_ALT 'Y' /* - other display */
+#define STL_PREVIEWFLAG 'w' /* window is showing the preview buf */
+#define STL_PREVIEWFLAG_ALT 'W' /* - other display */
+#define STL_MODIFIED 'm' /* modified flag */
+#define STL_MODIFIED_ALT 'M' /* - other display */
+#define STL_QUICKFIX 'q' /* quickfix window description */
+#define STL_PERCENTAGE 'p' /* percentage through file */
+#define STL_ALTPERCENT 'P' /* percentage as TOP BOT ALL or NN% */
+#define STL_ARGLISTSTAT 'a' /* argument list status as (x of y) */
+#define STL_PAGENUM 'N' /* page number (when printing)*/
+#define STL_VIM_EXPR '{' /* start of expression to substitute */
+#define STL_MIDDLEMARK '=' /* separation between left and right */
+#define STL_TRUNCMARK '<' /* truncation mark if line is too long*/
+#define STL_USER_HL '*' /* highlight from (User)1..9 or 0 */
+#define STL_HIGHLIGHT '#' /* highlight name */
+#define STL_TABPAGENR 'T' /* tab page label nr */
+#define STL_TABCLOSENR 'X' /* tab page close nr */
+#define STL_ALL ((char_u *) "fFtcvVlLknoObBrRhHmYyWwMqpPaN{#")
+
+/* flags used for parsed 'wildmode' */
+#define WIM_FULL 1
+#define WIM_LONGEST 2
+#define WIM_LIST 4
+
+/* arguments for can_bs() */
+#define BS_INDENT 'i' /* "Indent" */
+#define BS_EOL 'o' /* "eOl" */
+#define BS_START 's' /* "Start" */
+
+#define LISPWORD_VALUE \
+ "defun,define,defmacro,set!,lambda,if,case,let,flet,let*,letrec,do,do*,define-syntax,let-syntax,letrec-syntax,destructuring-bind,defpackage,defparameter,defstruct,deftype,defvar,do-all-symbols,do-external-symbols,do-symbols,dolist,dotimes,ecase,etypecase,eval-when,labels,macrolet,multiple-value-bind,multiple-value-call,multiple-value-prog1,multiple-value-setq,prog1,progv,typecase,unless,unwind-protect,when,with-input-from-string,with-open-file,with-open-stream,with-output-to-string,with-package-iterator,define-condition,handler-bind,handler-case,restart-bind,restart-case,with-simple-restart,store-value,use-value,muffle-warning,abort,continue,with-slots,with-slots*,with-accessors,with-accessors*,defclass,defmethod,print-unreadable-object"
+
+/*
+ * The following are actual variables for the options
+ */
+
+EXTERN long p_aleph; /* 'aleph' */
+EXTERN int p_acd; /* 'autochdir' */
+EXTERN char_u *p_ambw; /* 'ambiwidth' */
+EXTERN int p_ar; /* 'autoread' */
+EXTERN int p_aw; /* 'autowrite' */
+EXTERN int p_awa; /* 'autowriteall' */
+EXTERN char_u *p_bs; /* 'backspace' */
+EXTERN char_u *p_bg; /* 'background' */
+EXTERN int p_bk; /* 'backup' */
+EXTERN char_u *p_bkc; /* 'backupcopy' */
+EXTERN unsigned bkc_flags;
+#ifdef IN_OPTION_C
+static char *(p_bkc_values[]) =
+{"yes", "auto", "no", "breaksymlink", "breakhardlink", NULL};
+#endif
+# define BKC_YES 0x001
+# define BKC_AUTO 0x002
+# define BKC_NO 0x004
+# define BKC_BREAKSYMLINK 0x008
+# define BKC_BREAKHARDLINK 0x010
+EXTERN char_u *p_bdir; /* 'backupdir' */
+EXTERN char_u *p_bex; /* 'backupext' */
+EXTERN char_u *p_bsk; /* 'backupskip' */
+EXTERN char_u *p_cm; /* 'cryptmethod' */
+EXTERN char_u *p_breakat; /* 'breakat' */
+EXTERN char_u *p_cmp; /* 'casemap' */
+EXTERN unsigned cmp_flags;
+# ifdef IN_OPTION_C
+static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
+# endif
+# define CMP_INTERNAL 0x001
+# define CMP_KEEPASCII 0x002
+EXTERN char_u *p_enc; /* 'encoding' */
+EXTERN int p_deco; /* 'delcombine' */
+EXTERN char_u *p_ccv; /* 'charconvert' */
+EXTERN char_u *p_cedit; /* 'cedit' */
+EXTERN long p_cwh; /* 'cmdwinheight' */
+EXTERN long p_ch; /* 'cmdheight' */
+EXTERN int p_confirm; /* 'confirm' */
+EXTERN int p_cp; /* 'compatible' */
+EXTERN char_u *p_cot; /* 'completeopt' */
+EXTERN long p_ph; /* 'pumheight' */
+EXTERN char_u *p_cpo; /* 'cpoptions' */
+EXTERN char_u *p_csprg; /* 'cscopeprg' */
+EXTERN int p_csre; /* 'cscoperelative' */
+EXTERN char_u *p_csqf; /* 'cscopequickfix' */
+# define CSQF_CMDS "sgdctefi"
+# define CSQF_FLAGS "+-0"
+EXTERN int p_cst; /* 'cscopetag' */
+EXTERN long p_csto; /* 'cscopetagorder' */
+EXTERN long p_cspc; /* 'cscopepathcomp' */
+EXTERN int p_csverbose; /* 'cscopeverbose' */
+EXTERN char_u *p_debug; /* 'debug' */
+EXTERN char_u *p_def; /* 'define' */
+EXTERN char_u *p_inc;
+EXTERN char_u *p_dip; /* 'diffopt' */
+EXTERN char_u *p_dex; /* 'diffexpr' */
+EXTERN char_u *p_dict; /* 'dictionary' */
+EXTERN int p_dg; /* 'digraph' */
+EXTERN char_u *p_dir; /* 'directory' */
+EXTERN char_u *p_dy; /* 'display' */
+EXTERN unsigned dy_flags;
+#ifdef IN_OPTION_C
+static char *(p_dy_values[]) = {"lastline", "uhex", NULL};
+#endif
+#define DY_LASTLINE 0x001
+#define DY_UHEX 0x002
+EXTERN int p_ed; /* 'edcompatible' */
+EXTERN char_u *p_ead; /* 'eadirection' */
+EXTERN int p_ea; /* 'equalalways' */
+EXTERN char_u *p_ep; /* 'equalprg' */
+EXTERN int p_eb; /* 'errorbells' */
+EXTERN char_u *p_ef; /* 'errorfile' */
+EXTERN char_u *p_efm; /* 'errorformat' */
+EXTERN char_u *p_gefm; /* 'grepformat' */
+EXTERN char_u *p_gp; /* 'grepprg' */
+EXTERN char_u *p_ei; /* 'eventignore' */
+EXTERN int p_ek; /* 'esckeys' */
+EXTERN int p_exrc; /* 'exrc' */
+EXTERN char_u *p_fencs; /* 'fileencodings' */
+EXTERN char_u *p_ffs; /* 'fileformats' */
+EXTERN long p_fic; /* 'fileignorecase' */
+EXTERN char_u *p_fcl; /* 'foldclose' */
+EXTERN long p_fdls; /* 'foldlevelstart' */
+EXTERN char_u *p_fdo; /* 'foldopen' */
+EXTERN unsigned fdo_flags;
+# ifdef IN_OPTION_C
+static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
+ "quickfix", "search", "tag", "insert",
+ "undo", "jump", NULL};
+# endif
+# define FDO_ALL 0x001
+# define FDO_BLOCK 0x002
+# define FDO_HOR 0x004
+# define FDO_MARK 0x008
+# define FDO_PERCENT 0x010
+# define FDO_QUICKFIX 0x020
+# define FDO_SEARCH 0x040
+# define FDO_TAG 0x080
+# define FDO_INSERT 0x100
+# define FDO_UNDO 0x200
+# define FDO_JUMP 0x400
+EXTERN char_u *p_fp; /* 'formatprg' */
+#ifdef HAVE_FSYNC
+EXTERN int p_fs; /* 'fsync' */
+#endif
+EXTERN int p_gd; /* 'gdefault' */
+EXTERN char_u *p_pdev; /* 'printdevice' */
+EXTERN char_u *p_penc; /* 'printencoding' */
+EXTERN char_u *p_pexpr; /* 'printexpr' */
+EXTERN char_u *p_pmfn; /* 'printmbfont' */
+EXTERN char_u *p_pmcs; /* 'printmbcharset' */
+EXTERN char_u *p_pfn; /* 'printfont' */
+EXTERN char_u *p_popt; /* 'printoptions' */
+EXTERN char_u *p_header; /* 'printheader' */
+EXTERN int p_prompt; /* 'prompt' */
+#ifdef CURSOR_SHAPE
+EXTERN char_u *p_guicursor; /* 'guicursor' */
+#endif
+EXTERN char_u *p_hf; /* 'helpfile' */
+EXTERN long p_hh; /* 'helpheight' */
+EXTERN char_u *p_hlg; /* 'helplang' */
+EXTERN int p_hid; /* 'hidden' */
+/* Use P_HID to check if a buffer is to be hidden when it is no longer
+ * visible in a window. */
+# define P_HID(buf) (buf_hide(buf))
+EXTERN char_u *p_hl; /* 'highlight' */
+EXTERN int p_hls; /* 'hlsearch' */
+EXTERN long p_hi; /* 'history' */
+EXTERN int p_hkmap; /* 'hkmap' */
+EXTERN int p_hkmapp; /* 'hkmapp' */
+EXTERN int p_fkmap; /* 'fkmap' */
+EXTERN int p_altkeymap; /* 'altkeymap' */
+EXTERN int p_arshape; /* 'arabicshape' */
+EXTERN int p_icon; /* 'icon' */
+EXTERN char_u *p_iconstring; /* 'iconstring' */
+EXTERN int p_ic; /* 'ignorecase' */
+#ifdef USE_IM_CONTROL
+EXTERN int p_imcmdline; /* 'imcmdline' */
+EXTERN int p_imdisable; /* 'imdisable' */
+#endif
+EXTERN int p_is; /* 'incsearch' */
+EXTERN int p_im; /* 'insertmode' */
+EXTERN char_u *p_isf; /* 'isfname' */
+EXTERN char_u *p_isi; /* 'isident' */
+EXTERN char_u *p_isp; /* 'isprint' */
+EXTERN int p_js; /* 'joinspaces' */
+EXTERN char_u *p_kp; /* 'keywordprg' */
+EXTERN char_u *p_km; /* 'keymodel' */
+EXTERN char_u *p_langmap; /* 'langmap'*/
+EXTERN char_u *p_lm; /* 'langmenu' */
+EXTERN char_u *p_lispwords; /* 'lispwords' */
+EXTERN long p_ls; /* 'laststatus' */
+EXTERN long p_stal; /* 'showtabline' */
+EXTERN char_u *p_lcs; /* 'listchars' */
+
+EXTERN int p_lz; /* 'lazyredraw' */
+EXTERN int p_lpl; /* 'loadplugins' */
+EXTERN int p_magic; /* 'magic' */
+EXTERN char_u *p_mef; /* 'makeef' */
+EXTERN char_u *p_mp; /* 'makeprg' */
+EXTERN char_u *p_cc; /* 'colorcolumn' */
+EXTERN int p_cc_cols[256]; /* array for 'colorcolumn' columns */
+EXTERN long p_mat; /* 'matchtime' */
+EXTERN long p_mco; /* 'maxcombine' */
+EXTERN long p_mfd; /* 'maxfuncdepth' */
+EXTERN long p_mmd; /* 'maxmapdepth' */
+EXTERN long p_mm; /* 'maxmem' */
+EXTERN long p_mmp; /* 'maxmempattern' */
+EXTERN long p_mmt; /* 'maxmemtot' */
+EXTERN long p_mis; /* 'menuitems' */
+EXTERN char_u *p_msm; /* 'mkspellmem' */
+EXTERN long p_mls; /* 'modelines' */
+EXTERN char_u *p_mouse; /* 'mouse' */
+EXTERN char_u *p_mousem; /* 'mousemodel' */
+EXTERN long p_mouset; /* 'mousetime' */
+EXTERN int p_more; /* 'more' */
+EXTERN char_u *p_opfunc; /* 'operatorfunc' */
+EXTERN char_u *p_para; /* 'paragraphs' */
+EXTERN int p_paste; /* 'paste' */
+EXTERN char_u *p_pt; /* 'pastetoggle' */
+EXTERN char_u *p_pex; /* 'patchexpr' */
+EXTERN char_u *p_pm; /* 'patchmode' */
+EXTERN char_u *p_path; /* 'path' */
+EXTERN char_u *p_cdpath; /* 'cdpath' */
+EXTERN long p_rdt; /* 'redrawtime' */
+EXTERN int p_remap; /* 'remap' */
+EXTERN long p_re; /* 'regexpengine' */
+EXTERN long p_report; /* 'report' */
+EXTERN long p_pvh; /* 'previewheight' */
+EXTERN int p_ari; /* 'allowrevins' */
+EXTERN int p_ri; /* 'revins' */
+EXTERN int p_ru; /* 'ruler' */
+EXTERN char_u *p_ruf; /* 'rulerformat' */
+EXTERN char_u *p_rtp; /* 'runtimepath' */
+EXTERN long p_sj; /* 'scrolljump' */
+EXTERN long p_so; /* 'scrolloff' */
+EXTERN char_u *p_sbo; /* 'scrollopt' */
+EXTERN char_u *p_sections; /* 'sections' */
+EXTERN int p_secure; /* 'secure' */
+EXTERN char_u *p_sel; /* 'selection' */
+EXTERN char_u *p_slm; /* 'selectmode' */
+EXTERN char_u *p_ssop; /* 'sessionoptions' */
+EXTERN unsigned ssop_flags;
+# ifdef IN_OPTION_C
+/* Also used for 'viewoptions'! */
+static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
+ "localoptions", "options", "help", "blank",
+ "globals", "slash", "unix",
+ "sesdir", "curdir", "folds", "cursor",
+ "tabpages", NULL};
+# endif
+# define SSOP_BUFFERS 0x001
+# define SSOP_WINPOS 0x002
+# define SSOP_RESIZE 0x004
+# define SSOP_WINSIZE 0x008
+# define SSOP_LOCALOPTIONS 0x010
+# define SSOP_OPTIONS 0x020
+# define SSOP_HELP 0x040
+# define SSOP_BLANK 0x080
+# define SSOP_GLOBALS 0x100
+# define SSOP_SLASH 0x200
+# define SSOP_UNIX 0x400
+# define SSOP_SESDIR 0x800
+# define SSOP_CURDIR 0x1000
+# define SSOP_FOLDS 0x2000
+# define SSOP_CURSOR 0x4000
+# define SSOP_TABPAGES 0x8000
+EXTERN char_u *p_sh; /* 'shell' */
+EXTERN char_u *p_shcf; /* 'shellcmdflag' */
+EXTERN char_u *p_sp; /* 'shellpipe' */
+EXTERN char_u *p_shq; /* 'shellquote' */
+EXTERN char_u *p_sxq; /* 'shellxquote' */
+EXTERN char_u *p_sxe; /* 'shellxescape' */
+EXTERN char_u *p_srr; /* 'shellredir' */
+EXTERN int p_stmp; /* 'shelltemp' */
+#ifdef BACKSLASH_IN_FILENAME
+EXTERN int p_ssl; /* 'shellslash' */
+#endif
+EXTERN char_u *p_stl; /* 'statusline' */
+EXTERN int p_sr; /* 'shiftround' */
+EXTERN char_u *p_shm; /* 'shortmess' */
+EXTERN char_u *p_sbr; /* 'showbreak' */
+EXTERN int p_sc; /* 'showcmd' */
+EXTERN int p_sft; /* 'showfulltag' */
+EXTERN int p_sm; /* 'showmatch' */
+EXTERN int p_smd; /* 'showmode' */
+EXTERN long p_ss; /* 'sidescroll' */
+EXTERN long p_siso; /* 'sidescrolloff' */
+EXTERN int p_scs; /* 'smartcase' */
+EXTERN int p_sta; /* 'smarttab' */
+EXTERN int p_sb; /* 'splitbelow' */
+EXTERN long p_tpm; /* 'tabpagemax' */
+EXTERN char_u *p_tal; /* 'tabline' */
+EXTERN char_u *p_sps; /* 'spellsuggest' */
+EXTERN int p_spr; /* 'splitright' */
+EXTERN int p_sol; /* 'startofline' */
+EXTERN char_u *p_su; /* 'suffixes' */
+EXTERN char_u *p_sws; /* 'swapsync' */
+EXTERN char_u *p_swb; /* 'switchbuf' */
+EXTERN unsigned swb_flags;
+#ifdef IN_OPTION_C
+static char *(p_swb_values[]) = {"useopen", "usetab", "split", "newtab", NULL};
+#endif
+#define SWB_USEOPEN 0x001
+#define SWB_USETAB 0x002
+#define SWB_SPLIT 0x004
+#define SWB_NEWTAB 0x008
+EXTERN int p_tbs; /* 'tagbsearch' */
+EXTERN long p_tl; /* 'taglength' */
+EXTERN int p_tr; /* 'tagrelative' */
+EXTERN char_u *p_tags; /* 'tags' */
+EXTERN int p_tgst; /* 'tagstack' */
+EXTERN int p_tbidi; /* 'termbidi' */
+EXTERN char_u *p_tenc; /* 'termencoding' */
+EXTERN int p_terse; /* 'terse' */
+EXTERN int p_ta; /* 'textauto' */
+EXTERN int p_to; /* 'tildeop' */
+EXTERN int p_timeout; /* 'timeout' */
+EXTERN long p_tm; /* 'timeoutlen' */
+EXTERN int p_title; /* 'title' */
+EXTERN long p_titlelen; /* 'titlelen' */
+EXTERN char_u *p_titleold; /* 'titleold' */
+EXTERN char_u *p_titlestring; /* 'titlestring' */
+EXTERN char_u *p_tsr; /* 'thesaurus' */
+EXTERN int p_ttimeout; /* 'ttimeout' */
+EXTERN long p_ttm; /* 'ttimeoutlen' */
+EXTERN int p_tbi; /* 'ttybuiltin' */
+EXTERN int p_tf; /* 'ttyfast' */
+EXTERN long p_ttyscroll; /* 'ttyscroll' */
+#if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
+EXTERN char_u *p_ttym; /* 'ttymouse' */
+EXTERN unsigned ttym_flags;
+# ifdef IN_OPTION_C
+static char *(p_ttym_values[]) =
+{"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
+# endif
+# define TTYM_XTERM 0x01
+# define TTYM_XTERM2 0x02
+# define TTYM_DEC 0x04
+# define TTYM_NETTERM 0x08
+# define TTYM_JSBTERM 0x10
+# define TTYM_PTERM 0x20
+# define TTYM_URXVT 0x40
+# define TTYM_SGR 0x80
+#endif
+EXTERN char_u *p_udir; /* 'undodir' */
+EXTERN long p_ul; /* 'undolevels' */
+EXTERN long p_ur; /* 'undoreload' */
+EXTERN long p_uc; /* 'updatecount' */
+EXTERN long p_ut; /* 'updatetime' */
+EXTERN char_u *p_fcs; /* 'fillchar' */
+EXTERN char_u *p_viminfo; /* 'viminfo' */
+EXTERN char_u *p_vdir; /* 'viewdir' */
+EXTERN char_u *p_vop; /* 'viewoptions' */
+EXTERN unsigned vop_flags; /* uses SSOP_ flags */
+EXTERN int p_vb; /* 'visualbell' */
+EXTERN char_u *p_ve; /* 'virtualedit' */
+EXTERN unsigned ve_flags;
+# ifdef IN_OPTION_C
+static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", NULL};
+# endif
+# define VE_BLOCK 5 /* includes "all" */
+# define VE_INSERT 6 /* includes "all" */
+# define VE_ALL 4
+# define VE_ONEMORE 8
+EXTERN long p_verbose; /* 'verbose' */
+#ifdef IN_OPTION_C
+char_u *p_vfile = (char_u *)""; /* used before options are initialized */
+#else
+extern char_u *p_vfile; /* 'verbosefile' */
+#endif
+EXTERN int p_warn; /* 'warn' */
+EXTERN char_u *p_wop; /* 'wildoptions' */
+EXTERN long p_window; /* 'window' */
+#if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(LINT) \
+ || defined (FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)
+#define FEAT_WAK
+EXTERN char_u *p_wak; /* 'winaltkeys' */
+#endif
+EXTERN char_u *p_wak;
+EXTERN char_u *p_wig; /* 'wildignore' */
+EXTERN int p_wiv; /* 'weirdinvert' */
+EXTERN char_u *p_ww; /* 'whichwrap' */
+EXTERN long p_wc; /* 'wildchar' */
+EXTERN long p_wcm; /* 'wildcharm' */
+EXTERN long p_wic; /* 'wildignorecase' */
+EXTERN char_u *p_wim; /* 'wildmode' */
+EXTERN int p_wmnu; /* 'wildmenu' */
+EXTERN long p_wh; /* 'winheight' */
+EXTERN long p_wmh; /* 'winminheight' */
+EXTERN long p_wmw; /* 'winminwidth' */
+EXTERN long p_wiw; /* 'winwidth' */
+EXTERN int p_ws; /* 'wrapscan' */
+EXTERN int p_write; /* 'write' */
+EXTERN int p_wa; /* 'writeany' */
+EXTERN int p_wb; /* 'writebackup' */
+EXTERN long p_wd; /* 'writedelay' */
+
+/*
+ * "indir" values for buffer-local opions.
+ * These need to be defined globally, so that the BV_COUNT can be used with
+ * b_p_scriptID[].
+ */
+enum {
+ BV_AI = 0
+ , BV_AR
+ , BV_BH
+ , BV_BT
+ , BV_EFM
+ , BV_GP
+ , BV_MP
+ , BV_BIN
+ , BV_BL
+ , BV_BOMB
+ , BV_CI
+ , BV_CIN
+ , BV_CINK
+ , BV_CINO
+ , BV_CINW
+ , BV_CM
+ , BV_CMS
+ , BV_COM
+ , BV_CPT
+ , BV_DICT
+ , BV_TSR
+ , BV_CFU
+ , BV_DEF
+ , BV_INC
+ , BV_EOL
+ , BV_EP
+ , BV_ET
+ , BV_FENC
+ , BV_BEXPR
+ , BV_FEX
+ , BV_FF
+ , BV_FLP
+ , BV_FO
+ , BV_FT
+ , BV_IMI
+ , BV_IMS
+ , BV_INDE
+ , BV_INDK
+ , BV_INEX
+ , BV_INF
+ , BV_ISK
+ , BV_KEY
+ , BV_KMAP
+ , BV_KP
+ , BV_LISP
+ , BV_MA
+ , BV_ML
+ , BV_MOD
+ , BV_MPS
+ , BV_NF
+ , BV_OFU
+ , BV_PATH
+ , BV_PI
+ , BV_QE
+ , BV_RO
+ , BV_SI
+#ifndef SHORT_FNAME
+ , BV_SN
+#endif
+ , BV_SMC
+ , BV_SYN
+ , BV_SPC
+ , BV_SPF
+ , BV_SPL
+ , BV_STS
+ , BV_SUA
+ , BV_SW
+ , BV_SWF
+ , BV_TAGS
+ , BV_TS
+ , BV_TW
+ , BV_TX
+ , BV_UDF
+ , BV_UL
+ , BV_WM
+ , BV_COUNT /* must be the last one */
+};
+
+/*
+ * "indir" values for window-local options.
+ * These need to be defined globally, so that the WV_COUNT can be used in the
+ * window structure.
+ */
+enum {
+ WV_LIST = 0
+ , WV_ARAB
+ , WV_COCU
+ , WV_COLE
+ , WV_CRBIND
+ , WV_DIFF
+ , WV_FDC
+ , WV_FEN
+ , WV_FDI
+ , WV_FDL
+ , WV_FDM
+ , WV_FML
+ , WV_FDN
+ , WV_FDE
+ , WV_FDT
+ , WV_FMR
+ , WV_LBR
+ , WV_NU
+ , WV_RNU
+ , WV_NUW
+ , WV_PVW
+ , WV_RL
+ , WV_RLC
+ , WV_SCBIND
+ , WV_SCROLL
+ , WV_SPELL
+ , WV_CUC
+ , WV_CUL
+ , WV_CC
+ , WV_STL
+ , WV_WFH
+ , WV_WFW
+ , WV_WRAP
+ , WV_COUNT /* must be the last one */
+};
+
+/* Value for b_p_ul indicating the global value must be used. */
+#define NO_LOCAL_UNDOLEVEL -123456
diff --git a/src/os/fs.c b/src/os/fs.c
new file mode 100644
index 0000000000..bc9a495984
--- /dev/null
+++ b/src/os/fs.c
@@ -0,0 +1,129 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * fs.c -- filesystem access
+ */
+
+#include <uv.h>
+
+#include "os.h"
+#include "../message.h"
+#include "../misc2.h"
+
+int mch_chdir(char *path) {
+ if (p_verbose >= 5) {
+ verbose_enter();
+ smsg((char_u *)"chdir(%s)", path);
+ verbose_leave();
+ }
+ return uv_chdir(path);
+}
+
+/*
+ * Get name of current directory into buffer 'buf' of length 'len' bytes.
+ * Return OK for success, FAIL for failure.
+ */
+int mch_dirname(char_u *buf, int len)
+{
+ int errno;
+ if ((errno = uv_cwd((char *)buf, len)) != 0) {
+ STRCPY(buf, uv_strerror(errno));
+ return FAIL;
+ }
+ return OK;
+}
+
+/*
+ * Get absolute file name into "buf[len]".
+ *
+ * return FAIL for failure, OK for success
+ */
+int mch_FullName(
+ char_u *fname,
+ char_u *buf,
+ int len,
+ int force /* also expand when already absolute path */
+ )
+{
+ int l;
+ char_u olddir[MAXPATHL];
+ char_u *p;
+ int retval = OK;
+
+
+
+ /* expand it if forced or not an absolute path */
+ if (force || !mch_isFullName(fname)) {
+ /*
+ * If the file name has a path, change to that directory for a moment,
+ * and then do the getwd() (and get back to where we were).
+ * This will get the correct path name with "../" things.
+ */
+ if ((p = vim_strrchr(fname, '/')) != NULL) {
+
+ /* Only change directory when we are sure we can return to where
+ * we are now. After doing "su" chdir(".") might not work. */
+ if ((mch_dirname(olddir, MAXPATHL) == FAIL
+ || mch_chdir((char *)olddir) != 0)) {
+ p = NULL; /* can't get current dir: don't chdir */
+ retval = FAIL;
+ } else {
+ /* The directory is copied into buf[], to be able to remove
+ * the file name without changing it (could be a string in
+ * read-only memory) */
+ if (p - fname >= len)
+ retval = FAIL;
+ else {
+ vim_strncpy(buf, fname, p - fname);
+ if (mch_chdir((char *)buf))
+ retval = FAIL;
+ else
+ fname = p + 1;
+ *buf = NUL;
+ }
+ }
+ }
+ if (mch_dirname(buf, len) == FAIL) {
+ retval = FAIL;
+ *buf = NUL;
+ }
+ if (p != NULL) {
+ l = mch_chdir((char *)olddir);
+ if (l != 0)
+ EMSG(_(e_prev_dir));
+ }
+
+ l = STRLEN(buf);
+ if (l >= len - 1)
+ retval = FAIL; /* no space for trailing "/" */
+ else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
+ && STRCMP(fname, ".") != 0)
+ STRCAT(buf, "/");
+ }
+
+ /* Catch file names which are too long. */
+ if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
+ return FAIL;
+
+ /* Do not append ".", "/dir/." is equal to "/dir". */
+ if (STRCMP(fname, ".") != 0)
+ STRCAT(buf, fname);
+
+ return OK;
+}
+
+/*
+ * Return TRUE if "fname" does not depend on the current directory.
+ */
+int mch_isFullName(char_u *fname)
+{
+ return *fname == '/' || *fname == '~';
+}
+
diff --git a/src/os/mem.c b/src/os/mem.c
new file mode 100644
index 0000000000..20abd58261
--- /dev/null
+++ b/src/os/mem.c
@@ -0,0 +1,26 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * os.c -- OS-level calls to query hardware, etc.
+ */
+
+#include <uv.h>
+
+#include "os.h"
+
+/*
+ * Return total amount of memory available in Kbyte.
+ * Doesn't change when memory has been allocated.
+ */
+long_u mch_total_mem(int special) {
+ /* We need to return memory in *Kbytes* but uv_get_total_memory() returns the
+ * number of bytes of total memory. */
+ return uv_get_total_memory() >> 10;
+}
diff --git a/src/os/os.h b/src/os/os.h
new file mode 100644
index 0000000000..9cf2116091
--- /dev/null
+++ b/src/os/os.h
@@ -0,0 +1,12 @@
+#ifndef NEOVIM_OS_H
+#define NEOVIM_OS_H
+
+#include "../vim.h"
+
+long_u mch_total_mem(int special);
+int mch_chdir(char *path);
+int mch_dirname(char_u *buf, int len);
+int mch_FullName (char_u *fname, char_u *buf, int len, int force);
+int mch_isFullName (char_u *fname);
+
+#endif
diff --git a/src/os_unix.c b/src/os_unix.c
index 344be7b0df..856191ea95 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -28,11 +28,27 @@
# define select select_declared_wrong
#include "vim.h"
-
+#include "os_unix.h"
+#include "buffer.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "screen.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "os/os.h"
#include "os_unixx.h" /* unix includes for os_unix.c only */
-
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
static int selinux_enabled = -1;
@@ -221,23 +237,10 @@ static struct signalinfo {
{-1, "Unknown!", FALSE}
};
-int mch_chdir(path)
-char *path;
-{
- if (p_verbose >= 5) {
- verbose_enter();
- smsg((char_u *)"chdir(%s)", path);
- verbose_leave();
- }
- return chdir(path);
-}
-
/*
* Write s[len] to the screen.
*/
-void mch_write(s, len)
-char_u *s;
-int len;
+void mch_write(char_u *s, int len)
{
ignored = (int)write(1, (char *)s, len);
if (p_wd) /* Unix is too fast, slow down a bit more */
@@ -252,74 +255,75 @@ int len;
* If wtime == n wait a short time for characters.
* If wtime == -1 wait forever for characters.
*/
-int mch_inchar(buf, maxlen, wtime, tb_change_cnt)
-char_u *buf;
-int maxlen;
-long wtime; /* don't use "time", MIPS cannot handle it */
-int tb_change_cnt;
+int mch_inchar(
+ char_u *buf,
+ int maxlen,
+ long wtime, /* don't use "time", MIPS cannot handle it */
+ int tb_change_cnt
+ )
{
- int len;
+ int len;
- /* Check if window changed size while we were busy, perhaps the ":set
- * columns=99" command was used. */
- while (do_resize)
- handle_resize();
+ /* Check if window changed size while we were busy, perhaps the ":set
+ * columns=99" command was used. */
+ while (do_resize)
+ handle_resize();
- if (wtime >= 0) {
- while (WaitForChar(wtime) == 0) { /* no character available */
- if (!do_resize) /* return if not interrupted by resize */
- return 0;
- handle_resize();
- }
- } else { /* wtime == -1 */
- /*
- * If there is no character available within 'updatetime' seconds
- * flush all the swap files to disk.
- * Also done when interrupted by SIGWINCH.
- */
- if (WaitForChar(p_ut) == 0) {
- if (trigger_cursorhold() && maxlen >= 3
- && !typebuf_changed(tb_change_cnt)) {
- buf[0] = K_SPECIAL;
- buf[1] = KS_EXTRA;
- buf[2] = (int)KE_CURSORHOLD;
- return 3;
- }
- before_blocking();
+ if (wtime >= 0) {
+ while (WaitForChar(wtime) == 0) { /* no character available */
+ if (!do_resize) /* return if not interrupted by resize */
+ return 0;
+ handle_resize();
+ }
+ } else { /* wtime == -1 */
+ /*
+ * If there is no character available within 'updatetime' seconds
+ * flush all the swap files to disk.
+ * Also done when interrupted by SIGWINCH.
+ */
+ if (WaitForChar(p_ut) == 0) {
+ if (trigger_cursorhold() && maxlen >= 3
+ && !typebuf_changed(tb_change_cnt)) {
+ buf[0] = K_SPECIAL;
+ buf[1] = KS_EXTRA;
+ buf[2] = (int)KE_CURSORHOLD;
+ return 3;
+ }
+ before_blocking();
+ }
}
- }
- for (;; ) { /* repeat until we got a character */
- while (do_resize) /* window changed size */
- handle_resize();
+ for (;; ) { /* repeat until we got a character */
+ while (do_resize) /* window changed size */
+ handle_resize();
- /*
- * We want to be interrupted by the winch signal
- * or by an event on the monitored file descriptors.
- */
- if (WaitForChar(-1L) == 0) {
- if (do_resize) /* interrupted by SIGWINCH signal */
- handle_resize();
- return 0;
- }
+ /*
+ * We want to be interrupted by the winch signal
+ * or by an event on the monitored file descriptors.
+ */
+ if (WaitForChar(-1L) == 0) {
+ if (do_resize) /* interrupted by SIGWINCH signal */
+ handle_resize();
+ return 0;
+ }
- /* If input was put directly in typeahead buffer bail out here. */
- if (typebuf_changed(tb_change_cnt))
- return 0;
+ /* If input was put directly in typeahead buffer bail out here. */
+ if (typebuf_changed(tb_change_cnt))
+ return 0;
- /*
- * For some terminals we only get one character at a time.
- * We want the get all available characters, so we could keep on
- * trying until none is available
- * For some other terminals this is quite slow, that's why we don't do
- * it.
- */
- len = read_from_input_buf(buf, (long)maxlen);
- if (len > 0) {
- return len;
+ /*
+ * For some terminals we only get one character at a time.
+ * We want the get all available characters, so we could keep on
+ * trying until none is available
+ * For some other terminals this is quite slow, that's why we don't do
+ * it.
+ */
+ len = read_from_input_buf(buf, (long)maxlen);
+ if (len > 0) {
+ return len;
+ }
}
- }
}
static void handle_resize() {
@@ -334,105 +338,7 @@ int mch_char_avail() {
return WaitForChar(0L);
}
-#if defined(HAVE_TOTAL_MEM) || defined(PROTO)
-# ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-# endif
-# if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTL)
-# include <sys/sysctl.h>
-# endif
-# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
-# include <sys/sysinfo.h>
-# endif
-
-/*
- * Return total amount of memory available in Kbyte.
- * Doesn't change when memory has been allocated.
- */
-long_u mch_total_mem(special)
-int special UNUSED;
-{
- long_u mem = 0;
- long_u shiftright = 10; /* how much to shift "mem" right for Kbyte */
-
-# ifdef HAVE_SYSCTL
- int mib[2], physmem;
- size_t len;
-
- /* BSD way of getting the amount of RAM available. */
- mib[0] = CTL_HW;
- mib[1] = HW_USERMEM;
- len = sizeof(physmem);
- if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0)
- mem = (long_u)physmem;
-# endif
-
-# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
- if (mem == 0) {
- struct sysinfo sinfo;
-
- /* Linux way of getting amount of RAM available */
- if (sysinfo(&sinfo) == 0) {
-# ifdef HAVE_SYSINFO_MEM_UNIT
- /* avoid overflow as much as possible */
- while (shiftright > 0 && (sinfo.mem_unit & 1) == 0) {
- sinfo.mem_unit = sinfo.mem_unit >> 1;
- --shiftright;
- }
- mem = sinfo.totalram * sinfo.mem_unit;
-# else
- mem = sinfo.totalram;
-# endif
- }
- }
-# endif
-
-# ifdef HAVE_SYSCONF
- if (mem == 0) {
- long pagesize, pagecount;
-
- /* Solaris way of getting amount of RAM available */
- pagesize = sysconf(_SC_PAGESIZE);
- pagecount = sysconf(_SC_PHYS_PAGES);
- if (pagesize > 0 && pagecount > 0) {
- /* avoid overflow as much as possible */
- while (shiftright > 0 && (pagesize & 1) == 0) {
- pagesize = (long_u)pagesize >> 1;
- --shiftright;
- }
- mem = (long_u)pagesize * pagecount;
- }
- }
-# endif
-
- /* Return the minimum of the physical memory and the user limit, because
- * using more than the user limit may cause Vim to be terminated. */
-# if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)
- {
- struct rlimit rlp;
-
- if (getrlimit(RLIMIT_DATA, &rlp) == 0
- && rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1))
-# ifdef RLIM_INFINITY
- && rlp.rlim_cur != RLIM_INFINITY
-# endif
- && ((long_u)rlp.rlim_cur >> 10) < (mem >> shiftright)
- ) {
- mem = (long_u)rlp.rlim_cur;
- shiftright = 10;
- }
- }
-# endif
-
- if (mem > 0)
- return mem >> shiftright;
- return (long_u)0x1fffff;
-}
-#endif
-
-void mch_delay(msec, ignoreinput)
-long msec;
-int ignoreinput;
+void mch_delay(long msec, int ignoreinput)
{
int old_tmode;
@@ -508,8 +414,7 @@ static int stack_grows_downwards;
* Find out if the stack grows upwards or downwards.
* "p" points to a variable on the stack of the caller.
*/
-static void check_stack_growth(p)
-char *p;
+static void check_stack_growth(char *p)
{
int i;
@@ -577,8 +482,7 @@ static void get_stack_limit() {
* Return FAIL when running out of stack space.
* "p" must point to any variable local to the caller that's on the stack.
*/
-int mch_stackcheck(p)
-char *p;
+int mch_stackcheck(char *p)
{
if (stack_limit != NULL) {
if (stack_grows_downwards) {
@@ -1005,9 +909,10 @@ void reset_signals() {
#endif
}
-static void catch_signals(func_deadly, func_other)
-RETSIGTYPE (*func_deadly)();
-RETSIGTYPE (*func_other)();
+static void catch_signals(
+ RETSIGTYPE (*func_deadly)(),
+ RETSIGTYPE (*func_other)()
+ )
{
int i;
@@ -1056,8 +961,7 @@ RETSIGTYPE (*func_other)();
* signal
* Returns TRUE when Vim should exit.
*/
-int vim_handle_signal(sig)
-int sig;
+int vim_handle_signal(int sig)
{
static int got_signal = 0;
static int blocked = TRUE;
@@ -1088,9 +992,7 @@ int sig;
/*
* Check_win checks whether we have an interactive stdout.
*/
-int mch_check_win(argc, argv)
-int argc UNUSED;
-char **argv UNUSED;
+int mch_check_win(int argc, char **argv)
{
if (isatty(1))
return OK;
@@ -1106,14 +1008,12 @@ int mch_input_isatty() {
return FALSE;
}
-static int get_x11_title(test_only)
-int test_only UNUSED;
+static int get_x11_title(int test_only)
{
return FALSE;
}
-static int get_x11_icon(test_only)
-int test_only;
+static int get_x11_icon(int test_only)
{
if (!test_only) {
if (STRNCMP(T_NAME, "builtin_", 8) == 0)
@@ -1136,9 +1036,7 @@ int mch_can_restore_icon() {
/*
* Set the window title and icon.
*/
-void mch_settitle(title, icon)
-char_u *title;
-char_u *icon;
+void mch_settitle(char_u *title, char_u *icon)
{
int type = 0;
static int recursive = 0;
@@ -1195,8 +1093,7 @@ char_u *icon;
* 2 only restore icon
* 3 restore title and icon
*/
-void mch_restore_title(which)
-int which;
+void mch_restore_title(int which)
{
/* only restore the title or icon when it has been set */
mch_settitle(((which & 1) && did_set_title) ?
@@ -1209,8 +1106,7 @@ int which;
* Return TRUE if "name" looks like some xterm name.
* Seiichi Sato mentioned that "mlterm" works like xterm.
*/
-int vim_is_xterm(name)
-char_u *name;
+int vim_is_xterm(char_u *name)
{
if (name == NULL)
return FALSE;
@@ -1227,8 +1123,7 @@ char_u *name;
* known to support the xterm-style mouse protocol.
* Relies on term_is_xterm having been set to its correct value.
*/
-int use_xterm_like_mouse(name)
-char_u *name;
+int use_xterm_like_mouse(char_u *name)
{
return name != NULL
&& (term_is_xterm || STRNICMP(name, "screen", 6) == 0);
@@ -1253,8 +1148,7 @@ int use_xterm_mouse() {
return 0;
}
-int vim_is_iris(name)
-char_u *name;
+int vim_is_iris(char_u *name)
{
if (name == NULL)
return FALSE;
@@ -1262,8 +1156,7 @@ char_u *name;
|| STRCMP(name, "builtin_iris-ansi") == 0;
}
-int vim_is_vt300(name)
-char_u *name;
+int vim_is_vt300(char_u *name)
{
if (name == NULL)
return FALSE; /* actually all ANSI comp. terminals should be here */
@@ -1277,8 +1170,7 @@ char_u *name;
* Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
* This should include all windowed terminal emulators.
*/
-int vim_is_fastterm(name)
-char_u *name;
+int vim_is_fastterm(char_u *name)
{
if (name == NULL)
return FALSE;
@@ -1294,9 +1186,7 @@ char_u *name;
* Insert user name in s[len].
* Return OK if a name found.
*/
-int mch_get_user_name(s, len)
-char_u *s;
-int len;
+int mch_get_user_name(char_u *s, int len)
{
return mch_get_uname(getuid(), s, len);
}
@@ -1305,10 +1195,7 @@ int len;
* Insert user name for "uid" in s[len].
* Return OK if a name found.
*/
-int mch_get_uname(uid, s, len)
-uid_t uid;
-char_u *s;
-int len;
+int mch_get_uname(uid_t uid, char_u *s, int len)
{
#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
struct passwd *pw;
@@ -1328,9 +1215,7 @@ int len;
*/
#ifdef HAVE_SYS_UTSNAME_H
-void mch_get_host_name(s, len)
-char_u *s;
-int len;
+void mch_get_host_name(char_u *s, int len)
{
struct utsname vutsname;
@@ -1345,9 +1230,7 @@ int len;
# define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
# endif
-void mch_get_host_name(s, len)
-char_u *s;
-int len;
+void mch_get_host_name(char_u *s, int len)
{
gethostname((char *)s, len);
s[len - 1] = NUL; /* make sure it's terminated */
@@ -1361,172 +1244,16 @@ long mch_get_pid() {
return (long)getpid();
}
-#if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
-static char *strerror __ARGS((int));
-
-static char * strerror(err)
-int err;
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
- static char er[20];
-
- if (err > 0 && err < sys_nerr)
- return sys_errlist[err];
- sprintf(er, "Error %d", err);
- return er;
-}
-#endif
-
-/*
- * Get name of current directory into buffer 'buf' of length 'len' bytes.
- * Return OK for success, FAIL for failure.
- */
-int mch_dirname(buf, len)
-char_u *buf;
-int len;
-{
-#if defined(USE_GETCWD)
- if (getcwd((char *)buf, len) == NULL) {
- STRCPY(buf, strerror(errno));
- return FAIL;
- }
- return OK;
-#else
- return getwd((char *)buf) != NULL ? OK : FAIL;
-#endif
-}
-
-
-/*
- * Get absolute file name into "buf[len]".
- *
- * return FAIL for failure, OK for success
- */
-int mch_FullName(fname, buf, len, force)
-char_u *fname, *buf;
-int len;
-int force; /* also expand when already absolute path */
-{
- int l;
-#ifdef HAVE_FCHDIR
- int fd = -1;
- static int dont_fchdir = FALSE; /* TRUE when fchdir() doesn't work */
-#endif
- char_u olddir[MAXPATHL];
- char_u *p;
- int retval = OK;
-
-
-
- /* expand it if forced or not an absolute path */
- if (force || !mch_isFullName(fname)) {
- /*
- * If the file name has a path, change to that directory for a moment,
- * and then do the getwd() (and get back to where we were).
- * This will get the correct path name with "../" things.
- */
- if ((p = vim_strrchr(fname, '/')) != NULL) {
-#ifdef HAVE_FCHDIR
- /*
- * Use fchdir() if possible, it's said to be faster and more
- * reliable. But on SunOS 4 it might not work. Check this by
- * doing a fchdir() right now.
- */
- if (!dont_fchdir) {
- fd = open(".", O_RDONLY | O_EXTRA, 0);
- if (fd >= 0 && fchdir(fd) < 0) {
- close(fd);
- fd = -1;
- dont_fchdir = TRUE; /* don't try again */
- }
- }
-#endif
-
- /* Only change directory when we are sure we can return to where
- * we are now. After doing "su" chdir(".") might not work. */
- if (
-#ifdef HAVE_FCHDIR
- fd < 0 &&
-#endif
- (mch_dirname(olddir, MAXPATHL) == FAIL
- || mch_chdir((char *)olddir) != 0)) {
- p = NULL; /* can't get current dir: don't chdir */
- retval = FAIL;
- } else {
- /* The directory is copied into buf[], to be able to remove
- * the file name without changing it (could be a string in
- * read-only memory) */
- if (p - fname >= len)
- retval = FAIL;
- else {
- vim_strncpy(buf, fname, p - fname);
- if (mch_chdir((char *)buf))
- retval = FAIL;
- else
- fname = p + 1;
- *buf = NUL;
- }
- }
- }
- if (mch_dirname(buf, len) == FAIL) {
- retval = FAIL;
- *buf = NUL;
- }
- if (p != NULL) {
-#ifdef HAVE_FCHDIR
- if (fd >= 0) {
- if (p_verbose >= 5) {
- verbose_enter();
- MSG("fchdir() to previous dir");
- verbose_leave();
- }
- l = fchdir(fd);
- close(fd);
- } else
-#endif
- l = mch_chdir((char *)olddir);
- if (l != 0)
- EMSG(_(e_prev_dir));
- }
-
- l = STRLEN(buf);
- if (l >= len - 1)
- retval = FAIL; /* no space for trailing "/" */
- else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
- && STRCMP(fname, ".") != 0)
- STRCAT(buf, "/");
- }
-
- /* Catch file names which are too long. */
- if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
- return FAIL;
-
- /* Do not append ".", "/dir/." is equal to "/dir". */
- if (STRCMP(fname, ".") != 0)
- STRCAT(buf, fname);
-
- return OK;
-}
-
-/*
- * Return TRUE if "fname" does not depend on the current directory.
- */
-int mch_isFullName(fname)
-char_u *fname;
-{
- return *fname == '/' || *fname == '~';
-}
-
#if defined(USE_FNAME_CASE) || defined(PROTO)
/*
* Set the case of the file name, if it already exists. This will cause the
* file name to remain exactly the same.
* Only required for file systems where case is ignored and preserved.
*/
-void fname_case(name, len)
-char_u *name;
-int len UNUSED; /* buffer size, only used when name gets longer */
+void fname_case(
+char_u *name,
+int len; /* buffer size, only used when name gets longer */
+)
{
struct stat st;
char_u *slash, *tail;
@@ -1578,8 +1305,7 @@ int len UNUSED; /* buffer size, only used when name gets longer */
* Get file permissions for 'name'.
* Returns -1 when it doesn't exist.
*/
-long mch_getperm(name)
-char_u *name;
+long mch_getperm(char_u *name)
{
struct stat statb;
@@ -1600,9 +1326,7 @@ char_u *name;
*
* return FAIL for failure, OK otherwise
*/
-int mch_setperm(name, perm)
-char_u *name;
-long perm;
+int mch_setperm(char_u *name, long perm)
{
return chmod((char *)
name,
@@ -1622,9 +1346,7 @@ long perm;
/*
* Copy security info from "from_file" to "to_file".
*/
-void mch_copy_sec(from_file, to_file)
-char_u *from_file;
-char_u *to_file;
+void mch_copy_sec(char_u *from_file, char_u *to_file)
{
if (from_file == NULL)
return;
@@ -1672,8 +1394,7 @@ char_u *to_file;
* Return a pointer to the ACL of file "fname" in allocated memory.
* Return NULL if the ACL is not available for whatever reason.
*/
-vim_acl_T mch_get_acl(fname)
-char_u *fname UNUSED;
+vim_acl_T mch_get_acl(char_u *fname)
{
vim_acl_T ret = NULL;
return ret;
@@ -1682,16 +1403,13 @@ char_u *fname UNUSED;
/*
* Set the ACL of file "fname" to "acl" (unless it's NULL).
*/
-void mch_set_acl(fname, aclent)
-char_u *fname UNUSED;
-vim_acl_T aclent;
+void mch_set_acl(char_u *fname, vim_acl_T aclent)
{
if (aclent == NULL)
return;
}
-void mch_free_acl(aclent)
-vim_acl_T aclent;
+void mch_free_acl(vim_acl_T aclent)
{
if (aclent == NULL)
return;
@@ -1701,8 +1419,7 @@ vim_acl_T aclent;
/*
* Set hidden flag for "name".
*/
-void mch_hide(name)
-char_u *name UNUSED;
+void mch_hide(char_u *name)
{
/* can't hide a file */
}
@@ -1712,8 +1429,7 @@ char_u *name UNUSED;
* return FALSE if "name" is not a directory
* return FALSE for error
*/
-int mch_isdir(name)
-char_u *name;
+int mch_isdir(char_u *name)
{
struct stat statb;
@@ -1733,8 +1449,7 @@ static int executable_file __ARGS((char_u *name));
/*
* Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
*/
-static int executable_file(name)
-char_u *name;
+static int executable_file(char_u *name)
{
struct stat st;
@@ -1747,8 +1462,7 @@ char_u *name;
* Return 1 if "name" can be found in $PATH and executed, 0 if not.
* Return -1 if unknown.
*/
-int mch_can_exe(name)
-char_u *name;
+int mch_can_exe(char_u *name)
{
char_u *buf;
char_u *p, *e;
@@ -1801,8 +1515,7 @@ char_u *name;
* NODE_WRITABLE: writable device, socket, fifo, etc.
* NODE_OTHER: non-writable things
*/
-int mch_nodetype(name)
-char_u *name;
+int mch_nodetype(char_u *name)
{
struct stat st;
@@ -1876,8 +1589,7 @@ static void exit_scroll() {
}
}
-void mch_exit(r)
-int r;
+void mch_exit(int r)
{
exiting = TRUE;
@@ -1934,8 +1646,7 @@ static void may_core_dump() {
}
}
-void mch_settmode(tmode)
-int tmode;
+void mch_settmode(int tmode)
{
static int first = TRUE;
@@ -2196,7 +1907,7 @@ void check_mouse_termcode() {
* set screen mode, always fails.
*/
int mch_screenmode(arg)
-char_u *arg UNUSED;
+char_u *arg;
{
EMSG(_(e_screenmode));
return FAIL;
@@ -3153,7 +2864,7 @@ long msec;
static int RealWaitForChar(fd, msec, check_for_gpm)
int fd;
long msec;
-int *check_for_gpm UNUSED;
+int *check_for_gpm;
{
int ret;
diff --git a/src/os_unix.h b/src/os_unix.h
index f0fc3d5f9a..3a20c49252 100644
--- a/src/os_unix.h
+++ b/src/os_unix.h
@@ -1,372 +1,78 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * NextStep has a problem with configure, undefine a few things:
- */
-
-#include <stdio.h>
-#include <ctype.h>
-
-# include <sys/types.h>
-# include <sys/stat.h>
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-
-
-/* On AIX 4.2 there is a conflicting prototype for ioctl() in stropts.h and
- * unistd.h. This hack should fix that (suggested by Jeff George).
- * But on AIX 4.3 it's alright (suggested by Jake Hamby). */
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_LIBC_H
-# include <libc.h> /* for NeXT */
-#endif
-
-#ifdef HAVE_SYS_PARAM_H
-# include <sys/param.h> /* defines BSD, if it's a BSD system */
-#endif
-
-/*
- * Sun defines FILE on SunOS 4.x.x, Solaris has a typedef for FILE
- */
-
-/*
- * Using getcwd() is preferred, because it checks for a buffer overflow.
- * Don't use getcwd() on systems do use system("sh -c pwd"). There is an
- * autoconf check for this.
- * Use getcwd() anyway if getwd() isn't present.
- */
-#if defined(HAVE_GETCWD) && !(defined(BAD_GETCWD) && defined(HAVE_GETWD))
-# define USE_GETCWD
-#endif
-
-#ifndef __ARGS
-/* The AIX VisualAge cc compiler defines __EXTENDED__ instead of __STDC__
- * because it includes pre-ansi features. */
-# if defined(__STDC__) || defined(__GNUC__) || defined(__EXTENDED__)
-# define __ARGS(x) x
-# else
-# define __ARGS(x) ()
-# endif
-#endif
-
-/* always use unlink() to remove files */
-# define vim_mkdir(x, y) mkdir((char *)(x), y)
-# define mch_rmdir(x) rmdir((char *)(x))
-# define mch_remove(x) unlink((char *)(x))
-
-/* The number of arguments to a signal handler is configured here. */
-/* It used to be a long list of almost all systems. Any system that doesn't
- * have an argument??? */
-#define SIGHASARG
-
-/* List 3 arg systems here. I guess __sgi, please test and correct me. jw. */
-
-#ifdef SIGHASARG
-# ifdef SIGHAS3ARGS
-# define SIGPROTOARG (int, int, struct sigcontext *)
-# define SIGDEFARG(s) (s, sig2, scont) int s, sig2; struct sigcontext *scont;
-# define SIGDUMMYARG 0, 0, (struct sigcontext *)0
-# else
-# define SIGPROTOARG (int)
-# define SIGDEFARG(s) (s) int s UNUSED;
-# define SIGDUMMYARG 0
-# endif
-#else
-# define SIGPROTOARG (void)
-# define SIGDEFARG(s) ()
-# define SIGDUMMYARG
-#endif
-
-#ifdef HAVE_DIRENT_H
-# include <dirent.h>
-# ifndef NAMLEN
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-# endif
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-#if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
-# include <time.h> /* on some systems time.h should not be
- included together with sys/time.h */
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-
-#include <signal.h>
-
-#if defined(DIRSIZ) && !defined(MAXNAMLEN)
-# define MAXNAMLEN DIRSIZ
-#endif
-
-#if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN)
-# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */
-#endif
-
-#if defined(NAME_MAX) && !defined(MAXNAMLEN)
-# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */
-#endif
-
-/*
- * Note: if MAXNAMLEN has the wrong value, you will get error messages
- * for not being able to open the swap file.
- */
-#if !defined(MAXNAMLEN)
-# define MAXNAMLEN 512 /* for all other Unix */
-#endif
-
-#define BASENAMELEN (MAXNAMLEN - 5)
-
-#ifdef HAVE_PWD_H
-# include <pwd.h>
-#endif
-
-#ifdef __COHERENT__
-# undef __ARGS
-#endif
-
-#if (defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)) \
- || (defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)) \
- || defined(HAVE_SYSCTL) || defined(HAVE_SYSCONF)
-# define HAVE_TOTAL_MEM
-#endif
-
-
-
-
-
-
-/*
- * Unix system-dependent file names
- */
-#ifndef SYS_VIMRC_FILE
-# define SYS_VIMRC_FILE "$VIM/vimrc"
-#endif
-#ifndef SYS_GVIMRC_FILE
-# define SYS_GVIMRC_FILE "$VIM/gvimrc"
-#endif
-#ifndef DFLT_HELPFILE
-# define DFLT_HELPFILE "$VIMRUNTIME/doc/help.txt"
-#endif
-#ifndef FILETYPE_FILE
-# define FILETYPE_FILE "filetype.vim"
-#endif
-#ifndef FTPLUGIN_FILE
-# define FTPLUGIN_FILE "ftplugin.vim"
-#endif
-#ifndef INDENT_FILE
-# define INDENT_FILE "indent.vim"
-#endif
-#ifndef FTOFF_FILE
-# define FTOFF_FILE "ftoff.vim"
-#endif
-#ifndef FTPLUGOF_FILE
-# define FTPLUGOF_FILE "ftplugof.vim"
-#endif
-#ifndef INDOFF_FILE
-# define INDOFF_FILE "indoff.vim"
-#endif
-#ifndef SYS_MENU_FILE
-# define SYS_MENU_FILE "$VIMRUNTIME/menu.vim"
-#endif
-
-#ifndef USR_EXRC_FILE
-# define USR_EXRC_FILE "$HOME/.exrc"
-#endif
-
-
-#ifndef USR_VIMRC_FILE
-# define USR_VIMRC_FILE "$HOME/.vimrc"
-#endif
-
-
-#if !defined(USR_EXRC_FILE2)
-# define USR_VIMRC_FILE2 "~/.vim/vimrc"
-#endif
-
-
-#ifndef USR_GVIMRC_FILE
-# define USR_GVIMRC_FILE "$HOME/.gvimrc"
-#endif
-
-#ifndef USR_GVIMRC_FILE2
-# define USR_GVIMRC_FILE2 "~/.vim/gvimrc"
-#endif
-
-
-#ifndef EVIM_FILE
-# define EVIM_FILE "$VIMRUNTIME/evim.vim"
-#endif
-
-# ifndef VIMINFO_FILE
-# define VIMINFO_FILE "$HOME/.viminfo"
-# endif
-
-#ifndef EXRC_FILE
-# define EXRC_FILE ".exrc"
-#endif
-
-#ifndef VIMRC_FILE
-# define VIMRC_FILE ".vimrc"
-#endif
-
-
-#ifndef SYNTAX_FNAME
-# define SYNTAX_FNAME "$VIMRUNTIME/syntax/%s.vim"
-#endif
-
-#ifndef DFLT_BDIR
-# define DFLT_BDIR ".,~/tmp,~/" /* default for 'backupdir' */
-#endif
-
-#ifndef DFLT_DIR
-# define DFLT_DIR ".,~/tmp,/var/tmp,/tmp" /* default for 'directory' */
-#endif
-
-#ifndef DFLT_VDIR
-# define DFLT_VDIR "$HOME/.vim/view" /* default for 'viewdir' */
-#endif
-
-#define DFLT_ERRORFILE "errors.err"
-
-# ifdef RUNTIME_GLOBAL
-# define DFLT_RUNTIMEPATH "~/.vim," RUNTIME_GLOBAL ",$VIMRUNTIME," \
- RUNTIME_GLOBAL "/after,~/.vim/after"
-# else
-# define DFLT_RUNTIMEPATH \
- "~/.vim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.vim/after"
-# endif
-
-# define TEMPDIRNAMES "$TMPDIR", "/tmp", ".", "$HOME"
-# define TEMPNAMELEN 256
-
-/* Special wildcards that need to be handled by the shell */
-#define SPECIAL_WILDCHAR "`'{"
-
-#ifndef HAVE_OPENDIR
-# define NO_EXPANDPATH
-#endif
-
-/*
- * Unix has plenty of memory, use large buffers
- */
-#define CMDBUFFSIZE 1024 /* size of the command processing buffer */
-
-/* Use the system path length if it makes sense. */
-#if defined(PATH_MAX) && (PATH_MAX > 1000)
-# define MAXPATHL PATH_MAX
-#else
-# define MAXPATHL 1024
-#endif
-
-#define CHECK_INODE /* used when checking if a swap file already
- exists for a file */
-# ifndef DFLT_MAXMEM
-# define DFLT_MAXMEM (5*1024) /* use up to 5 Mbyte for a buffer */
-# endif
-# ifndef DFLT_MAXMEMTOT
-# define DFLT_MAXMEMTOT (10*1024) /* use up to 10 Mbyte for Vim */
-# endif
-
-/* memmove is not present on all systems, use memmove, bcopy, memcpy or our
- * own version */
-/* Some systems have (void *) arguments, some (char *). If we use (char *) it
- * works for all */
-#ifdef USEMEMMOVE
-# define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
-#else
-# ifdef USEBCOPY
-# define mch_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
-# else
-# ifdef USEMEMCPY
-# define mch_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
-# else
-# define VIM_MEMMOVE /* found in misc2.c */
-# endif
-# endif
-#endif
-
-# ifdef HAVE_RENAME
-# define mch_rename(src, dst) rename(src, dst)
-# else
-int mch_rename __ARGS((const char *src, const char *dest));
-# endif
-# ifdef __MVS__
-/* on OS390 Unix getenv() doesn't return a pointer to persistent
- * storage -> use __getenv() */
-# define mch_getenv(x) (char_u *)__getenv((char *)(x))
-# else
-# define mch_getenv(x) (char_u *)getenv((char *)(x))
-# endif
-# define mch_setenv(name, val, x) setenv(name, val, x)
-
-#if !defined(S_ISDIR) && defined(S_IFDIR)
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#endif
-#if !defined(S_ISREG) && defined(S_IFREG)
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-#if !defined(S_ISBLK) && defined(S_IFBLK)
-# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#endif
-#if !defined(S_ISSOCK) && defined(S_IFSOCK)
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-#endif
-#if !defined(S_ISFIFO) && defined(S_IFIFO)
-# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#endif
-#if !defined(S_ISCHR) && defined(S_IFCHR)
-# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#endif
-
-/* Note: Some systems need both string.h and strings.h (Savage). However,
- * some systems can't handle both, only use string.h in that case. */
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
-# include <strings.h>
-#endif
-
-#if defined(HAVE_SETJMP_H)
-# include <setjmp.h>
-# ifdef HAVE_SIGSETJMP
-# define JMP_BUF sigjmp_buf
-# define SETJMP(x) sigsetjmp((x), 1)
-# define LONGJMP siglongjmp
-# else
-# define JMP_BUF jmp_buf
-# define SETJMP(x) setjmp(x)
-# define LONGJMP longjmp
-# endif
-#endif
-
-#define HAVE_DUP /* have dup() */
-#define HAVE_ST_MODE /* have stat.st_mode */
-
-/* We have three kinds of ACL support. */
-#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL || HAVE_AIX_ACL)
+#ifndef NEOVIM_OS_UNIX_H
+#define NEOVIM_OS_UNIX_H
+/* os_unix.c */
+void mch_write __ARGS((char_u *s, int len));
+int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
+int mch_char_avail __ARGS((void));
+void mch_delay __ARGS((long msec, int ignoreinput));
+int mch_stackcheck __ARGS((char *p));
+void mch_startjmp __ARGS((void));
+void mch_endjmp __ARGS((void));
+void mch_didjmp __ARGS((void));
+void mch_suspend __ARGS((void));
+void mch_init __ARGS((void));
+void reset_signals __ARGS((void));
+int vim_handle_signal __ARGS((int sig));
+int mch_check_win __ARGS((int argc, char **argv));
+int mch_input_isatty __ARGS((void));
+int mch_can_restore_title __ARGS((void));
+int mch_can_restore_icon __ARGS((void));
+void mch_settitle __ARGS((char_u *title, char_u *icon));
+void mch_restore_title __ARGS((int which));
+int vim_is_xterm __ARGS((char_u *name));
+int use_xterm_like_mouse __ARGS((char_u *name));
+int use_xterm_mouse __ARGS((void));
+int vim_is_iris __ARGS((char_u *name));
+int vim_is_vt300 __ARGS((char_u *name));
+int vim_is_fastterm __ARGS((char_u *name));
+int mch_get_user_name __ARGS((char_u *s, int len));
+int mch_get_uname __ARGS((uid_t uid, char_u *s, int len));
+void mch_get_host_name __ARGS((char_u *s, int len));
+long mch_get_pid __ARGS((void));
+void slash_adjust __ARGS((char_u *p));
+void fname_case __ARGS((char_u *name, int len));
+long mch_getperm __ARGS((char_u *name));
+int mch_setperm __ARGS((char_u *name, long perm));
+void mch_copy_sec __ARGS((char_u *from_file, char_u *to_file));
+vim_acl_T mch_get_acl __ARGS((char_u *fname));
+void mch_set_acl __ARGS((char_u *fname, vim_acl_T aclent));
+void mch_free_acl __ARGS((vim_acl_T aclent));
+void mch_hide __ARGS((char_u *name));
+int mch_isdir __ARGS((char_u *name));
+int mch_can_exe __ARGS((char_u *name));
+int mch_nodetype __ARGS((char_u *name));
+void mch_early_init __ARGS((void));
+void mch_free_mem __ARGS((void));
+void mch_exit __ARGS((int r));
+void mch_settmode __ARGS((int tmode));
+void get_stty __ARGS((void));
+void mch_setmouse __ARGS((int on));
+void check_mouse_termcode __ARGS((void));
+int mch_screenmode __ARGS((char_u *arg));
+int mch_get_shellsize __ARGS((void));
+void mch_set_shellsize __ARGS((void));
+void mch_new_shellsize __ARGS((void));
+int mch_call_shell __ARGS((char_u *cmd, int options));
+void mch_breakcheck __ARGS((void));
+int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags));
+int mch_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file,
+ char_u ***file,
+ int flags));
+int mch_has_exp_wildcard __ARGS((char_u *p));
+int mch_has_wildcard __ARGS((char_u *p));
+int mch_libcall __ARGS((char_u *libname, char_u *funcname, char_u *argstring,
+ int argint, char_u **string_result,
+ int *number_result));
+void setup_term_clip __ARGS((void));
+void start_xterm_trace __ARGS((int button));
+void stop_xterm_trace __ARGS((void));
+void clear_xterm_clip __ARGS((void));
+int clip_xterm_own_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_lose_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_request_selection __ARGS((VimClipboard *cbd));
+void clip_xterm_set_selection __ARGS((VimClipboard *cbd));
+int xsmp_handle_requests __ARGS((void));
+void xsmp_init __ARGS((void));
+void xsmp_close __ARGS((void));
+/* vim: set ft=c : */
+#endif /* NEOVIM_OS_UNIX_H */
diff --git a/src/os_unix_defs.h b/src/os_unix_defs.h
new file mode 100644
index 0000000000..3eb79e9a25
--- /dev/null
+++ b/src/os_unix_defs.h
@@ -0,0 +1,351 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * NextStep has a problem with configure, undefine a few things:
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+# include <sys/types.h>
+# include <sys/stat.h>
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+
+
+/* On AIX 4.2 there is a conflicting prototype for ioctl() in stropts.h and
+ * unistd.h. This hack should fix that (suggested by Jeff George).
+ * But on AIX 4.3 it's alright (suggested by Jake Hamby). */
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_LIBC_H
+# include <libc.h> /* for NeXT */
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h> /* defines BSD, if it's a BSD system */
+#endif
+
+/*
+ * Sun defines FILE on SunOS 4.x.x, Solaris has a typedef for FILE
+ */
+
+#ifndef __ARGS
+/* The AIX VisualAge cc compiler defines __EXTENDED__ instead of __STDC__
+ * because it includes pre-ansi features. */
+# if defined(__STDC__) || defined(__GNUC__) || defined(__EXTENDED__)
+# define __ARGS(x) x
+# else
+# define __ARGS(x) ()
+# endif
+#endif
+
+/* always use unlink() to remove files */
+# define vim_mkdir(x, y) mkdir((char *)(x), y)
+# define mch_rmdir(x) rmdir((char *)(x))
+# define mch_remove(x) unlink((char *)(x))
+
+/* The number of arguments to a signal handler is configured here. */
+/* It used to be a long list of almost all systems. Any system that doesn't
+ * have an argument??? */
+#define SIGHASARG
+
+/* List 3 arg systems here. I guess __sgi, please test and correct me. jw. */
+
+#ifdef SIGHASARG
+# ifdef SIGHAS3ARGS
+# define SIGPROTOARG (int, int, struct sigcontext *)
+# define SIGDEFARG(s) (s, sig2, scont) int s, sig2; struct sigcontext *scont;
+# define SIGDUMMYARG 0, 0, (struct sigcontext *)0
+# else
+# define SIGPROTOARG (int)
+# define SIGDEFARG(s) (s) int s;
+# define SIGDUMMYARG 0
+# endif
+#else
+# define SIGPROTOARG (void)
+# define SIGDEFARG(s) ()
+# define SIGDUMMYARG
+#endif
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# ifndef NAMLEN
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+# endif
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
+# include <time.h> /* on some systems time.h should not be
+ included together with sys/time.h */
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <signal.h>
+
+#if defined(DIRSIZ) && !defined(MAXNAMLEN)
+# define MAXNAMLEN DIRSIZ
+#endif
+
+#if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN)
+# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */
+#endif
+
+#if defined(NAME_MAX) && !defined(MAXNAMLEN)
+# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */
+#endif
+
+/*
+ * Note: if MAXNAMLEN has the wrong value, you will get error messages
+ * for not being able to open the swap file.
+ */
+#if !defined(MAXNAMLEN)
+# define MAXNAMLEN 512 /* for all other Unix */
+#endif
+
+#define BASENAMELEN (MAXNAMLEN - 5)
+
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+
+#ifdef __COHERENT__
+# undef __ARGS
+#endif
+
+/*
+ * Unix system-dependent file names
+ */
+#ifndef SYS_VIMRC_FILE
+# define SYS_VIMRC_FILE "$VIM/vimrc"
+#endif
+#ifndef SYS_GVIMRC_FILE
+# define SYS_GVIMRC_FILE "$VIM/gvimrc"
+#endif
+#ifndef DFLT_HELPFILE
+# define DFLT_HELPFILE "$VIMRUNTIME/doc/help.txt"
+#endif
+#ifndef FILETYPE_FILE
+# define FILETYPE_FILE "filetype.vim"
+#endif
+#ifndef FTPLUGIN_FILE
+# define FTPLUGIN_FILE "ftplugin.vim"
+#endif
+#ifndef INDENT_FILE
+# define INDENT_FILE "indent.vim"
+#endif
+#ifndef FTOFF_FILE
+# define FTOFF_FILE "ftoff.vim"
+#endif
+#ifndef FTPLUGOF_FILE
+# define FTPLUGOF_FILE "ftplugof.vim"
+#endif
+#ifndef INDOFF_FILE
+# define INDOFF_FILE "indoff.vim"
+#endif
+#ifndef SYS_MENU_FILE
+# define SYS_MENU_FILE "$VIMRUNTIME/menu.vim"
+#endif
+
+#ifndef USR_EXRC_FILE
+# define USR_EXRC_FILE "$HOME/.exrc"
+#endif
+
+
+#ifndef USR_VIMRC_FILE
+# define USR_VIMRC_FILE "$HOME/.neovimrc"
+#endif
+
+
+#if !defined(USR_EXRC_FILE2)
+# define USR_VIMRC_FILE2 "~/.neovim/vimrc"
+#endif
+
+
+#ifndef USR_GVIMRC_FILE
+# define USR_GVIMRC_FILE "$HOME/.neogvimrc"
+#endif
+
+#ifndef USR_GVIMRC_FILE2
+# define USR_GVIMRC_FILE2 "~/.neovim/gvimrc"
+#endif
+
+
+#ifndef EVIM_FILE
+# define EVIM_FILE "$VIMRUNTIME/evim.vim"
+#endif
+
+# ifndef VIMINFO_FILE
+# define VIMINFO_FILE "$HOME/.neoviminfo"
+# endif
+
+#ifndef EXRC_FILE
+# define EXRC_FILE ".exrc"
+#endif
+
+#ifndef VIMRC_FILE
+# define VIMRC_FILE ".neovimrc"
+#endif
+
+
+#ifndef SYNTAX_FNAME
+# define SYNTAX_FNAME "$VIMRUNTIME/syntax/%s.vim"
+#endif
+
+#ifndef DFLT_BDIR
+# define DFLT_BDIR ".,~/tmp,~/" /* default for 'backupdir' */
+#endif
+
+#ifndef DFLT_DIR
+# define DFLT_DIR ".,~/tmp,/var/tmp,/tmp" /* default for 'directory' */
+#endif
+
+#ifndef DFLT_VDIR
+# define DFLT_VDIR "$HOME/.neovim/view" /* default for 'viewdir' */
+#endif
+
+#define DFLT_ERRORFILE "errors.err"
+
+# ifdef RUNTIME_GLOBAL
+# define DFLT_RUNTIMEPATH "~/.neovim," RUNTIME_GLOBAL ",$VIMRUNTIME," \
+ RUNTIME_GLOBAL "/after,~/.neovim/after"
+# else
+# define DFLT_RUNTIMEPATH \
+ "~/.neovim,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after,~/.neovim/after"
+# endif
+
+# define TEMPDIRNAMES "$TMPDIR", "/tmp", ".", "$HOME"
+# define TEMPNAMELEN 256
+
+/* Special wildcards that need to be handled by the shell */
+#define SPECIAL_WILDCHAR "`'{"
+
+#ifndef HAVE_OPENDIR
+# define NO_EXPANDPATH
+#endif
+
+/*
+ * Unix has plenty of memory, use large buffers
+ */
+#define CMDBUFFSIZE 1024 /* size of the command processing buffer */
+
+/* Use the system path length if it makes sense. */
+#if defined(PATH_MAX) && (PATH_MAX > 1000)
+# define MAXPATHL PATH_MAX
+#else
+# define MAXPATHL 1024
+#endif
+
+#define CHECK_INODE /* used when checking if a swap file already
+ exists for a file */
+# ifndef DFLT_MAXMEM
+# define DFLT_MAXMEM (5*1024) /* use up to 5 Mbyte for a buffer */
+# endif
+# ifndef DFLT_MAXMEMTOT
+# define DFLT_MAXMEMTOT (10*1024) /* use up to 10 Mbyte for Vim */
+# endif
+
+/* memmove is not present on all systems, use memmove, bcopy, memcpy or our
+ * own version */
+/* Some systems have (void *) arguments, some (char *). If we use (char *) it
+ * works for all */
+#ifdef USEMEMMOVE
+# define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
+#else
+# ifdef USEBCOPY
+# define mch_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
+# else
+# ifdef USEMEMCPY
+# define mch_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
+# else
+# define VIM_MEMMOVE /* found in misc2.c */
+# endif
+# endif
+#endif
+
+# ifdef HAVE_RENAME
+# define mch_rename(src, dst) rename(src, dst)
+# else
+int mch_rename __ARGS((const char *src, const char *dest));
+# endif
+# ifdef __MVS__
+/* on OS390 Unix getenv() doesn't return a pointer to persistent
+ * storage -> use __getenv() */
+# define mch_getenv(x) (char_u *)__getenv((char *)(x))
+# else
+# define mch_getenv(x) (char_u *)getenv((char *)(x))
+# endif
+# define mch_setenv(name, val, x) setenv(name, val, x)
+
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISBLK) && defined(S_IFBLK)
+# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFIFO)
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#endif
+
+/* Note: Some systems need both string.h and strings.h (Savage). However,
+ * some systems can't handle both, only use string.h in that case. */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
+# include <strings.h>
+#endif
+
+#if defined(HAVE_SETJMP_H)
+# include <setjmp.h>
+# ifdef HAVE_SIGSETJMP
+# define JMP_BUF sigjmp_buf
+# define SETJMP(x) sigsetjmp((x), 1)
+# define LONGJMP siglongjmp
+# else
+# define JMP_BUF jmp_buf
+# define SETJMP(x) setjmp(x)
+# define LONGJMP longjmp
+# endif
+#endif
+
+#define HAVE_DUP /* have dup() */
+#define HAVE_ST_MODE /* have stat.st_mode */
+
+/* We have three kinds of ACL support. */
+#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL || HAVE_AIX_ACL)
diff --git a/src/po/Makefile b/src/po/Makefile
index 8674031d84..d702b9f277 100644
--- a/src/po/Makefile
+++ b/src/po/Makefile
@@ -125,9 +125,9 @@ CHECKFILES = \
uk.cp1251.ck \
zh_CN.cp936.ck
-PACKAGE = vim
+PACKAGE = nvim
SHELL = /bin/sh
-VIM = ../../build/src/vim
+VIM = ../../build/bin/nvim
# The OLD_PO_FILE_INPUT and OLD_PO_FILE_OUTPUT are for the new GNU gettext
# tools 0.10.37, which use a slightly different .po file format that is not
diff --git a/src/po/sjiscorr.c b/src/po/sjiscorr.c
index fec4740c04..6976ed8b9e 100644
--- a/src/po/sjiscorr.c
+++ b/src/po/sjiscorr.c
@@ -1,15 +1,4 @@
-/*
- * Simplistic program to correct SJIS inside strings. When a trail byte is a
- * backslash it needs to be doubled.
- * Public domain.
- */
-#include <stdio.h>
-#include <string.h>
-
- int
-main(argc, argv)
- int argc;
- char **argv;
+__END_DECLS int main(int argc, char **argv)
{
char buffer[BUFSIZ];
char *p;
diff --git a/src/popupmnu.c b/src/popupmnu.c
index ff28fc2676..293e1f0bb2 100644
--- a/src/popupmnu.c
+++ b/src/popupmnu.c
@@ -11,7 +11,16 @@
* popupmnu.c: Popup menu (PUM)
*/
#include "vim.h"
-
+#include "popupmnu.h"
+#include "charset.h"
+#include "ex_cmds.h"
+#include "memline.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "screen.h"
+#include "search.h"
+#include "window.h"
static pumitem_T *pum_array = NULL; /* items of displayed pum */
static int pum_size; /* nr of items in "pum_array" */
@@ -40,11 +49,13 @@ static int pum_set_selected __ARGS((int n, int repeat));
* When possible the leftmost character is aligned with screen column "col".
* The menu appears above the screen line "row" or at "row" + "height" - 1.
*/
-void pum_display(array, size, selected)
-pumitem_T *array;
-int size;
-int selected; /* index of initially selected item, none if
+void
+pum_display (
+ pumitem_T *array,
+ int size,
+ int selected /* index of initially selected item, none if
out of range */
+)
{
int w;
int def_width;
@@ -231,7 +242,7 @@ redo:
/*
* Redraw the popup menu, using "pum_first" and "pum_selected".
*/
-void pum_redraw() {
+void pum_redraw(void) {
int row = pum_row;
int col;
int attr_norm = highlight_attr[HLF_PNI];
@@ -415,9 +426,7 @@ void pum_redraw() {
* Returns TRUE when the window was resized and the location of the popup menu
* must be recomputed.
*/
-static int pum_set_selected(n, repeat)
-int n;
-int repeat;
+static int pum_set_selected(int n, int repeat)
{
int resized = FALSE;
int context = pum_height / 2;
@@ -584,7 +593,7 @@ int repeat;
/*
* Undisplay the popup menu (later).
*/
-void pum_undisplay() {
+void pum_undisplay(void) {
pum_array = NULL;
redraw_all_later(SOME_VALID);
redraw_tabline = TRUE;
@@ -595,7 +604,7 @@ void pum_undisplay() {
* Clear the popup menu. Currently only resets the offset to the first
* displayed item.
*/
-void pum_clear() {
+void pum_clear(void) {
pum_first = 0;
}
@@ -603,7 +612,7 @@ void pum_clear() {
* Return TRUE if the popup menu is displayed.
* Overruled when "pum_do_redraw" is set, used to redraw the status lines.
*/
-int pum_visible() {
+int pum_visible(void) {
return !pum_do_redraw && pum_array != NULL;
}
@@ -611,7 +620,7 @@ int pum_visible() {
* Return the height of the popup menu, the number of entries visible.
* Only valid when pum_visible() returns TRUE!
*/
-int pum_get_height() {
+int pum_get_height(void) {
return pum_height;
}
diff --git a/src/proto/popupmnu.pro b/src/popupmnu.h
index 74a53e2f0e..8a619fdb36 100644
--- a/src/proto/popupmnu.pro
+++ b/src/popupmnu.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_POPUPMNU_H
+#define NEOVIM_POPUPMNU_H
/* popupmnu.c */
void pum_display __ARGS((pumitem_T *array, int size, int selected));
void pum_redraw __ARGS((void));
@@ -6,3 +8,4 @@ void pum_clear __ARGS((void));
int pum_visible __ARGS((void));
int pum_get_height __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_POPUPMNU_H */
diff --git a/src/proto.h b/src/proto.h
index b040ff70cc..5037dfa26f 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -26,35 +26,6 @@
# define GdkEventKey int
# define XImage int
-# if defined(UNIX) || defined(__EMX__) || defined(VMS)
-# include "os_unix.pro"
-# endif
-
-# include "blowfish.pro"
-# include "buffer.pro"
-# include "charset.pro"
-# include "if_cscope.pro"
-# include "diff.pro"
-# include "digraph.pro"
-# include "edit.pro"
-# include "eval.pro"
-# include "ex_cmds.pro"
-# include "ex_cmds2.pro"
-# include "ex_docmd.pro"
-# include "ex_eval.pro"
-# include "ex_getln.pro"
-# include "fileio.pro"
-# include "fold.pro"
-# include "getchar.pro"
-# include "hangulin.pro"
-# include "hardcopy.pro"
-# include "hashtab.pro"
-# include "main.pro"
-# include "mark.pro"
-# include "memfile.pro"
-# include "memline.pro"
-# include "menu.pro"
-
# if !defined MESSAGE_FILE || defined(HAVE_STDARG_H)
/* These prototypes cannot be produced automatically and conflict with
* the old-style prototypes in message.c. */
@@ -75,9 +46,6 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
# endif
# endif
-# include "message.pro"
-# include "misc1.pro"
-# include "misc2.pro"
#ifndef HAVE_STRPBRK /* not generated automatically from misc2.c */
char_u *vim_strpbrk __ARGS((char_u *s, char_u *charset));
#endif
@@ -86,52 +54,9 @@ char_u *vim_strpbrk __ARGS((char_u *s, char_u *charset));
void qsort __ARGS((void *base, size_t elm_count, size_t elm_size, int (*cmp)(
const void *, const void *)));
#endif
-# include "move.pro"
-# if defined(FEAT_MBYTE) || defined(FEAT_XIM) || defined(FEAT_KEYMAP) \
- || defined(FEAT_POSTSCRIPT)
-# include "mbyte.pro"
-# endif
-# include "normal.pro"
-# include "ops.pro"
-# include "option.pro"
-# include "popupmnu.pro"
-# include "quickfix.pro"
-# include "regexp.pro"
-# include "screen.pro"
-# include "sha256.pro"
-# include "search.pro"
-# include "spell.pro"
-# include "syntax.pro"
-# include "tag.pro"
-# include "term.pro"
-# include "ui.pro"
-# include "undo.pro"
-# include "version.pro"
-# include "window.pro"
-
-
-
-
-
-
/* Ugly solution for "BalloonEval" not being defined while it's used in some
* .pro files. */
# define BalloonEval int
-
-
-# ifdef FEAT_OLE
-# endif
-
-/*
- * The perl include files pollute the namespace, therefore proto.h must be
- * included before the perl include files. But then CV is not defined, which
- * not included here for the perl files. Use a dummy define for CV for the
- * other files.
- */
-
-#ifdef MACOS_CONVERT
-#endif
-
#endif /* !PROTO && !NOPROTO */
diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro
deleted file mode 100644
index 6d566e7f05..0000000000
--- a/src/proto/ex_cmds.pro
+++ /dev/null
@@ -1,72 +0,0 @@
-/* ex_cmds.c */
-void do_ascii __ARGS((exarg_T *eap));
-void ex_align __ARGS((exarg_T *eap));
-void ex_sort __ARGS((exarg_T *eap));
-void ex_retab __ARGS((exarg_T *eap));
-int do_move __ARGS((linenr_T line1, linenr_T line2, linenr_T dest));
-void ex_copy __ARGS((linenr_T line1, linenr_T line2, linenr_T n));
-void free_prev_shellcmd __ARGS((void));
-void do_bang __ARGS((int addr_count, exarg_T *eap, int forceit, int do_in,
- int do_out));
-void do_shell __ARGS((char_u *cmd, int flags));
-char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp));
-void append_redir __ARGS((char_u *buf, int buflen, char_u *opt, char_u *fname));
-int viminfo_error __ARGS((char *errnum, char *message, char_u *line));
-int read_viminfo __ARGS((char_u *file, int flags));
-void write_viminfo __ARGS((char_u *file, int forceit));
-int viminfo_readline __ARGS((vir_T *virp));
-char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
-void viminfo_writestring __ARGS((FILE *fd, char_u *p));
-void do_fixdel __ARGS((exarg_T *eap));
-void print_line_no_prefix __ARGS((linenr_T lnum, int use_number, int list));
-void print_line __ARGS((linenr_T lnum, int use_number, int list));
-int rename_buffer __ARGS((char_u *new_fname));
-void ex_file __ARGS((exarg_T *eap));
-void ex_update __ARGS((exarg_T *eap));
-void ex_write __ARGS((exarg_T *eap));
-int do_write __ARGS((exarg_T *eap));
-int check_overwrite __ARGS((exarg_T *eap, buf_T *buf, char_u *fname, char_u *
- ffname,
- int other));
-void ex_wnext __ARGS((exarg_T *eap));
-void do_wqall __ARGS((exarg_T *eap));
-int not_writing __ARGS((void));
-int getfile __ARGS((int fnum, char_u *ffname, char_u *sfname, int setpm,
- linenr_T lnum,
- int forceit));
-int do_ecmd __ARGS((int fnum, char_u *ffname, char_u *sfname, exarg_T *eap,
- linenr_T newlnum, int flags,
- win_T *oldwin));
-void ex_append __ARGS((exarg_T *eap));
-void ex_change __ARGS((exarg_T *eap));
-void ex_z __ARGS((exarg_T *eap));
-int check_restricted __ARGS((void));
-int check_secure __ARGS((void));
-void do_sub __ARGS((exarg_T *eap));
-int do_sub_msg __ARGS((int count_only));
-void ex_global __ARGS((exarg_T *eap));
-void global_exe __ARGS((char_u *cmd));
-int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
-void write_viminfo_sub_string __ARGS((FILE *fp));
-void free_old_sub __ARGS((void));
-int prepare_tagpreview __ARGS((int undo_sync));
-void ex_help __ARGS((exarg_T *eap));
-char_u *check_help_lang __ARGS((char_u *arg));
-int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case));
-int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches,
- int keep_lang));
-void fix_help_buffer __ARGS((void));
-void ex_exusage __ARGS((exarg_T *eap));
-void ex_viusage __ARGS((exarg_T *eap));
-void ex_helptags __ARGS((exarg_T *eap));
-void ex_sign __ARGS((exarg_T *eap));
-void sign_gui_started __ARGS((void));
-int sign_get_attr __ARGS((int typenr, int line));
-char_u *sign_get_text __ARGS((int typenr));
-void *sign_get_image __ARGS((int typenr));
-char_u *sign_typenr2name __ARGS((int typenr));
-void free_signs __ARGS((void));
-char_u *get_sign_name __ARGS((expand_T *xp, int idx));
-void set_context_in_sign_cmd __ARGS((expand_T *xp, char_u *arg));
-void ex_drop __ARGS((exarg_T *eap));
-/* vim: set ft=c : */
diff --git a/src/proto/if_cscope.pro b/src/proto/if_cscope.pro
deleted file mode 100644
index 1239835d79..0000000000
--- a/src/proto/if_cscope.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-/* if_cscope.c */
-char_u *get_cscope_name __ARGS((expand_T *xp, int idx));
-void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg,
- cmdidx_T cmdidx));
-void do_cscope __ARGS((exarg_T *eap));
-void do_scscope __ARGS((exarg_T *eap));
-void do_cstag __ARGS((exarg_T *eap));
-int cs_fgets __ARGS((char_u *buf, int size));
-void cs_free_tags __ARGS((void));
-void cs_print_tags __ARGS((void));
-int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
-void cs_end __ARGS((void));
-/* vim: set ft=c : */
diff --git a/src/proto/option.pro b/src/proto/option.pro
deleted file mode 100644
index 00aa74d34a..0000000000
--- a/src/proto/option.pro
+++ /dev/null
@@ -1,74 +0,0 @@
-/* option.c */
-void set_init_1 __ARGS((void));
-void set_string_default __ARGS((char *name, char_u *val));
-void set_number_default __ARGS((char *name, long val));
-void free_all_options __ARGS((void));
-void set_init_2 __ARGS((void));
-void set_init_3 __ARGS((void));
-void set_helplang_default __ARGS((char_u *lang));
-void init_gui_options __ARGS((void));
-void set_title_defaults __ARGS((void));
-int do_set __ARGS((char_u *arg, int opt_flags));
-void set_options_bin __ARGS((int oldval, int newval, int opt_flags));
-int get_viminfo_parameter __ARGS((int type));
-char_u *find_viminfo_parameter __ARGS((int type));
-void check_options __ARGS((void));
-void check_buf_options __ARGS((buf_T *buf));
-void free_string_option __ARGS((char_u *p));
-void clear_string_option __ARGS((char_u **pp));
-void set_term_option_alloced __ARGS((char_u **p));
-int was_set_insecurely __ARGS((char_u *opt, int opt_flags));
-void set_string_option_direct __ARGS((char_u *name, int opt_idx, char_u *val,
- int opt_flags,
- int set_sid));
-char_u *check_colorcolumn __ARGS((win_T *wp));
-char_u *check_stl_option __ARGS((char_u *s));
-int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval,
- int opt_flags));
-int get_option_value_strict __ARGS((char_u *name, long *numval, char_u *
- *stringval, int opt_type,
- void *from));
-char_u *option_iter_next __ARGS((void **option, int opt_type));
-char_u *set_option_value __ARGS((char_u *name, long number, char_u *string,
- int opt_flags));
-char_u *get_term_code __ARGS((char_u *tname));
-char_u *get_highlight_default __ARGS((void));
-char_u *get_encoding_default __ARGS((void));
-int makeset __ARGS((FILE *fd, int opt_flags, int local_only));
-int makefoldset __ARGS((FILE *fd));
-void clear_termoptions __ARGS((void));
-void free_termoptions __ARGS((void));
-void free_one_termoption __ARGS((char_u *var));
-void set_term_defaults __ARGS((void));
-void comp_col __ARGS((void));
-void unset_global_local_option __ARGS((char_u *name, void *from));
-char_u *get_equalprg __ARGS((void));
-void win_copy_options __ARGS((win_T *wp_from, win_T *wp_to));
-void copy_winopt __ARGS((winopt_T *from, winopt_T *to));
-void check_win_options __ARGS((win_T *win));
-void check_winopt __ARGS((winopt_T *wop));
-void clear_winopt __ARGS((winopt_T *wop));
-void buf_copy_options __ARGS((buf_T *buf, int flags));
-void reset_modifiable __ARGS((void));
-void set_iminsert_global __ARGS((void));
-void set_imsearch_global __ARGS((void));
-void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
-int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file,
- char_u ***file));
-int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
-int langmap_adjust_mb __ARGS((int c));
-int has_format_option __ARGS((int x));
-int shortmess __ARGS((int x));
-void vimrc_found __ARGS((char_u *fname, char_u *envname));
-void change_compatible __ARGS((int on));
-int option_was_set __ARGS((char_u *name));
-void reset_option_was_set __ARGS((char_u *name));
-int can_bs __ARGS((int what));
-void save_file_ff __ARGS((buf_T *buf));
-int file_ff_differs __ARGS((buf_T *buf, int ignore_empty));
-int check_ff_value __ARGS((char_u *p));
-long get_sw_value __ARGS((buf_T *buf));
-long get_sts_value __ARGS((void));
-void find_mps_values __ARGS((int *initc, int *findc, int *backwards,
- int switchit));
-/* vim: set ft=c : */
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
deleted file mode 100644
index 3c97345d00..0000000000
--- a/src/proto/os_unix.pro
+++ /dev/null
@@ -1,80 +0,0 @@
-/* os_unix.c */
-int mch_chdir __ARGS((char *path));
-void mch_write __ARGS((char_u *s, int len));
-int mch_inchar __ARGS((char_u *buf, int maxlen, long wtime, int tb_change_cnt));
-int mch_char_avail __ARGS((void));
-long_u mch_total_mem __ARGS((int special));
-void mch_delay __ARGS((long msec, int ignoreinput));
-int mch_stackcheck __ARGS((char *p));
-void mch_startjmp __ARGS((void));
-void mch_endjmp __ARGS((void));
-void mch_didjmp __ARGS((void));
-void mch_suspend __ARGS((void));
-void mch_init __ARGS((void));
-void reset_signals __ARGS((void));
-int vim_handle_signal __ARGS((int sig));
-int mch_check_win __ARGS((int argc, char **argv));
-int mch_input_isatty __ARGS((void));
-int mch_can_restore_title __ARGS((void));
-int mch_can_restore_icon __ARGS((void));
-void mch_settitle __ARGS((char_u *title, char_u *icon));
-void mch_restore_title __ARGS((int which));
-int vim_is_xterm __ARGS((char_u *name));
-int use_xterm_like_mouse __ARGS((char_u *name));
-int use_xterm_mouse __ARGS((void));
-int vim_is_iris __ARGS((char_u *name));
-int vim_is_vt300 __ARGS((char_u *name));
-int vim_is_fastterm __ARGS((char_u *name));
-int mch_get_user_name __ARGS((char_u *s, int len));
-int mch_get_uname __ARGS((uid_t uid, char_u *s, int len));
-void mch_get_host_name __ARGS((char_u *s, int len));
-long mch_get_pid __ARGS((void));
-int mch_dirname __ARGS((char_u *buf, int len));
-void slash_adjust __ARGS((char_u *p));
-int mch_FullName __ARGS((char_u *fname, char_u *buf, int len, int force));
-int mch_isFullName __ARGS((char_u *fname));
-void fname_case __ARGS((char_u *name, int len));
-long mch_getperm __ARGS((char_u *name));
-int mch_setperm __ARGS((char_u *name, long perm));
-void mch_copy_sec __ARGS((char_u *from_file, char_u *to_file));
-vim_acl_T mch_get_acl __ARGS((char_u *fname));
-void mch_set_acl __ARGS((char_u *fname, vim_acl_T aclent));
-void mch_free_acl __ARGS((vim_acl_T aclent));
-void mch_hide __ARGS((char_u *name));
-int mch_isdir __ARGS((char_u *name));
-int mch_can_exe __ARGS((char_u *name));
-int mch_nodetype __ARGS((char_u *name));
-void mch_early_init __ARGS((void));
-void mch_free_mem __ARGS((void));
-void mch_exit __ARGS((int r));
-void mch_settmode __ARGS((int tmode));
-void get_stty __ARGS((void));
-void mch_setmouse __ARGS((int on));
-void check_mouse_termcode __ARGS((void));
-int mch_screenmode __ARGS((char_u *arg));
-int mch_get_shellsize __ARGS((void));
-void mch_set_shellsize __ARGS((void));
-void mch_new_shellsize __ARGS((void));
-int mch_call_shell __ARGS((char_u *cmd, int options));
-void mch_breakcheck __ARGS((void));
-int mch_expandpath __ARGS((garray_T *gap, char_u *path, int flags));
-int mch_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file,
- char_u ***file,
- int flags));
-int mch_has_exp_wildcard __ARGS((char_u *p));
-int mch_has_wildcard __ARGS((char_u *p));
-int mch_libcall __ARGS((char_u *libname, char_u *funcname, char_u *argstring,
- int argint, char_u **string_result,
- int *number_result));
-void setup_term_clip __ARGS((void));
-void start_xterm_trace __ARGS((int button));
-void stop_xterm_trace __ARGS((void));
-void clear_xterm_clip __ARGS((void));
-int clip_xterm_own_selection __ARGS((VimClipboard *cbd));
-void clip_xterm_lose_selection __ARGS((VimClipboard *cbd));
-void clip_xterm_request_selection __ARGS((VimClipboard *cbd));
-void clip_xterm_set_selection __ARGS((VimClipboard *cbd));
-int xsmp_handle_requests __ARGS((void));
-void xsmp_init __ARGS((void));
-void xsmp_close __ARGS((void));
-/* vim: set ft=c : */
diff --git a/src/proto/regexp.pro b/src/proto/regexp.pro
deleted file mode 100644
index b77a8e8ea9..0000000000
--- a/src/proto/regexp.pro
+++ /dev/null
@@ -1,24 +0,0 @@
-/* regexp.c */
-int re_multiline __ARGS((regprog_T *prog));
-int re_lookbehind __ARGS((regprog_T *prog));
-char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
-int vim_regcomp_had_eol __ARGS((void));
-void free_regexp_stuff __ARGS((void));
-reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
-void unref_extmatch __ARGS((reg_extmatch_T *em));
-char_u *regtilde __ARGS((char_u *source, int magic));
-int vim_regsub __ARGS((regmatch_T *rmp, char_u *source, char_u *dest, int copy,
- int magic,
- int backslash));
-int vim_regsub_multi __ARGS((regmmatch_T *rmp, linenr_T lnum, char_u *source,
- char_u *dest, int copy, int magic,
- int backslash));
-char_u *reg_submatch __ARGS((int no));
-regprog_T *vim_regcomp __ARGS((char_u *expr_arg, int re_flags));
-void vim_regfree __ARGS((regprog_T *prog));
-int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
-int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
-long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf,
- linenr_T lnum, colnr_T col,
- proftime_T *tm));
-/* vim: set ft=c : */
diff --git a/src/proto/term.pro b/src/proto/term.pro
deleted file mode 100644
index 9a348c0a72..0000000000
--- a/src/proto/term.pro
+++ /dev/null
@@ -1,65 +0,0 @@
-/* term.c */
-int set_termname __ARGS((char_u *term));
-void set_mouse_termcode __ARGS((int n, char_u *s));
-void del_mouse_termcode __ARGS((int n));
-void getlinecol __ARGS((long *cp, long *rp));
-int add_termcap_entry __ARGS((char_u *name, int force));
-int term_is_8bit __ARGS((char_u *name));
-int term_is_gui __ARGS((char_u *name));
-char_u *tltoa __ARGS((unsigned long i));
-void termcapinit __ARGS((char_u *name));
-void out_flush __ARGS((void));
-void out_flush_check __ARGS((void));
-void out_trash __ARGS((void));
-void out_char __ARGS((unsigned c));
-void out_str_nf __ARGS((char_u *s));
-void out_str __ARGS((char_u *s));
-void term_windgoto __ARGS((int row, int col));
-void term_cursor_right __ARGS((int i));
-void term_append_lines __ARGS((int line_count));
-void term_delete_lines __ARGS((int line_count));
-void term_set_winpos __ARGS((int x, int y));
-void term_set_winsize __ARGS((int width, int height));
-void term_fg_color __ARGS((int n));
-void term_bg_color __ARGS((int n));
-void term_settitle __ARGS((char_u *title));
-void ttest __ARGS((int pairs));
-void add_long_to_buf __ARGS((long_u val, char_u *dst));
-void check_shellsize __ARGS((void));
-void limit_screen_size __ARGS((void));
-void win_new_shellsize __ARGS((void));
-void shell_resized __ARGS((void));
-void shell_resized_check __ARGS((void));
-void set_shellsize __ARGS((int width, int height, int mustset));
-void settmode __ARGS((int tmode));
-void starttermcap __ARGS((void));
-void stoptermcap __ARGS((void));
-void may_req_termresponse __ARGS((void));
-void may_req_ambiguous_char_width __ARGS((void));
-int swapping_screen __ARGS((void));
-void setmouse __ARGS((void));
-int mouse_has __ARGS((int c));
-int mouse_model_popup __ARGS((void));
-void scroll_start __ARGS((void));
-void cursor_on __ARGS((void));
-void cursor_off __ARGS((void));
-void term_cursor_shape __ARGS((void));
-void scroll_region_set __ARGS((win_T *wp, int off));
-void scroll_region_reset __ARGS((void));
-void clear_termcodes __ARGS((void));
-void add_termcode __ARGS((char_u *name, char_u *string, int flags));
-char_u *find_termcode __ARGS((char_u *name));
-char_u *get_termcode __ARGS((int i));
-void del_termcode __ARGS((char_u *name));
-void set_mouse_topline __ARGS((win_T *wp));
-int check_termcode __ARGS((int max_offset, char_u *buf, int bufsize,
- int *buflen));
-char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part,
- int do_lt,
- int special));
-int find_term_bykeys __ARGS((char_u *src));
-void show_termcodes __ARGS((void));
-int show_one_termcode __ARGS((char_u *name, char_u *code, int printit));
-char_u *translate_mapping __ARGS((char_u *str, int expmap));
-void update_tcap __ARGS((int attr));
-/* vim: set ft=c : */
diff --git a/src/proto/version.pro b/src/proto/version.pro
deleted file mode 100644
index e6fb78f069..0000000000
--- a/src/proto/version.pro
+++ /dev/null
@@ -1,10 +0,0 @@
-/* version.c */
-void make_version __ARGS((void));
-int highest_patch __ARGS((void));
-int has_patch __ARGS((int n));
-void ex_version __ARGS((exarg_T *eap));
-void list_version __ARGS((void));
-void maybe_intro_message __ARGS((void));
-void intro_message __ARGS((int colon));
-void ex_intro __ARGS((exarg_T *eap));
-/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 28f3a469f6..af134d19f9 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -12,6 +12,35 @@
*/
#include "vim.h"
+#include "quickfix.h"
+#include "buffer.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "term.h"
+#include "ui.h"
+#include "window.h"
+#include "os/os.h"
struct dir_stack_T {
@@ -152,12 +181,14 @@ static qf_info_T *ll_get_or_alloc_list __ARGS((win_T *));
* list. Set the error list's title to qf_title.
* Return -1 for error, number of errors for success.
*/
-int qf_init(wp, efile, errorformat, newlist, qf_title)
-win_T *wp;
-char_u *efile;
-char_u *errorformat;
-int newlist; /* TRUE: start a new error list */
-char_u *qf_title;
+int
+qf_init (
+ win_T *wp,
+ char_u *efile,
+ char_u *errorformat,
+ int newlist, /* TRUE: start a new error list */
+ char_u *qf_title
+)
{
qf_info_T *qi = &ql_info;
@@ -184,18 +215,18 @@ char_u *qf_title;
* Set the title of the list to "qf_title".
* Return -1 for error, number of errors for success.
*/
-static int qf_init_ext(qi, efile, buf, tv, errorformat, newlist, lnumfirst,
- lnumlast,
- qf_title)
-qf_info_T *qi;
-char_u *efile;
-buf_T *buf;
-typval_T *tv;
-char_u *errorformat;
-int newlist; /* TRUE: start a new error list */
-linenr_T lnumfirst; /* first line number to use */
-linenr_T lnumlast; /* last line number to use */
-char_u *qf_title;
+static int
+qf_init_ext (
+ qf_info_T *qi,
+ char_u *efile,
+ buf_T *buf,
+ typval_T *tv,
+ char_u *errorformat,
+ int newlist, /* TRUE: start a new error list */
+ linenr_T lnumfirst, /* first line number to use */
+ linenr_T lnumlast, /* last line number to use */
+ char_u *qf_title
+)
{
char_u *namebuf;
char_u *errmsg;
@@ -803,9 +834,7 @@ qf_init_end:
/*
* Prepare for adding a new quickfix list.
*/
-static void qf_new_list(qi, qf_title)
-qf_info_T *qi;
-char_u *qf_title;
+static void qf_new_list(qf_info_T *qi, char_u *qf_title)
{
int i;
@@ -841,8 +870,7 @@ char_u *qf_title;
/*
* Free a location list
*/
-static void ll_free_all(pqi)
-qf_info_T **pqi;
+static void ll_free_all(qf_info_T **pqi)
{
int i;
qf_info_T *qi;
@@ -861,8 +889,7 @@ qf_info_T **pqi;
}
}
-void qf_free_all(wp)
-win_T *wp;
+void qf_free_all(win_T *wp)
{
int i;
qf_info_T *qi = &ql_info;
@@ -881,23 +908,22 @@ win_T *wp;
* Add an entry to the end of the list of errors.
* Returns OK or FAIL.
*/
-static int qf_add_entry(qi, prevp, dir, fname, bufnum, mesg, lnum, col, vis_col,
- pattern,
- nr, type,
- valid)
-qf_info_T *qi; /* quickfix list */
-qfline_T **prevp; /* pointer to previously added entry or NULL */
-char_u *dir; /* optional directory name */
-char_u *fname; /* file name or NULL */
-int bufnum; /* buffer number or zero */
-char_u *mesg; /* message */
-long lnum; /* line number */
-int col; /* column */
-int vis_col; /* using visual column */
-char_u *pattern; /* search pattern */
-int nr; /* error number */
-int type; /* type character */
-int valid; /* valid entry */
+static int
+qf_add_entry (
+ qf_info_T *qi, /* quickfix list */
+ qfline_T **prevp, /* pointer to previously added entry or NULL */
+ char_u *dir, /* optional directory name */
+ char_u *fname, /* file name or NULL */
+ int bufnum, /* buffer number or zero */
+ char_u *mesg, /* message */
+ long lnum, /* line number */
+ int col, /* column */
+ int vis_col, /* using visual column */
+ char_u *pattern, /* search pattern */
+ int nr, /* error number */
+ int type, /* type character */
+ int valid /* valid entry */
+)
{
qfline_T *qfp;
@@ -952,7 +978,7 @@ int valid; /* valid entry */
/*
* Allocate a new location list
*/
-static qf_info_T * ll_new_list() {
+static qf_info_T *ll_new_list(void) {
qf_info_T *qi;
qi = (qf_info_T *)alloc((unsigned)sizeof(qf_info_T));
@@ -968,8 +994,7 @@ static qf_info_T * ll_new_list() {
* Return the location list for window 'wp'.
* If not present, allocate a location list
*/
-static qf_info_T * ll_get_or_alloc_list(wp)
-win_T *wp;
+static qf_info_T *ll_get_or_alloc_list(win_T *wp)
{
if (IS_LL_WINDOW(wp))
/* For a location list window, use the referenced location list */
@@ -989,9 +1014,7 @@ win_T *wp;
/*
* Copy the location list from window "from" to window "to".
*/
-void copy_loclist(from, to)
-win_T *from;
-win_T *to;
+void copy_loclist(win_T *from, win_T *to)
{
qf_info_T *qi;
int idx;
@@ -1087,9 +1110,7 @@ win_T *to;
/*
* get buffer number for file "dir.name"
*/
-static int qf_get_fnum(directory, fname)
-char_u *directory;
-char_u *fname;
+static int qf_get_fnum(char_u *directory, char_u *fname)
{
if (fname == NULL || *fname == NUL) /* no file name */
return 0;
@@ -1131,9 +1152,7 @@ char_u *fname;
* push dirbuf onto the directory stack and return pointer to actual dir or
* NULL on error
*/
-static char_u * qf_push_dir(dirbuf, stackptr)
-char_u *dirbuf;
-struct dir_stack_T **stackptr;
+static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr)
{
struct dir_stack_T *ds_new;
struct dir_stack_T *ds_ptr;
@@ -1198,8 +1217,7 @@ struct dir_stack_T **stackptr;
* pop dirbuf from the directory stack and return previous directory or NULL if
* stack is empty
*/
-static char_u * qf_pop_dir(stackptr)
-struct dir_stack_T **stackptr;
+static char_u *qf_pop_dir(struct dir_stack_T **stackptr)
{
struct dir_stack_T *ds_ptr;
@@ -1221,8 +1239,7 @@ struct dir_stack_T **stackptr;
/*
* clean up directory stack
*/
-static void qf_clean_dir_stack(stackptr)
-struct dir_stack_T **stackptr;
+static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
{
struct dir_stack_T *ds_ptr;
@@ -1253,8 +1270,7 @@ struct dir_stack_T **stackptr;
* Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb.
* qf_guess_filepath will return NULL.
*/
-static char_u * qf_guess_filepath(filename)
-char_u *filename;
+static char_u *qf_guess_filepath(char_u *filename)
{
struct dir_stack_T *ds_ptr;
struct dir_stack_T *ds_tmp;
@@ -1302,11 +1318,7 @@ char_u *filename;
* else if "errornr" is zero, redisplay the same line
* else go to entry "errornr"
*/
-void qf_jump(qi, dir, errornr, forceit)
-qf_info_T *qi;
-int dir;
-int errornr;
-int forceit;
+void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
{
qf_info_T *ll_ref;
qfline_T *qf_ptr;
@@ -1734,8 +1746,7 @@ theend:
* ":clist": list all errors
* ":llist": list all locations
*/
-void qf_list(eap)
-exarg_T *eap;
+void qf_list(exarg_T *eap)
{
buf_T *buf;
char_u *fname;
@@ -1831,10 +1842,7 @@ exarg_T *eap;
* Remove newlines and leading whitespace from an error message.
* Put the result in "buf[bufsize]".
*/
-static void qf_fmt_text(text, buf, bufsize)
-char_u *text;
-char_u *buf;
-int bufsize;
+static void qf_fmt_text(char_u *text, char_u *buf, int bufsize)
{
int i;
char_u *p = text;
@@ -1857,8 +1865,7 @@ int bufsize;
* ":lolder [count]": Up in the location list stack.
* ":lnewer [count]": Down in the location list stack.
*/
-void qf_age(eap)
-exarg_T *eap;
+void qf_age(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
int count;
@@ -1893,8 +1900,7 @@ exarg_T *eap;
qf_msg(qi);
}
-static void qf_msg(qi)
-qf_info_T *qi;
+static void qf_msg(qf_info_T *qi)
{
smsg((char_u *)_("error list %d of %d; %d errors"),
qi->qf_curlist + 1, qi->qf_listcount,
@@ -1905,9 +1911,7 @@ qf_info_T *qi;
/*
* Free error list "idx".
*/
-static void qf_free(qi, idx)
-qf_info_T *qi;
-int idx;
+static void qf_free(qf_info_T *qi, int idx)
{
qfline_T *qfp;
int stop = FALSE;
@@ -1935,12 +1939,7 @@ int idx;
/*
* qf_mark_adjust: adjust marks
*/
-void qf_mark_adjust(wp, line1, line2, amount, amount_after)
-win_T *wp;
-linenr_T line1;
-linenr_T line2;
-long amount;
-long amount_after;
+void qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
{
int i;
qfline_T *qfp;
@@ -1983,8 +1982,7 @@ long amount_after;
* other n " c n"
* 1 x "" :helpgrep
*/
-static char_u * qf_types(c, nr)
-int c, nr;
+static char_u *qf_types(int c, int nr)
{
static char_u buf[20];
static char_u cc[3];
@@ -2018,8 +2016,7 @@ int c, nr;
* ":lwindow": open the location list window if we have locations to display,
* close it if not.
*/
-void ex_cwindow(eap)
-exarg_T *eap;
+void ex_cwindow(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
win_T *win;
@@ -2051,8 +2048,7 @@ exarg_T *eap;
* ":cclose": close the window showing the list of errors.
* ":lclose": close the window showing the location list
*/
-void ex_cclose(eap)
-exarg_T *eap;
+void ex_cclose(exarg_T *eap)
{
win_T *win = NULL;
qf_info_T *qi = &ql_info;
@@ -2073,8 +2069,7 @@ exarg_T *eap;
* ":copen": open a window that shows the list of errors.
* ":lopen": open a window that shows the location list.
*/
-void ex_copen(eap)
-exarg_T *eap;
+void ex_copen(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
int height;
@@ -2178,8 +2173,7 @@ exarg_T *eap;
* Return the number of the current entry (line number in the quickfix
* window).
*/
-linenr_T qf_current_entry(wp)
-win_T *wp;
+linenr_T qf_current_entry(win_T *wp)
{
qf_info_T *qi = &ql_info;
@@ -2194,9 +2188,11 @@ win_T *wp;
* Update the cursor position in the quickfix window to the current error.
* Return TRUE if there is a quickfix window.
*/
-static int qf_win_pos_update(qi, old_qf_index)
-qf_info_T *qi;
-int old_qf_index; /* previous qf_index or zero */
+static int
+qf_win_pos_update (
+ qf_info_T *qi,
+ int old_qf_index /* previous qf_index or zero */
+)
{
win_T *win;
int qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
@@ -2235,9 +2231,7 @@ int old_qf_index; /* previous qf_index or zero */
* Check whether the given window is displaying the specified quickfix/location
* list buffer
*/
-static int is_qf_win(win, qi)
-win_T *win;
-qf_info_T *qi;
+static int is_qf_win(win_T *win, qf_info_T *qi)
{
/*
* A window displaying the quickfix buffer will have the w_llist_ref field
@@ -2257,8 +2251,7 @@ qf_info_T *qi;
* Find a window displaying the quickfix/location list 'qi'
* Searches in only the windows opened in the current tab.
*/
-static win_T * qf_find_win(qi)
-qf_info_T *qi;
+static win_T *qf_find_win(qf_info_T *qi)
{
win_T *win;
@@ -2273,8 +2266,7 @@ qf_info_T *qi;
* Find a quickfix buffer.
* Searches in windows opened in all the tabs.
*/
-static buf_T * qf_find_buf(qi)
-qf_info_T *qi;
+static buf_T *qf_find_buf(qf_info_T *qi)
{
tabpage_T *tp;
win_T *win;
@@ -2289,8 +2281,7 @@ qf_info_T *qi;
/*
* Find the quickfix buffer. If it exists, update the contents.
*/
-static void qf_update_buffer(qi)
-qf_info_T *qi;
+static void qf_update_buffer(qf_info_T *qi)
{
buf_T *buf;
win_T *win;
@@ -2321,8 +2312,7 @@ qf_info_T *qi;
}
}
-static void qf_set_title(qi)
-qf_info_T *qi;
+static void qf_set_title(qf_info_T *qi)
{
set_internal_string_var((char_u *)"w:quickfix_title",
qi->qf_lists[qi->qf_curlist].qf_title);
@@ -2332,8 +2322,7 @@ qf_info_T *qi;
* Fill current buffer with quickfix errors, replacing any previous contents.
* curbuf must be the quickfix buffer!
*/
-static void qf_fill_buffer(qi)
-qf_info_T *qi;
+static void qf_fill_buffer(qf_info_T *qi)
{
linenr_T lnum;
qfline_T *qfp;
@@ -2423,8 +2412,7 @@ qf_info_T *qi;
/*
* Return TRUE if "buf" is the quickfix buffer.
*/
-int bt_quickfix(buf)
-buf_T *buf;
+int bt_quickfix(buf_T *buf)
{
return buf != NULL && buf->b_p_bt[0] == 'q';
}
@@ -2433,8 +2421,7 @@ buf_T *buf;
* Return TRUE if "buf" is a "nofile" or "acwrite" buffer.
* This means the buffer name is not a file name.
*/
-int bt_nofile(buf)
-buf_T *buf;
+int bt_nofile(buf_T *buf)
{
return buf != NULL && ((buf->b_p_bt[0] == 'n' && buf->b_p_bt[2] == 'f')
|| buf->b_p_bt[0] == 'a');
@@ -2443,14 +2430,12 @@ buf_T *buf;
/*
* Return TRUE if "buf" is a "nowrite" or "nofile" buffer.
*/
-int bt_dontwrite(buf)
-buf_T *buf;
+int bt_dontwrite(buf_T *buf)
{
return buf != NULL && buf->b_p_bt[0] == 'n';
}
-int bt_dontwrite_msg(buf)
-buf_T *buf;
+int bt_dontwrite_msg(buf_T *buf)
{
if (bt_dontwrite(buf)) {
EMSG(_("E382: Cannot write, 'buftype' option is set"));
@@ -2463,8 +2448,7 @@ buf_T *buf;
* Return TRUE if the buffer should be hidden, according to 'hidden', ":hide"
* and 'bufhidden'.
*/
-int buf_hide(buf)
-buf_T *buf;
+int buf_hide(buf_T *buf)
{
/* 'bufhidden' overrules 'hidden' and ":hide", check it first */
switch (buf->b_p_bh[0]) {
@@ -2479,8 +2463,7 @@ buf_T *buf;
/*
* Return TRUE when using ":vimgrep" for ":grep".
*/
-int grep_internal(cmdidx)
-cmdidx_T cmdidx;
+int grep_internal(cmdidx_T cmdidx)
{
return (cmdidx == CMD_grep
|| cmdidx == CMD_lgrep
@@ -2493,8 +2476,7 @@ cmdidx_T cmdidx;
/*
* Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
*/
-void ex_make(eap)
-exarg_T *eap;
+void ex_make(exarg_T *eap)
{
char_u *fname;
char_u *cmd;
@@ -2591,7 +2573,7 @@ exarg_T *eap;
* Find a new unique name when 'makeef' contains "##".
* Returns NULL for error.
*/
-static char_u * get_mef_name() {
+static char_u *get_mef_name(void) {
char_u *p;
char_u *name;
static int start = -1;
@@ -2643,8 +2625,7 @@ static char_u * get_mef_name() {
* ":cc", ":crewind", ":cfirst" and ":clast".
* ":ll", ":lrewind", ":lfirst" and ":llast".
*/
-void ex_cc(eap)
-exarg_T *eap;
+void ex_cc(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
@@ -2675,8 +2656,7 @@ exarg_T *eap;
* ":cnext", ":cnfile", ":cNext" and ":cprevious".
* ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile".
*/
-void ex_cnext(eap)
-exarg_T *eap;
+void ex_cnext(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
@@ -2708,8 +2688,7 @@ exarg_T *eap;
* ":cfile"/":cgetfile"/":caddfile" commands.
* ":lfile"/":lgetfile"/":laddfile" commands.
*/
-void ex_cfile(eap)
-exarg_T *eap;
+void ex_cfile(exarg_T *eap)
{
win_T *wp = NULL;
qf_info_T *qi = &ql_info;
@@ -2765,8 +2744,7 @@ exarg_T *eap;
* ":lvimgrep {pattern} file(s)"
* ":lvimgrepadd {pattern} file(s)"
*/
-void ex_vimgrep(eap)
-exarg_T *eap;
+void ex_vimgrep(exarg_T *eap)
{
regmmatch_T regmatch;
int fcount;
@@ -3103,10 +3081,7 @@ theend:
* If "s" is not NULL terminate the pattern with a NUL.
* Return a pointer to the char just past the pattern plus flags.
*/
-char_u * skip_vimgrep_pat(p, s, flags)
-char_u *p;
-char_u **s;
-int *flags;
+char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
{
int c;
@@ -3149,8 +3124,7 @@ int *flags;
* Restore current working directory to "dirname_start" if they differ, taking
* into account whether it is set locally or globally.
*/
-static void restore_start_dir(dirname_start)
-char_u *dirname_start;
+static void restore_start_dir(char_u *dirname_start)
{
char_u *dirname_now = alloc(MAXPATHL);
@@ -3181,10 +3155,12 @@ char_u *dirname_start;
*
* Returns NULL if it fails.
*/
-static buf_T * load_dummy_buffer(fname, dirname_start, resulting_dir)
-char_u *fname;
-char_u *dirname_start; /* in: old directory */
-char_u *resulting_dir; /* out: new directory */
+static buf_T *
+load_dummy_buffer (
+ char_u *fname,
+ char_u *dirname_start, /* in: old directory */
+ char_u *resulting_dir /* out: new directory */
+)
{
buf_T *newbuf;
buf_T *newbuf_to_wipe = NULL;
@@ -3258,9 +3234,7 @@ char_u *resulting_dir; /* out: new directory */
* directory to "dirname_start" prior to returning, if autocmds or the
* 'autochdir' option have changed it.
*/
-static void wipe_dummy_buffer(buf, dirname_start)
-buf_T *buf;
-char_u *dirname_start;
+static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start)
{
if (curbuf != buf) { /* safety check */
cleanup_T cs;
@@ -3285,9 +3259,7 @@ char_u *dirname_start;
* directory to "dirname_start" prior to returning, if autocmds or the
* 'autochdir' option have changed it.
*/
-static void unload_dummy_buffer(buf, dirname_start)
-buf_T *buf;
-char_u *dirname_start;
+static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
{
if (curbuf != buf) { /* safety check */
close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE);
@@ -3300,9 +3272,7 @@ char_u *dirname_start;
/*
* Add each quickfix error to list "list" as a dictionary.
*/
-int get_errorlist(wp, list)
-win_T *wp;
-list_T *list;
+int get_errorlist(win_T *wp, list_T *list)
{
qf_info_T *qi = &ql_info;
dict_T *dict;
@@ -3357,11 +3327,7 @@ list_T *list;
* Populate the quickfix list with the items supplied in the list
* of dictionaries. "title" will be copied to w:quickfix_title
*/
-int set_errorlist(wp, list, action, title)
-win_T *wp;
-list_T *list;
-int action;
-char_u *title;
+int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
{
listitem_T *li;
dict_T *d;
@@ -3473,8 +3439,7 @@ char_u *title;
* ":[range]laddbuffer [bufnr]" command.
* ":[range]lgetbuffer [bufnr]" command.
*/
-void ex_cbuffer(eap)
-exarg_T *eap;
+void ex_cbuffer(exarg_T *eap)
{
buf_T *buf = NULL;
qf_info_T *qi = &ql_info;
@@ -3527,8 +3492,7 @@ exarg_T *eap;
* ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command.
* ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command.
*/
-void ex_cexpr(eap)
-exarg_T *eap;
+void ex_cexpr(exarg_T *eap)
{
typval_T *tv;
qf_info_T *qi = &ql_info;
@@ -3562,8 +3526,7 @@ exarg_T *eap;
/*
* ":helpgrep {pattern}"
*/
-void ex_helpgrep(eap)
-exarg_T *eap;
+void ex_helpgrep(exarg_T *eap)
{
regmatch_T regmatch;
char_u *save_cpo;
diff --git a/src/proto/quickfix.pro b/src/quickfix.h
index 98d64a7a3f..949d60bd73 100644
--- a/src/proto/quickfix.pro
+++ b/src/quickfix.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_QUICKFIX_H
+#define NEOVIM_QUICKFIX_H
/* quickfix.c */
int qf_init __ARGS((win_T *wp, char_u *efile, char_u *errorformat, int newlist,
char_u *qf_title));
@@ -31,3 +33,4 @@ void ex_cbuffer __ARGS((exarg_T *eap));
void ex_cexpr __ARGS((exarg_T *eap));
void ex_helpgrep __ARGS((exarg_T *eap));
/* vim: set ft=c : */
+#endif /* NEOVIM_QUICKFIX_H */
diff --git a/src/regexp.c b/src/regexp.c
index d1852f7ba9..3641f16cdb 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -45,6 +45,15 @@
/* #define REGEXP_DEBUG */
#include "vim.h"
+#include "regexp.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "mark.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
#ifdef REGEXP_DEBUG
/* show/save debugging data when BT engine is used */
@@ -56,7 +65,7 @@
#endif
/*
- * The "internal use only" fields in regexp.h are present to pass info from
+ * The "internal use only" fields in regexp_defs.h are present to pass info from
* compile to execute that permits the execute phase to run lots faster on
* simple cases. They are:
*
@@ -255,16 +264,14 @@
static int no_Magic __ARGS((int x));
static int toggle_Magic __ARGS((int x));
-static int no_Magic(x)
-int x;
+static int no_Magic(int x)
{
if (is_Magic(x))
return un_Magic(x);
return x;
}
-static int toggle_Magic(x)
-int x;
+static int toggle_Magic(int x)
{
if (is_Magic(x))
return un_Magic(x);
@@ -376,8 +383,7 @@ static char_u e_empty_sb[] = N_("E70: Empty %s%%[]");
* Return MULTI_ONE if c is a single "multi" operator.
* Return MULTI_MULT if c is a multi "multi" operator.
*/
-static int re_multi_type(c)
-int c;
+static int re_multi_type(int c)
{
if (c == Magic('@') || c == Magic('=') || c == Magic('?'))
return MULTI_ONE;
@@ -434,8 +440,7 @@ static void init_class_tab __ARGS((void));
/*
* Translate '\x' to its control character, except "\n", which is Magic.
*/
-static int backslash_trans(c)
-int c;
+static int backslash_trans(int c)
{
switch (c) {
case 'r': return CAR;
@@ -451,8 +456,7 @@ int c;
* Returns one of the CLASS_ items. CLASS_NONE means that no item was
* recognized. Otherwise "pp" is advanced to after the item.
*/
-static int get_char_class(pp)
-char_u **pp;
+static int get_char_class(char_u **pp)
{
static const char *(class_names[]) =
{
@@ -518,7 +522,7 @@ static short class_tab[256];
#define RI_UPPER 0x80
#define RI_WHITE 0x100
-static void init_class_tab() {
+static void init_class_tab(void) {
int i;
static int done = FALSE;
@@ -687,8 +691,7 @@ static regengine_T nfa_regengine;
/*
* Return TRUE if compiled regular expression "prog" can match a line break.
*/
-int re_multiline(prog)
-regprog_T *prog;
+int re_multiline(regprog_T *prog)
{
return prog->regflags & RF_HASNL;
}
@@ -697,8 +700,7 @@ regprog_T *prog;
* Return TRUE if compiled regular expression "prog" looks before the start
* position (pattern contains "\@<=" or "\@<!").
*/
-int re_lookbehind(prog)
-regprog_T *prog;
+int re_lookbehind(regprog_T *prog)
{
return prog->regflags & RF_LOOKBH;
}
@@ -708,8 +710,7 @@ regprog_T *prog;
* Returns a character representing the class. Zero means that no item was
* recognized. Otherwise "pp" is advanced to after the item.
*/
-static int get_equi_class(pp)
-char_u **pp;
+static int get_equi_class(char_u **pp)
{
int c;
int l = 1;
@@ -736,8 +737,7 @@ char_u **pp;
* Currently only handles latin1, latin9 and utf-8.
* NOTE: When changing this function, also change nfa_emit_equi_class()
*/
-static void reg_equi_class(c)
-int c;
+static void reg_equi_class(int c)
{
if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
|| STRCMP(p_enc, "iso-8859-15") == 0) {
@@ -1044,8 +1044,7 @@ int c;
* "pp" is advanced to after the item.
* Currently only single characters are recognized!
*/
-static int get_coll_element(pp)
-char_u **pp;
+static int get_coll_element(char_u **pp)
{
int c;
int l = 1;
@@ -1070,7 +1069,7 @@ static void get_cpo_flags __ARGS((void));
static int reg_cpo_lit; /* 'cpoptions' contains 'l' flag */
static int reg_cpo_bsl; /* 'cpoptions' contains '\' flag */
-static void get_cpo_flags() {
+static void get_cpo_flags(void) {
reg_cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
reg_cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
}
@@ -1080,8 +1079,7 @@ static void get_cpo_flags() {
* "p" must point to the character after the '['.
* The returned pointer is on the matching ']', or the terminating NUL.
*/
-static char_u * skip_anyof(p)
-char_u *p;
+static char_u *skip_anyof(char_u *p)
{
int l;
@@ -1122,11 +1120,7 @@ char_u *p;
* expression and change "\?" to "?". If "*newp" is not NULL the expression
* is changed in-place.
*/
-char_u * skip_regexp(startp, dirc, magic, newp)
-char_u *startp;
-int dirc;
-int magic;
-char_u **newp;
+char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp)
{
int mymagic;
char_u *p = startp;
@@ -1192,9 +1186,7 @@ static void bt_regfree __ARGS((regprog_T *prog));
* of the structure of the compiled regexp.
* "re_flags": RE_MAGIC and/or RE_STRING.
*/
-static regprog_T * bt_regcomp(expr, re_flags)
-char_u *expr;
-int re_flags;
+static regprog_T *bt_regcomp(char_u *expr, int re_flags)
{
bt_regprog_T *r;
char_u *scan;
@@ -1314,8 +1306,7 @@ int re_flags;
/*
* Free a compiled regexp program, returned by bt_regcomp().
*/
-static void bt_regfree(prog)
-regprog_T *prog;
+static void bt_regfree(regprog_T *prog)
{
vim_free(prog);
}
@@ -1323,9 +1314,11 @@ regprog_T *prog;
/*
* Setup to parse the regexp. Used once to get the length and once to do it.
*/
-static void regcomp_start(expr, re_flags)
-char_u *expr;
-int re_flags; /* see vim_regcomp() */
+static void
+regcomp_start (
+ char_u *expr,
+ int re_flags /* see vim_regcomp() */
+)
{
initchr(expr);
if (re_flags & RE_MAGIC)
@@ -1351,7 +1344,7 @@ int re_flags; /* see vim_regcomp() */
* Check if during the previous call to vim_regcomp the EOL item "$" has been
* found. This is messy, but it works fine.
*/
-int vim_regcomp_had_eol() {
+int vim_regcomp_had_eol(void) {
return had_eol;
}
@@ -1364,9 +1357,11 @@ int vim_regcomp_had_eol() {
* is a trifle forced, but the need to tie the tails of the branches to what
* follows makes it hard to avoid.
*/
-static char_u * reg(paren, flagp)
-int paren; /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
-int *flagp;
+static char_u *
+reg (
+ int paren, /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+ int *flagp
+)
{
char_u *ret;
char_u *br;
@@ -1460,8 +1455,7 @@ int *flagp;
* Parse one alternative of an | operator.
* Implements the & operator.
*/
-static char_u * regbranch(flagp)
-int *flagp;
+static char_u *regbranch(int *flagp)
{
char_u *ret;
char_u *chain = NULL;
@@ -1501,8 +1495,7 @@ int *flagp;
* Parse one alternative of an | or & operator.
* Implements the concatenation operator.
*/
-static char_u * regconcat(flagp)
-int *flagp;
+static char_u *regconcat(int *flagp)
{
char_u *first = NULL;
char_u *chain = NULL;
@@ -1581,8 +1574,7 @@ int *flagp;
* It might seem that this node could be dispensed with entirely, but the
* endmarker role is not redundant.
*/
-static char_u * regpiece(flagp)
-int *flagp;
+static char_u *regpiece(int *flagp)
{
char_u *ret;
int op;
@@ -1728,8 +1720,7 @@ static int classcodes[] = {
* it can turn them into a single node, which is smaller to store and
* faster to run. Don't do this when one_exactly is set.
*/
-static char_u * regatom(flagp)
-int *flagp;
+static char_u *regatom(int *flagp)
{
char_u *ret;
int flags;
@@ -2427,8 +2418,7 @@ do_multibyte:
* Return TRUE if MULTIBYTECODE should be used instead of EXACTLY for
* character "c".
*/
-static int use_multibytecode(c)
-int c;
+static int use_multibytecode(int c)
{
return has_mbyte && (*mb_char2len)(c) > 1
&& (re_multi_type(peekchr()) != NOT_MULTI
@@ -2439,8 +2429,7 @@ int c;
* Emit a node.
* Return pointer to generated code.
*/
-static char_u * regnode(op)
-int op;
+static char_u *regnode(int op)
{
char_u *ret;
@@ -2458,8 +2447,7 @@ int op;
/*
* Emit (if appropriate) a byte of code
*/
-static void regc(b)
-int b;
+static void regc(int b)
{
if (regcode == JUST_CALC_SIZE)
regsize++;
@@ -2470,8 +2458,7 @@ int b;
/*
* Emit (if appropriate) a multi-byte character of code
*/
-static void regmbc(c)
-int c;
+static void regmbc(int c)
{
if (!has_mbyte && c > 0xff)
return;
@@ -2486,9 +2473,7 @@ int c;
*
* Means relocating the operand.
*/
-static void reginsert(op, opnd)
-int op;
-char_u *opnd;
+static void reginsert(int op, char_u *opnd)
{
char_u *src;
char_u *dst;
@@ -2514,10 +2499,7 @@ char_u *opnd;
* Insert an operator in front of already-emitted operand.
* Add a number to the operator.
*/
-static void reginsert_nr(op, val, opnd)
-int op;
-long val;
-char_u *opnd;
+static void reginsert_nr(int op, long val, char_u *opnd)
{
char_u *src;
char_u *dst;
@@ -2546,11 +2528,7 @@ char_u *opnd;
*
* Means relocating the operand.
*/
-static void reginsert_limits(op, minval, maxval, opnd)
-int op;
-long minval;
-long maxval;
-char_u *opnd;
+static void reginsert_limits(int op, long minval, long maxval, char_u *opnd)
{
char_u *src;
char_u *dst;
@@ -2578,9 +2556,7 @@ char_u *opnd;
/*
* Write a long as four bytes at "p" and return pointer to the next char.
*/
-static char_u * re_put_long(p, val)
-char_u *p;
-long_u val;
+static char_u *re_put_long(char_u *p, long_u val)
{
*p++ = (char_u) ((val >> 24) & 0377);
*p++ = (char_u) ((val >> 16) & 0377);
@@ -2592,9 +2568,7 @@ long_u val;
/*
* Set the next-pointer at the end of a node chain.
*/
-static void regtail(p, val)
-char_u *p;
-char_u *val;
+static void regtail(char_u *p, char_u *val)
{
char_u *scan;
char_u *temp;
@@ -2630,9 +2604,7 @@ char_u *val;
/*
* Like regtail, on item after a BRANCH; nop if none.
*/
-static void regoptail(p, val)
-char_u *p;
-char_u *val;
+static void regoptail(char_u *p, char_u *val)
{
/* When op is neither BRANCH nor BRACE_COMPLEX0-9, it is "operandless" */
if (p == NULL || p == JUST_CALC_SIZE
@@ -2652,8 +2624,7 @@ static int prev_at_start; /* True when on the second character */
/*
* Start parsing at "str".
*/
-static void initchr(str)
-char_u *str;
+static void initchr(char_u *str)
{
regparse = str;
prevchr_len = 0;
@@ -2666,8 +2637,7 @@ char_u *str;
* Save the current parse state, so that it can be restored and parsing
* starts in the same state again.
*/
-static void save_parse_state(ps)
-parse_state_T *ps;
+static void save_parse_state(parse_state_T *ps)
{
ps->regparse = regparse;
ps->prevchr_len = prevchr_len;
@@ -2683,8 +2653,7 @@ parse_state_T *ps;
/*
* Restore a previously saved parse state.
*/
-static void restore_parse_state(ps)
-parse_state_T *ps;
+static void restore_parse_state(parse_state_T *ps)
{
regparse = ps->regparse;
prevchr_len = ps->prevchr_len;
@@ -2701,7 +2670,7 @@ parse_state_T *ps;
/*
* Get the next character without advancing.
*/
-static int peekchr() {
+static int peekchr(void) {
static int after_slash = FALSE;
if (curchr == -1) {
@@ -2844,7 +2813,7 @@ static int peekchr() {
/*
* Eat one lexed character. Do this in a way that we can undo it.
*/
-static void skipchr() {
+static void skipchr(void) {
/* peekchr() eats a backslash, do the same here */
if (*regparse == '\\')
prevchr_len = 1;
@@ -2872,7 +2841,7 @@ static void skipchr() {
* Skip a character while keeping the value of prev_at_start for at_start.
* prevchr and prevprevchr are also kept.
*/
-static void skipchr_keepstart() {
+static void skipchr_keepstart(void) {
int as = prev_at_start;
int pr = prevchr;
int prpr = prevprevchr;
@@ -2887,7 +2856,7 @@ static void skipchr_keepstart() {
* Get the next character from the pattern. We know about magic and such, so
* therefore we need a lexical analyzer.
*/
-static int getchr() {
+static int getchr(void) {
int chr = peekchr();
skipchr();
@@ -2897,7 +2866,7 @@ static int getchr() {
/*
* put character back. Works only once!
*/
-static void ungetchr() {
+static void ungetchr(void) {
nextchr = curchr;
curchr = prevchr;
prevchr = prevprevchr;
@@ -2918,8 +2887,7 @@ static void ungetchr() {
* The parameter controls the maximum number of input characters. This will be
* 2 when reading a \%x20 sequence and 4 when reading a \%u20AC sequence.
*/
-static int gethexchrs(maxinputlen)
-int maxinputlen;
+static int gethexchrs(int maxinputlen)
{
int nr = 0;
int c;
@@ -2943,7 +2911,7 @@ int maxinputlen;
* Get and return the value of the decimal string immediately after the
* current position. Return -1 for invalid. Consumes all digits.
*/
-static int getdecchrs() {
+static int getdecchrs(void) {
int nr = 0;
int c;
int i;
@@ -2971,7 +2939,7 @@ static int getdecchrs() {
* blahblah\%o210asdf
* before-^ ^-after
*/
-static int getoctchrs() {
+static int getoctchrs(void) {
int nr = 0;
int c;
int i;
@@ -2994,7 +2962,7 @@ static int getoctchrs() {
* Get a number after a backslash that is inside [].
* When nothing is recognized return a backslash.
*/
-static int coll_get_char() {
+static int coll_get_char(void) {
int nr = -1;
switch (*regparse++) {
@@ -3019,9 +2987,7 @@ static int coll_get_char() {
* Should end with 'end'. If minval is missing, zero is default, if maxval is
* missing, a very big number is the default.
*/
-static int read_limits(minval, maxval)
-long *minval;
-long *maxval;
+static int read_limits(long *minval, long *maxval)
{
int reverse = FALSE;
char_u *first_char;
@@ -3282,7 +3248,7 @@ static garray_T backpos = {0, 0, 0, 0, NULL};
#define BACKPOS_INITIAL 64
#if defined(EXITFREE) || defined(PROTO)
-void free_regexp_stuff() {
+void free_regexp_stuff(void) {
ga_clear(&regstack);
ga_clear(&backpos);
vim_free(reg_tofree);
@@ -3294,8 +3260,7 @@ void free_regexp_stuff() {
/*
* Get pointer to the line "lnum", which is relative to "reg_firstlnum".
*/
-static char_u * reg_getline(lnum)
-linenr_T lnum;
+static char_u *reg_getline(linenr_T lnum)
{
/* when looking behind for a match/no-match lnum is negative. But we
* can't go before line 1 */
@@ -3326,10 +3291,12 @@ static int bt_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
*
* Return TRUE if there is a match, FALSE if not.
*/
-static int bt_regexec(rmp, line, col)
-regmatch_T *rmp;
-char_u *line; /* string to match against */
-colnr_T col; /* column to start looking for match */
+static int
+bt_regexec (
+ regmatch_T *rmp,
+ char_u *line, /* string to match against */
+ colnr_T col /* column to start looking for match */
+)
{
reg_match = rmp;
reg_mmatch = NULL;
@@ -3351,10 +3318,12 @@ static int bt_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
/*
* Like vim_regexec(), but consider a "\n" in "line" to be a line break.
*/
-static int bt_regexec_nl(rmp, line, col)
-regmatch_T *rmp;
-char_u *line; /* string to match against */
-colnr_T col; /* column to start looking for match */
+static int
+bt_regexec_nl (
+ regmatch_T *rmp,
+ char_u *line, /* string to match against */
+ colnr_T col /* column to start looking for match */
+)
{
reg_match = rmp;
reg_mmatch = NULL;
@@ -3414,7 +3383,7 @@ proftime_T *tm; /* timeout limit or NULL */
static long bt_regexec_both(line, col, tm)
char_u *line;
colnr_T col; /* column to start looking for match */
-proftime_T *tm UNUSED; /* timeout limit or NULL */
+proftime_T *tm; /* timeout limit or NULL */
{
bt_regprog_T *prog;
char_u *s;
@@ -3602,7 +3571,7 @@ static reg_extmatch_T *make_extmatch __ARGS((void));
/*
* Create a new extmatch and mark it as referenced once.
*/
-static reg_extmatch_T * make_extmatch() {
+static reg_extmatch_T *make_extmatch(void) {
reg_extmatch_T *em;
em = (reg_extmatch_T *)alloc_clear((unsigned)sizeof(reg_extmatch_T));
@@ -3614,8 +3583,7 @@ static reg_extmatch_T * make_extmatch() {
/*
* Add a reference to an extmatch.
*/
-reg_extmatch_T * ref_extmatch(em)
-reg_extmatch_T *em;
+reg_extmatch_T *ref_extmatch(reg_extmatch_T *em)
{
if (em != NULL)
em->refcnt++;
@@ -3626,8 +3594,7 @@ reg_extmatch_T *em;
* Remove a reference to an extmatch. If there are no references left, free
* the info.
*/
-void unref_extmatch(em)
-reg_extmatch_T *em;
+void unref_extmatch(reg_extmatch_T *em)
{
int i;
@@ -3642,9 +3609,7 @@ reg_extmatch_T *em;
* regtry - try match of "prog" with at regline["col"].
* Returns 0 for failure, number of lines contained in the match otherwise.
*/
-static long regtry(prog, col)
-bt_regprog_T *prog;
-colnr_T col;
+static long regtry(bt_regprog_T *prog, colnr_T col)
{
reginput = regline + col;
need_clear_subexpr = TRUE;
@@ -3707,7 +3672,7 @@ static int reg_prev_class __ARGS((void));
/*
* Get class of previous character.
*/
-static int reg_prev_class() {
+static int reg_prev_class(void) {
if (reginput > regline)
return mb_get_class_buf(reginput - 1
- (*mb_head_off)(regline, reginput - 1), reg_buf);
@@ -3719,7 +3684,7 @@ static int reg_match_visual __ARGS((void));
/*
* Return TRUE if the current reginput position matches the Visual area.
*/
-static int reg_match_visual() {
+static int reg_match_visual(void) {
pos_T top, bot;
linenr_T lnum;
colnr_T col;
@@ -3802,8 +3767,10 @@ static long bl_maxval;
* Returns FALSE when there is no match. Leaves reginput and reglnum in an
* undefined state!
*/
-static int regmatch(scan)
-char_u *scan; /* Current node. */
+static int
+regmatch (
+ char_u *scan /* Current node. */
+)
{
char_u *next; /* Next node. */
int op;
@@ -5103,9 +5070,7 @@ char_u *scan; /* Current node. */
* Push an item onto the regstack.
* Returns pointer to new item. Returns NULL when out of memory.
*/
-static regitem_T * regstack_push(state, scan)
-regstate_T state;
-char_u *scan;
+static regitem_T *regstack_push(regstate_T state, char_u *scan)
{
regitem_T *rp;
@@ -5127,8 +5092,7 @@ char_u *scan;
/*
* Pop an item from the regstack.
*/
-static void regstack_pop(scan)
-char_u **scan;
+static void regstack_pop(char_u **scan)
{
regitem_T *rp;
@@ -5142,9 +5106,11 @@ char_u **scan;
* regrepeat - repeatedly match something simple, return how many.
* Advances reginput (and reglnum) to just after the matched chars.
*/
-static int regrepeat(p, maxcount)
-char_u *p;
-long maxcount; /* maximum number of matches allowed */
+static int
+regrepeat (
+ char_u *p,
+ long maxcount /* maximum number of matches allowed */
+)
{
long count = 0;
char_u *scan;
@@ -5486,8 +5452,7 @@ do_class:
* Returns NULL when calculating size, when there is no next item and when
* there is an error.
*/
-static char_u * regnext(p)
-char_u *p;
+static char_u *regnext(char_u *p)
{
int offset;
@@ -5508,7 +5473,7 @@ char_u *p;
* Check the regexp program for its magic number.
* Return TRUE if it's wrong.
*/
-static int prog_magic_wrong() {
+static int prog_magic_wrong(void) {
regprog_T *prog;
prog = REG_MULTI ? reg_mmatch->regprog : reg_match->regprog;
@@ -5528,7 +5493,7 @@ static int prog_magic_wrong() {
* This construction is used to clear the subexpressions only when they are
* used (to increase speed).
*/
-static void cleanup_subexpr() {
+static void cleanup_subexpr(void) {
if (need_clear_subexpr) {
if (REG_MULTI) {
/* Use 0xff to set lnum to -1 */
@@ -5542,7 +5507,7 @@ static void cleanup_subexpr() {
}
}
-static void cleanup_zsubexpr() {
+static void cleanup_zsubexpr(void) {
if (need_clear_zsubexpr) {
if (REG_MULTI) {
/* Use 0xff to set lnum to -1 */
@@ -5560,8 +5525,7 @@ static void cleanup_zsubexpr() {
* Save the current subexpr to "bp", so that they can be restored
* later by restore_subexpr().
*/
-static void save_subexpr(bp)
-regbehind_T *bp;
+static void save_subexpr(regbehind_T *bp)
{
int i;
@@ -5584,8 +5548,7 @@ regbehind_T *bp;
/*
* Restore the subexpr from "bp".
*/
-static void restore_subexpr(bp)
-regbehind_T *bp;
+static void restore_subexpr(regbehind_T *bp)
{
int i;
@@ -5607,7 +5570,7 @@ regbehind_T *bp;
/*
* Advance reglnum, regline and reginput to the next line.
*/
-static void reg_nextline() {
+static void reg_nextline(void) {
regline = reg_getline(++reglnum);
reginput = regline;
fast_breakcheck();
@@ -5616,9 +5579,7 @@ static void reg_nextline() {
/*
* Save the input line and position in a regsave_T.
*/
-static void reg_save(save, gap)
-regsave_T *save;
-garray_T *gap;
+static void reg_save(regsave_T *save, garray_T *gap)
{
if (REG_MULTI) {
save->rs_u.pos.col = (colnr_T)(reginput - regline);
@@ -5631,9 +5592,7 @@ garray_T *gap;
/*
* Restore the input line and position from a regsave_T.
*/
-static void reg_restore(save, gap)
-regsave_T *save;
-garray_T *gap;
+static void reg_restore(regsave_T *save, garray_T *gap)
{
if (REG_MULTI) {
if (reglnum != save->rs_u.pos.lnum) {
@@ -5651,8 +5610,7 @@ garray_T *gap;
/*
* Return TRUE if current position is equal to saved position.
*/
-static int reg_save_equal(save)
-regsave_T *save;
+static int reg_save_equal(regsave_T *save)
{
if (REG_MULTI)
return reglnum == save->rs_u.pos.lnum
@@ -5667,18 +5625,14 @@ regsave_T *save;
* Use se_save() to use pointer (save_se_multi()) or position (save_se_one()),
* depending on REG_MULTI.
*/
-static void save_se_multi(savep, posp)
-save_se_T *savep;
-lpos_T *posp;
+static void save_se_multi(save_se_T *savep, lpos_T *posp)
{
savep->se_u.pos = *posp;
posp->lnum = reglnum;
posp->col = (colnr_T)(reginput - regline);
}
-static void save_se_one(savep, pp)
-save_se_T *savep;
-char_u **pp;
+static void save_se_one(save_se_T *savep, char_u **pp)
{
savep->se_u.ptr = *pp;
*pp = reginput;
@@ -5687,9 +5641,7 @@ char_u **pp;
/*
* Compare a number with the operand of RE_LNUM, RE_COL or RE_VCOL.
*/
-static int re_num_cmp(val, scan)
-long_u val;
-char_u *scan;
+static int re_num_cmp(long_u val, char_u *scan)
{
long_u n = OPERAND_MIN(scan);
@@ -5706,12 +5658,7 @@ char_u *scan;
* If "bytelen" is not NULL, it is set to the byte length of the match in the
* last line.
*/
-static int match_with_backref(start_lnum, start_col, end_lnum, end_col, bytelen)
-linenr_T start_lnum;
-colnr_T start_col;
-linenr_T end_lnum;
-colnr_T end_col;
-int *bytelen;
+static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T end_lnum, colnr_T end_col, int *bytelen)
{
linenr_T clnum = start_lnum;
colnr_T ccol = start_col;
@@ -5774,9 +5721,7 @@ int *bytelen;
/*
* regdump - dump a regexp onto stdout in vaguely comprehensible form
*/
-static void regdump(pattern, r)
-char_u *pattern;
-bt_regprog_T *r;
+static void regdump(char_u *pattern, bt_regprog_T *r)
{
char_u *s;
int op = EXACTLY; /* Arbitrary non-END op. */
@@ -5857,8 +5802,7 @@ bt_regprog_T *r;
/*
* regprop - printable representation of opcode
*/
-static char_u * regprop(op)
-char_u *op;
+static char_u *regprop(char_u *op)
{
char *p;
static char buf[50];
@@ -6265,21 +6209,21 @@ static decomp_T decomp_table[0xfb4f-0xfb20+1] =
{0x5d4, 0x5bc, 0}, /* 0xfb34 he+dagesh */
{0x5d5, 0x5bc, 0}, /* 0xfb35 vav+dagesh */
{0x5d6, 0x5bc, 0}, /* 0xfb36 zayin+dagesh */
- {0xfb37, 0, 0}, /* 0xfb37 -- UNUSED */
+ {0xfb37, 0, 0}, /* 0xfb37 -- */
{0x5d8, 0x5bc, 0}, /* 0xfb38 tet+dagesh */
{0x5d9, 0x5bc, 0}, /* 0xfb39 yud+dagesh */
{0x5da, 0x5bc, 0}, /* 0xfb3a kaf sofit+dagesh */
{0x5db, 0x5bc, 0}, /* 0xfb3b kaf+dagesh */
{0x5dc, 0x5bc, 0}, /* 0xfb3c lamed+dagesh */
- {0xfb3d, 0, 0}, /* 0xfb3d -- UNUSED */
+ {0xfb3d, 0, 0}, /* 0xfb3d -- */
{0x5de, 0x5bc, 0}, /* 0xfb3e mem+dagesh */
- {0xfb3f, 0, 0}, /* 0xfb3f -- UNUSED */
+ {0xfb3f, 0, 0}, /* 0xfb3f -- */
{0x5e0, 0x5bc, 0}, /* 0xfb40 nun+dagesh */
{0x5e1, 0x5bc, 0}, /* 0xfb41 samech+dagesh */
- {0xfb42, 0, 0}, /* 0xfb42 -- UNUSED */
+ {0xfb42, 0, 0}, /* 0xfb42 -- */
{0x5e3, 0x5bc, 0}, /* 0xfb43 pe sofit+dagesh */
{0x5e4, 0x5bc,0}, /* 0xfb44 pe+dagesh */
- {0xfb45, 0, 0}, /* 0xfb45 -- UNUSED */
+ {0xfb45, 0, 0}, /* 0xfb45 -- */
{0x5e6, 0x5bc, 0}, /* 0xfb46 tsadi+dagesh */
{0x5e7, 0x5bc, 0}, /* 0xfb47 qof+dagesh */
{0x5e8, 0x5bc, 0}, /* 0xfb48 resh+dagesh */
@@ -6292,8 +6236,7 @@ static decomp_T decomp_table[0xfb4f-0xfb20+1] =
{0x5d0, 0x5dc, 0} /* 0xfb4f alef-lamed */
};
-static void mb_decompose(c, c1, c2, c3)
-int c, *c1, *c2, *c3;
+static void mb_decompose(int c, int *c1, int *c2, int *c3)
{
decomp_T d;
@@ -6313,9 +6256,7 @@ int c, *c1, *c2, *c3;
* Return 0 if strings match, non-zero otherwise.
* Correct the length "*n" when composing characters are ignored.
*/
-static int cstrncmp(s1, s2, n)
-char_u *s1, *s2;
-int *n;
+static int cstrncmp(char_u *s1, char_u *s2, int *n)
{
int result;
@@ -6363,9 +6304,7 @@ int *n;
/*
* cstrchr: This function is used a lot for simple searches, keep it fast!
*/
-static char_u * cstrchr(s, c)
-char_u *s;
-int c;
+static char_u *cstrchr(char_u *s, int c)
{
char_u *p;
int cc;
@@ -6475,9 +6414,7 @@ int c;
*
* The tildes are parsed once before the first call to vim_regsub().
*/
-char_u * regtilde(source, magic)
-char_u *source;
-int magic;
+char_u *regtilde(char_u *source, int magic)
{
char_u *newsub = source;
char_u *tmpsub;
@@ -6557,13 +6494,7 @@ static int submatch_line_lbr;
*
* Returns the size of the replacement, including terminating NUL.
*/
-int vim_regsub(rmp, source, dest, copy, magic, backslash)
-regmatch_T *rmp;
-char_u *source;
-char_u *dest;
-int copy;
-int magic;
-int backslash;
+int vim_regsub(regmatch_T *rmp, char_u *source, char_u *dest, int copy, int magic, int backslash)
{
reg_match = rmp;
reg_mmatch = NULL;
@@ -6572,14 +6503,7 @@ int backslash;
return vim_regsub_both(source, dest, copy, magic, backslash);
}
-int vim_regsub_multi(rmp, lnum, source, dest, copy, magic, backslash)
-regmmatch_T *rmp;
-linenr_T lnum;
-char_u *source;
-char_u *dest;
-int copy;
-int magic;
-int backslash;
+int vim_regsub_multi(regmmatch_T *rmp, linenr_T lnum, char_u *source, char_u *dest, int copy, int magic, int backslash)
{
reg_match = NULL;
reg_mmatch = rmp;
@@ -6589,12 +6513,7 @@ int backslash;
return vim_regsub_both(source, dest, copy, magic, backslash);
}
-static int vim_regsub_both(source, dest, copy, magic, backslash)
-char_u *source;
-char_u *dest;
-int copy;
-int magic;
-int backslash;
+static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, int backslash)
{
char_u *src;
char_u *dst;
@@ -6902,8 +6821,7 @@ static char_u *reg_getline_submatch __ARGS((linenr_T lnum));
* substitute() was used the reg_maxline and other values have been
* overwritten.
*/
-static char_u * reg_getline_submatch(lnum)
-linenr_T lnum;
+static char_u *reg_getline_submatch(linenr_T lnum)
{
char_u *s;
linenr_T save_first = reg_firstlnum;
@@ -6924,8 +6842,7 @@ linenr_T lnum;
* allocated memory.
* Returns NULL when not in a ":s" command and for a non-existing submatch.
*/
-char_u * reg_submatch(no)
-int no;
+char_u *reg_submatch(int no)
{
char_u *retval = NULL;
char_u *s;
@@ -7054,9 +6971,7 @@ static char_u regname[][30] = {
* Use vim_regfree() to free the memory.
* Returns NULL for an error.
*/
-regprog_T * vim_regcomp(expr_arg, re_flags)
-char_u *expr_arg;
-int re_flags;
+regprog_T *vim_regcomp(char_u *expr_arg, int re_flags)
{
regprog_T *prog = NULL;
char_u *expr = expr_arg;
@@ -7122,8 +7037,7 @@ int re_flags;
/*
* Free a compiled regexp program, returned by vim_regcomp().
*/
-void vim_regfree(prog)
-regprog_T *prog;
+void vim_regfree(regprog_T *prog)
{
if (prog != NULL)
prog->engine->regfree(prog);
@@ -7136,10 +7050,12 @@ regprog_T *prog;
*
* Return TRUE if there is a match, FALSE if not.
*/
-int vim_regexec(rmp, line, col)
-regmatch_T *rmp;
-char_u *line; /* string to match against */
-colnr_T col; /* column to start looking for match */
+int
+vim_regexec (
+ regmatch_T *rmp,
+ char_u *line, /* string to match against */
+ colnr_T col /* column to start looking for match */
+)
{
return rmp->regprog->engine->regexec(rmp, line, col);
}
@@ -7149,10 +7065,7 @@ colnr_T col; /* column to start looking for match */
/*
* Like vim_regexec(), but consider a "\n" in "line" to be a line break.
*/
-int vim_regexec_nl(rmp, line, col)
-regmatch_T *rmp;
-char_u *line;
-colnr_T col;
+int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
{
return rmp->regprog->engine->regexec_nl(rmp, line, col);
}
diff --git a/src/regexp.h b/src/regexp.h
index 0426f242a4..a843983e3c 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -1,152 +1,27 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
- *
- * This is NOT the original regular expression code as written by Henry
- * Spencer. This code has been modified specifically for use with Vim, and
- * should not be used apart from compiling Vim. If you want a good regular
- * expression library, get the original code.
- *
- * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
- */
-
-#ifndef _REGEXP_H
-#define _REGEXP_H
-
-/*
- * The number of sub-matches is limited to 10.
- * The first one (index 0) is the whole match, referenced with "\0".
- * The second one (index 1) is the first sub-match, referenced with "\1".
- * This goes up to the tenth (index 9), referenced with "\9".
- */
-#define NSUBEXP 10
-
-/*
- * In the NFA engine: how many braces are allowed.
- * TODO(RE): Use dynamic memory allocation instead of static, like here
- */
-#define NFA_MAX_BRACES 20
-
-typedef struct regengine regengine_T;
-
-/*
- * Structure returned by vim_regcomp() to pass on to vim_regexec().
- * This is the general structure. For the actual matcher, two specific
- * structures are used. See code below.
- */
-typedef struct regprog {
- regengine_T *engine;
- unsigned regflags;
-} regprog_T;
-
-/*
- * Structure used by the back track matcher.
- * These fields are only to be used in regexp.c!
- * See regexp.c for an explanation.
- */
-typedef struct {
- /* These two members implement regprog_T */
- regengine_T *engine;
- unsigned regflags;
-
- int regstart;
- char_u reganch;
- char_u *regmust;
- int regmlen;
- char_u reghasz;
- char_u program[1]; /* actually longer.. */
-} bt_regprog_T;
-
-/*
- * Structure representing a NFA state.
- * A NFA state may have no outgoing edge, when it is a NFA_MATCH state.
- */
-typedef struct nfa_state nfa_state_T;
-struct nfa_state {
- int c;
- nfa_state_T *out;
- nfa_state_T *out1;
- int id;
- int lastlist[2]; /* 0: normal, 1: recursive */
- int val;
-};
-
-/*
- * Structure used by the NFA matcher.
- */
-typedef struct {
- /* These two members implement regprog_T */
- regengine_T *engine;
- unsigned regflags;
-
- nfa_state_T *start; /* points into state[] */
-
- int reganch; /* pattern starts with ^ */
- int regstart; /* char at start of pattern */
- char_u *match_text; /* plain text to match with */
-
- int has_zend; /* pattern contains \ze */
- int has_backref; /* pattern contains \1 .. \9 */
- int reghasz;
-#ifdef DEBUG
- char_u *pattern;
-#endif
- int nsubexp; /* number of () */
- int nstate;
- nfa_state_T state[1]; /* actually longer.. */
-} nfa_regprog_T;
-
-/*
- * Structure to be used for single-line matching.
- * Sub-match "no" starts at "startp[no]" and ends just before "endp[no]".
- * When there is no match, the pointer is NULL.
- */
-typedef struct {
- regprog_T *regprog;
- char_u *startp[NSUBEXP];
- char_u *endp[NSUBEXP];
- int rm_ic;
-} regmatch_T;
-
-/*
- * Structure to be used for multi-line matching.
- * Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col"
- * and ends in line "endpos[no].lnum" just before column "endpos[no].col".
- * The line numbers are relative to the first line, thus startpos[0].lnum is
- * always 0.
- * When there is no match, the line number is -1.
- */
-typedef struct {
- regprog_T *regprog;
- lpos_T startpos[NSUBEXP];
- lpos_T endpos[NSUBEXP];
- int rmm_ic;
- colnr_T rmm_maxcol; /* when not zero: maximum column */
-} regmmatch_T;
-
-/*
- * Structure used to store external references: "\z\(\)" to "\z\1".
- * Use a reference count to avoid the need to copy this around. When it goes
- * from 1 to zero the matches need to be freed.
- */
-typedef struct {
- short refcnt;
- char_u *matches[NSUBEXP];
-} reg_extmatch_T;
-
-struct regengine {
- regprog_T *(*regcomp)(char_u*, int);
- void (*regfree)(regprog_T *);
- int (*regexec)(regmatch_T*, char_u*, colnr_T);
-#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
- || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
- int (*regexec_nl)(regmatch_T*, char_u*, colnr_T);
-#endif
- long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T,
- proftime_T*);
-#ifdef DEBUG
- char_u *expr;
-#endif
-};
-
-#endif /* _REGEXP_H */
+#ifndef NEOVIM_REGEXP_H
+#define NEOVIM_REGEXP_H
+/* regexp.c */
+int re_multiline __ARGS((regprog_T *prog));
+int re_lookbehind __ARGS((regprog_T *prog));
+char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
+int vim_regcomp_had_eol __ARGS((void));
+void free_regexp_stuff __ARGS((void));
+reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
+void unref_extmatch __ARGS((reg_extmatch_T *em));
+char_u *regtilde __ARGS((char_u *source, int magic));
+int vim_regsub __ARGS((regmatch_T *rmp, char_u *source, char_u *dest, int copy,
+ int magic,
+ int backslash));
+int vim_regsub_multi __ARGS((regmmatch_T *rmp, linenr_T lnum, char_u *source,
+ char_u *dest, int copy, int magic,
+ int backslash));
+char_u *reg_submatch __ARGS((int no));
+regprog_T *vim_regcomp __ARGS((char_u *expr_arg, int re_flags));
+void vim_regfree __ARGS((regprog_T *prog));
+int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
+long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf,
+ linenr_T lnum, colnr_T col,
+ proftime_T *tm));
+/* vim: set ft=c : */
+#endif /* NEOVIM_REGEXP_H */
diff --git a/src/regexp_defs.h b/src/regexp_defs.h
new file mode 100644
index 0000000000..0426f242a4
--- /dev/null
+++ b/src/regexp_defs.h
@@ -0,0 +1,152 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ *
+ * This is NOT the original regular expression code as written by Henry
+ * Spencer. This code has been modified specifically for use with Vim, and
+ * should not be used apart from compiling Vim. If you want a good regular
+ * expression library, get the original code.
+ *
+ * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
+ */
+
+#ifndef _REGEXP_H
+#define _REGEXP_H
+
+/*
+ * The number of sub-matches is limited to 10.
+ * The first one (index 0) is the whole match, referenced with "\0".
+ * The second one (index 1) is the first sub-match, referenced with "\1".
+ * This goes up to the tenth (index 9), referenced with "\9".
+ */
+#define NSUBEXP 10
+
+/*
+ * In the NFA engine: how many braces are allowed.
+ * TODO(RE): Use dynamic memory allocation instead of static, like here
+ */
+#define NFA_MAX_BRACES 20
+
+typedef struct regengine regengine_T;
+
+/*
+ * Structure returned by vim_regcomp() to pass on to vim_regexec().
+ * This is the general structure. For the actual matcher, two specific
+ * structures are used. See code below.
+ */
+typedef struct regprog {
+ regengine_T *engine;
+ unsigned regflags;
+} regprog_T;
+
+/*
+ * Structure used by the back track matcher.
+ * These fields are only to be used in regexp.c!
+ * See regexp.c for an explanation.
+ */
+typedef struct {
+ /* These two members implement regprog_T */
+ regengine_T *engine;
+ unsigned regflags;
+
+ int regstart;
+ char_u reganch;
+ char_u *regmust;
+ int regmlen;
+ char_u reghasz;
+ char_u program[1]; /* actually longer.. */
+} bt_regprog_T;
+
+/*
+ * Structure representing a NFA state.
+ * A NFA state may have no outgoing edge, when it is a NFA_MATCH state.
+ */
+typedef struct nfa_state nfa_state_T;
+struct nfa_state {
+ int c;
+ nfa_state_T *out;
+ nfa_state_T *out1;
+ int id;
+ int lastlist[2]; /* 0: normal, 1: recursive */
+ int val;
+};
+
+/*
+ * Structure used by the NFA matcher.
+ */
+typedef struct {
+ /* These two members implement regprog_T */
+ regengine_T *engine;
+ unsigned regflags;
+
+ nfa_state_T *start; /* points into state[] */
+
+ int reganch; /* pattern starts with ^ */
+ int regstart; /* char at start of pattern */
+ char_u *match_text; /* plain text to match with */
+
+ int has_zend; /* pattern contains \ze */
+ int has_backref; /* pattern contains \1 .. \9 */
+ int reghasz;
+#ifdef DEBUG
+ char_u *pattern;
+#endif
+ int nsubexp; /* number of () */
+ int nstate;
+ nfa_state_T state[1]; /* actually longer.. */
+} nfa_regprog_T;
+
+/*
+ * Structure to be used for single-line matching.
+ * Sub-match "no" starts at "startp[no]" and ends just before "endp[no]".
+ * When there is no match, the pointer is NULL.
+ */
+typedef struct {
+ regprog_T *regprog;
+ char_u *startp[NSUBEXP];
+ char_u *endp[NSUBEXP];
+ int rm_ic;
+} regmatch_T;
+
+/*
+ * Structure to be used for multi-line matching.
+ * Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col"
+ * and ends in line "endpos[no].lnum" just before column "endpos[no].col".
+ * The line numbers are relative to the first line, thus startpos[0].lnum is
+ * always 0.
+ * When there is no match, the line number is -1.
+ */
+typedef struct {
+ regprog_T *regprog;
+ lpos_T startpos[NSUBEXP];
+ lpos_T endpos[NSUBEXP];
+ int rmm_ic;
+ colnr_T rmm_maxcol; /* when not zero: maximum column */
+} regmmatch_T;
+
+/*
+ * Structure used to store external references: "\z\(\)" to "\z\1".
+ * Use a reference count to avoid the need to copy this around. When it goes
+ * from 1 to zero the matches need to be freed.
+ */
+typedef struct {
+ short refcnt;
+ char_u *matches[NSUBEXP];
+} reg_extmatch_T;
+
+struct regengine {
+ regprog_T *(*regcomp)(char_u*, int);
+ void (*regfree)(regprog_T *);
+ int (*regexec)(regmatch_T*, char_u*, colnr_T);
+#if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
+ || defined(FIND_REPLACE_DIALOG) || defined(PROTO)
+ int (*regexec_nl)(regmatch_T*, char_u*, colnr_T);
+#endif
+ long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T,
+ proftime_T*);
+#ifdef DEBUG
+ char_u *expr;
+#endif
+};
+
+#endif /* _REGEXP_H */
diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c
index 96d6a01a90..75deff1b3e 100644
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -5,6 +5,8 @@
* This file is included in "regexp.c".
*/
+#include "misc2.h"
+
/*
* Logging of NFA engine.
*
@@ -327,9 +329,11 @@ static int failure_chance __ARGS((nfa_state_T *state, int depth));
* Initialize internal variables before NFA compilation.
* Return OK on success, FAIL otherwise.
*/
-static int nfa_regcomp_start(expr, re_flags)
-char_u *expr;
-int re_flags; /* see vim_regcomp() */
+static int
+nfa_regcomp_start (
+ char_u *expr,
+ int re_flags /* see vim_regcomp() */
+)
{
size_t postfix_size;
int nstate_max;
@@ -364,9 +368,7 @@ int re_flags; /* see vim_regcomp() */
* Figure out if the NFA state list starts with an anchor, must match at start
* of the line.
*/
-static int nfa_get_reganch(start, depth)
-nfa_state_T *start;
-int depth;
+static int nfa_get_reganch(nfa_state_T *start, int depth)
{
nfa_state_T *p = start;
@@ -423,9 +425,7 @@ int depth;
* Figure out if the NFA state list starts with a character which must match
* at start of the match.
*/
-static int nfa_get_regstart(start, depth)
-nfa_state_T *start;
-int depth;
+static int nfa_get_regstart(nfa_state_T *start, int depth)
{
nfa_state_T *p = start;
@@ -504,8 +504,7 @@ int depth;
* else. If so return a string in allocated memory with what must match after
* regstart. Otherwise return NULL.
*/
-static char_u * nfa_get_match_text(start)
-nfa_state_T *start;
+static char_u *nfa_get_match_text(nfa_state_T *start)
{
nfa_state_T *p = start;
int len = 0;
@@ -543,7 +542,7 @@ nfa_state_T *start;
* Allocate more space for post_start. Called when
* running above the estimated number of states.
*/
-static int realloc_post_list() {
+static int realloc_post_list(void) {
int nstate_max = (int)(post_end - post_start);
int new_max = nstate_max + 1000;
int *new_start;
@@ -571,10 +570,7 @@ static int realloc_post_list() {
* Keep in mind that 'ignorecase' applies at execution time, thus [a-z] may
* need to be interpreted as [a-zA-Z].
*/
-static int nfa_recognize_char_class(start, end, extra_newl)
-char_u *start;
-char_u *end;
-int extra_newl;
+static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
{
# define CLASS_not 0x80
# define CLASS_af 0x40
@@ -696,8 +692,7 @@ int extra_newl;
*
* NOTE! When changing this function, also update reg_equi_class()
*/
-static int nfa_emit_equi_class(c)
-int c;
+static int nfa_emit_equi_class(int c)
{
#define EMIT2(c) EMIT(c); EMIT(NFA_CONCAT);
# define EMITMBC(c) EMIT(c); EMIT(NFA_CONCAT);
@@ -1061,7 +1056,7 @@ int c;
* or \%( pattern \)
* or \z( pattern \)
*/
-static int nfa_regatom() {
+static int nfa_regatom(void) {
int c;
int charclass;
int equiclass;
@@ -1740,7 +1735,7 @@ nfa_do_multibyte:
* piece ::= atom
* or atom multi
*/
-static int nfa_regpiece() {
+static int nfa_regpiece(void) {
int i;
int op;
int ret;
@@ -1931,7 +1926,7 @@ static int nfa_regpiece() {
* or piece piece piece
* etc.
*/
-static int nfa_regconcat() {
+static int nfa_regconcat(void) {
int cont = TRUE;
int first = TRUE;
@@ -2003,7 +1998,7 @@ static int nfa_regconcat() {
* or concat \& concat \& concat
* etc.
*/
-static int nfa_regbranch() {
+static int nfa_regbranch(void) {
int ch;
int old_post_pos;
@@ -2047,8 +2042,10 @@ static int nfa_regbranch() {
* or branch \| branch \| branch
* etc.
*/
-static int nfa_reg(paren)
-int paren; /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+static int
+nfa_reg (
+ int paren /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
+)
{
int parno = 0;
@@ -2101,8 +2098,7 @@ int paren; /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */
#ifdef REGEXP_DEBUG
static char_u code[50];
-static void nfa_set_code(c)
-int c;
+static void nfa_set_code(int c)
{
int addnl = FALSE;
@@ -2330,9 +2326,7 @@ static FILE *log_fd;
/*
* Print the postfix notation of the current regexp.
*/
-static void nfa_postfix_dump(expr, retval)
-char_u *expr;
-int retval;
+static void nfa_postfix_dump(char_u *expr, int retval)
{
int *p;
FILE *f;
@@ -2360,9 +2354,7 @@ int retval;
/*
* Print the NFA starting with a root node "state".
*/
-static void nfa_print_state(debugf, state)
-FILE *debugf;
-nfa_state_T *state;
+static void nfa_print_state(FILE *debugf, nfa_state_T *state)
{
garray_T indent;
@@ -2372,10 +2364,7 @@ nfa_state_T *state;
ga_clear(&indent);
}
-static void nfa_print_state2(debugf, state, indent)
-FILE *debugf;
-nfa_state_T *state;
-garray_T *indent;
+static void nfa_print_state2(FILE *debugf, nfa_state_T *state, garray_T *indent)
{
char_u *p;
@@ -2433,8 +2422,7 @@ garray_T *indent;
/*
* Print the NFA state machine.
*/
-static void nfa_dump(prog)
-nfa_regprog_T *prog;
+static void nfa_dump(nfa_regprog_T *prog)
{
FILE *debugf = fopen(NFA_REGEXP_DUMP_LOG, "a");
@@ -2459,7 +2447,7 @@ nfa_regprog_T *prog;
* Parse r.e. @expr and convert it into postfix form.
* Return the postfix string on success, NULL otherwise.
*/
-static int * re2post() {
+static int *re2post(void) {
if (nfa_reg(REG_NOPAREN) == FAIL)
return NULL;
EMIT(NFA_MOPEN);
@@ -2480,10 +2468,7 @@ static nfa_state_T *state_ptr; /* points to nfa_prog->state */
/*
* Allocate and initialize nfa_state_T.
*/
-static nfa_state_T * alloc_state(c, out, out1)
-int c;
-nfa_state_T *out;
-nfa_state_T *out1;
+static nfa_state_T *alloc_state(int c, nfa_state_T *out, nfa_state_T *out1)
{
nfa_state_T *s;
@@ -2536,9 +2521,7 @@ static Frag_T st_pop __ARGS((Frag_T **p, Frag_T *stack));
/*
* Initialize a Frag_T struct and return it.
*/
-static Frag_T frag(start, out)
-nfa_state_T *start;
-Ptrlist *out;
+static Frag_T frag(nfa_state_T *start, Ptrlist *out)
{
Frag_T n;
@@ -2550,8 +2533,7 @@ Ptrlist *out;
/*
* Create singleton list containing just outp.
*/
-static Ptrlist * list1(outp)
-nfa_state_T **outp;
+static Ptrlist *list1(nfa_state_T **outp)
{
Ptrlist *l;
@@ -2563,9 +2545,7 @@ nfa_state_T **outp;
/*
* Patch the list of states at out to point to start.
*/
-static void patch(l, s)
-Ptrlist *l;
-nfa_state_T *s;
+static void patch(Ptrlist *l, nfa_state_T *s)
{
Ptrlist *next;
@@ -2579,9 +2559,7 @@ nfa_state_T *s;
/*
* Join the two lists l1 and l2, returning the combination.
*/
-static Ptrlist * append(l1, l2)
-Ptrlist *l1;
-Ptrlist *l2;
+static Ptrlist *append(Ptrlist *l1, Ptrlist *l2)
{
Ptrlist *oldl1;
@@ -2597,10 +2575,7 @@ Ptrlist *l2;
*/
static Frag_T empty;
-static void st_error(postfix, end, p)
-int *postfix UNUSED;
-int *end UNUSED;
-int *p UNUSED;
+static void st_error(int *postfix, int *end, int *p)
{
#ifdef NFA_REGEXP_ERROR_LOG
FILE *df;
@@ -2643,10 +2618,7 @@ int *p UNUSED;
/*
* Push an item onto the stack.
*/
-static void st_push(s, p, stack_end)
-Frag_T s;
-Frag_T **p;
-Frag_T *stack_end;
+static void st_push(Frag_T s, Frag_T **p, Frag_T *stack_end)
{
Frag_T *stackp = *p;
@@ -2659,9 +2631,7 @@ Frag_T *stack_end;
/*
* Pop an item from the stack.
*/
-static Frag_T st_pop(p, stack)
-Frag_T **p;
-Frag_T *stack;
+static Frag_T st_pop(Frag_T **p, Frag_T *stack)
{
Frag_T *stackp;
@@ -2676,9 +2646,7 @@ Frag_T *stack;
* Estimate the maximum byte length of anything matching "state".
* When unknown or unlimited return -1.
*/
-static int nfa_max_width(startstate, depth)
-nfa_state_T *startstate;
-int depth;
+static int nfa_max_width(nfa_state_T *startstate, int depth)
{
int l, r;
nfa_state_T *state = startstate;
@@ -2888,10 +2856,7 @@ int depth;
* Convert a postfix form into its equivalent NFA.
* Return the NFA start state on success, NULL otherwise.
*/
-static nfa_state_T * post2nfa(postfix, end, nfa_calc_size)
-int *postfix;
-int *end;
-int nfa_calc_size;
+static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
{
int *p;
int mopen;
@@ -3375,8 +3340,7 @@ theend:
/*
* After building the NFA program, inspect it to add optimization hints.
*/
-static void nfa_postprocess(prog)
-nfa_regprog_T *prog;
+static void nfa_postprocess(nfa_regprog_T *prog)
{
int i;
int c;
@@ -3489,16 +3453,14 @@ static void log_subsexpr __ARGS((regsubs_T *subs));
static void log_subexpr __ARGS((regsub_T *sub));
static char *pim_info __ARGS((nfa_pim_T *pim));
-static void log_subsexpr(subs)
-regsubs_T *subs;
+static void log_subsexpr(regsubs_T *subs)
{
log_subexpr(&subs->norm);
if (nfa_has_zsubexpr)
log_subexpr(&subs->synt);
}
-static void log_subexpr(sub)
-regsub_T *sub;
+static void log_subexpr(regsub_T *sub)
{
int j;
@@ -3521,8 +3483,7 @@ regsub_T *sub;
}
}
-static char * pim_info(pim)
-nfa_pim_T *pim;
+static char *pim_info(nfa_pim_T *pim)
{
static char buf[30];
@@ -3563,9 +3524,7 @@ static void addstate_here __ARGS((nfa_list_T *l, nfa_state_T *state,
/*
* Copy postponed invisible match info from "from" to "to".
*/
-static void copy_pim(to, from)
-nfa_pim_T *to;
-nfa_pim_T *from;
+static void copy_pim(nfa_pim_T *to, nfa_pim_T *from)
{
to->result = from->result;
to->state = from->state;
@@ -3575,8 +3534,7 @@ nfa_pim_T *from;
to->end = from->end;
}
-static void clear_sub(sub)
-regsub_T *sub;
+static void clear_sub(regsub_T *sub)
{
if (REG_MULTI)
/* Use 0xff to set lnum to -1 */
@@ -3590,9 +3548,7 @@ regsub_T *sub;
/*
* Copy the submatches from "from" to "to".
*/
-static void copy_sub(to, from)
-regsub_T *to;
-regsub_T *from;
+static void copy_sub(regsub_T *to, regsub_T *from)
{
to->in_use = from->in_use;
if (from->in_use > 0) {
@@ -3611,9 +3567,7 @@ regsub_T *from;
/*
* Like copy_sub() but exclude the main match.
*/
-static void copy_sub_off(to, from)
-regsub_T *to;
-regsub_T *from;
+static void copy_sub_off(regsub_T *to, regsub_T *from)
{
if (to->in_use < from->in_use)
to->in_use = from->in_use;
@@ -3633,9 +3587,7 @@ regsub_T *from;
/*
* Like copy_sub() but only do the end of the main match if \ze is present.
*/
-static void copy_ze_off(to, from)
-regsub_T *to;
-regsub_T *from;
+static void copy_ze_off(regsub_T *to, regsub_T *from)
{
if (nfa_has_zend) {
if (REG_MULTI) {
@@ -3651,9 +3603,7 @@ regsub_T *from;
/*
* Return TRUE if "sub1" and "sub2" have the same start positions.
*/
-static int sub_equal(sub1, sub2)
-regsub_T *sub1;
-regsub_T *sub2;
+static int sub_equal(regsub_T *sub1, regsub_T *sub2)
{
int i;
int todo;
@@ -3723,11 +3673,13 @@ static void report_state(char *action,
* Return TRUE if the same state is already in list "l" with the same
* positions as "subs".
*/
-static int has_state_with_pos(l, state, subs, pim)
-nfa_list_T *l; /* runtime state list */
-nfa_state_T *state; /* state to update */
-regsubs_T *subs; /* pointers to subexpressions */
-nfa_pim_T *pim; /* postponed match or NULL */
+static int
+has_state_with_pos (
+ nfa_list_T *l, /* runtime state list */
+ nfa_state_T *state, /* state to update */
+ regsubs_T *subs, /* pointers to subexpressions */
+ nfa_pim_T *pim /* postponed match or NULL */
+)
{
nfa_thread_T *thread;
int i;
@@ -3748,9 +3700,7 @@ nfa_pim_T *pim; /* postponed match or NULL */
* Return TRUE if "one" and "two" are equal. That includes when both are not
* set.
*/
-static int pim_equal(one, two)
-nfa_pim_T *one;
-nfa_pim_T *two;
+static int pim_equal(nfa_pim_T *one, nfa_pim_T *two)
{
int one_unused = (one == NULL || one->result == NFA_PIM_UNUSED);
int two_unused = (two == NULL || two->result == NFA_PIM_UNUSED);
@@ -3774,9 +3724,7 @@ nfa_pim_T *two;
/*
* Return TRUE if "state" leads to a NFA_MATCH without advancing the input.
*/
-static int match_follows(startstate, depth)
-nfa_state_T *startstate;
-int depth;
+static int match_follows(nfa_state_T *startstate, int depth)
{
nfa_state_T *state = startstate;
@@ -3865,10 +3813,12 @@ int depth;
/*
* Return TRUE if "state" is already in list "l".
*/
-static int state_in_list(l, state, subs)
-nfa_list_T *l; /* runtime state list */
-nfa_state_T *state; /* state to update */
-regsubs_T *subs; /* pointers to subexpressions */
+static int
+state_in_list (
+ nfa_list_T *l, /* runtime state list */
+ nfa_state_T *state, /* state to update */
+ regsubs_T *subs /* pointers to subexpressions */
+)
{
if (state->lastlist[nfa_ll_index] == l->id) {
if (!nfa_has_backref || has_state_with_pos(l, state, subs, NULL))
@@ -3882,12 +3832,14 @@ regsubs_T *subs; /* pointers to subexpressions */
* Returns "subs_arg", possibly copied into temp_subs.
*/
-static regsubs_T * addstate(l, state, subs_arg, pim, off)
-nfa_list_T *l; /* runtime state list */
-nfa_state_T *state; /* state to update */
-regsubs_T *subs_arg; /* pointers to subexpressions */
-nfa_pim_T *pim; /* postponed look-behind match */
-int off; /* byte offset, when -1 go to next line */
+static regsubs_T *
+addstate (
+ nfa_list_T *l, /* runtime state list */
+ nfa_state_T *state, /* state to update */
+ regsubs_T *subs_arg, /* pointers to subexpressions */
+ nfa_pim_T *pim, /* postponed look-behind match */
+ int off /* byte offset, when -1 go to next line */
+)
{
int subidx;
nfa_thread_T *thread;
@@ -4226,12 +4178,14 @@ skip_add:
* This makes sure the order of states to be tried does not change, which
* matters for alternatives.
*/
-static void addstate_here(l, state, subs, pim, ip)
-nfa_list_T *l; /* runtime state list */
-nfa_state_T *state; /* state to update */
-regsubs_T *subs; /* pointers to subexpressions */
-nfa_pim_T *pim; /* postponed look-behind match */
-int *ip;
+static void
+addstate_here (
+ nfa_list_T *l, /* runtime state list */
+ nfa_state_T *state, /* state to update */
+ regsubs_T *subs, /* pointers to subexpressions */
+ nfa_pim_T *pim, /* postponed look-behind match */
+ int *ip
+)
{
int tlen = l->n;
int count;
@@ -4290,9 +4244,7 @@ int *ip;
/*
* Check character class "class" against current character c.
*/
-static int check_char_class(class, c)
-int class;
-int c;
+static int check_char_class(int class, int c)
{
switch (class) {
case NFA_CLASS_ALNUM:
@@ -4372,10 +4324,12 @@ int c;
* Check for a match with subexpression "subidx".
* Return TRUE if it matches.
*/
-static int match_backref(sub, subidx, bytelen)
-regsub_T *sub; /* pointers to subexpressions */
-int subidx;
-int *bytelen; /* out: length of match in bytes */
+static int
+match_backref (
+ regsub_T *sub, /* pointers to subexpressions */
+ int subidx,
+ int *bytelen /* out: length of match in bytes */
+)
{
int len;
@@ -4428,9 +4382,11 @@ static int match_zref __ARGS((int subidx, int *bytelen));
* Check for a match with \z subexpression "subidx".
* Return TRUE if it matches.
*/
-static int match_zref(subidx, bytelen)
-int subidx;
-int *bytelen; /* out: length of match in bytes */
+static int
+match_zref (
+ int subidx,
+ int *bytelen /* out: length of match in bytes */
+)
{
int len;
@@ -4454,9 +4410,7 @@ int *bytelen; /* out: length of match in bytes */
* Also reset the IDs to zero.
* Only used for the recursive value lastlist[1].
*/
-static void nfa_save_listids(prog, list)
-nfa_regprog_T *prog;
-int *list;
+static void nfa_save_listids(nfa_regprog_T *prog, int *list)
{
int i;
nfa_state_T *p;
@@ -4473,9 +4427,7 @@ int *list;
/*
* Restore list IDs from "list" to all NFA states.
*/
-static void nfa_restore_listids(prog, list)
-nfa_regprog_T *prog;
-int *list;
+static void nfa_restore_listids(nfa_regprog_T *prog, int *list)
{
int i;
nfa_state_T *p;
@@ -4487,10 +4439,7 @@ int *list;
}
}
-static int nfa_re_num_cmp(val, op, pos)
-long_u val;
-int op;
-long_u pos;
+static int nfa_re_num_cmp(long_u val, int op, long_u pos)
{
if (op == 1) return pos > val;
if (op == 2) return pos < val;
@@ -4510,13 +4459,7 @@ static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start,
* "pim" is NULL or contains info about a Postponed Invisible Match (start
* position).
*/
-static int recursive_regmatch(state, pim, prog, submatch, m, listids)
-nfa_state_T *state;
-nfa_pim_T *pim;
-nfa_regprog_T *prog;
-regsubs_T *submatch;
-regsubs_T *m;
-int **listids;
+static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T *prog, regsubs_T *submatch, regsubs_T *m, int **listids)
{
int save_reginput_col = (int)(reginput - regline);
int save_reglnum = reglnum;
@@ -4666,9 +4609,7 @@ static long find_match_text __ARGS((colnr_T startcol, int regstart,
* NFA_ANY: 1
* specific character: 99
*/
-static int failure_chance(state, depth)
-nfa_state_T *state;
-int depth;
+static int failure_chance(nfa_state_T *state, int depth)
{
int c = state->c;
int l, r;
@@ -4821,9 +4762,7 @@ int depth;
/*
* Skip until the char "c" we know a match must start with.
*/
-static int skip_to_start(c, colp)
-int c;
-colnr_T *colp;
+static int skip_to_start(int c, colnr_T *colp)
{
char_u *s;
@@ -4845,10 +4784,7 @@ colnr_T *colp;
* Called after skip_to_start() has found regstart.
* Returns zero for no match, 1 for a match.
*/
-static long find_match_text(startcol, regstart, match_text)
-colnr_T startcol;
-int regstart;
-char_u *match_text;
+static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
{
colnr_T col = startcol;
int c1, c2;
@@ -4904,11 +4840,7 @@ char_u *match_text;
* When there is a match "submatch" contains the positions.
* Note: Caller must ensure that: start != NULL.
*/
-static int nfa_regmatch(prog, start, submatch, m)
-nfa_regprog_T *prog;
-nfa_state_T *start;
-regsubs_T *submatch;
-regsubs_T *m;
+static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *submatch, regsubs_T *m)
{
int result;
int size = 0;
@@ -6116,9 +6048,7 @@ theend:
* Try match of "prog" with at regline["col"].
* Returns 0 for failure, number of lines contained in the match otherwise.
*/
-static long nfa_regtry(prog, col)
-nfa_regprog_T *prog;
-colnr_T col;
+static long nfa_regtry(nfa_regprog_T *prog, colnr_T col)
{
int i;
regsubs_T subs, m;
@@ -6221,9 +6151,11 @@ colnr_T col;
*
* Returns 0 for failure, number of lines contained in the match otherwise.
*/
-static long nfa_regexec_both(line, startcol)
-char_u *line;
-colnr_T startcol; /* column to start looking for match */
+static long
+nfa_regexec_both (
+ char_u *line,
+ colnr_T startcol /* column to start looking for match */
+)
{
nfa_regprog_T *prog;
long retval = 0L;
@@ -6319,9 +6251,7 @@ theend:
* Compile a regular expression into internal code for the NFA matcher.
* Returns the program in allocated space. Returns NULL for an error.
*/
-static regprog_T * nfa_regcomp(expr, re_flags)
-char_u *expr;
-int re_flags;
+static regprog_T *nfa_regcomp(char_u *expr, int re_flags)
{
nfa_regprog_T *prog = NULL;
size_t prog_size;
@@ -6435,8 +6365,7 @@ fail:
/*
* Free a compiled regexp program, returned by nfa_regcomp().
*/
-static void nfa_regfree(prog)
-regprog_T *prog;
+static void nfa_regfree(regprog_T *prog)
{
if (prog != NULL) {
vim_free(((nfa_regprog_T *)prog)->match_text);
@@ -6454,10 +6383,12 @@ regprog_T *prog;
*
* Return TRUE if there is a match, FALSE if not.
*/
-static int nfa_regexec(rmp, line, col)
-regmatch_T *rmp;
-char_u *line; /* string to match against */
-colnr_T col; /* column to start looking for match */
+static int
+nfa_regexec (
+ regmatch_T *rmp,
+ char_u *line, /* string to match against */
+ colnr_T col /* column to start looking for match */
+)
{
reg_match = rmp;
reg_mmatch = NULL;
@@ -6479,10 +6410,12 @@ static int nfa_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
/*
* Like nfa_regexec(), but consider a "\n" in "line" to be a line break.
*/
-static int nfa_regexec_nl(rmp, line, col)
-regmatch_T *rmp;
-char_u *line; /* string to match against */
-colnr_T col; /* column to start looking for match */
+static int
+nfa_regexec_nl (
+ regmatch_T *rmp,
+ char_u *line, /* string to match against */
+ colnr_T col /* column to start looking for match */
+)
{
reg_match = rmp;
reg_mmatch = NULL;
@@ -6529,7 +6462,7 @@ win_T *win; /* window in which to search or NULL */
buf_T *buf; /* buffer in which to search */
linenr_T lnum; /* nr of line to start looking for match */
colnr_T col; /* column to start looking for match */
-proftime_T *tm UNUSED; /* timeout limit or NULL */
+proftime_T *tm; /* timeout limit or NULL */
{
reg_match = NULL;
reg_mmatch = rmp;
diff --git a/src/screen.c b/src/screen.c
index cb04ab6964..293a41b9c6 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -88,6 +88,37 @@
*/
#include "vim.h"
+#include "screen.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "menu.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "popupmnu.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "search.h"
+#include "spell.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+#include "version.h"
+#include "window.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
@@ -163,15 +194,12 @@ static int screen_char_attr = 0;
* Set must_redraw only if not already set to a higher value.
* e.g. if must_redraw is CLEAR, type NOT_VALID will do nothing.
*/
-void redraw_later(type)
-int type;
+void redraw_later(int type)
{
redraw_win_later(curwin, type);
}
-void redraw_win_later(wp, type)
-win_T *wp;
-int type;
+void redraw_win_later(win_T *wp, int type)
{
if (wp->w_redr_type < type) {
wp->w_redr_type = type;
@@ -186,7 +214,7 @@ int type;
* Force a complete redraw later. Also resets the highlighting. To be used
* after executing a shell command that messes up the screen.
*/
-void redraw_later_clear() {
+void redraw_later_clear(void) {
redraw_all_later(CLEAR);
/* Use attributes that is very unlikely to appear in text. */
screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE;
@@ -195,8 +223,7 @@ void redraw_later_clear() {
/*
* Mark all windows to be redrawn later.
*/
-void redraw_all_later(type)
-int type;
+void redraw_all_later(int type)
{
win_T *wp;
@@ -209,15 +236,12 @@ int type;
/*
* Mark all windows that are editing the current buffer to be updated later.
*/
-void redraw_curbuf_later(type)
-int type;
+void redraw_curbuf_later(int type)
{
redraw_buf_later(curbuf, type);
}
-void redraw_buf_later(buf, type)
-buf_T *buf;
-int type;
+void redraw_buf_later(buf_T *buf, int type)
{
win_T *wp;
@@ -233,8 +257,7 @@ int type;
* right away and restore what was on the command line.
* Return a code indicating what happened.
*/
-int redraw_asap(type)
-int type;
+int redraw_asap(int type)
{
int rows;
int r;
@@ -360,9 +383,11 @@ int type;
* Note that when also inserting/deleting lines w_redraw_top and w_redraw_bot
* may become invalid and the whole window will have to be redrawn.
*/
-void redrawWinline(lnum, invalid)
-linenr_T lnum;
-int invalid UNUSED; /* window line height is invalid now */
+void
+redrawWinline (
+ linenr_T lnum,
+ int invalid /* window line height is invalid now */
+)
{
int i;
@@ -385,8 +410,7 @@ int invalid UNUSED; /* window line height is invalid now */
/*
* update all windows that are editing the current buffer
*/
-void update_curbuf(type)
-int type;
+void update_curbuf(int type)
{
redraw_curbuf_later(type);
update_screen(type);
@@ -399,8 +423,7 @@ int type;
* Based on the current value of curwin->w_topline, transfer a screenfull
* of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
*/
-void update_screen(type)
-int type;
+void update_screen(int type)
{
win_T *wp;
static int did_intro = FALSE;
@@ -591,8 +614,7 @@ int type;
* Return TRUE if the cursor line in window "wp" may be concealed, according
* to the 'concealcursor' option.
*/
-int conceal_cursor_line(wp)
-win_T *wp;
+int conceal_cursor_line(win_T *wp)
{
int c;
@@ -614,7 +636,7 @@ win_T *wp;
/*
* Check if the cursor line needs to be redrawn because of 'concealcursor'.
*/
-void conceal_check_cursur_line() {
+void conceal_check_cursur_line(void) {
if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) {
need_cursor_line_redraw = TRUE;
/* Need to recompute cursor column, e.g., when starting Visual mode
@@ -623,9 +645,7 @@ void conceal_check_cursur_line() {
}
}
-void update_single_line(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+void update_single_line(win_T *wp, linenr_T lnum)
{
int row;
int j;
@@ -680,8 +700,7 @@ linenr_T lnum;
* mid: from mid_start to mid_end (update inversion or changed text)
* bot: from bot_start to last row (when scrolled up)
*/
-static void win_update(wp)
-win_T *wp;
+static void win_update(win_T *wp)
{
buf_T *buf = wp->w_buffer;
int type;
@@ -1633,13 +1652,7 @@ win_T *wp;
* Clear the rest of the window and mark the unused lines with "c1". use "c2"
* as the filler character.
*/
-static void win_draw_end(wp, c1, c2, row, endrow, hl)
-win_T *wp;
-int c1;
-int c2;
-int row;
-int endrow;
-hlf_T hl;
+static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T hl)
{
int n = 0;
# define FDC_OFF n
@@ -1695,9 +1708,7 @@ static int advance_color_col __ARGS((int vcol, int **color_cols));
/*
* Advance **color_cols and return TRUE when there are columns to draw.
*/
-static int advance_color_col(vcol, color_cols)
-int vcol;
-int **color_cols;
+static int advance_color_col(int vcol, int **color_cols)
{
while (**color_cols >= 0 && vcol > **color_cols)
++*color_cols;
@@ -1707,12 +1718,7 @@ int **color_cols;
/*
* Display one folded line.
*/
-static void fold_line(wp, fold_count, foldinfo, lnum, row)
-win_T *wp;
-long fold_count;
-foldinfo_T *foldinfo;
-linenr_T lnum;
-int row;
+static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row)
{
char_u buf[51];
pos_T *top, *bot;
@@ -2018,11 +2024,7 @@ int row;
/*
* Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr".
*/
-static void copy_text_attr(off, buf, len, attr)
-int off;
-char_u *buf;
-int len;
-int attr;
+static void copy_text_attr(int off, char_u *buf, int len, int attr)
{
int i;
@@ -2037,11 +2039,13 @@ int attr;
* Fill the foldcolumn at "p" for window "wp".
* Only to be called when 'foldcolumn' > 0.
*/
-static void fill_foldcolumn(p, wp, closed, lnum)
-char_u *p;
-win_T *wp;
-int closed; /* TRUE of FALSE */
-linenr_T lnum; /* current line number */
+static void
+fill_foldcolumn (
+ char_u *p,
+ win_T *wp,
+ int closed, /* TRUE of FALSE */
+ linenr_T lnum /* current line number */
+)
{
int i = 0;
int level;
@@ -2087,12 +2091,14 @@ linenr_T lnum; /* current line number */
*
* Return the number of last row the line occupies.
*/
-static int win_line(wp, lnum, startrow, endrow, nochange)
-win_T *wp;
-linenr_T lnum;
-int startrow;
-int endrow;
-int nochange UNUSED; /* not updating for changed text */
+static int
+win_line (
+ win_T *wp,
+ linenr_T lnum,
+ int startrow,
+ int endrow,
+ int nochange /* not updating for changed text */
+)
{
int col; /* visual column on screen */
unsigned off; /* offset in ScreenLines/ScreenAttrs */
@@ -4056,9 +4062,7 @@ static int comp_char_differs __ARGS((int, int));
* Return if the composing characters at "off_from" and "off_to" differ.
* Only to be used when ScreenLinesUC[off_from] != 0.
*/
-static int comp_char_differs(off_from, off_to)
-int off_from;
-int off_to;
+static int comp_char_differs(int off_from, int off_to)
{
int i;
@@ -4078,10 +4082,7 @@ int off_to;
* - the character is multi-byte and the next byte is different
* - the character is two cells wide and the second cell differs.
*/
-static int char_needs_redraw(off_from, off_to, cols)
-int off_from;
-int off_to;
-int cols;
+static int char_needs_redraw(int off_from, int off_to, int cols)
{
if (cols > 0
&& ((ScreenLines[off_from] != ScreenLines[off_to]
@@ -4116,13 +4117,7 @@ int cols;
* When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
* When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
*/
-static void screen_line(row, coloff, endcol, clear_width
- , rlflag )
-int row;
-int coloff;
-int endcol;
-int clear_width;
-int rlflag;
+static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag)
{
unsigned off_from;
unsigned off_to;
@@ -4376,8 +4371,7 @@ int rlflag;
* Mirror text "str" for right-left displaying.
* Only works for single-byte characters (e.g., numbers).
*/
-void rl_mirror(str)
-char_u *str;
+void rl_mirror(char_u *str)
{
char_u *p1, *p2;
int t;
@@ -4392,7 +4386,7 @@ char_u *str;
/*
* mark all status lines for redraw; used after first :cd
*/
-void status_redraw_all() {
+void status_redraw_all(void) {
win_T *wp;
for (wp = firstwin; wp; wp = wp->w_next)
@@ -4405,7 +4399,7 @@ void status_redraw_all() {
/*
* mark all status lines of the current buffer for redraw
*/
-void status_redraw_curbuf() {
+void status_redraw_curbuf(void) {
win_T *wp;
for (wp = firstwin; wp; wp = wp->w_next)
@@ -4418,7 +4412,7 @@ void status_redraw_curbuf() {
/*
* Redraw all status lines that need to be redrawn.
*/
-void redraw_statuslines() {
+void redraw_statuslines(void) {
win_T *wp;
for (wp = firstwin; wp; wp = wp->w_next)
@@ -4431,8 +4425,7 @@ void redraw_statuslines() {
/*
* Redraw all status lines at the bottom of frame "frp".
*/
-void win_redraw_last_status(frp)
-frame_T *frp;
+void win_redraw_last_status(frame_T *frp)
{
if (frp->fr_layout == FR_LEAF)
frp->fr_win->w_redr_status = TRUE;
@@ -4450,9 +4443,7 @@ frame_T *frp;
/*
* Draw the verticap separator right of window "wp" starting with line "row".
*/
-static void draw_vsep_win(wp, row)
-win_T *wp;
-int row;
+static void draw_vsep_win(win_T *wp, int row)
{
int hl;
int c;
@@ -4472,9 +4463,7 @@ static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
/*
* Get the length of an item as it will be shown in the status line.
*/
-static int status_match_len(xp, s)
-expand_T *xp;
-char_u *s;
+static int status_match_len(expand_T *xp, char_u *s)
{
int len = 0;
@@ -4498,9 +4487,7 @@ char_u *s;
* Return the number of characters that should be skipped in a status match.
* These are backslashes used for escaping. Do show backslashes in help tags.
*/
-static int skip_status_match_char(xp, s)
-expand_T *xp;
-char_u *s;
+static int skip_status_match_char(expand_T *xp, char_u *s)
{
if ((rem_backslash(s) && xp->xp_context != EXPAND_HELP)
|| ((xp->xp_context == EXPAND_MENUS
@@ -4523,12 +4510,14 @@ char_u *s;
*
* If inversion is possible we use it. Else '=' characters are used.
*/
-void win_redr_status_matches(xp, num_matches, matches, match, showtail)
-expand_T *xp;
-int num_matches;
-char_u **matches; /* list of matches */
-int match;
-int showtail;
+void
+win_redr_status_matches (
+ expand_T *xp,
+ int num_matches,
+ char_u **matches, /* list of matches */
+ int match,
+ int showtail
+)
{
#define L_MATCH(m) (showtail ? sm_gettail(matches[m]) : matches[m])
int row;
@@ -4702,8 +4691,7 @@ int showtail;
*
* If inversion is possible we use it. Else '=' characters are used.
*/
-void win_redr_status(wp)
-win_T *wp;
+void win_redr_status(win_T *wp)
{
int row;
char_u *p;
@@ -4823,8 +4811,7 @@ win_T *wp;
* Redraw the status line according to 'statusline' and take care of any
* errors encountered.
*/
-static void redraw_custom_statusline(wp)
-win_T *wp;
+static void redraw_custom_statusline(win_T *wp)
{
static int entered = FALSE;
int save_called_emsg = called_emsg;
@@ -4854,8 +4841,7 @@ win_T *wp;
* line of the window right of it. If not, then it's a vertical separator.
* Only call if (wp->w_vsep_width != 0).
*/
-int stl_connected(wp)
-win_T *wp;
+int stl_connected(win_T *wp)
{
frame_T *fr;
@@ -4877,10 +4863,12 @@ win_T *wp;
/*
* Get the value to show for the language mappings, active 'keymap'.
*/
-int get_keymap_str(wp, buf, len)
-win_T *wp;
-char_u *buf; /* buffer for the result */
-int len; /* length of buffer */
+int
+get_keymap_str (
+ win_T *wp,
+ char_u *buf, /* buffer for the result */
+ int len /* length of buffer */
+)
{
char_u *p;
@@ -4919,9 +4907,11 @@ int len; /* length of buffer */
* Redraw the status line or ruler of window "wp".
* When "wp" is NULL redraw the tab pages line from 'tabline'.
*/
-static void win_redr_custom(wp, draw_ruler)
-win_T *wp;
-int draw_ruler; /* TRUE or FALSE */
+static void
+win_redr_custom (
+ win_T *wp,
+ int draw_ruler /* TRUE or FALSE */
+)
{
static int entered = FALSE;
int attr;
@@ -5079,10 +5069,7 @@ theend:
/*
* Output a single character directly to the screen and update ScreenLines.
*/
-void screen_putchar(c, row, col, attr)
-int c;
-int row, col;
-int attr;
+void screen_putchar(int c, int row, int col, int attr)
{
char_u buf[MB_MAXBYTES + 1];
@@ -5099,10 +5086,7 @@ int attr;
* Get a single character directly from ScreenLines into "bytes[]".
* Also return its attribute in *attrp;
*/
-void screen_getbytes(row, col, bytes, attrp)
-int row, col;
-char_u *bytes;
-int *attrp;
+void screen_getbytes(int row, int col, char_u *bytes, int *attrp)
{
unsigned off;
@@ -5133,9 +5117,7 @@ static int screen_comp_differs __ARGS((int, int*));
* composing characters in "u8cc".
* Only to be used when ScreenLinesUC[off] != 0.
*/
-static int screen_comp_differs(off, u8cc)
-int off;
-int *u8cc;
+static int screen_comp_differs(int off, int *u8cc)
{
int i;
@@ -5154,11 +5136,7 @@ int *u8cc;
* Note: only outputs within one row, message is truncated at screen boundary!
* Note: if ScreenLines[], row and/or col is invalid, nothing is done.
*/
-void screen_puts(text, row, col, attr)
-char_u *text;
-int row;
-int col;
-int attr;
+void screen_puts(char_u *text, int row, int col, int attr)
{
screen_puts_len(text, -1, row, col, attr);
}
@@ -5167,12 +5145,7 @@ int attr;
* Like screen_puts(), but output "text[len]". When "len" is -1 output up to
* a NUL.
*/
-void screen_puts_len(text, len, row, col, attr)
-char_u *text;
-int len;
-int row;
-int col;
-int attr;
+void screen_puts_len(char_u *text, int len, int row, int col, int attr)
{
unsigned off;
char_u *ptr = text;
@@ -5383,7 +5356,7 @@ int attr;
/*
* Prepare for 'hlsearch' highlighting.
*/
-static void start_search_hl() {
+static void start_search_hl(void) {
if (p_hls && !no_hlsearch) {
last_pat_prog(&search_hl.rm);
search_hl.attr = hl_attr(HLF_L);
@@ -5395,7 +5368,7 @@ static void start_search_hl() {
/*
* Clean up for 'hlsearch' highlighting.
*/
-static void end_search_hl() {
+static void end_search_hl(void) {
if (search_hl.rm.regprog != NULL) {
vim_regfree(search_hl.rm.regprog);
search_hl.rm.regprog = NULL;
@@ -5405,8 +5378,7 @@ static void end_search_hl() {
/*
* Init for calling prepare_search_hl().
*/
-static void init_search_hl(wp)
-win_T *wp;
+static void init_search_hl(win_T *wp)
{
matchitem_T *cur;
@@ -5435,9 +5407,7 @@ win_T *wp;
/*
* Advance to the match in window "wp" line "lnum" or past it.
*/
-static void prepare_search_hl(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+static void prepare_search_hl(win_T *wp, linenr_T lnum)
{
matchitem_T *cur; /* points to the match list */
match_T *shl; /* points to search_hl or a match */
@@ -5495,11 +5465,13 @@ linenr_T lnum;
* shl->lnum is zero.
* Careful: Any pointers for buffer lines will become invalid.
*/
-static void next_search_hl(win, shl, lnum, mincol)
-win_T *win;
-match_T *shl; /* points to search_hl or a match */
-linenr_T lnum;
-colnr_T mincol; /* minimal column for a match */
+static void
+next_search_hl (
+ win_T *win,
+ match_T *shl, /* points to search_hl or a match */
+ linenr_T lnum,
+ colnr_T mincol /* minimal column for a match */
+)
{
linenr_T l;
colnr_T matchcol;
@@ -5586,8 +5558,7 @@ colnr_T mincol; /* minimal column for a match */
}
}
-static void screen_start_highlight(attr)
-int attr;
+static void screen_start_highlight(int attr)
{
attrentry_T *aep = NULL;
@@ -5641,7 +5612,7 @@ int attr;
}
}
-void screen_stop_highlight() {
+void screen_stop_highlight(void) {
int do_ME = FALSE; /* output T_ME code */
if (screen_attr != 0
@@ -5716,7 +5687,7 @@ void screen_stop_highlight() {
* Reset the colors for a cterm. Used when leaving Vim.
* The machine specific code may override this again.
*/
-void reset_cterm_colors() {
+void reset_cterm_colors(void) {
if (t_colors > 1) {
/* set Normal cterm colors */
if (cterm_normal_fg_color > 0 || cterm_normal_bg_color > 0) {
@@ -5734,10 +5705,7 @@ void reset_cterm_colors() {
* Put character ScreenLines["off"] on the screen at position "row" and "col",
* using the attributes from ScreenAttrs["off"].
*/
-static void screen_char(off, row, col)
-unsigned off;
-int row;
-int col;
+static void screen_char(unsigned off, int row, int col)
{
int attr;
@@ -5799,10 +5767,7 @@ int col;
* The attributes of the first byte is used for all. This is required to
* output the two bytes of a double-byte character with nothing in between.
*/
-static void screen_char_2(off, row, col)
-unsigned off;
-int row;
-int col;
+static void screen_char_2(unsigned off, int row, int col)
{
/* Check for illegal values (could be wrong when screen was resized). */
if (off + 1 >= (unsigned)(screen_Rows * screen_Columns))
@@ -5826,12 +5791,7 @@ int col;
* Draw a rectangle of the screen, inverted when "invert" is TRUE.
* This uses the contents of ScreenLines[] and doesn't change it.
*/
-void screen_draw_rectangle(row, col, height, width, invert)
-int row;
-int col;
-int height;
-int width;
-int invert;
+void screen_draw_rectangle(int row, int col, int height, int width, int invert)
{
int r, c;
int off;
@@ -5863,10 +5823,7 @@ int invert;
/*
* Redraw the characters for a vertically split window.
*/
-static void redraw_block(row, end, wp)
-int row;
-int end;
-win_T *wp;
+static void redraw_block(int row, int end, win_T *wp)
{
int col;
int width;
@@ -5887,11 +5844,7 @@ win_T *wp;
* with character 'c1' in first column followed by 'c2' in the other columns.
* Use attributes 'attr'.
*/
-void screen_fill(start_row, end_row, start_col, end_col, c1, c2, attr)
-int start_row, end_row;
-int start_col, end_col;
-int c1, c2;
-int attr;
+void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr)
{
int row;
int col;
@@ -6042,8 +5995,7 @@ int attr;
* Check if there should be a delay. Used before clearing or redrawing the
* screen or the command line.
*/
-void check_for_delay(check_msg_scroll)
-int check_msg_scroll;
+void check_for_delay(int check_msg_scroll)
{
if ((emsg_on_display || (check_msg_scroll && msg_scroll))
&& !did_wait_return
@@ -6062,8 +6014,7 @@ int check_msg_scroll;
* Returns TRUE if there is a valid screen to write to.
* Returns FALSE when starting up and screen not initialized yet.
*/
-int screen_valid(doclear)
-int doclear;
+int screen_valid(int doclear)
{
screenalloc(doclear); /* allocate screen buffers if size changed */
return ScreenLines != NULL;
@@ -6079,8 +6030,7 @@ int doclear;
* in ScreenLines[]. Use Rows and Columns for positioning text etc. where the
* final size of the shell is needed.
*/
-void screenalloc(doclear)
-int doclear;
+void screenalloc(int doclear)
{
int new_row, old_row;
win_T *wp;
@@ -6327,7 +6277,7 @@ give_up:
}
}
-void free_screenlines() {
+void free_screenlines(void) {
int i;
vim_free(ScreenLinesUC);
@@ -6341,13 +6291,13 @@ void free_screenlines() {
vim_free(TabPageIdxs);
}
-void screenclear() {
+void screenclear(void) {
check_for_delay(FALSE);
screenalloc(FALSE); /* allocate screen buffers if size changed */
screenclear2(); /* clear the screen */
}
-static void screenclear2() {
+static void screenclear2(void) {
int i;
if (starting == NO_SCREEN || ScreenLines == NULL
@@ -6394,9 +6344,7 @@ static void screenclear2() {
/*
* Clear one line in ScreenLines.
*/
-static void lineclear(off, width)
-unsigned off;
-int width;
+static void lineclear(unsigned off, int width)
{
(void)vim_memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T));
if (enc_utf8)
@@ -6409,9 +6357,7 @@ int width;
* Mark one line in ScreenLines invalid by setting the attributes to an
* invalid value.
*/
-static void lineinvalid(off, width)
-unsigned off;
-int width;
+static void lineinvalid(unsigned off, int width)
{
(void)vim_memset(ScreenAttrs + off, -1, (size_t)width * sizeof(sattr_T));
}
@@ -6419,10 +6365,7 @@ int width;
/*
* Copy part of a Screenline for vertically split window "wp".
*/
-static void linecopy(to, from, wp)
-int to;
-int from;
-win_T *wp;
+static void linecopy(int to, int from, win_T *wp)
{
unsigned off_to = LineOffset[to] + wp->w_wincol;
unsigned off_from = LineOffset[from] + wp->w_wincol;
@@ -6449,8 +6392,7 @@ win_T *wp;
* Return TRUE if clearing with term string "p" would work.
* It can't work when the string is empty or it won't set the right background.
*/
-int can_clear(p)
-char_u *p;
+int can_clear(char_u *p)
{
return *p != NUL && (t_colors <= 1
|| cterm_normal_bg_color == 0 || *T_UT != NUL);
@@ -6461,7 +6403,7 @@ char_u *p;
* something directly to the screen (shell commands) or a terminal control
* code.
*/
-void screen_start() {
+void screen_start(void) {
screen_cur_row = screen_cur_col = 9999;
}
@@ -6470,9 +6412,7 @@ void screen_start() {
* This tries to find the most efficient way to move, minimizing the number of
* characters sent to the terminal.
*/
-void windgoto(row, col)
-int row;
-int col;
+void windgoto(int row, int col)
{
sattr_T *p;
int i;
@@ -6685,7 +6625,7 @@ int col;
/*
* Set cursor to its position in the current window.
*/
-void setcursor() {
+void setcursor(void) {
if (redrawing()) {
validate_cursor();
windgoto(W_WINROW(curwin) + curwin->w_wrow,
@@ -6708,12 +6648,7 @@ void setcursor() {
* scrolling.
* Returns FAIL if the lines are not inserted, OK for success.
*/
-int win_ins_lines(wp, row, line_count, invalid, mayclear)
-win_T *wp;
-int row;
-int line_count;
-int invalid;
-int mayclear;
+int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
int did_delete;
int nextrow;
@@ -6782,12 +6717,7 @@ int mayclear;
* scrolling
* Return OK for success, FAIL if the lines are not deleted.
*/
-int win_del_lines(wp, row, line_count, invalid, mayclear)
-win_T *wp;
-int row;
-int line_count;
-int invalid;
-int mayclear;
+int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
{
int retval;
@@ -6830,12 +6760,7 @@ int mayclear;
* Returns OK or FAIL when the work has been done.
* Returns MAYBE when not finished yet.
*/
-static int win_do_lines(wp, row, line_count, mayclear, del)
-win_T *wp;
-int row;
-int line_count;
-int mayclear;
-int del;
+static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del)
{
int retval;
@@ -6900,8 +6825,7 @@ int del;
/*
* window 'wp' and everything after it is messed up, mark it for redraw
*/
-static void win_rest_invalid(wp)
-win_T *wp;
+static void win_rest_invalid(win_T *wp)
{
while (wp != NULL) {
redraw_win_later(wp, NOT_VALID);
@@ -6942,12 +6866,14 @@ win_T *wp;
*
* return FAIL for failure, OK for success.
*/
-int screen_ins_lines(off, row, line_count, end, wp)
-int off;
-int row;
-int line_count;
-int end;
-win_T *wp; /* NULL or window to use width from */
+int
+screen_ins_lines (
+ int off,
+ int row,
+ int line_count,
+ int end,
+ win_T *wp /* NULL or window to use width from */
+)
{
int i;
int j;
@@ -7113,13 +7039,15 @@ win_T *wp; /* NULL or window to use width from */
*
* Return OK for success, FAIL if the lines are not deleted.
*/
-int screen_del_lines(off, row, line_count, end, force, wp)
-int off;
-int row;
-int line_count;
-int end;
-int force; /* even when line_count > p_ttyscroll */
-win_T *wp UNUSED; /* NULL or window to use width from */
+int
+screen_del_lines (
+ int off,
+ int row,
+ int line_count,
+ int end,
+ int force, /* even when line_count > p_ttyscroll */
+ win_T *wp /* NULL or window to use width from */
+)
{
int j;
int i;
@@ -7292,7 +7220,7 @@ win_T *wp UNUSED; /* NULL or window to use width from */
* cleared only if a mode is shown.
* Return the length of the message (0 if no message).
*/
-int showmode() {
+int showmode(void) {
int need_clear;
int length = 0;
int do_mode;
@@ -7443,7 +7371,7 @@ int showmode() {
/*
* Position for a mode message.
*/
-static void msg_pos_mode() {
+static void msg_pos_mode(void) {
msg_col = 0;
msg_row = Rows - 1;
}
@@ -7453,8 +7381,7 @@ static void msg_pos_mode() {
* Insert mode (but Insert mode didn't end yet!).
* Caller should check "mode_displayed".
*/
-void unshowmode(force)
-int force;
+void unshowmode(int force)
{
/*
* Don't delete it right now, when not redrawing or inside a mapping.
@@ -7472,7 +7399,7 @@ int force;
/*
* Draw the tab pages line at the top of the Vim window.
*/
-static void draw_tabline() {
+static void draw_tabline(void) {
int tabcount = 0;
tabpage_T *tp;
int tabwidth;
@@ -7622,8 +7549,7 @@ static void draw_tabline() {
* Get buffer name for "buf" into NameBuff[].
* Takes care of special buffer names and translates special characters.
*/
-void get_trans_bufname(buf)
-buf_T *buf;
+void get_trans_bufname(buf_T *buf)
{
if (buf_spname(buf) != NULL)
vim_strncpy(NameBuff, buf_spname(buf), MAXPATHL - 1);
@@ -7635,9 +7561,7 @@ buf_T *buf;
/*
* Get the character to use in a status line. Get its attributes in "*attr".
*/
-static int fillchar_status(attr, is_curwin)
-int *attr;
-int is_curwin;
+static int fillchar_status(int *attr, int is_curwin)
{
int fill;
if (is_curwin) {
@@ -7663,8 +7587,7 @@ int is_curwin;
* Get the character to use in a separator between vertically split windows.
* Get its attributes in "*attr".
*/
-static int fillchar_vsep(attr)
-int *attr;
+static int fillchar_vsep(int *attr)
{
*attr = hl_attr(HLF_C);
if (*attr == 0 && fill_vert == ' ')
@@ -7676,7 +7599,7 @@ int *attr;
/*
* Return TRUE if redrawing should currently be done.
*/
-int redrawing() {
+int redrawing(void) {
return !RedrawingDisabled
&& !(p_lz && char_avail() && !KeyTyped && !do_redraw);
}
@@ -7684,7 +7607,7 @@ int redrawing() {
/*
* Return TRUE if printing messages should currently be done.
*/
-int messaging() {
+int messaging(void) {
return !(p_lz && char_avail() && !KeyTyped);
}
@@ -7692,8 +7615,7 @@ int messaging() {
* Show current status info in ruler and various other places
* If always is FALSE, only show ruler if position has changed.
*/
-void showruler(always)
-int always;
+void showruler(int always)
{
if (!always && !redrawing())
return;
@@ -7717,9 +7639,7 @@ int always;
draw_tabline();
}
-static void win_redr_ruler(wp, always)
-win_T *wp;
-int always;
+static void win_redr_ruler(win_T *wp, int always)
{
#define RULER_BUF_LEN 70
char_u buffer[RULER_BUF_LEN];
@@ -7887,8 +7807,7 @@ int always;
* Caller may need to check if 'number' or 'relativenumber' is set.
* Otherwise it depends on 'numberwidth' and the line count.
*/
-int number_width(wp)
-win_T *wp;
+int number_width(win_T *wp)
{
int n;
linenr_T lnum;
@@ -7922,7 +7841,7 @@ win_T *wp;
* Return the current cursor column. This is the actual position on the
* screen. First column is 0.
*/
-int screen_screencol() {
+int screen_screencol(void) {
return screen_cur_col;
}
@@ -7930,7 +7849,7 @@ int screen_screencol() {
* Return the current cursor row. This is the actual position on the screen.
* First row is 0.
*/
-int screen_screenrow() {
+int screen_screenrow(void) {
return screen_cur_row;
}
diff --git a/src/proto/screen.pro b/src/screen.h
index 53a909e242..2f25798757 100644
--- a/src/proto/screen.pro
+++ b/src/screen.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_SCREEN_H
+#define NEOVIM_SCREEN_H
/* screen.c */
void redraw_later __ARGS((int type));
void redraw_win_later __ARGS((win_T *wp, int type));
@@ -64,3 +66,4 @@ int number_width __ARGS((win_T *wp));
int screen_screencol __ARGS((void));
int screen_screenrow __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_SCREEN_H */
diff --git a/src/search.c b/src/search.c
index 6007b53375..7c89b775d0 100644
--- a/src/search.c
+++ b/src/search.c
@@ -11,6 +11,31 @@
*/
#include "vim.h"
+#include "search.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "main.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "regexp.h"
+#include "screen.h"
+#include "term.h"
+#include "ui.h"
+#include "window.h"
static void save_re_pat __ARGS((int idx, char_u *pat, int magic));
static void set_vv_searchforward __ARGS((void));
@@ -113,12 +138,14 @@ typedef struct SearchedFile {
*
* returns FAIL if failed, OK otherwise.
*/
-int search_regcomp(pat, pat_save, pat_use, options, regmatch)
-char_u *pat;
-int pat_save;
-int pat_use;
-int options;
-regmmatch_T *regmatch; /* return: pattern and ignore-case flag */
+int
+search_regcomp (
+ char_u *pat,
+ int pat_save,
+ int pat_use,
+ int options,
+ regmmatch_T *regmatch /* return: pattern and ignore-case flag */
+)
{
int magic;
int i;
@@ -190,7 +217,7 @@ regmmatch_T *regmatch; /* return: pattern and ignore-case flag */
/*
* Get search pattern used by search_regcomp().
*/
-char_u * get_search_pat() {
+char_u *get_search_pat(void) {
return mr_pattern;
}
@@ -198,8 +225,7 @@ char_u * get_search_pat() {
* Reverse text into allocated memory.
* Returns the allocated string, NULL when out of memory.
*/
-char_u * reverse_text(s)
-char_u *s;
+char_u *reverse_text(char_u *s)
{
unsigned len;
unsigned s_i, rev_i;
@@ -229,10 +255,7 @@ char_u *s;
return rev;
}
-static void save_re_pat(idx, pat, magic)
-int idx;
-char_u *pat;
-int magic;
+static void save_re_pat(int idx, char_u *pat, int magic)
{
if (spats[idx].pat != pat) {
vim_free(spats[idx].pat);
@@ -253,7 +276,7 @@ int magic;
*/
static int save_level = 0;
-void save_search_patterns() {
+void save_search_patterns(void) {
if (save_level++ == 0) {
saved_spats[0] = spats[0];
if (spats[0].pat != NULL)
@@ -266,7 +289,7 @@ void save_search_patterns() {
}
}
-void restore_search_patterns() {
+void restore_search_patterns(void) {
if (--save_level == 0) {
vim_free(spats[0].pat);
spats[0] = saved_spats[0];
@@ -279,7 +302,7 @@ void restore_search_patterns() {
}
#if defined(EXITFREE) || defined(PROTO)
-void free_search_patterns() {
+void free_search_patterns(void) {
vim_free(spats[0].pat);
vim_free(spats[1].pat);
@@ -296,8 +319,7 @@ void free_search_patterns() {
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.
*/
-int ignorecase(pat)
-char_u *pat;
+int ignorecase(char_u *pat)
{
int ic = p_ic;
@@ -313,8 +335,7 @@ char_u *pat;
/*
* Return TRUE if patter "pat" has an uppercase character.
*/
-int pat_has_uppercase(pat)
-char_u *pat;
+int pat_has_uppercase(char_u *pat)
{
char_u *p = pat;
@@ -342,14 +363,14 @@ char_u *pat;
return FALSE;
}
-char_u * last_search_pat() {
+char_u *last_search_pat(void) {
return spats[last_idx].pat;
}
/*
* Reset search direction to forward. For "gd" and "gD" commands.
*/
-void reset_search_dir() {
+void reset_search_dir(void) {
spats[0].off.dir = '/';
set_vv_searchforward();
}
@@ -358,11 +379,7 @@ void reset_search_dir() {
* Set the last search pattern. For ":let @/ =" and viminfo.
* Also set the saved search pattern, so that this works in an autocommand.
*/
-void set_last_search_pat(s, idx, magic, setlast)
-char_u *s;
-int idx;
-int magic;
-int setlast;
+void set_last_search_pat(char_u *s, int idx, int magic, int setlast)
{
vim_free(spats[idx].pat);
/* An empty string means that nothing should be matched. */
@@ -398,8 +415,7 @@ int setlast;
* This is used for highlighting all matches in a window.
* Values returned in regmatch->regprog and regmatch->rmm_ic.
*/
-void last_pat_prog(regmatch)
-regmmatch_T *regmatch;
+void last_pat_prog(regmmatch_T *regmatch)
{
if (spats[last_idx].pat == NULL) {
regmatch->regprog = NULL;
@@ -440,7 +456,7 @@ long count;
int options;
int pat_use; /* which pattern to use when "pat" is empty */
linenr_T stop_lnum; /* stop after this line number when != 0 */
-proftime_T *tm UNUSED; /* timeout limit or NULL */
+proftime_T *tm; /* timeout limit or NULL */
{
int found;
linenr_T lnum; /* no init to shut up Apollo cc */
@@ -827,21 +843,19 @@ proftime_T *tm UNUSED; /* timeout limit or NULL */
return submatch + 1;
}
-void set_search_direction(cdir)
-int cdir;
+void set_search_direction(int cdir)
{
spats[0].off.dir = cdir;
}
-static void set_vv_searchforward() {
+static void set_vv_searchforward(void) {
set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/'));
}
/*
* Return the number of the first subpat that matched.
*/
-static int first_submatch(rp)
-regmmatch_T *rp;
+static int first_submatch(regmmatch_T *rp)
{
int submatch;
@@ -1208,11 +1222,7 @@ end_do_search:
* ADDING is set. if p_ic is set then the pattern must be in lowercase.
* Return OK for success, or FAIL if no line found.
*/
-int search_for_exact_line(buf, pos, dir, pat)
-buf_T *buf;
-pos_T *pos;
-int dir;
-char_u *pat;
+int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
{
linenr_T start = 0;
char_u *ptr;
@@ -1275,9 +1285,7 @@ char_u *pat;
* Do this "cap->count1" times.
* Return FAIL or OK.
*/
-int searchc(cap, t_cmd)
-cmdarg_T *cap;
-int t_cmd;
+int searchc(cmdarg_T *cap, int t_cmd)
{
int c = cap->nchar; /* char to search for */
int dir = cap->arg; /* TRUE for searching forward */
@@ -1389,9 +1397,7 @@ int t_cmd;
*
* Improvement over vi: Braces inside quotes are ignored.
*/
-pos_T * findmatch(oap, initc)
-oparg_T *oap;
-int initc;
+pos_T *findmatch(oparg_T *oap, int initc)
{
return findmatchlimit(oap, initc, 0, 0);
}
@@ -1403,11 +1409,7 @@ int initc;
* is NULL.
* Handles multibyte string correctly.
*/
-static int check_prevcol(linep, col, ch, prevcol)
-char_u *linep;
-int col;
-int ch;
-int *prevcol;
+static int check_prevcol(char_u *linep, int col, int ch, int *prevcol)
{
--col;
if (col > 0 && has_mbyte)
@@ -1434,11 +1436,7 @@ int *prevcol;
* NULL
*/
-pos_T * findmatchlimit(oap, initc, flags, maxtravel)
-oparg_T *oap;
-int initc;
-int flags;
-int maxtravel;
+pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int maxtravel)
{
static pos_T pos; /* current search position */
int findc = 0; /* matching brace */
@@ -1945,8 +1943,7 @@ int maxtravel;
* Return MAXCOL if not, otherwise return the column.
* TODO: skip strings.
*/
-static int check_linecomment(line)
-char_u *line;
+static int check_linecomment(char_u *line)
{
char_u *p;
@@ -1993,8 +1990,10 @@ char_u *line;
* Show the match only if it is visible on the screen.
* If there isn't a match, then beep.
*/
-void showmatch(c)
-int c; /* char to show match for */
+void
+showmatch (
+ int c /* char to show match for */
+)
{
pos_T *lpos, save_cursor;
pos_T mpos;
@@ -2085,9 +2084,7 @@ int c; /* char to show match for */
* space or a line break. Also stop at an empty line.
* Return OK if the next sentence was found.
*/
-int findsent(dir, count)
-int dir;
-long count;
+int findsent(int dir, long count)
{
pos_T pos, tpos;
int c;
@@ -2201,12 +2198,14 @@ found:
* If 'both' is TRUE also stop at '}'.
* Return TRUE if the next paragraph or section was found.
*/
-int findpar(pincl, dir, count, what, both)
-int *pincl; /* Return: TRUE if last char is to be included */
-int dir;
-long count;
-int what;
-int both;
+int
+findpar (
+ int *pincl, /* Return: TRUE if last char is to be included */
+ int dir,
+ long count,
+ int what,
+ int both
+)
{
linenr_T curr;
int did_skip; /* TRUE after separating lines have been skipped */
@@ -2267,9 +2266,7 @@ int both;
/*
* check if the string 's' is a nroff macro that is in option 'opt'
*/
-static int inmacro(opt, s)
-char_u *opt;
-char_u *s;
+static int inmacro(char_u *opt, char_u *s)
{
char_u *macro;
@@ -2296,10 +2293,7 @@ char_u *s;
* If 'para' is '{' or '}' only check for sections.
* If 'both' is TRUE also stop at '}'
*/
-int startPS(lnum, para, both)
-linenr_T lnum;
-int para;
-int both;
+int startPS(linenr_T lnum, int para, int both)
{
char_u *s;
@@ -2337,7 +2331,7 @@ static int cls_bigword; /* TRUE for "W", "B" or "E" */
* from class 2 and higher are reported as class 1 since only white space
* boundaries are of interest.
*/
-static int cls() {
+static int cls(void) {
int c;
c = gchar_cursor();
@@ -2375,10 +2369,12 @@ static int cls() {
* Returns FAIL if the cursor was already at the end of the file.
* If eol is TRUE, last word stops at end of line (for operators).
*/
-int fwd_word(count, bigword, eol)
-long count;
-int bigword; /* "W", "E" or "B" */
-int eol;
+int
+fwd_word (
+ long count,
+ int bigword, /* "W", "E" or "B" */
+ int eol
+)
{
int sclass; /* starting class */
int i;
@@ -2439,10 +2435,7 @@ int eol;
*
* Returns FAIL if top of the file was reached.
*/
-int bck_word(count, bigword, stop)
-long count;
-int bigword;
-int stop;
+int bck_word(long count, int bigword, int stop)
{
int sclass; /* starting class */
@@ -2499,11 +2492,7 @@ finished:
* If stop is TRUE and we are already on the end of a word, move one less.
* If empty is TRUE stop on an empty line.
*/
-int end_word(count, bigword, stop, empty)
-long count;
-int bigword;
-int stop;
-int empty;
+int end_word(long count, int bigword, int stop, int empty)
{
int sclass; /* starting class */
@@ -2559,10 +2548,12 @@ finished:
*
* Returns FAIL if start of the file was reached.
*/
-int bckend_word(count, bigword, eol)
-long count;
-int bigword; /* TRUE for "B" */
-int eol; /* TRUE: stop at end of line. */
+int
+bckend_word (
+ long count,
+ int bigword, /* TRUE for "B" */
+ int eol /* TRUE: stop at end of line. */
+)
{
int sclass; /* starting class */
int i;
@@ -2602,9 +2593,7 @@ int eol; /* TRUE: stop at end of line. */
* Skip a row of characters of the same class.
* Return TRUE when end-of-file reached, FALSE otherwise.
*/
-static int skip_chars(cclass, dir)
-int cclass;
-int dir;
+static int skip_chars(int cclass, int dir)
{
while (cls() == cclass)
if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)
@@ -2615,7 +2604,7 @@ int dir;
/*
* Go back to the start of the word or the start of white space
*/
-static void back_in_line() {
+static void back_in_line(void) {
int sclass; /* starting class */
sclass = cls();
@@ -2630,8 +2619,7 @@ static void back_in_line() {
}
}
-static void find_first_blank(posp)
-pos_T *posp;
+static void find_first_blank(pos_T *posp)
{
int c;
@@ -2647,9 +2635,11 @@ pos_T *posp;
/*
* Skip count/2 sentences and count/2 separating white spaces.
*/
-static void findsent_forward(count, at_start_sent)
-long count;
-int at_start_sent; /* cursor is at start of sentence */
+static void
+findsent_forward (
+ long count,
+ int at_start_sent /* cursor is at start of sentence */
+)
{
while (count--) {
findsent(FORWARD, 1L);
@@ -2665,11 +2655,13 @@ int at_start_sent; /* cursor is at start of sentence */
* Find word under cursor, cursor at end.
* Used while an operator is pending, and in Visual mode.
*/
-int current_word(oap, count, include, bigword)
-oparg_T *oap;
-long count;
-int include; /* TRUE: include word and white space */
-int bigword; /* FALSE == word, TRUE == WORD */
+int
+current_word (
+ oparg_T *oap,
+ long count,
+ int include, /* TRUE: include word and white space */
+ int bigword /* FALSE == word, TRUE == WORD */
+)
{
pos_T start_pos;
pos_T pos;
@@ -2815,10 +2807,7 @@ int bigword; /* FALSE == word, TRUE == WORD */
* Find sentence(s) under the cursor, cursor at end.
* When Visual active, extend it by one or more sentences.
*/
-int current_sent(oap, count, include)
-oparg_T *oap;
-long count;
-int include;
+int current_sent(oparg_T *oap, long count, int include)
{
pos_T start_pos;
pos_T pos;
@@ -2973,12 +2962,14 @@ extend:
* Find block under the cursor, cursor at end.
* "what" and "other" are two matching parenthesis/brace/etc.
*/
-int current_block(oap, count, include, what, other)
-oparg_T *oap;
-long count;
-int include; /* TRUE == include white space */
-int what; /* '(', '{', etc. */
-int other; /* ')', '}', etc. */
+int
+current_block (
+ oparg_T *oap,
+ long count,
+ int include, /* TRUE == include white space */
+ int what, /* '(', '{', etc. */
+ int other /* ')', '}', etc. */
+)
{
pos_T old_pos;
pos_T *pos = NULL;
@@ -3106,8 +3097,7 @@ static int in_html_tag __ARGS((int));
* Return TRUE if the cursor is on a "<aaa>" tag. Ignore "<aaa/>".
* When "end_tag" is TRUE return TRUE if the cursor is on "</aaa>".
*/
-static int in_html_tag(end_tag)
-int end_tag;
+static int in_html_tag(int end_tag)
{
char_u *line = ml_get_curline();
char_u *p;
@@ -3169,10 +3159,12 @@ int end_tag;
/*
* Find tag block under the cursor, cursor at end.
*/
-int current_tagblock(oap, count_arg, include)
-oparg_T *oap;
-long count_arg;
-int include; /* TRUE == include white space */
+int
+current_tagblock (
+ oparg_T *oap,
+ long count_arg,
+ int include /* TRUE == include white space */
+)
{
long count = count_arg;
long n;
@@ -3344,11 +3336,13 @@ theend:
return retval;
}
-int current_par(oap, count, include, type)
-oparg_T *oap;
-long count;
-int include; /* TRUE == include white space */
-int type; /* 'p' for paragraph, 'S' for section */
+int
+current_par (
+ oparg_T *oap,
+ long count,
+ int include, /* TRUE == include white space */
+ int type /* 'p' for paragraph, 'S' for section */
+)
{
linenr_T start_lnum;
linenr_T end_lnum;
@@ -3509,11 +3503,13 @@ static int find_prev_quote __ARGS((char_u *line, int col_start, int quotechar,
* as a quote.
* Returns column number of "quotechar" or -1 when not found.
*/
-static int find_next_quote(line, col, quotechar, escape)
-char_u *line;
-int col;
-int quotechar;
-char_u *escape; /* escape characters, can be NULL */
+static int
+find_next_quote (
+ char_u *line,
+ int col,
+ int quotechar,
+ char_u *escape /* escape characters, can be NULL */
+)
{
int c;
@@ -3539,11 +3535,13 @@ char_u *escape; /* escape characters, can be NULL */
* as a quote.
* Return the found column or zero.
*/
-static int find_prev_quote(line, col_start, quotechar, escape)
-char_u *line;
-int col_start;
-int quotechar;
-char_u *escape; /* escape characters, can be NULL */
+static int
+find_prev_quote (
+ char_u *line,
+ int col_start,
+ int quotechar,
+ char_u *escape /* escape characters, can be NULL */
+)
{
int n;
@@ -3567,11 +3565,13 @@ char_u *escape; /* escape characters, can be NULL */
* Find quote under the cursor, cursor at end.
* Returns TRUE if found, else FALSE.
*/
-int current_quote(oap, count, include, quotechar)
-oparg_T *oap;
-long count;
-int include; /* TRUE == include quote char */
-int quotechar; /* Quote character */
+int
+current_quote (
+ oparg_T *oap,
+ long count,
+ int include, /* TRUE == include quote char */
+ int quotechar /* Quote character */
+)
{
char_u *line = ml_get_curline();
int col_end;
@@ -3779,9 +3779,11 @@ static int is_one_char __ARGS((char_u *pattern));
* Used while an operator is pending, and in Visual mode.
* TODO: redo only works when used in operator pending mode
*/
-int current_search(count, forward)
-long count;
-int forward; /* move forward or backwards */
+int
+current_search (
+ long count,
+ int forward /* move forward or backwards */
+)
{
pos_T start_pos; /* position before the pattern */
pos_T orig_pos; /* position of the cursor at beginning */
@@ -3909,8 +3911,7 @@ int forward; /* move forward or backwards */
* Check if the pattern is one character or zero-width.
* Returns TRUE, FALSE or -1 for failure.
*/
-static int is_one_char(pattern)
-char_u *pattern;
+static int is_one_char(char_u *pattern)
{
regmmatch_T regmatch;
int nmatched = 0;
@@ -3951,8 +3952,7 @@ char_u *pattern;
/*
* return TRUE if line 'lnum' is empty or has white chars only.
*/
-int linewhite(lnum)
-linenr_T lnum;
+int linewhite(linenr_T lnum)
{
char_u *p;
@@ -3965,19 +3965,20 @@ linenr_T lnum;
* Find identifiers or defines in included files.
* If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
*/
-void find_pattern_in_path(ptr, dir, len, whole, skip_comments,
- type, count, action, start_lnum, end_lnum)
-char_u *ptr; /* pointer to search pattern */
-int dir UNUSED; /* direction of expansion */
-int len; /* length of search pattern */
-int whole; /* match whole words only */
-int skip_comments; /* don't match inside comments */
-int type; /* Type of search; are we looking for a type?
+void
+find_pattern_in_path (
+ char_u *ptr, /* pointer to search pattern */
+ int dir, /* direction of expansion */
+ int len, /* length of search pattern */
+ int whole, /* match whole words only */
+ int skip_comments, /* don't match inside comments */
+ int type, /* Type of search; are we looking for a type?
a macro? */
-long count;
-int action; /* What to do when we find it */
-linenr_T start_lnum; /* first line to start searching */
-linenr_T end_lnum; /* last line for searching */
+ long count,
+ int action, /* What to do when we find it */
+ linenr_T start_lnum, /* first line to start searching */
+ linenr_T end_lnum /* last line for searching */
+)
{
SearchedFile *files; /* Stack of included files */
SearchedFile *bigger; /* When we need more space */
@@ -4554,14 +4555,7 @@ fpip_end:
vim_regfree(def_regmatch.regprog);
}
-static void show_pat_in_path(line, type, did_show, action, fp, lnum, count)
-char_u *line;
-int type;
-int did_show;
-int action;
-FILE *fp;
-linenr_T *lnum;
-long count;
+static void show_pat_in_path(char_u *line, int type, int did_show, int action, FILE *fp, linenr_T *lnum, long count)
{
char_u *p;
@@ -4609,9 +4603,7 @@ long count;
}
}
-int read_viminfo_search_pattern(virp, force)
-vir_T *virp;
-int force;
+int read_viminfo_search_pattern(vir_T *virp, int force)
{
char_u *lp;
int idx = -1;
@@ -4684,8 +4676,7 @@ int force;
return viminfo_readline(virp);
}
-void write_viminfo_search_pattern(fp)
-FILE *fp;
+void write_viminfo_search_pattern(FILE *fp)
{
if (get_viminfo_parameter('/') != 0) {
fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c",
@@ -4695,11 +4686,13 @@ FILE *fp;
}
}
-static void wvsp_one(fp, idx, s, sc)
-FILE *fp; /* file to write to */
-int idx; /* spats[] index */
-char *s; /* search pat */
-int sc; /* dir char */
+static void
+wvsp_one (
+ FILE *fp, /* file to write to */
+ int idx, /* spats[] index */
+ char *s, /* search pat */
+ int sc /* dir char */
+)
{
if (spats[idx].pat != NULL) {
fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s);
diff --git a/src/proto/search.pro b/src/search.h
index 9c3c520c9f..b24d2aa69a 100644
--- a/src/proto/search.pro
+++ b/src/search.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_SEARCH_H
+#define NEOVIM_SEARCH_H
/* search.c */
int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options,
regmmatch_T *regmatch));
@@ -47,3 +49,4 @@ void find_pattern_in_path __ARGS((char_u *ptr, int dir, int len, int whole,
int read_viminfo_search_pattern __ARGS((vir_T *virp, int force));
void write_viminfo_search_pattern __ARGS((FILE *fp));
/* vim: set ft=c : */
+#endif /* NEOVIM_SEARCH_H */
diff --git a/src/sha256.c b/src/sha256.c
index 0761987ebe..bc2be2678f 100644
--- a/src/sha256.c
+++ b/src/sha256.c
@@ -21,7 +21,7 @@
*/
#include "vim.h"
-
+#include "sha256.h"
static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
@@ -41,8 +41,7 @@ static void sha256_process __ARGS((context_sha256_T *ctx, char_u data[64]));
(b)[(i) + 3] = (char_u)((n) ); \
}
-void sha256_start(ctx)
-context_sha256_T *ctx;
+void sha256_start(context_sha256_T *ctx)
{
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -57,9 +56,7 @@ context_sha256_T *ctx;
ctx->state[7] = 0x5BE0CD19;
}
-static void sha256_process(ctx, data)
-context_sha256_T *ctx;
-char_u data[64];
+static void sha256_process(context_sha256_T *ctx, char_u data[64])
{
UINT32_T temp1, temp2, W[64];
UINT32_T A, B, C, D, E, F, G, H;
@@ -190,10 +187,7 @@ char_u data[64];
ctx->state[7] += H;
}
-void sha256_update(ctx, input, length)
-context_sha256_T *ctx;
-char_u *input;
-UINT32_T length;
+void sha256_update(context_sha256_T *ctx, char_u *input, UINT32_T length)
{
UINT32_T left, fill;
@@ -234,9 +228,7 @@ static char_u sha256_padding[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-void sha256_finish(ctx, digest)
-context_sha256_T *ctx;
-char_u digest[32];
+void sha256_finish(context_sha256_T *ctx, char_u digest[32])
{
UINT32_T last, padn;
UINT32_T high, low;
@@ -270,11 +262,7 @@ static unsigned int get_some_time __ARGS((void));
* Returns hex digest of "buf[buf_len]" in a static array.
* if "salt" is not NULL also do "salt[salt_len]".
*/
-char_u * sha256_bytes(buf, buf_len, salt, salt_len)
-char_u *buf;
-int buf_len;
-char_u *salt;
-int salt_len;
+char_u *sha256_bytes(char_u *buf, int buf_len, char_u *salt, int salt_len)
{
char_u sha256sum[32];
static char_u hexit[65];
@@ -297,10 +285,7 @@ int salt_len;
/*
* Returns sha256(buf) as 64 hex chars in static array.
*/
-char_u * sha256_key(buf, salt, salt_len)
-char_u *buf;
-char_u *salt;
-int salt_len;
+char_u *sha256_key(char_u *buf, char_u *salt, int salt_len)
{
/* No passwd means don't encrypt */
if (buf == NULL || *buf == NUL)
@@ -332,7 +317,7 @@ static char *sha_self_test_vector[] = {
* Perform a test on the SHA256 algorithm.
* Return FAIL or OK.
*/
-int sha256_self_test() {
+int sha256_self_test(void) {
int i, j;
char output[65];
context_sha256_T ctx;
@@ -370,7 +355,7 @@ int sha256_self_test() {
return failures > 0 ? FAIL : OK;
}
-static unsigned int get_some_time() {
+static unsigned int get_some_time(void) {
# ifdef HAVE_GETTIMEOFDAY
struct timeval tv;
@@ -386,11 +371,7 @@ static unsigned int get_some_time() {
* Fill "header[header_len]" with random_data.
* Also "salt[salt_len]" when "salt" is not NULL.
*/
-void sha2_seed(header, header_len, salt, salt_len)
-char_u *header;
-int header_len;
-char_u *salt;
-int salt_len;
+void sha2_seed(char_u *header, int header_len, char_u *salt, int salt_len)
{
int i;
static char_u random_data[1000];
diff --git a/src/proto/sha256.pro b/src/sha256.h
index dca9e37998..03e8aa6bea 100644
--- a/src/proto/sha256.pro
+++ b/src/sha256.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_SHA256_H
+#define NEOVIM_SHA256_H
/* sha256.c */
void sha256_start __ARGS((context_sha256_T *ctx));
void sha256_update __ARGS((context_sha256_T *ctx, char_u *input,
@@ -10,3 +12,4 @@ int sha256_self_test __ARGS((void));
void sha2_seed __ARGS((char_u *header, int header_len, char_u *salt,
int salt_len));
/* vim: set ft=c : */
+#endif /* NEOVIM_SHA256_H */
diff --git a/src/spell.c b/src/spell.c
index 05c6543ef6..3fae72ffd2 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -298,9 +298,34 @@
*/
#include "vim.h"
-
-
-#ifndef UNIX /* it's in os_unix.h for Unix */
+#include "spell.h"
+#include "buffer.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "syntax.h"
+#include "term.h"
+#include "ui.h"
+#include "undo.h"
+
+#ifndef UNIX /* it's in os_unix_defs.h for Unix */
# include <time.h> /* for time_t */
#endif
@@ -996,12 +1021,14 @@ static char_u *repl_to = NULL;
* Returns the length of the word in bytes, also when it's OK, so that the
* caller can skip over the word.
*/
-int spell_check(wp, ptr, attrp, capcol, docount)
-win_T *wp; /* current window */
-char_u *ptr;
-hlf_T *attrp;
-int *capcol; /* column to check for Capital */
-int docount; /* count good words */
+int
+spell_check (
+ win_T *wp, /* current window */
+ char_u *ptr,
+ hlf_T *attrp,
+ int *capcol, /* column to check for Capital */
+ int docount /* count good words */
+)
{
matchinf_T mi; /* Most things are put in "mi" so that it can
be passed to functions quickly. */
@@ -1191,9 +1218,7 @@ int docount; /* count good words */
*
* For a match mip->mi_result is updated.
*/
-static void find_word(mip, mode)
-matchinf_T *mip;
-int mode;
+static void find_word(matchinf_T *mip, int mode)
{
idx_T arridx = 0;
int endlen[MAXWLEN]; /* length at possible word endings */
@@ -1643,10 +1668,12 @@ int mode;
* A match means that the first part of CHECKCOMPOUNDPATTERN matches at the
* end of ptr[wlen] and the second part matches after it.
*/
-static int match_checkcompoundpattern(ptr, wlen, gap)
-char_u *ptr;
-int wlen;
-garray_T *gap; /* &sl_comppat */
+static int
+match_checkcompoundpattern (
+ char_u *ptr,
+ int wlen,
+ garray_T *gap /* &sl_comppat */
+)
{
int i;
char_u *p;
@@ -1670,10 +1697,7 @@ garray_T *gap; /* &sl_comppat */
* Return TRUE if "flags" is a valid sequence of compound flags and "word"
* does not have too many syllables.
*/
-static int can_compound(slang, word, flags)
-slang_T *slang;
-char_u *word;
-char_u *flags;
+static int can_compound(slang_T *slang, char_u *word, char_u *flags)
{
regmatch_T regmatch;
char_u uflags[MAXWLEN * 2];
@@ -1710,11 +1734,7 @@ char_u *flags;
* possibly form a valid compounded word. This also checks the COMPOUNDRULE
* lines if they don't contain wildcards.
*/
-static int can_be_compound(sp, slang, compflags, flag)
-trystate_T *sp;
-slang_T *slang;
-char_u *compflags;
-int flag;
+static int can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags, int flag)
{
/* If the flag doesn't appear in sl_compstartflags or sl_compallflags
* then it can't possibly compound. */
@@ -1745,9 +1765,7 @@ int flag;
* collected so far can't possibly match any compound rule.
* Caller must check that slang->sl_comprules is not NULL.
*/
-static int match_compoundrule(slang, compflags)
-slang_T *slang;
-char_u *compflags;
+static int match_compoundrule(slang_T *slang, char_u *compflags)
{
char_u *p;
int i;
@@ -1795,13 +1813,15 @@ char_u *compflags;
* ID in "flags" for the word "word".
* The WF_RAREPFX flag is included in the return value for a rare prefix.
*/
-static int valid_word_prefix(totprefcnt, arridx, flags, word, slang, cond_req)
-int totprefcnt; /* nr of prefix IDs */
-int arridx; /* idx in sl_pidxs[] */
-int flags;
-char_u *word;
-slang_T *slang;
-int cond_req; /* only use prefixes with a condition */
+static int
+valid_word_prefix (
+ int totprefcnt, /* nr of prefix IDs */
+ int arridx, /* idx in sl_pidxs[] */
+ int flags,
+ char_u *word,
+ slang_T *slang,
+ int cond_req /* only use prefixes with a condition */
+)
{
int prefcnt;
int pidx;
@@ -1848,9 +1868,7 @@ int cond_req; /* only use prefixes with a condition */
*
* For a match mip->mi_result is updated.
*/
-static void find_prefix(mip, mode)
-matchinf_T *mip;
-int mode;
+static void find_prefix(matchinf_T *mip, int mode)
{
idx_T arridx = 0;
int len;
@@ -1960,8 +1978,7 @@ int mode;
* for efficiency. Include the non-word character too.
* Return the length of the folded chars in bytes.
*/
-static int fold_more(mip)
-matchinf_T *mip;
+static int fold_more(matchinf_T *mip)
{
int flen;
char_u *p;
@@ -1987,9 +2004,11 @@ matchinf_T *mip;
* Check case flags for a word. Return TRUE if the word has the requested
* case.
*/
-static int spell_valid_case(wordflags, treeflags)
-int wordflags; /* flags for the checked word. */
-int treeflags; /* flags for the word in the spell tree */
+static int
+spell_valid_case (
+ int wordflags, /* flags for the checked word. */
+ int treeflags /* flags for the word in the spell tree */
+)
{
return (wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0)
|| ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0
@@ -2000,8 +2019,7 @@ int treeflags; /* flags for the word in the spell tree */
/*
* Return TRUE if spell checking is not enabled.
*/
-static int no_spell_checking(wp)
-win_T *wp;
+static int no_spell_checking(win_T *wp)
{
if (!wp->w_p_spell || *wp->w_s->b_p_spl == NUL
|| wp->w_s->b_langp.ga_len == 0) {
@@ -2019,13 +2037,15 @@ win_T *wp;
* to after badly spelled word before the cursor.
* Return 0 if not found, length of the badly spelled word otherwise.
*/
-int spell_move_to(wp, dir, allwords, curline, attrp)
-win_T *wp;
-int dir; /* FORWARD or BACKWARD */
-int allwords; /* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */
-int curline;
-hlf_T *attrp; /* return: attributes of bad word or NULL
+int
+spell_move_to (
+ win_T *wp,
+ int dir, /* FORWARD or BACKWARD */
+ int allwords, /* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */
+ int curline,
+ hlf_T *attrp /* return: attributes of bad word or NULL
(only when "dir" is FORWARD) */
+)
{
linenr_T lnum;
pos_T found_pos;
@@ -2240,10 +2260,7 @@ hlf_T *attrp; /* return: attributes of bad word or NULL
* Keep the blanks at the start of the next line, this is used in win_line()
* to skip those bytes if the word was OK.
*/
-void spell_cat_line(buf, line, maxlen)
-char_u *buf;
-char_u *line;
-int maxlen;
+void spell_cat_line(char_u *buf, char_u *line, int maxlen)
{
char_u *p;
int n;
@@ -2276,8 +2293,7 @@ typedef struct spelload_S {
* Load word list(s) for "lang" from Vim spell file(s).
* "lang" must be the language without the region: e.g., "en".
*/
-static void spell_load_lang(lang)
-char_u *lang;
+static void spell_load_lang(char_u *lang)
{
char_u fname_enc[85];
int r;
@@ -2332,7 +2348,7 @@ char_u *lang;
* Return the encoding used for spell checking: Use 'encoding', except that we
* use "latin1" for "latin9". And limit to 60 characters (just in case).
*/
-static char_u * spell_enc() {
+static char_u *spell_enc(void) {
if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
return p_enc;
@@ -2343,8 +2359,7 @@ static char_u * spell_enc() {
* Get the name of the .spl file for the internal wordlist into
* "fname[MAXPATHL]".
*/
-static void int_wordlist_spl(fname)
-char_u *fname;
+static void int_wordlist_spl(char_u *fname)
{
vim_snprintf((char *)fname, MAXPATHL, SPL_FNAME_TMPL,
int_wordlist, spell_enc());
@@ -2354,8 +2369,7 @@ char_u *fname;
* Allocate a new slang_T for language "lang". "lang" can be NULL.
* Caller must fill "sl_next".
*/
-static slang_T * slang_alloc(lang)
-char_u *lang;
+static slang_T *slang_alloc(char_u *lang)
{
slang_T *lp;
@@ -2376,8 +2390,7 @@ char_u *lang;
/*
* Free the contents of an slang_T and the structure itself.
*/
-static void slang_free(lp)
-slang_T *lp;
+static void slang_free(slang_T *lp)
{
vim_free(lp->sl_name);
vim_free(lp->sl_fname);
@@ -2388,8 +2401,7 @@ slang_T *lp;
/*
* Clear an slang_T so that the file can be reloaded.
*/
-static void slang_clear(lp)
-slang_T *lp;
+static void slang_clear(slang_T *lp)
{
garray_T *gap;
fromto_T *ftp;
@@ -2485,8 +2497,7 @@ slang_T *lp;
/*
* Clear the info from the .sug file in "lp".
*/
-static void slang_clear_sug(lp)
-slang_T *lp;
+static void slang_clear_sug(slang_T *lp)
{
vim_free(lp->sl_sbyts);
lp->sl_sbyts = NULL;
@@ -2502,9 +2513,7 @@ slang_T *lp;
* Load one spell file and store the info into a slang_T.
* Invoked through do_in_runtimepath().
*/
-static void spell_load_cb(fname, cookie)
-char_u *fname;
-void *cookie;
+static void spell_load_cb(char_u *fname, void *cookie)
{
spelload_T *slp = (spelload_T *)cookie;
slang_T *slang;
@@ -2535,11 +2544,13 @@ void *cookie;
*
* Returns the slang_T the spell file was loaded into. NULL for error.
*/
-static slang_T * spell_load_file(fname, lang, old_lp, silent)
-char_u *fname;
-char_u *lang;
-slang_T *old_lp;
-int silent; /* no error if file doesn't exist */
+static slang_T *
+spell_load_file (
+ char_u *fname,
+ char_u *lang,
+ slang_T *old_lp,
+ int silent /* no error if file doesn't exist */
+)
{
FILE *fd;
char_u buf[VIMSPELLMAGICL];
@@ -2773,10 +2784,7 @@ endOK:
* Sets "*cntp" to SP_*ERROR when there is an error, length of the result
* otherwise.
*/
-static char_u * read_cnt_string(fd, cnt_bytes, cntp)
-FILE *fd;
-int cnt_bytes;
-int *cntp;
+static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
{
int cnt = 0;
int i;
@@ -2803,10 +2811,7 @@ int *cntp;
* Read SN_REGION: <regionname> ...
* Return SP_*ERROR flags.
*/
-static int read_region_section(fd, lp, len)
-FILE *fd;
-slang_T *lp;
-int len;
+static int read_region_section(FILE *fd, slang_T *lp, int len)
{
int i;
@@ -2823,8 +2828,7 @@ int len;
* <folcharslen> <folchars>
* Return SP_*ERROR flags.
*/
-static int read_charflags_section(fd)
-FILE *fd;
+static int read_charflags_section(FILE *fd)
{
char_u *flags;
char_u *fol;
@@ -2859,9 +2863,7 @@ FILE *fd;
* Read SN_PREFCOND section.
* Return SP_*ERROR flags.
*/
-static int read_prefcond_section(fd, lp)
-FILE *fd;
-slang_T *lp;
+static int read_prefcond_section(FILE *fd, slang_T *lp)
{
int cnt;
int i;
@@ -2904,10 +2906,7 @@ slang_T *lp;
* Read REP or REPSAL items section from "fd": <repcount> <rep> ...
* Return SP_*ERROR flags.
*/
-static int read_rep_section(fd, gap, first)
-FILE *fd;
-garray_T *gap;
-short *first;
+static int read_rep_section(FILE *fd, garray_T *gap, short *first)
{
int cnt;
fromto_T *ftp;
@@ -2952,9 +2951,7 @@ short *first;
* Read SN_SAL section: <salflags> <salcount> <sal> ...
* Return SP_*ERROR flags.
*/
-static int read_sal_section(fd, slang)
-FILE *fd;
-slang_T *slang;
+static int read_sal_section(FILE *fd, slang_T *slang)
{
int i;
int cnt;
@@ -3090,10 +3087,7 @@ slang_T *slang;
* Read SN_WORDS: <word> ...
* Return SP_*ERROR flags.
*/
-static int read_words_section(fd, lp, len)
-FILE *fd;
-slang_T *lp;
-int len;
+static int read_words_section(FILE *fd, slang_T *lp, int len)
{
int done = 0;
int i;
@@ -3124,11 +3118,13 @@ int len;
* Add a word to the hashtable of common words.
* If it's already there then the counter is increased.
*/
-static void count_common_word(lp, word, len, count)
-slang_T *lp;
-char_u *word;
-int len; /* word length, -1 for upto NUL */
-int count; /* 1 to count once, 10 to init */
+static void
+count_common_word (
+ slang_T *lp,
+ char_u *word,
+ int len, /* word length, -1 for upto NUL */
+ int count /* 1 to count once, 10 to init */
+)
{
hash_T hash;
hashitem_T *hi;
@@ -3162,11 +3158,13 @@ int count; /* 1 to count once, 10 to init */
/*
* Adjust the score of common words.
*/
-static int score_wordcount_adj(slang, score, word, split)
-slang_T *slang;
-int score;
-char_u *word;
-int split; /* word was split, less bonus */
+static int
+score_wordcount_adj (
+ slang_T *slang,
+ int score,
+ char_u *word,
+ int split /* word was split, less bonus */
+)
{
hashitem_T *hi;
wordcount_T *wc;
@@ -3197,9 +3195,7 @@ int split; /* word was split, less bonus */
* SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
* Return SP_*ERROR flags.
*/
-static int read_sofo_section(fd, slang)
-FILE *fd;
-slang_T *slang;
+static int read_sofo_section(FILE *fd, slang_T *slang)
{
int cnt;
char_u *from, *to;
@@ -3237,10 +3233,7 @@ slang_T *slang;
* <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
* Returns SP_*ERROR flags.
*/
-static int read_compound(fd, slang, len)
-FILE *fd;
-slang_T *slang;
-int len;
+static int read_compound(FILE *fd, slang_T *slang, int len)
{
int todo = len;
int c;
@@ -3416,9 +3409,7 @@ int len;
* Return TRUE if byte "n" appears in "str".
* Like strchr() but independent of locale.
*/
-static int byte_in_str(str, n)
-char_u *str;
-int n;
+static int byte_in_str(char_u *str, int n)
{
char_u *p;
@@ -3438,8 +3429,7 @@ typedef struct syl_item_S {
* Truncate "slang->sl_syllable" at the first slash and put the following items
* in "slang->sl_syl_items".
*/
-static int init_syl_tab(slang)
-slang_T *slang;
+static int init_syl_tab(slang_T *slang)
{
char_u *p;
char_u *s;
@@ -3475,9 +3465,7 @@ slang_T *slang;
* When "word" contains spaces the syllables after the last space are counted.
* Returns zero if syllables are not defines.
*/
-static int count_syllables(slang, word)
-slang_T *slang;
-char_u *word;
+static int count_syllables(slang_T *slang, char_u *word)
{
int cnt = 0;
int skip = FALSE;
@@ -3528,10 +3516,7 @@ char_u *word;
* Set the SOFOFROM and SOFOTO items in language "lp".
* Returns SP_*ERROR flags when there is something wrong.
*/
-static int set_sofo(lp, from, to)
-slang_T *lp;
-char_u *from;
-char_u *to;
+static int set_sofo(slang_T *lp, char_u *from, char_u *to)
{
int i;
@@ -3609,8 +3594,7 @@ char_u *to;
/*
* Fill the first-index table for "lp".
*/
-static void set_sal_first(lp)
-slang_T *lp;
+static void set_sal_first(slang_T *lp)
{
salfirst_T *sfirst;
int i;
@@ -3665,8 +3649,7 @@ slang_T *lp;
* Turn a multi-byte string into a wide character string.
* Return it in allocated memory (NULL for out-of-memory)
*/
-static int * mb_str2wide(s)
-char_u *s;
+static int *mb_str2wide(char_u *s)
{
int *res;
char_u *p;
@@ -3687,12 +3670,14 @@ char_u *s;
* This is skipped when the tree has zero length.
* Returns zero when OK, SP_ value for an error.
*/
-static int spell_read_tree(fd, bytsp, idxsp, prefixtree, prefixcnt)
-FILE *fd;
-char_u **bytsp;
-idx_T **idxsp;
-int prefixtree; /* TRUE for the prefix tree */
-int prefixcnt; /* when "prefixtree" is TRUE: prefix count */
+static int
+spell_read_tree (
+ FILE *fd,
+ char_u **bytsp,
+ idx_T **idxsp,
+ int prefixtree, /* TRUE for the prefix tree */
+ int prefixcnt /* when "prefixtree" is TRUE: prefix count */
+)
{
int len;
int idx;
@@ -3735,15 +3720,16 @@ int prefixcnt; /* when "prefixtree" is TRUE: prefix count */
* Returns SP_TRUNCERROR if the file is shorter than expected.
* Returns SP_FORMERROR if there is a format error.
*/
-static idx_T read_tree_node(fd, byts, idxs, maxidx, startidx, prefixtree,
- maxprefcondnr)
-FILE *fd;
-char_u *byts;
-idx_T *idxs;
-int maxidx; /* size of arrays */
-idx_T startidx; /* current index in "byts" and "idxs" */
-int prefixtree; /* TRUE for reading PREFIXTREE */
-int maxprefcondnr; /* maximum for <prefcondnr> */
+static idx_T
+read_tree_node (
+ FILE *fd,
+ char_u *byts,
+ idx_T *idxs,
+ int maxidx, /* size of arrays */
+ idx_T startidx, /* current index in "byts" and "idxs" */
+ int prefixtree, /* TRUE for reading PREFIXTREE */
+ int maxprefcondnr /* maximum for <prefcondnr> */
+)
{
int len;
int i;
@@ -3839,8 +3825,7 @@ int maxprefcondnr; /* maximum for <prefcondnr> */
* Parse 'spelllang' and set w_s->b_langp accordingly.
* Returns NULL if it's OK, an error message otherwise.
*/
-char_u * did_set_spelllang(wp)
-win_T *wp;
+char_u *did_set_spelllang(win_T *wp)
{
garray_T ga;
char_u *splp;
@@ -4120,8 +4105,7 @@ theend:
/*
* Clear the midword characters for buffer "buf".
*/
-static void clear_midword(wp)
-win_T *wp;
+static void clear_midword(win_T *wp)
{
vim_memset(wp->w_s->b_spell_ismw, 0, 256);
vim_free(wp->w_s->b_spell_ismw_mb);
@@ -4132,9 +4116,7 @@ win_T *wp;
* Use the "sl_midword" field of language "lp" for buffer "buf".
* They add up to any currently used midword characters.
*/
-static void use_midword(lp, wp)
-slang_T *lp;
-win_T *wp;
+static void use_midword(slang_T *lp, win_T *wp)
{
char_u *p;
@@ -4173,9 +4155,7 @@ win_T *wp;
* Each region is simply stored as the two characters of it's name.
* Returns the index if found (first is 0), REGION_ALL if not found.
*/
-static int find_region(rp, region)
-char_u *rp;
-char_u *region;
+static int find_region(char_u *rp, char_u *region)
{
int i;
@@ -4195,9 +4175,11 @@ char_u *region;
* W WORD WF_ALLCAP
* WoRd wOrd WF_KEEPCAP
*/
-static int captype(word, end)
-char_u *word;
-char_u *end; /* When NULL use up to NUL byte. */
+static int
+captype (
+ char_u *word,
+ char_u *end /* When NULL use up to NUL byte. */
+)
{
char_u *p;
int c;
@@ -4245,9 +4227,7 @@ char_u *end; /* When NULL use up to NUL byte. */
* capital. So that make_case_word() can turn WOrd into Word.
* Add ALLCAP for "WOrD".
*/
-static int badword_captype(word, end)
-char_u *word;
-char_u *end;
+static int badword_captype(char_u *word, char_u *end)
{
int flags = captype(word, end);
int c;
@@ -4287,7 +4267,7 @@ char_u *end;
/*
* Delete the internal wordlist and its .spl file.
*/
-void spell_delete_wordlist() {
+void spell_delete_wordlist(void) {
char_u fname[MAXPATHL];
if (int_wordlist != NULL) {
@@ -4302,7 +4282,7 @@ void spell_delete_wordlist() {
/*
* Free all languages.
*/
-void spell_free_all() {
+void spell_free_all(void) {
slang_T *slang;
buf_T *buf;
@@ -4328,7 +4308,7 @@ void spell_free_all() {
* Clear all spelling tables and reload them.
* Used after 'encoding' is set and when ":mkspell" was used.
*/
-void spell_reload() {
+void spell_reload(void) {
win_T *wp;
/* Initialize the table for spell_iswordp(). */
@@ -4353,9 +4333,11 @@ void spell_reload() {
/*
* Reload the spell file "fname" if it's loaded.
*/
-static void spell_reload_one(fname, added_word)
-char_u *fname;
-int added_word; /* invoked through "zg" */
+static void
+spell_reload_one (
+ char_u *fname,
+ int added_word /* invoked through "zg" */
+)
{
slang_T *slang;
int didit = FALSE;
@@ -4756,9 +4738,7 @@ static void spell_print_tree(wordnode_T *root) {
* Read the affix file "fname".
* Returns an afffile_T, NULL for complete failure.
*/
-static afffile_T * spell_read_aff(spin, fname)
-spellinfo_T *spin;
-char_u *fname;
+static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
{
FILE *fd;
afffile_T *aff;
@@ -5536,11 +5516,7 @@ char_u *fname;
* Return TRUE when items[0] equals "rulename", there are "mincount" items or
* a comment is following after item "mincount".
*/
-static int is_aff_rule(items, itemcnt, rulename, mincount)
-char_u **items;
-int itemcnt;
-char *rulename;
-int mincount;
+static int is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount)
{
return STRCMP(items[0], rulename) == 0
&& (itemcnt == mincount
@@ -5551,9 +5527,7 @@ int mincount;
* For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
* ae_flags to ae_comppermit and ae_compforbid.
*/
-static void aff_process_flags(affile, entry)
-afffile_T *affile;
-affentry_T *entry;
+static void aff_process_flags(afffile_T *affile, affentry_T *entry)
{
char_u *p;
char_u *prevp;
@@ -5583,8 +5557,7 @@ affentry_T *entry;
/*
* Return TRUE if "s" is the name of an info item in the affix file.
*/
-static int spell_info_item(s)
-char_u *s;
+static int spell_info_item(char_u *s)
{
return STRCMP(s, "NAME") == 0
|| STRCMP(s, "HOME") == 0
@@ -5598,11 +5571,7 @@ char_u *s;
* Turn an affix flag name into a number, according to the FLAG type.
* returns zero for failure.
*/
-static unsigned affitem2flag(flagtype, item, fname, lnum)
-int flagtype;
-char_u *item;
-char_u *fname;
-int lnum;
+static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
{
unsigned res;
char_u *p = item;
@@ -5628,9 +5597,7 @@ int lnum;
* Get one affix name from "*pp" and advance the pointer.
* Returns zero for an error, still advances the pointer then.
*/
-static unsigned get_affitem(flagtype, pp)
-int flagtype;
-char_u **pp;
+static unsigned get_affitem(int flagtype, char_u **pp)
{
int res;
@@ -5658,10 +5625,7 @@ char_u **pp;
* The processing involves changing the affix names to ID numbers, so that
* they fit in one byte.
*/
-static void process_compflags(spin, aff, compflags)
-spellinfo_T *spin;
-afffile_T *aff;
-char_u *compflags;
+static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
{
char_u *p;
char_u *prevp;
@@ -5735,8 +5699,7 @@ char_u *compflags;
* using two bytes for utf-8. When the 0-127 range is used up go to 128-255.
* When that is used up an error message is given.
*/
-static void check_renumber(spin)
-spellinfo_T *spin;
+static void check_renumber(spellinfo_T *spin)
{
if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
spin->si_newprefID = 127;
@@ -5747,10 +5710,7 @@ spellinfo_T *spin;
/*
* Return TRUE if flag "flag" appears in affix list "afflist".
*/
-static int flag_in_afflist(flagtype, afflist, flag)
-int flagtype;
-char_u *afflist;
-unsigned flag;
+static int flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
{
char_u *p;
unsigned n;
@@ -5787,10 +5747,7 @@ unsigned flag;
/*
* Give a warning when "spinval" and "affval" numbers are set and not the same.
*/
-static void aff_check_number(spinval, affval, name)
-int spinval;
-int affval;
-char *name;
+static void aff_check_number(int spinval, int affval, char *name)
{
if (spinval != 0 && spinval != affval)
smsg((char_u *)_(
@@ -5800,10 +5757,7 @@ char *name;
/*
* Give a warning when "spinval" and "affval" strings are set and not the same.
*/
-static void aff_check_string(spinval, affval, name)
-char_u *spinval;
-char_u *affval;
-char *name;
+static void aff_check_string(char_u *spinval, char_u *affval, char *name)
{
if (spinval != NULL && STRCMP(spinval, affval) != 0)
smsg((char_u *)_(
@@ -5814,9 +5768,7 @@ char *name;
* Return TRUE if strings "s1" and "s2" are equal. Also consider both being
* NULL as equal.
*/
-static int str_equal(s1, s2)
-char_u *s1;
-char_u *s2;
+static int str_equal(char_u *s1, char_u *s2)
{
if (s1 == NULL || s2 == NULL)
return s1 == s2;
@@ -5827,11 +5779,7 @@ char_u *s2;
* Add a from-to item to "gap". Used for REP and SAL items.
* They are stored case-folded.
*/
-static void add_fromto(spin, gap, from, to)
-spellinfo_T *spin;
-garray_T *gap;
-char_u *from;
-char_u *to;
+static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to)
{
fromto_T *ftp;
char_u word[MAXWLEN];
@@ -5849,8 +5797,7 @@ char_u *to;
/*
* Convert a boolean argument in a SAL line to TRUE or FALSE;
*/
-static int sal_to_bool(s)
-char_u *s;
+static int sal_to_bool(char_u *s)
{
return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
}
@@ -5858,8 +5805,7 @@ char_u *s;
/*
* Free the structure filled by spell_read_aff().
*/
-static void spell_free_aff(aff)
-afffile_T *aff;
+static void spell_free_aff(afffile_T *aff)
{
hashtab_T *ht;
hashitem_T *hi;
@@ -5893,10 +5839,7 @@ afffile_T *aff;
* Read dictionary file "fname".
* Returns OK or FAIL;
*/
-static int spell_read_dic(spin, fname, affile)
-spellinfo_T *spin;
-char_u *fname;
-afffile_T *affile;
+static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
{
hashtab_T ht;
char_u line[MAXLINELEN];
@@ -6092,9 +6035,7 @@ afffile_T *affile;
* Check for affix flags in "afflist" that are turned into word flags.
* Return WF_ flags.
*/
-static int get_affix_flags(affile, afflist)
-afffile_T *affile;
-char_u *afflist;
+static int get_affix_flags(afffile_T *affile, char_u *afflist)
{
int flags = 0;
@@ -6125,10 +6066,7 @@ char_u *afflist;
* Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
* and return the number of affixes.
*/
-static int get_pfxlist(affile, afflist, store_afflist)
-afffile_T *affile;
-char_u *afflist;
-char_u *store_afflist;
+static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
char_u *p;
char_u *prevp;
@@ -6163,10 +6101,7 @@ char_u *store_afflist;
* for compound words.
* Puts the flags in "store_afflist[]".
*/
-static void get_compflags(affile, afflist, store_afflist)
-afffile_T *affile;
-char_u *afflist;
-char_u *store_afflist;
+static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
{
char_u *p;
char_u *prevp;
@@ -6199,19 +6134,20 @@ char_u *store_afflist;
*
* Returns FAIL when out of memory.
*/
-static int store_aff_word(spin, word, afflist, affile, ht, xht, condit, flags,
- pfxlist, pfxlen)
-spellinfo_T *spin; /* spell info */
-char_u *word; /* basic word start */
-char_u *afflist; /* list of names of supported affixes */
-afffile_T *affile;
-hashtab_T *ht;
-hashtab_T *xht;
-int condit; /* CONDIT_SUF et al. */
-int flags; /* flags for the word */
-char_u *pfxlist; /* list of prefix IDs */
-int pfxlen; /* nr of flags in "pfxlist" for prefixes, rest
+static int
+store_aff_word (
+ spellinfo_T *spin, /* spell info */
+ char_u *word, /* basic word start */
+ char_u *afflist, /* list of names of supported affixes */
+ afffile_T *affile,
+ hashtab_T *ht,
+ hashtab_T *xht,
+ int condit, /* CONDIT_SUF et al. */
+ int flags, /* flags for the word */
+ char_u *pfxlist, /* list of prefix IDs */
+ int pfxlen /* nr of flags in "pfxlist" for prefixes, rest
* is compound flags */
+)
{
int todo;
hashitem_T *hi;
@@ -6442,9 +6378,7 @@ int pfxlen; /* nr of flags in "pfxlist" for prefixes, rest
/*
* Read a file with a list of words.
*/
-static int spell_read_wordfile(spin, fname)
-spellinfo_T *spin;
-char_u *fname;
+static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
{
FILE *fd;
long lnum = 0;
@@ -6626,10 +6560,12 @@ char_u *fname;
* The memory is cleared to all zeros.
* Returns NULL when out of memory.
*/
-static void * getroom(spin, len, align)
-spellinfo_T *spin;
-size_t len; /* length needed */
-int align; /* align for pointer */
+static void *
+getroom (
+ spellinfo_T *spin,
+ size_t len, /* length needed */
+ int align /* align for pointer */
+)
{
char_u *p;
sblock_T *bl = spin->si_blocks;
@@ -6670,9 +6606,7 @@ int align; /* align for pointer */
* Make a copy of a string into memory allocated with getroom().
* Returns NULL when out of memory.
*/
-static char_u * getroom_save(spin, s)
-spellinfo_T *spin;
-char_u *s;
+static char_u *getroom_save(spellinfo_T *spin, char_u *s)
{
char_u *sc;
@@ -6686,8 +6620,7 @@ char_u *s;
/*
* Free the list of allocated sblock_T.
*/
-static void free_blocks(bl)
-sblock_T *bl;
+static void free_blocks(sblock_T *bl)
{
sblock_T *next;
@@ -6702,8 +6635,7 @@ sblock_T *bl;
* Allocate the root of a word tree.
* Returns NULL when out of memory.
*/
-static wordnode_T * wordtree_alloc(spin)
-spellinfo_T *spin;
+static wordnode_T *wordtree_alloc(spellinfo_T *spin)
{
return (wordnode_T *)getroom(spin, sizeof(wordnode_T), TRUE);
}
@@ -6717,13 +6649,15 @@ spellinfo_T *spin;
* When "pfxlist" is not NULL store the word for each postponed prefix ID and
* compound flag.
*/
-static int store_word(spin, word, flags, region, pfxlist, need_affix)
-spellinfo_T *spin;
-char_u *word;
-int flags; /* extra flags, WF_BANNED */
-int region; /* supported region(s) */
-char_u *pfxlist; /* list of prefix IDs or NULL */
-int need_affix; /* only store word with affix ID */
+static int
+store_word (
+ spellinfo_T *spin,
+ char_u *word,
+ int flags, /* extra flags, WF_BANNED */
+ int region, /* supported region(s) */
+ char_u *pfxlist, /* list of prefix IDs or NULL */
+ int need_affix /* only store word with affix ID */
+)
{
int len = (int)STRLEN(word);
int ct = captype(word, word + len);
@@ -6760,13 +6694,7 @@ int need_affix; /* only store word with affix ID */
* "rare" and "region" is the condition nr.
* Returns FAIL when out of memory.
*/
-static int tree_add_word(spin, word, root, flags, region, affixID)
-spellinfo_T *spin;
-char_u *word;
-wordnode_T *root;
-int flags;
-int region;
-int affixID;
+static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
{
wordnode_T *node = root;
wordnode_T *np;
@@ -6929,7 +6857,7 @@ int affixID;
* Check the 'mkspellmem' option. Return FAIL if it's wrong.
* Sets "sps_flags".
*/
-int spell_check_msm() {
+int spell_check_msm(void) {
char_u *p = p_msm;
long start = 0;
long incr = 0;
@@ -6968,8 +6896,7 @@ int spell_check_msm() {
* allocate a new one.
* Returns NULL when out of memory.
*/
-static wordnode_T * get_wordnode(spin)
-spellinfo_T *spin;
+static wordnode_T *get_wordnode(spellinfo_T *spin)
{
wordnode_T *n;
@@ -6994,9 +6921,7 @@ spellinfo_T *spin;
* siblings.
* Returns the number of nodes actually freed.
*/
-static int deref_wordnode(spin, node)
-spellinfo_T *spin;
-wordnode_T *node;
+static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
{
wordnode_T *np;
int cnt = 0;
@@ -7017,9 +6942,7 @@ wordnode_T *node;
* Free a wordnode_T for re-use later.
* Only the "wn_child" field becomes invalid.
*/
-static void free_wordnode(spin, n)
-spellinfo_T *spin;
-wordnode_T *n;
+static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
{
n->wn_child = spin->si_first_free;
spin->si_first_free = n;
@@ -7029,9 +6952,7 @@ wordnode_T *n;
/*
* Compress a tree: find tails that are identical and can be shared.
*/
-static void wordtree_compress(spin, root)
-spellinfo_T *spin;
-wordnode_T *root;
+static void wordtree_compress(spellinfo_T *spin, wordnode_T *root)
{
hashtab_T ht;
int n;
@@ -7070,12 +6991,14 @@ wordnode_T *root;
* Compress a node, its siblings and its children, depth first.
* Returns the number of compressed nodes.
*/
-static int node_compress(spin, node, ht, tot)
-spellinfo_T *spin;
-wordnode_T *node;
-hashtab_T *ht;
-int *tot; /* total count of nodes before compressing,
+static int
+node_compress (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ hashtab_T *ht,
+ int *tot /* total count of nodes before compressing,
incremented while going through the tree */
+)
{
wordnode_T *np;
wordnode_T *tp;
@@ -7168,9 +7091,7 @@ int *tot; /* total count of nodes before compressing,
/*
* Return TRUE when two nodes have identical siblings and children.
*/
-static int node_equal(n1, n2)
-wordnode_T *n1;
-wordnode_T *n2;
+static int node_equal(wordnode_T *n1, wordnode_T *n2)
{
wordnode_T *p1;
wordnode_T *p2;
@@ -7194,9 +7115,7 @@ rep_compare __ARGS((const void *s1, const void *s2));
/*
* Function given to qsort() to sort the REP items on "from" string.
*/
-static int rep_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int rep_compare(const void *s1, const void *s2)
{
fromto_T *p1 = (fromto_T *)s1;
fromto_T *p2 = (fromto_T *)s2;
@@ -7208,9 +7127,7 @@ const void *s2;
* Write the Vim .spl file "fname".
* Return FAIL or OK;
*/
-static int write_vim_spell(spin, fname)
-spellinfo_T *spin;
-char_u *fname;
+static int write_vim_spell(spellinfo_T *spin, char_u *fname)
{
FILE *fd;
int regionmask;
@@ -7589,8 +7506,7 @@ theend:
* children. This is needed because they are a union with other items to save
* space.
*/
-static void clear_node(node)
-wordnode_T *node;
+static void clear_node(wordnode_T *node)
{
wordnode_T *np;
@@ -7617,12 +7533,14 @@ wordnode_T *node;
*
* Returns the number of nodes used.
*/
-static int put_node(fd, node, idx, regionmask, prefixtree)
-FILE *fd; /* NULL when only counting */
-wordnode_T *node;
-int idx;
-int regionmask;
-int prefixtree; /* TRUE for PREFIXTREE */
+static int
+put_node (
+ FILE *fd, /* NULL when only counting */
+ wordnode_T *node,
+ int idx,
+ int regionmask,
+ int prefixtree /* TRUE for PREFIXTREE */
+)
{
int newindex = idx;
int siblingcount = 0;
@@ -7727,8 +7645,7 @@ int prefixtree; /* TRUE for PREFIXTREE */
* ":mkspell [-ascii] outfile infile ..."
* ":mkspell [-ascii] addfile"
*/
-void ex_mkspell(eap)
-exarg_T *eap;
+void ex_mkspell(exarg_T *eap)
{
int fcount;
char_u **fnames;
@@ -7752,9 +7669,7 @@ exarg_T *eap;
* Uses the soundfold info in "spin".
* Writes the file with the name "wfname", with ".spl" changed to ".sug".
*/
-static void spell_make_sugfile(spin, wfname)
-spellinfo_T *spin;
-char_u *wfname;
+static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
{
char_u *fname = NULL;
int len;
@@ -7839,9 +7754,7 @@ theend:
/*
* Build the soundfold trie for language "slang".
*/
-static int sug_filltree(spin, slang)
-spellinfo_T *spin;
-slang_T *slang;
+static int sug_filltree(spellinfo_T *spin, slang_T *slang)
{
char_u *byts;
idx_T *idxs;
@@ -7938,8 +7851,7 @@ slang_T *slang;
* the table efficiently.
* Returns FAIL when out of memory.
*/
-static int sug_maketable(spin)
-spellinfo_T *spin;
+static int sug_maketable(spellinfo_T *spin)
{
garray_T ga;
int res = OK;
@@ -7967,11 +7879,13 @@ spellinfo_T *spin;
* Returns the wordnr at the start of the node.
* Returns -1 when out of memory.
*/
-static int sug_filltable(spin, node, startwordnr, gap)
-spellinfo_T *spin;
-wordnode_T *node;
-int startwordnr;
-garray_T *gap; /* place to store line of numbers */
+static int
+sug_filltable (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ int startwordnr,
+ garray_T *gap /* place to store line of numbers */
+)
{
wordnode_T *p, *np;
int wordnr = startwordnr;
@@ -8028,9 +7942,7 @@ garray_T *gap; /* place to store line of numbers */
* Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
* bytes.
*/
-static int offset2bytes(nr, buf)
-int nr;
-char_u *buf;
+static int offset2bytes(int nr, char_u *buf)
{
int rem;
int b1, b2, b3, b4;
@@ -8071,8 +7983,7 @@ char_u *buf;
* "pp" points to the bytes and is advanced over it.
* Returns the offset.
*/
-static int bytes2offset(pp)
-char_u **pp;
+static int bytes2offset(char_u **pp)
{
char_u *p = *pp;
int nr;
@@ -8102,9 +8013,7 @@ char_u **pp;
/*
* Write the .sug file in "fname".
*/
-static void sug_write(spin, fname)
-spellinfo_T *spin;
-char_u *fname;
+static void sug_write(spellinfo_T *spin, char_u *fname)
{
FILE *fd;
wordnode_T *tree;
@@ -8196,7 +8105,7 @@ theend:
* NULL and there is no undo info.
* Returns NULL when out of memory.
*/
-static buf_T * open_spellbuf() {
+static buf_T *open_spellbuf(void) {
buf_T *buf;
buf = (buf_T *)alloc_clear(sizeof(buf_T));
@@ -8213,8 +8122,7 @@ static buf_T * open_spellbuf() {
/*
* Close the buffer used for spell info.
*/
-static void close_spellbuf(buf)
-buf_T *buf;
+static void close_spellbuf(buf_T *buf)
{
if (buf != NULL) {
ml_close(buf, TRUE);
@@ -8230,12 +8138,14 @@ buf_T *buf;
* Exception: when "fnames[0]" ends in ".add" it's used as the input file name
* and ".spl" is appended to make the output file name.
*/
-static void mkspell(fcount, fnames, ascii, over_write, added_word)
-int fcount;
-char_u **fnames;
-int ascii; /* -ascii argument given */
-int over_write; /* overwrite existing output file */
-int added_word; /* invoked through "zg" */
+static void
+mkspell (
+ int fcount,
+ char_u **fnames,
+ int ascii, /* -ascii argument given */
+ int over_write, /* overwrite existing output file */
+ int added_word /* invoked through "zg" */
+)
{
char_u *fname = NULL;
char_u *wfname;
@@ -8466,9 +8376,7 @@ theend:
* Display a message for spell file processing when 'verbose' is set or using
* ":mkspell". "str" can be IObuff.
*/
-static void spell_message(spin, str)
-spellinfo_T *spin;
-char_u *str;
+static void spell_message(spellinfo_T *spin, char_u *str)
{
if (spin->si_verbose || p_verbose > 2) {
if (!spin->si_verbose)
@@ -8485,8 +8393,7 @@ char_u *str;
* ":[count]spellwrong {word}"
* ":[count]spellundo {word}"
*/
-void ex_spell(eap)
-exarg_T *eap;
+void ex_spell(exarg_T *eap)
{
spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
eap->forceit ? 0 : (int)eap->line2,
@@ -8496,13 +8403,15 @@ exarg_T *eap;
/*
* Add "word[len]" to 'spellfile' as a good or bad word.
*/
-void spell_add_word(word, len, bad, idx, undo)
-char_u *word;
-int len;
-int bad;
-int idx; /* "zG" and "zW": zero, otherwise index in
+void
+spell_add_word (
+ char_u *word,
+ int len,
+ int bad,
+ int idx, /* "zG" and "zW": zero, otherwise index in
'spellfile' */
-int undo; /* TRUE for "zug", "zuG", "zuw" and "zuW" */
+ int undo /* TRUE for "zug", "zuG", "zuw" and "zuW" */
+)
{
FILE *fd = NULL;
buf_T *buf = NULL;
@@ -8644,7 +8553,7 @@ int undo; /* TRUE for "zug", "zuG", "zuw" and "zuW" */
/*
* Initialize 'spellfile' for the current buffer.
*/
-static void init_spellfile() {
+static void init_spellfile(void) {
char_u *buf;
int l;
char_u *fname;
@@ -8717,8 +8626,7 @@ static void init_spellfile() {
* Init the chartab used for spelling for ASCII.
* EBCDIC is not supported!
*/
-static void clear_spell_chartab(sp)
-spelltab_T *sp;
+static void clear_spell_chartab(spelltab_T *sp)
{
int i;
@@ -8752,7 +8660,7 @@ spelltab_T *sp;
* characters to make it possible that 'encoding' differs from the current
* locale. For utf-8 we don't use isalpha() but our own functions.
*/
-void init_spell_chartab() {
+void init_spell_chartab(void) {
int i;
did_set_spelltab = FALSE;
@@ -8793,10 +8701,7 @@ void init_spell_chartab() {
/*
* Set the spell character tables from strings in the affix file.
*/
-static int set_spell_chartab(fol, low, upp)
-char_u *fol;
-char_u *low;
-char_u *upp;
+static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
{
/* We build the new tables here first, so that we can compare with the
* previous one. */
@@ -8857,10 +8762,12 @@ char_u *upp;
/*
* Set the spell character tables from strings in the .spl file.
*/
-static void set_spell_charflags(flags, cnt, fol)
-char_u *flags;
-int cnt; /* length of "flags" */
-char_u *fol;
+static void
+set_spell_charflags (
+ char_u *flags,
+ int cnt, /* length of "flags" */
+ char_u *fol
+)
{
/* We build the new tables here first, so that we can compare with the
* previous one. */
@@ -8888,8 +8795,7 @@ char_u *fol;
(void)set_spell_finish(&new_st);
}
-static int set_spell_finish(new_st)
-spelltab_T *new_st;
+static int set_spell_finish(spelltab_T *new_st)
{
int i;
@@ -8919,9 +8825,11 @@ spelltab_T *new_st;
* followed by a word character. This finds they'there but not 'they there'.
* Thus this only works properly when past the first character of the word.
*/
-static int spell_iswordp(p, wp)
-char_u *p;
-win_T *wp; /* buffer used */
+static int
+spell_iswordp (
+ char_u *p,
+ win_T *wp /* buffer used */
+)
{
char_u *s;
int l;
@@ -8955,9 +8863,7 @@ win_T *wp; /* buffer used */
* Return TRUE if "p" points to a word character.
* Unlike spell_iswordp() this doesn't check for "midword" characters.
*/
-static int spell_iswordp_nmw(p, wp)
-char_u *p;
-win_T *wp;
+static int spell_iswordp_nmw(char_u *p, win_T *wp)
{
int c;
@@ -8976,9 +8882,7 @@ win_T *wp;
* Unicode subscript and superscript are not considered word characters.
* See also dbcs_class() and utf_class() in mbyte.c.
*/
-static int spell_mb_isword_class(cl, wp)
-int cl;
-win_T *wp;
+static int spell_mb_isword_class(int cl, win_T *wp)
{
if (wp->w_s->b_cjk)
/* East Asian characters are not considered word characters. */
@@ -8990,9 +8894,7 @@ win_T *wp;
* Return TRUE if "p" points to a word character.
* Wide version of spell_iswordp().
*/
-static int spell_iswordp_w(p, wp)
-int *p;
-win_T *wp;
+static int spell_iswordp_w(int *p, win_T *wp)
{
int *s;
@@ -9018,9 +8920,7 @@ win_T *wp;
* Write the table with prefix conditions to the .spl file.
* When "fd" is NULL only count the length of what is written.
*/
-static int write_spell_prefcond(fd, gap)
-FILE *fd;
-garray_T *gap;
+static int write_spell_prefcond(FILE *fd, garray_T *gap)
{
int i;
char_u *p;
@@ -9056,11 +8956,7 @@ garray_T *gap;
* When using a multi-byte 'encoding' the length may change!
* Returns FAIL when something wrong.
*/
-static int spell_casefold(str, len, buf, buflen)
-char_u *str;
-int len;
-char_u *buf;
-int buflen;
+static int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
{
int i;
@@ -9106,7 +9002,7 @@ static int sps_limit = 9999; /* max nr of suggestions given */
* Check the 'spellsuggest' option. Return FAIL if it's wrong.
* Sets "sps_flags" and "sps_limit".
*/
-int spell_check_sps() {
+int spell_check_sps(void) {
char_u *p;
char_u *s;
char_u buf[MAXPATHL];
@@ -9155,8 +9051,7 @@ int spell_check_sps() {
* In Visual mode use the highlighted word as the bad word.
* When "count" is non-zero use that suggestion.
*/
-void spell_suggest(count)
-int count;
+void spell_suggest(int count)
{
char_u *line;
pos_T prev_cursor = curwin->w_cursor;
@@ -9370,9 +9265,7 @@ skip:
* Check if the word at line "lnum" column "col" is required to start with a
* capital. This uses 'spellcapcheck' of the current buffer.
*/
-static int check_need_cap(lnum, col)
-linenr_T lnum;
-colnr_T col;
+static int check_need_cap(linenr_T lnum, colnr_T col)
{
int need_cap = FALSE;
char_u *line;
@@ -9431,8 +9324,7 @@ colnr_T col;
/*
* ":spellrepall"
*/
-void ex_spellrepall(eap)
-exarg_T *eap UNUSED;
+void ex_spellrepall(exarg_T *eap)
{
pos_T pos = curwin->w_cursor;
char_u *frompat;
@@ -9499,12 +9391,14 @@ exarg_T *eap UNUSED;
* Find spell suggestions for "word". Return them in the growarray "*gap" as
* a list of allocated strings.
*/
-void spell_suggest_list(gap, word, maxcount, need_cap, interactive)
-garray_T *gap;
-char_u *word;
-int maxcount; /* maximum nr of suggestions */
-int need_cap; /* 'spellcapcheck' matched */
-int interactive;
+void
+spell_suggest_list (
+ garray_T *gap,
+ char_u *word,
+ int maxcount, /* maximum nr of suggestions */
+ int need_cap, /* 'spellcapcheck' matched */
+ int interactive
+)
{
suginfo_T sug;
int i;
@@ -9541,16 +9435,16 @@ int interactive;
* Note: does use info for the current window.
* This is based on the mechanisms of Aspell, but completely reimplemented.
*/
-static void spell_find_suggest(badptr, badlen, su, maxcount, banbadword,
- need_cap,
- interactive)
-char_u *badptr;
-int badlen; /* length of bad word or 0 if unknown */
-suginfo_T *su;
-int maxcount;
-int banbadword; /* don't include badword in suggestions */
-int need_cap; /* word should start with capital */
-int interactive;
+static void
+spell_find_suggest (
+ char_u *badptr,
+ int badlen, /* length of bad word or 0 if unknown */
+ suginfo_T *su,
+ int maxcount,
+ int banbadword, /* don't include badword in suggestions */
+ int need_cap, /* word should start with capital */
+ int interactive
+)
{
hlf_T attr = HLF_COUNT;
char_u buf[MAXPATHL];
@@ -9662,9 +9556,7 @@ int interactive;
/*
* Find suggestions by evaluating expression "expr".
*/
-static void spell_suggest_expr(su, expr)
-suginfo_T *su;
-char_u *expr;
+static void spell_suggest_expr(suginfo_T *su, char_u *expr)
{
list_T *list;
listitem_T *li;
@@ -9696,9 +9588,7 @@ char_u *expr;
/*
* Find suggestions in file "fname". Used for "file:" in 'spellsuggest'.
*/
-static void spell_suggest_file(su, fname)
-suginfo_T *su;
-char_u *fname;
+static void spell_suggest_file(suginfo_T *su, char_u *fname)
{
FILE *fd;
char_u line[MAXWLEN * 2];
@@ -9749,9 +9639,7 @@ char_u *fname;
/*
* Find suggestions for the internal method indicated by "sps_flags".
*/
-static void spell_suggest_intern(su, interactive)
-suginfo_T *su;
-int interactive;
+static void spell_suggest_intern(suginfo_T *su, int interactive)
{
/*
* Load the .sug file(s) that are available and not done yet.
@@ -9837,7 +9725,7 @@ int interactive;
/*
* Load the .sug files for languages that have one and weren't loaded yet.
*/
-static void suggest_load_files() {
+static void suggest_load_files(void) {
langp_T *lp;
int lpi;
slang_T *slang;
@@ -9965,9 +9853,7 @@ nextone:
* Fill in the wordcount fields for a trie.
* Returns the total number of words.
*/
-static void tree_count_words(byts, idxs)
-char_u *byts;
-idx_T *idxs;
+static void tree_count_words(char_u *byts, idx_T *idxs)
{
int depth;
idx_T arridx[MAXWLEN];
@@ -10019,8 +9905,7 @@ idx_T *idxs;
/*
* Free the info put in "*su" by spell_find_suggest().
*/
-static void spell_find_cleanup(su)
-suginfo_T *su;
+static void spell_find_cleanup(suginfo_T *su)
{
int i;
@@ -10041,10 +9926,12 @@ suginfo_T *su;
* "wcopy[MAXWLEN]". "word" must not be empty.
* The result is NUL terminated.
*/
-static void onecap_copy(word, wcopy, upper)
-char_u *word;
-char_u *wcopy;
-int upper; /* TRUE: first letter made upper case */
+static void
+onecap_copy (
+ char_u *word,
+ char_u *wcopy,
+ int upper /* TRUE: first letter made upper case */
+)
{
char_u *p;
int c;
@@ -10072,9 +9959,7 @@ int upper; /* TRUE: first letter made upper case */
* Make a copy of "word" with all the letters upper cased into
* "wcopy[MAXWLEN]". The result is NUL terminated.
*/
-static void allcap_copy(word, wcopy)
-char_u *word;
-char_u *wcopy;
+static void allcap_copy(char_u *word, char_u *wcopy)
{
char_u *s;
char_u *d;
@@ -10113,8 +9998,7 @@ char_u *wcopy;
/*
* Try finding suggestions by recognizing specific situations.
*/
-static void suggest_try_special(su)
-suginfo_T *su;
+static void suggest_try_special(suginfo_T *su)
{
char_u *p;
size_t len;
@@ -10145,8 +10029,7 @@ suginfo_T *su;
/*
* Try finding suggestions by adding/removing/swapping letters.
*/
-static void suggest_try_change(su)
-suginfo_T *su;
+static void suggest_try_change(suginfo_T *su)
{
char_u fword[MAXWLEN]; /* copy of the bad word, case-folded */
int n;
@@ -10210,11 +10093,7 @@ suginfo_T *su;
* "similar_chars()"
* use "slang->sl_repsal" instead of "lp->lp_replang->sl_rep"
*/
-static void suggest_trie_walk(su, lp, fword, soundfold)
-suginfo_T *su;
-langp_T *lp;
-char_u *fword;
-int soundfold;
+static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, int soundfold)
{
char_u tword[MAXWLEN]; /* good word collected so far */
trystate_T stack[MAXWLEN];
@@ -11484,10 +11363,7 @@ int soundfold;
/*
* Go one level deeper in the tree.
*/
-static void go_deeper(stack, depth, score_add)
-trystate_T *stack;
-int depth;
-int score_add;
+static void go_deeper(trystate_T *stack, int depth, int score_add)
{
stack[depth + 1] = stack[depth];
stack[depth + 1].ts_state = STATE_START;
@@ -11500,10 +11376,7 @@ int score_add;
* Case-folding may change the number of bytes: Count nr of chars in
* fword[flen] and return the byte length of that many chars in "word".
*/
-static int nofold_len(fword, flen, word)
-char_u *fword;
-int flen;
-char_u *word;
+static int nofold_len(char_u *fword, int flen, char_u *word)
{
char_u *p;
int i = 0;
@@ -11521,10 +11394,7 @@ char_u *word;
* Theoretically there could be several keep-case words that result in the
* same case-folded word, but we only find one...
*/
-static void find_keepcap_word(slang, fword, kword)
-slang_T *slang;
-char_u *fword;
-char_u *kword;
+static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
{
char_u uword[MAXWLEN]; /* "fword" in upper-case */
int depth;
@@ -11657,8 +11527,7 @@ char_u *kword;
* Compute the sound-a-like score for suggestions in su->su_ga and add them to
* su->su_sga.
*/
-static void score_comp_sal(su)
-suginfo_T *su;
+static void score_comp_sal(suginfo_T *su)
{
langp_T *lp;
char_u badsound[MAXWLEN];
@@ -11706,8 +11575,7 @@ suginfo_T *su;
* Combine the list of suggestions in su->su_ga and su->su_sga.
* They are entwined.
*/
-static void score_combine(su)
-suginfo_T *su;
+static void score_combine(suginfo_T *su)
{
int i;
int j;
@@ -11809,11 +11677,13 @@ suginfo_T *su;
* For the goodword in "stp" compute the soundalike score compared to the
* badword.
*/
-static int stp_sal_score(stp, su, slang, badsound)
-suggest_T *stp;
-suginfo_T *su;
-slang_T *slang;
-char_u *badsound; /* sound-folded badword */
+static int
+stp_sal_score (
+ suggest_T *stp,
+ suginfo_T *su,
+ slang_T *slang,
+ char_u *badsound /* sound-folded badword */
+)
{
char_u *p;
char_u *pbad;
@@ -11874,7 +11744,7 @@ static sftword_T dumsft;
/*
* Prepare for calling suggest_try_soundalike().
*/
-static void suggest_try_soundalike_prep() {
+static void suggest_try_soundalike_prep(void) {
langp_T *lp;
int lpi;
slang_T *slang;
@@ -11894,8 +11764,7 @@ static void suggest_try_soundalike_prep() {
* Find suggestions by comparing the word in a sound-a-like form.
* Note: This doesn't support postponed prefixes.
*/
-static void suggest_try_soundalike(su)
-suginfo_T *su;
+static void suggest_try_soundalike(suginfo_T *su)
{
char_u salword[MAXWLEN];
langp_T *lp;
@@ -11922,7 +11791,7 @@ suginfo_T *su;
/*
* Finish up after calling suggest_try_soundalike().
*/
-static void suggest_try_soundalike_finish() {
+static void suggest_try_soundalike_finish(void) {
langp_T *lp;
int lpi;
slang_T *slang;
@@ -11954,11 +11823,13 @@ static void suggest_try_soundalike_finish() {
* A match with a soundfolded word is found. Add the good word(s) that
* produce this soundfolded word.
*/
-static void add_sound_suggest(su, goodword, score, lp)
-suginfo_T *su;
-char_u *goodword;
-int score; /* soundfold score */
-langp_T *lp;
+static void
+add_sound_suggest (
+ suginfo_T *su,
+ char_u *goodword,
+ int score, /* soundfold score */
+ langp_T *lp
+)
{
slang_T *slang = lp->lp_slang; /* language for sound folding */
int sfwordnr;
@@ -12141,9 +12012,7 @@ badword:
/*
* Find word "word" in fold-case tree for "slang" and return the word number.
*/
-static int soundfold_find(slang, word)
-slang_T *slang;
-char_u *word;
+static int soundfold_find(slang_T *slang, char_u *word)
{
idx_T arridx = 0;
int len;
@@ -12212,10 +12081,7 @@ char_u *word;
/*
* Copy "fword" to "cword", fixing case according to "flags".
*/
-static void make_case_word(fword, cword, flags)
-char_u *fword;
-char_u *cword;
-int flags;
+static void make_case_word(char_u *fword, char_u *cword, int flags)
{
if (flags & WF_ALLCAP)
/* Make it all upper-case */
@@ -12231,9 +12097,7 @@ int flags;
/*
* Use map string "map" for languages "lp".
*/
-static void set_map_str(lp, map)
-slang_T *lp;
-char_u *map;
+static void set_map_str(slang_T *lp, char_u *map)
{
char_u *p;
int headc = 0;
@@ -12301,10 +12165,7 @@ char_u *map;
* Return TRUE if "c1" and "c2" are similar characters according to the MAP
* lines in the .aff file.
*/
-static int similar_chars(slang, c1, c2)
-slang_T *slang;
-int c1;
-int c2;
+static int similar_chars(slang_T *slang, int c1, int c2)
{
int m1, m2;
char_u buf[MB_MAXBYTES + 1];
@@ -12340,20 +12201,19 @@ int c2;
* Add a suggestion to the list of suggestions.
* For a suggestion that is already in the list the lowest score is remembered.
*/
-static void add_suggestion(su, gap, goodword, badlenarg, score, altscore,
- had_bonus,
- slang,
- maxsf)
-suginfo_T *su;
-garray_T *gap; /* either su_ga or su_sga */
-char_u *goodword;
-int badlenarg; /* len of bad word replaced with "goodword" */
-int score;
-int altscore;
-int had_bonus; /* value for st_had_bonus */
-slang_T *slang; /* language for sound folding */
-int maxsf; /* su_maxscore applies to soundfold score,
+static void
+add_suggestion (
+ suginfo_T *su,
+ garray_T *gap, /* either su_ga or su_sga */
+ char_u *goodword,
+ int badlenarg, /* len of bad word replaced with "goodword" */
+ int score,
+ int altscore,
+ int had_bonus, /* value for st_had_bonus */
+ slang_T *slang, /* language for sound folding */
+ int maxsf /* su_maxscore applies to soundfold score,
su_sfmaxscore to the total score. */
+)
{
int goodlen; /* len of goodword changed */
int badlen; /* len of bad word changed */
@@ -12464,9 +12324,11 @@ int maxsf; /* su_maxscore applies to soundfold score,
* Suggestions may in fact be flagged as errors. Esp. for banned words and
* for split words, such as "the the". Remove these from the list here.
*/
-static void check_suggestions(su, gap)
-suginfo_T *su;
-garray_T *gap; /* either su_ga or su_sga */
+static void
+check_suggestions (
+ suginfo_T *su,
+ garray_T *gap /* either su_ga or su_sga */
+)
{
suggest_T *stp;
int i;
@@ -12498,9 +12360,7 @@ garray_T *gap; /* either su_ga or su_sga */
/*
* Add a word to be banned.
*/
-static void add_banned(su, word)
-suginfo_T *su;
-char_u *word;
+static void add_banned(suginfo_T *su, char_u *word)
{
char_u *s;
hash_T hash;
@@ -12519,8 +12379,7 @@ char_u *word;
* Recompute the score for all suggestions if sound-folding is possible. This
* is slow, thus only done for the final results.
*/
-static void rescore_suggestions(su)
-suginfo_T *su;
+static void rescore_suggestions(suginfo_T *su)
{
int i;
@@ -12532,9 +12391,7 @@ suginfo_T *su;
/*
* Recompute the score for one suggestion if sound-folding is possible.
*/
-static void rescore_one(su, stp)
-suginfo_T *su;
-suggest_T *stp;
+static void rescore_one(suginfo_T *su, suggest_T *stp)
{
slang_T *slang = stp->st_slang;
char_u sal_badword[MAXWLEN];
@@ -12565,9 +12422,7 @@ sug_compare __ARGS((const void *s1, const void *s2));
* Function given to qsort() to sort the suggestions on st_score.
* First on "st_score", then "st_altscore" then alphabetically.
*/
-static int sug_compare(s1, s2)
-const void *s1;
-const void *s2;
+static int sug_compare(const void *s1, const void *s2)
{
suggest_T *p1 = (suggest_T *)s1;
suggest_T *p2 = (suggest_T *)s2;
@@ -12587,10 +12442,12 @@ const void *s2;
* - Remove words that won't be displayed.
* Returns the maximum score in the list or "maxscore" unmodified.
*/
-static int cleanup_suggestions(gap, maxscore, keep)
-garray_T *gap;
-int maxscore;
-int keep; /* nr of suggestions to keep */
+static int
+cleanup_suggestions (
+ garray_T *gap,
+ int maxscore,
+ int keep /* nr of suggestions to keep */
+)
{
suggest_T *stp = &SUG(*gap, 0);
int i;
@@ -12612,8 +12469,7 @@ int keep; /* nr of suggestions to keep */
* Soundfold a string, for soundfold().
* Result is in allocated memory, NULL for an error.
*/
-char_u * eval_soundfold(word)
-char_u *word;
+char_u *eval_soundfold(char_u *word)
{
langp_T *lp;
char_u sound[MAXWLEN];
@@ -12646,11 +12502,13 @@ char_u *word;
* 1. SOFOFROM/SOFOTO do a simple character mapping.
* 2. SAL items define a more advanced sound-folding (and much slower).
*/
-static void spell_soundfold(slang, inword, folded, res)
-slang_T *slang;
-char_u *inword;
-int folded; /* "inword" is already case-folded */
-char_u *res;
+static void
+spell_soundfold (
+ slang_T *slang,
+ char_u *inword,
+ int folded, /* "inword" is already case-folded */
+ char_u *res
+)
{
char_u fword[MAXWLEN];
char_u *word;
@@ -12678,10 +12536,7 @@ char_u *res;
* Perform sound folding of "inword" into "res" according to SOFOFROM and
* SOFOTO lines.
*/
-static void spell_soundfold_sofo(slang, inword, res)
-slang_T *slang;
-char_u *inword;
-char_u *res;
+static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
{
char_u *s;
int ri = 0;
@@ -12739,10 +12594,7 @@ char_u *res;
res[ri] = NUL;
}
-static void spell_soundfold_sal(slang, inword, res)
-slang_T *slang;
-char_u *inword;
-char_u *res;
+static void spell_soundfold_sal(slang_T *slang, char_u *inword, char_u *res)
{
salitem_T *smp;
char_u word[MAXWLEN];
@@ -12986,10 +12838,7 @@ char_u *res;
* Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
* Multi-byte version of spell_soundfold().
*/
-static void spell_soundfold_wsal(slang, inword, res)
-slang_T *slang;
-char_u *inword;
-char_u *res;
+static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
{
salitem_T *smp = (salitem_T *)slang->sl_sal.ga_data;
int word[MAXWLEN];
@@ -13271,9 +13120,11 @@ char_u *res;
* Instead of a generic loop we write out the code. That keeps it fast by
* avoiding checks that will not be possible.
*/
-static int soundalike_score(goodstart, badstart)
-char_u *goodstart; /* sound-folded good word */
-char_u *badstart; /* sound-folded bad word */
+static int
+soundalike_score (
+ char_u *goodstart, /* sound-folded good word */
+ char_u *badstart /* sound-folded bad word */
+)
{
char_u *goodsound = goodstart;
char_u *badsound = badstart;
@@ -13486,10 +13337,7 @@ char_u *badstart; /* sound-folded bad word */
* edit_distance(). It has been converted from C++ to C and modified to
* support multi-byte characters.
*/
-static int spell_edit_score(slang, badword, goodword)
-slang_T *slang;
-char_u *badword;
-char_u *goodword;
+static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
{
int *cnt;
int badlen, goodlen; /* lengths including NUL */
@@ -13595,11 +13443,7 @@ typedef struct {
* The idea comes from Aspell leditdist.cpp. Rewritten in C and added support
* for multi-byte characters.
*/
-static int spell_edit_score_limit(slang, badword, goodword, limit)
-slang_T *slang;
-char_u *badword;
-char_u *goodword;
-int limit;
+static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit)
{
limitscore_T stack[10]; /* allow for over 3 * 2 edits */
int stackidx;
@@ -13752,11 +13596,7 @@ pop:
* Multi-byte version of spell_edit_score_limit().
* Keep it in sync with the above!
*/
-static int spell_edit_score_limit_w(slang, badword, goodword, limit)
-slang_T *slang;
-char_u *badword;
-char_u *goodword;
-int limit;
+static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goodword, int limit)
{
limitscore_T stack[10]; /* allow for over 3 * 2 edits */
int stackidx;
@@ -13918,8 +13758,7 @@ pop:
/*
* ":spellinfo"
*/
-void ex_spellinfo(eap)
-exarg_T *eap UNUSED;
+void ex_spellinfo(exarg_T *eap)
{
int lpi;
langp_T *lp;
@@ -13952,8 +13791,7 @@ exarg_T *eap UNUSED;
/*
* ":spelldump"
*/
-void ex_spelldump(eap)
-exarg_T *eap;
+void ex_spelldump(exarg_T *eap)
{
char_u *spl;
long dummy;
@@ -13988,11 +13826,13 @@ exarg_T *eap;
* "ic" and "dir" are not used.
* 2. When "pat" is not NULL: add matching words to insert mode completion.
*/
-void spell_dump_compl(pat, ic, dir, dumpflags_arg)
-char_u *pat; /* leading part of the word */
-int ic; /* ignore case */
-int *dir; /* direction for adding matches */
-int dumpflags_arg; /* DUMPFLAG_* */
+void
+spell_dump_compl (
+ char_u *pat, /* leading part of the word */
+ int ic, /* ignore case */
+ int *dir, /* direction for adding matches */
+ int dumpflags_arg /* DUMPFLAG_* */
+)
{
langp_T *lp;
slang_T *slang;
@@ -14161,14 +14001,7 @@ int dumpflags_arg; /* DUMPFLAG_* */
* Dump one word: apply case modifications and append a line to the buffer.
* When "lnum" is zero add insert mode completion.
*/
-static void dump_word(slang, word, pat, dir, dumpflags, wordflags, lnum)
-slang_T *slang;
-char_u *word;
-char_u *pat;
-int *dir;
-int dumpflags;
-int wordflags;
-linenr_T lnum;
+static void dump_word(slang_T *slang, char_u *word, char_u *pat, int *dir, int dumpflags, int wordflags, linenr_T lnum)
{
int keepcap = FALSE;
char_u *p;
@@ -14242,15 +14075,16 @@ linenr_T lnum;
* When "lnum" is zero add insert mode completion.
* Return the updated line number.
*/
-static linenr_T dump_prefixes(slang, word, pat, dir, dumpflags, flags,
- startlnum)
-slang_T *slang;
-char_u *word; /* case-folded word */
-char_u *pat;
-int *dir;
-int dumpflags;
-int flags; /* flags with prefix ID */
-linenr_T startlnum;
+static linenr_T
+dump_prefixes (
+ slang_T *slang,
+ char_u *word, /* case-folded word */
+ char_u *pat,
+ int *dir,
+ int dumpflags,
+ int flags, /* flags with prefix ID */
+ linenr_T startlnum
+)
{
idx_T arridx[MAXWLEN];
int curi[MAXWLEN];
@@ -14346,9 +14180,7 @@ linenr_T startlnum;
* Move "p" to the end of word "start".
* Uses the spell-checking word characters.
*/
-char_u * spell_to_word_end(start, win)
-char_u *start;
-win_T *win;
+char_u *spell_to_word_end(char_u *start, win_T *win)
{
char_u *p = start;
@@ -14364,8 +14196,7 @@ win_T *win;
* the word in front of the cursor.
* Returns the column number of the word.
*/
-int spell_word_start(startcol)
-int startcol;
+int spell_word_start(int startcol)
{
char_u *line;
char_u *p;
@@ -14400,8 +14231,7 @@ int startcol;
*/
static int spell_expand_need_cap;
-void spell_expand_check_cap(col)
-colnr_T col;
+void spell_expand_check_cap(colnr_T col)
{
spell_expand_need_cap = check_need_cap(curwin->w_cursor.lnum, col);
}
@@ -14412,10 +14242,7 @@ colnr_T col;
* Returns the number of matches. The matches are in "matchp[]", array of
* allocated strings.
*/
-int expand_spelling(lnum, pat, matchp)
-linenr_T lnum UNUSED;
-char_u *pat;
-char_u ***matchp;
+int expand_spelling(linenr_T lnum, char_u *pat, char_u ***matchp)
{
garray_T ga;
diff --git a/src/proto/spell.pro b/src/spell.h
index cba277509e..8a349300a3 100644
--- a/src/proto/spell.pro
+++ b/src/spell.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_SPELL_H
+#define NEOVIM_SPELL_H
/* spell.c */
int spell_check __ARGS((win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol,
int docount));
@@ -28,3 +30,4 @@ int spell_word_start __ARGS((int startcol));
void spell_expand_check_cap __ARGS((colnr_T col));
int expand_spelling __ARGS((linenr_T lnum, char_u *pat, char_u ***matchp));
/* vim: set ft=c : */
+#endif /* NEOVIM_SPELL_H */
diff --git a/src/structs.h b/src/structs.h
index c29848a9af..639d50f674 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -56,9 +56,9 @@ typedef int scid_T; /* script ID */
typedef struct file_buffer buf_T; /* forward declaration */
/*
- * This is here because regexp.h needs pos_T and below regprog_T is used.
+ * This is here because regexp_defs.h needs pos_T and below regprog_T is used.
*/
-#include "regexp.h"
+#include "regexp_defs.h"
/*
* This is here because gui.h needs the pos_T and win_T, and win_T needs gui.h
diff --git a/src/syntax.c b/src/syntax.c
index 375f16cd0d..4b22137fda 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -12,6 +12,26 @@
*/
#include "vim.h"
+#include "syntax.h"
+#include "charset.h"
+#include "eval.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "fileio.h"
+#include "fold.h"
+#include "hashtab.h"
+#include "mbyte.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "os_unix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "term.h"
+#include "ui.h"
+#include "os/os.h"
/*
* Structure that stores information about a highlight group.
@@ -448,9 +468,7 @@ static void syn_incl_toplevel __ARGS((int id, int *flagsp));
* it. Careful: curbuf and curwin are likely to point to another buffer and
* window.
*/
-void syntax_start(wp, lnum)
-win_T *wp;
-linenr_T lnum;
+void syntax_start(win_T *wp, linenr_T lnum)
{
synstate_T *p;
synstate_T *last_valid = NULL;
@@ -610,8 +628,7 @@ linenr_T lnum;
* We cannot simply discard growarrays full of state_items or buf_states; we
* have to manually release their extmatch pointers first.
*/
-static void clear_syn_state(p)
-synstate_T *p;
+static void clear_syn_state(synstate_T *p)
{
int i;
garray_T *gap;
@@ -630,7 +647,7 @@ synstate_T *p;
/*
* Cleanup the current_state stack.
*/
-static void clear_current_state() {
+static void clear_current_state(void) {
int i;
stateitem_T *sip;
@@ -649,10 +666,7 @@ static void clear_current_state() {
* 2. Search backwards for given sync patterns.
* 3. Simply start on a given number of lines above "lnum".
*/
-static void syn_sync(wp, start_lnum, last_valid)
-win_T *wp;
-linenr_T start_lnum;
-synstate_T *last_valid;
+static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
{
buf_T *curbuf_save;
win_T *curwin_save;
@@ -901,8 +915,7 @@ synstate_T *last_valid;
/*
* Return TRUE if the line-continuation pattern matches in line "lnum".
*/
-static int syn_match_linecont(lnum)
-linenr_T lnum;
+static int syn_match_linecont(linenr_T lnum)
{
regmmatch_T regmatch;
@@ -918,7 +931,7 @@ linenr_T lnum;
/*
* Prepare the current state for the start of a line.
*/
-static void syn_start_line() {
+static void syn_start_line(void) {
current_finished = FALSE;
current_col = 0;
@@ -940,8 +953,7 @@ static void syn_start_line() {
* When "startofline" is TRUE the last item is always updated.
* When "startofline" is FALSE the item with "keepend" is forcefully updated.
*/
-static void syn_update_ends(startofline)
-int startofline;
+static void syn_update_ends(int startofline)
{
stateitem_T *cur_si;
int i;
@@ -1035,8 +1047,7 @@ int startofline;
* number of entries SST_MAX_ENTRIES, and the distance is computed.
*/
-static void syn_stack_free_block(block)
-synblock_T *block;
+static void syn_stack_free_block(synblock_T *block)
{
synstate_T *p;
@@ -1052,8 +1063,7 @@ synblock_T *block;
* Free b_sst_array[] for buffer "buf".
* Used when syntax items changed to force resyncing everywhere.
*/
-void syn_stack_free_all(block)
-synblock_T *block;
+void syn_stack_free_all(synblock_T *block)
{
win_T *wp;
@@ -1074,7 +1084,7 @@ synblock_T *block;
* small, reallocate it.
* Also used to allocate b_sst_array[] for the first time.
*/
-static void syn_stack_alloc() {
+static void syn_stack_alloc(void) {
long len;
synstate_T *to, *from;
synstate_T *sstp;
@@ -1144,8 +1154,7 @@ static void syn_stack_alloc() {
* Called from update_screen(), before screen is being updated, once for each
* displayed buffer.
*/
-void syn_stack_apply_changes(buf)
-buf_T *buf;
+void syn_stack_apply_changes(buf_T *buf)
{
win_T *wp;
@@ -1158,9 +1167,7 @@ buf_T *buf;
}
}
-static void syn_stack_apply_changes_block(block, buf)
-synblock_T *block;
-buf_T *buf;
+static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf)
{
synstate_T *p, *prev, *np;
linenr_T n;
@@ -1207,7 +1214,7 @@ buf_T *buf;
* Reduce the number of entries in the state stack for syn_buf.
* Returns TRUE if at least one entry was freed.
*/
-static int syn_stack_cleanup() {
+static int syn_stack_cleanup(void) {
synstate_T *p, *prev;
disptick_T tick;
int above;
@@ -1263,9 +1270,7 @@ static int syn_stack_cleanup() {
* Free the allocated memory for a syn_state item.
* Move the entry into the free list.
*/
-static void syn_stack_free_entry(block, p)
-synblock_T *block;
-synstate_T *p;
+static void syn_stack_free_entry(synblock_T *block, synstate_T *p)
{
clear_syn_state(p);
p->sst_next = block->b_sst_firstfree;
@@ -1277,8 +1282,7 @@ synstate_T *p;
* Find an entry in the list of state stacks at or before "lnum".
* Returns NULL when there is no entry or the first entry is after "lnum".
*/
-static synstate_T * syn_stack_find_entry(lnum)
-linenr_T lnum;
+static synstate_T *syn_stack_find_entry(linenr_T lnum)
{
synstate_T *p, *prev;
@@ -1296,7 +1300,7 @@ linenr_T lnum;
* Try saving the current state in b_sst_array[].
* The current state must be valid for the start of the current_lnum line!
*/
-static synstate_T * store_current_state() {
+static synstate_T *store_current_state(void) {
int i;
synstate_T *p;
bufstate_T *bp;
@@ -1400,8 +1404,7 @@ static synstate_T * store_current_state() {
/*
* Copy a state stack from "from" in b_sst_array[] to current_state;
*/
-static void load_current_state(from)
-synstate_T *from;
+static void load_current_state(synstate_T *from)
{
int i;
bufstate_T *bp;
@@ -1443,8 +1446,7 @@ synstate_T *from;
* Compare saved state stack "*sp" with the current state.
* Return TRUE when they are equal.
*/
-static int syn_stack_equal(sp)
-synstate_T *sp;
+static int syn_stack_equal(synstate_T *sp)
{
int i, j;
bufstate_T *bp;
@@ -1510,8 +1512,7 @@ synstate_T *sp;
* displayed line
* lnum -> line below window
*/
-void syntax_end_parsing(lnum)
-linenr_T lnum;
+void syntax_end_parsing(linenr_T lnum)
{
synstate_T *sp;
@@ -1527,14 +1528,14 @@ linenr_T lnum;
* End of handling of the state stack.
****************************************/
-static void invalidate_current_state() {
+static void invalidate_current_state(void) {
clear_current_state();
current_state.ga_itemsize = 0; /* mark current_state invalid */
current_next_list = NULL;
keepend_level = -1;
}
-static void validate_current_state() {
+static void validate_current_state(void) {
current_state.ga_itemsize = sizeof(stateitem_T);
current_state.ga_growsize = 3;
}
@@ -1544,8 +1545,7 @@ static void validate_current_state() {
* This will only be called just after get_syntax_attr() for the previous
* line, to check if the next line needs to be redrawn too.
*/
-int syntax_check_changed(lnum)
-linenr_T lnum;
+int syntax_check_changed(linenr_T lnum)
{
int retval = TRUE;
synstate_T *sp;
@@ -1590,8 +1590,10 @@ linenr_T lnum;
* the line. It can start anywhere in the line, as long as the current state
* is valid.
*/
-static int syn_finish_line(syncing)
-int syncing; /* called for syncing */
+static int
+syn_finish_line (
+ int syncing /* called for syncing */
+)
{
stateitem_T *cur_si;
colnr_T prev_current_col;
@@ -1636,10 +1638,12 @@ int syncing; /* called for syncing */
* When "can_spell" is not NULL set it to TRUE when spell-checking should be
* done.
*/
-int get_syntax_attr(col, can_spell, keep_state)
-colnr_T col;
-int *can_spell;
-int keep_state; /* keep state of char at "col" */
+int
+get_syntax_attr (
+ colnr_T col,
+ int *can_spell,
+ int keep_state /* keep state of char at "col" */
+)
{
int attr = 0;
@@ -1682,11 +1686,13 @@ int keep_state; /* keep state of char at "col" */
/*
* Get syntax attributes for current_lnum, current_col.
*/
-static int syn_current_attr(syncing, displaying, can_spell, keep_state)
-int syncing; /* When 1: called for syncing */
-int displaying; /* result will be displayed */
-int *can_spell; /* return: do spell checking */
-int keep_state; /* keep syntax stack afterwards */
+static int
+syn_current_attr (
+ int syncing, /* When 1: called for syncing */
+ int displaying, /* result will be displayed */
+ int *can_spell, /* return: do spell checking */
+ int keep_state /* keep syntax stack afterwards */
+)
{
int syn_id;
lpos_T endpos; /* was: char_u *endp; */
@@ -2203,9 +2209,7 @@ int keep_state; /* keep syntax stack afterwards */
/*
* Check if we already matched pattern "idx" at the current column.
*/
-static int did_match_already(idx, gap)
-int idx;
-garray_T *gap;
+static int did_match_already(int idx, garray_T *gap)
{
int i;
@@ -2227,8 +2231,7 @@ garray_T *gap;
/*
* Push the next match onto the stack.
*/
-static stateitem_T * push_next_match(cur_si)
-stateitem_T *cur_si;
+static stateitem_T *push_next_match(stateitem_T *cur_si)
{
synpat_T *spp;
int save_flags;
@@ -2307,7 +2310,7 @@ stateitem_T *cur_si;
/*
* Check for end of current state (and the states before it).
*/
-static void check_state_ends() {
+static void check_state_ends(void) {
stateitem_T *cur_si;
int had_extend;
@@ -2400,8 +2403,7 @@ static void check_state_ends() {
* Update an entry in the current_state stack for a match or region. This
* fills in si_attr, si_next_list and si_cont_list.
*/
-static void update_si_attr(idx)
-int idx;
+static void update_si_attr(int idx)
{
stateitem_T *sip = &CUR_STATE(idx);
synpat_T *spp;
@@ -2450,7 +2452,7 @@ int idx;
* Check the current stack for patterns with "keepend" flag.
* Propagate the match-end to contained items, until a "skipend" item is found.
*/
-static void check_keepend() {
+static void check_keepend(void) {
int i;
lpos_T maxpos;
lpos_T maxpos_h;
@@ -2505,10 +2507,12 @@ static void check_keepend() {
*
* Return the flags for the matched END.
*/
-static void update_si_end(sip, startcol, force)
-stateitem_T *sip;
-int startcol; /* where to start searching for the end */
-int force; /* when TRUE overrule a previous end */
+static void
+update_si_end (
+ stateitem_T *sip,
+ int startcol, /* where to start searching for the end */
+ int force /* when TRUE overrule a previous end */
+)
{
lpos_T startpos;
lpos_T endpos;
@@ -2564,8 +2568,7 @@ int force; /* when TRUE overrule a previous end */
* It is cleared and the index set to "idx".
* Return FAIL if it's not possible (out of memory).
*/
-static int push_current_state(idx)
-int idx;
+static int push_current_state(int idx)
{
if (ga_grow(&current_state, 1) == FAIL)
return FAIL;
@@ -2578,7 +2581,7 @@ int idx;
/*
* Remove a state from the current_state stack.
*/
-static void pop_current_state() {
+static void pop_current_state(void) {
if (current_state.ga_len) {
unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch);
--current_state.ga_len;
@@ -2600,16 +2603,17 @@ static void pop_current_state() {
* If found, the end of the region and the end of the highlighting is
* computed.
*/
-static void find_endpos(idx, startpos, m_endpos, hl_endpos, flagsp, end_endpos,
- end_idx, start_ext)
-int idx; /* index of the pattern */
-lpos_T *startpos; /* where to start looking for an END match */
-lpos_T *m_endpos; /* return: end of match */
-lpos_T *hl_endpos; /* return: end of highlighting */
-long *flagsp; /* return: flags of matching END */
-lpos_T *end_endpos; /* return: end of end pattern match */
-int *end_idx; /* return: group ID for end pat. match, or 0 */
-reg_extmatch_T *start_ext; /* submatches from the start pattern */
+static void
+find_endpos (
+ int idx, /* index of the pattern */
+ lpos_T *startpos, /* where to start looking for an END match */
+ lpos_T *m_endpos, /* return: end of match */
+ lpos_T *hl_endpos, /* return: end of highlighting */
+ long *flagsp, /* return: flags of matching END */
+ lpos_T *end_endpos, /* return: end of end pattern match */
+ int *end_idx, /* return: group ID for end pat. match, or 0 */
+ reg_extmatch_T *start_ext /* submatches from the start pattern */
+)
{
colnr_T matchcol;
synpat_T *spp, *spp_skip;
@@ -2806,9 +2810,7 @@ reg_extmatch_T *start_ext; /* submatches from the start pattern */
/*
* Limit "pos" not to be after "limit".
*/
-static void limit_pos(pos, limit)
-lpos_T *pos;
-lpos_T *limit;
+static void limit_pos(lpos_T *pos, lpos_T *limit)
{
if (pos->lnum > limit->lnum)
*pos = *limit;
@@ -2819,9 +2821,7 @@ lpos_T *limit;
/*
* Limit "pos" not to be after "limit", unless pos->lnum is zero.
*/
-static void limit_pos_zero(pos, limit)
-lpos_T *pos;
-lpos_T *limit;
+static void limit_pos_zero(lpos_T *pos, lpos_T *limit)
{
if (pos->lnum == 0)
*pos = *limit;
@@ -2832,12 +2832,14 @@ lpos_T *limit;
/*
* Add offset to matched text for end of match or highlight.
*/
-static void syn_add_end_off(result, regmatch, spp, idx, extra)
-lpos_T *result; /* returned position */
-regmmatch_T *regmatch; /* start/end of match */
-synpat_T *spp; /* matched pattern */
-int idx; /* index of offset */
-int extra; /* extra chars for offset to start */
+static void
+syn_add_end_off (
+ lpos_T *result, /* returned position */
+ regmmatch_T *regmatch, /* start/end of match */
+ synpat_T *spp, /* matched pattern */
+ int idx, /* index of offset */
+ int extra /* extra chars for offset to start */
+)
{
int col;
int off;
@@ -2876,12 +2878,14 @@ int extra; /* extra chars for offset to start */
* Add offset to matched text for start of match or highlight.
* Avoid resulting column to become negative.
*/
-static void syn_add_start_off(result, regmatch, spp, idx, extra)
-lpos_T *result; /* returned position */
-regmmatch_T *regmatch; /* start/end of match */
-synpat_T *spp;
-int idx;
-int extra; /* extra chars for offset to end */
+static void
+syn_add_start_off (
+ lpos_T *result, /* returned position */
+ regmmatch_T *regmatch, /* start/end of match */
+ synpat_T *spp,
+ int idx,
+ int extra /* extra chars for offset to end */
+)
{
int col;
int off;
@@ -2920,7 +2924,7 @@ int extra; /* extra chars for offset to end */
/*
* Get current line in syntax buffer.
*/
-static char_u * syn_getcurline() {
+static char_u *syn_getcurline(void) {
return ml_get_buf(syn_buf, current_lnum, FALSE);
}
@@ -2928,11 +2932,7 @@ static char_u * syn_getcurline() {
* Call vim_regexec() to find a match with "rmp" in "syn_buf".
* Returns TRUE when there is a match.
*/
-static int syn_regexec(rmp, lnum, col, st)
-regmmatch_T *rmp;
-linenr_T lnum;
-colnr_T col;
-syn_time_T *st UNUSED;
+static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T *st)
{
int r;
proftime_T pt;
@@ -2966,15 +2966,16 @@ syn_time_T *st UNUSED;
* The caller must check if a keyword can start at startcol.
* Return it's ID if found, 0 otherwise.
*/
-static int check_keyword_id(line, startcol, endcolp, flagsp, next_listp, cur_si,
- ccharp)
-char_u *line;
-int startcol; /* position in line to check for keyword */
-int *endcolp; /* return: character after found keyword */
-long *flagsp; /* return: flags of matching keyword */
-short **next_listp; /* return: next_list of matching keyword */
-stateitem_T *cur_si; /* item at the top of the stack */
-int *ccharp UNUSED; /* conceal substitution char */
+static int
+check_keyword_id (
+ char_u *line,
+ int startcol, /* position in line to check for keyword */
+ int *endcolp, /* return: character after found keyword */
+ long *flagsp, /* return: flags of matching keyword */
+ short **next_listp, /* return: next_list of matching keyword */
+ stateitem_T *cur_si, /* item at the top of the stack */
+ int *ccharp /* conceal substitution char */
+)
{
keyentry_T *kp;
char_u *kwp;
@@ -3046,9 +3047,7 @@ int *ccharp UNUSED; /* conceal substitution char */
/*
* Handle ":syntax conceal" command.
*/
-static void syn_cmd_conceal(eap, syncing)
-exarg_T *eap UNUSED;
-int syncing UNUSED;
+static void syn_cmd_conceal(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *next;
@@ -3069,9 +3068,7 @@ int syncing UNUSED;
/*
* Handle ":syntax case" command.
*/
-static void syn_cmd_case(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_case(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *next;
@@ -3092,9 +3089,7 @@ int syncing UNUSED;
/*
* Handle ":syntax spell" command.
*/
-static void syn_cmd_spell(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_spell(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *next;
@@ -3117,8 +3112,7 @@ int syncing UNUSED;
/*
* Clear all syntax info for one buffer.
*/
-void syntax_clear(block)
-synblock_T *block;
+void syntax_clear(synblock_T *block)
{
int i;
@@ -3165,8 +3159,7 @@ synblock_T *block;
/*
* Get rid of ownsyntax for window "wp".
*/
-void reset_synblock(wp)
-win_T *wp;
+void reset_synblock(win_T *wp)
{
if (wp->w_s != &wp->w_buffer->b_s) {
syntax_clear(wp->w_s);
@@ -3178,7 +3171,7 @@ win_T *wp;
/*
* Clear syncing info for one buffer.
*/
-static void syntax_sync_clear() {
+static void syntax_sync_clear(void) {
int i;
/* free the syntax patterns */
@@ -3202,9 +3195,7 @@ static void syntax_sync_clear() {
/*
* Remove one pattern from the buffer's pattern list.
*/
-static void syn_remove_pattern(block, idx)
-synblock_T *block;
-int idx;
+static void syn_remove_pattern(synblock_T *block, int idx)
{
synpat_T *spp;
@@ -3221,9 +3212,7 @@ int idx;
* Clear and free one syntax pattern. When clearing all, must be called from
* last to first!
*/
-static void syn_clear_pattern(block, i)
-synblock_T *block;
-int i;
+static void syn_clear_pattern(synblock_T *block, int i)
{
vim_free(SYN_ITEMS(block)[i].sp_pattern);
vim_regfree(SYN_ITEMS(block)[i].sp_prog);
@@ -3238,9 +3227,7 @@ int i;
/*
* Clear and free one syntax cluster.
*/
-static void syn_clear_cluster(block, i)
-synblock_T *block;
-int i;
+static void syn_clear_cluster(synblock_T *block, int i)
{
vim_free(SYN_CLSTR(block)[i].scl_name);
vim_free(SYN_CLSTR(block)[i].scl_name_u);
@@ -3250,9 +3237,7 @@ int i;
/*
* Handle ":syntax clear" command.
*/
-static void syn_cmd_clear(eap, syncing)
-exarg_T *eap;
-int syncing;
+static void syn_cmd_clear(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *arg_end;
@@ -3323,9 +3308,7 @@ int syncing;
/*
* Clear one syntax group for the current buffer.
*/
-static void syn_clear_one(id, syncing)
-int id;
-int syncing;
+static void syn_clear_one(int id, int syncing)
{
synpat_T *spp;
int idx;
@@ -3348,9 +3331,7 @@ int syncing;
/*
* Handle ":syntax on" command.
*/
-static void syn_cmd_on(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_on(exarg_T *eap, int syncing)
{
syn_cmd_onoff(eap, "syntax");
}
@@ -3358,9 +3339,7 @@ int syncing UNUSED;
/*
* Handle ":syntax enable" command.
*/
-static void syn_cmd_enable(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_enable(exarg_T *eap, int syncing)
{
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
syn_cmd_onoff(eap, "syntax");
@@ -3370,9 +3349,7 @@ int syncing UNUSED;
/*
* Handle ":syntax reset" command.
*/
-static void syn_cmd_reset(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_reset(exarg_T *eap, int syncing)
{
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
@@ -3385,9 +3362,7 @@ int syncing UNUSED;
/*
* Handle ":syntax manual" command.
*/
-static void syn_cmd_manual(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_manual(exarg_T *eap, int syncing)
{
syn_cmd_onoff(eap, "manual");
}
@@ -3395,16 +3370,12 @@ int syncing UNUSED;
/*
* Handle ":syntax off" command.
*/
-static void syn_cmd_off(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_off(exarg_T *eap, int syncing)
{
syn_cmd_onoff(eap, "nosyntax");
}
-static void syn_cmd_onoff(eap, name)
-exarg_T *eap;
-char *name;
+static void syn_cmd_onoff(exarg_T *eap, char *name)
{
char_u buf[100];
@@ -3419,9 +3390,11 @@ char *name;
/*
* Handle ":syntax [list]" command: list current syntax words.
*/
-static void syn_cmd_list(eap, syncing)
-exarg_T *eap;
-int syncing; /* when TRUE: list syncing items */
+static void
+syn_cmd_list (
+ exarg_T *eap,
+ int syncing /* when TRUE: list syncing items */
+)
{
char_u *arg = eap->arg;
int id;
@@ -3496,7 +3469,7 @@ int syncing; /* when TRUE: list syncing items */
eap->nextcmd = check_nextcmd(arg);
}
-static void syn_lines_msg() {
+static void syn_lines_msg(void) {
if (curwin->w_s->b_syn_sync_maxlines > 0
|| curwin->w_s->b_syn_sync_minlines > 0) {
MSG_PUTS("; ");
@@ -3514,7 +3487,7 @@ static void syn_lines_msg() {
}
}
-static void syn_match_msg() {
+static void syn_match_msg(void) {
if (curwin->w_s->b_syn_sync_linebreaks > 0) {
MSG_PUTS(_("; match "));
msg_outnum(curwin->w_s->b_syn_sync_linebreaks);
@@ -3534,10 +3507,12 @@ static void syn_list_flags __ARGS((struct name_list *nl, int flags, int attr));
/*
* List one syntax item, for ":syntax" or "syntax list syntax_name".
*/
-static void syn_list_one(id, syncing, link_only)
-int id;
-int syncing; /* when TRUE: list syncing items */
-int link_only; /* when TRUE; list link-only too */
+static void
+syn_list_one (
+ int id,
+ int syncing, /* when TRUE: list syncing items */
+ int link_only /* when TRUE; list link-only too */
+)
{
int attr;
int idx;
@@ -3634,10 +3609,7 @@ int link_only; /* when TRUE; list link-only too */
}
}
-static void syn_list_flags(nlist, flags, attr)
-struct name_list *nlist;
-int flags;
-int attr;
+static void syn_list_flags(struct name_list *nlist, int flags, int attr)
{
int i;
@@ -3651,8 +3623,7 @@ int attr;
/*
* List one syntax cluster, for ":syntax" or "syntax list syntax_name".
*/
-static void syn_list_cluster(id)
-int id;
+static void syn_list_cluster(int id)
{
int endcol = 15;
@@ -3675,10 +3646,7 @@ int id;
}
}
-static void put_id_list(name, list, attr)
-char_u *name;
-short *list;
-int attr;
+static void put_id_list(char_u *name, short *list, int attr)
{
short *p;
@@ -3707,11 +3675,7 @@ int attr;
msg_putchar(' ');
}
-static void put_pattern(s, c, spp, attr)
-char *s;
-int c;
-synpat_T *spp;
-int attr;
+static void put_pattern(char *s, int c, synpat_T *spp, int attr)
{
long n;
int mask;
@@ -3774,11 +3738,13 @@ int attr;
* List or clear the keywords for one syntax group.
* Return TRUE if the header has been printed.
*/
-static int syn_list_keywords(id, ht, did_header, attr)
-int id;
-hashtab_T *ht;
-int did_header; /* header has already been printed */
-int attr;
+static int
+syn_list_keywords (
+ int id,
+ hashtab_T *ht,
+ int did_header, /* header has already been printed */
+ int attr
+)
{
int outlen;
hashitem_T *hi;
@@ -3860,9 +3826,7 @@ int attr;
return did_header;
}
-static void syn_clear_keyword(id, ht)
-int id;
-hashtab_T *ht;
+static void syn_clear_keyword(int id, hashtab_T *ht)
{
hashitem_T *hi;
keyentry_T *kp;
@@ -3903,8 +3867,7 @@ hashtab_T *ht;
/*
* Clear a whole keyword table.
*/
-static void clear_keywtab(ht)
-hashtab_T *ht;
+static void clear_keywtab(hashtab_T *ht)
{
hashitem_T *hi;
int todo;
@@ -3930,13 +3893,15 @@ hashtab_T *ht;
/*
* Add a keyword to the list of keywords.
*/
-static void add_keyword(name, id, flags, cont_in_list, next_list, conceal_char)
-char_u *name; /* name of keyword */
-int id; /* group ID for this keyword */
-int flags; /* flags for this keyword */
-short *cont_in_list; /* containedin for this keyword */
-short *next_list; /* nextgroup for this keyword */
-int conceal_char;
+static void
+add_keyword (
+ char_u *name, /* name of keyword */
+ int id, /* group ID for this keyword */
+ int flags, /* flags for this keyword */
+ short *cont_in_list, /* containedin for this keyword */
+ short *next_list, /* nextgroup for this keyword */
+ int conceal_char
+)
{
keyentry_T *kp;
hashtab_T *ht;
@@ -3986,9 +3951,11 @@ int conceal_char;
* Return a pointer to the first argument.
* Return NULL if the end of the command was found instead of further args.
*/
-static char_u * get_group_name(arg, name_end)
-char_u *arg; /* start of the argument */
-char_u **name_end; /* pointer to end of the name */
+static char_u *
+get_group_name (
+ char_u *arg, /* start of the argument */
+ char_u **name_end /* pointer to end of the name */
+)
{
char_u *rest;
@@ -4012,10 +3979,12 @@ char_u **name_end; /* pointer to end of the name */
* Return a pointer to the next argument (which isn't an option).
* Return NULL for any error;
*/
-static char_u * get_syn_options(arg, opt, conceal_char)
-char_u *arg; /* next argument to be checked */
-syn_opt_arg_T *opt; /* various things */
-int *conceal_char UNUSED;
+static char_u *
+get_syn_options (
+ char_u *arg, /* next argument to be checked */
+ syn_opt_arg_T *opt, /* various things */
+ int *conceal_char
+)
{
char_u *gname_start, *gname;
int syn_id;
@@ -4161,9 +4130,7 @@ int *conceal_char UNUSED;
* Set the contained flag, and if the item is not already contained, add it
* to the specified top-level group, if any.
*/
-static void syn_incl_toplevel(id, flagsp)
-int id;
-int *flagsp;
+static void syn_incl_toplevel(int id, int *flagsp)
{
if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0)
return;
@@ -4185,9 +4152,7 @@ int *flagsp;
/*
* Handle ":syntax include [@{group-name}] filename" command.
*/
-static void syn_cmd_include(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_include(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
int sgl_id = 1;
@@ -4256,9 +4221,7 @@ int syncing UNUSED;
/*
* Handle ":syntax keyword {group-name} [{option}] keyword .." command.
*/
-static void syn_cmd_keyword(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_keyword(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *group_name_end;
@@ -4365,9 +4328,11 @@ int syncing UNUSED;
*
* Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
*/
-static void syn_cmd_match(eap, syncing)
-exarg_T *eap;
-int syncing; /* TRUE for ":syntax sync match .. " */
+static void
+syn_cmd_match (
+ exarg_T *eap,
+ int syncing /* TRUE for ":syntax sync match .. " */
+)
{
char_u *arg = eap->arg;
char_u *group_name_end;
@@ -4462,9 +4427,11 @@ int syncing; /* TRUE for ":syntax sync match .. " */
* Handle ":syntax region {group-name} [matchgroup={group-name}]
* start {start} .. [skip {skip}] end {end} .. [{options}]".
*/
-static void syn_cmd_region(eap, syncing)
-exarg_T *eap;
-int syncing; /* TRUE for ":syntax sync region .." */
+static void
+syn_cmd_region (
+ exarg_T *eap,
+ int syncing /* TRUE for ":syntax sync region .." */
+)
{
char_u *arg = eap->arg;
char_u *group_name_end;
@@ -4699,9 +4666,7 @@ int syncing; /* TRUE for ":syntax sync region .." */
/*
* A simple syntax group ID comparison function suitable for use in qsort()
*/
-static int syn_compare_stub(v1, v2)
-const void *v1;
-const void *v2;
+static int syn_compare_stub(const void *v1, const void *v2)
{
const short *s1 = v1;
const short *s2 = v2;
@@ -4713,10 +4678,7 @@ const void *v2;
* Combines lists of syntax clusters.
* *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
*/
-static void syn_combine_list(clstr1, clstr2, list_op)
-short **clstr1;
-short **clstr2;
-int list_op;
+static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
{
int count1 = 0;
int count2 = 0;
@@ -4832,8 +4794,7 @@ int list_op;
* Lookup a syntax cluster name and return it's ID.
* If it is not found, 0 is returned.
*/
-static int syn_scl_name2id(name)
-char_u *name;
+static int syn_scl_name2id(char_u *name)
{
int i;
char_u *name_u;
@@ -4853,9 +4814,7 @@ char_u *name;
/*
* Like syn_scl_name2id(), but take a pointer + length argument.
*/
-static int syn_scl_namen2id(linep, len)
-char_u *linep;
-int len;
+static int syn_scl_namen2id(char_u *linep, int len)
{
char_u *name;
int id = 0;
@@ -4874,9 +4833,7 @@ int len;
* If it doesn't exist yet, a new entry is created.
* Return 0 for failure.
*/
-static int syn_check_cluster(pp, len)
-char_u *pp;
-int len;
+static int syn_check_cluster(char_u *pp, int len)
{
int id;
char_u *name;
@@ -4898,8 +4855,7 @@ int len;
* "name" must be an allocated string, it will be consumed.
* Return 0 for failure.
*/
-static int syn_add_cluster(name)
-char_u *name;
+static int syn_add_cluster(char_u *name)
{
int len;
@@ -4944,9 +4900,7 @@ char_u *name;
* Handle ":syntax cluster {cluster-name} [contains={groupname},..]
* [add={groupname},..] [remove={groupname},..]".
*/
-static void syn_cmd_cluster(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_cluster(exarg_T *eap, int syncing)
{
char_u *arg = eap->arg;
char_u *group_name_end;
@@ -5010,7 +4964,7 @@ int syncing UNUSED;
/*
* On first call for current buffer: Init growing array.
*/
-static void init_syn_patterns() {
+static void init_syn_patterns(void) {
curwin->w_s->b_syn_patterns.ga_itemsize = sizeof(synpat_T);
curwin->w_s->b_syn_patterns.ga_growsize = 10;
}
@@ -5020,9 +4974,7 @@ static void init_syn_patterns() {
* Stores the pattern and program in a synpat_T.
* Returns a pointer to the next argument, or NULL in case of an error.
*/
-static char_u * get_syn_pattern(arg, ci)
-char_u *arg;
-synpat_T *ci;
+static char_u *get_syn_pattern(char_u *arg, synpat_T *ci)
{
char_u *end;
int *p;
@@ -5108,9 +5060,7 @@ synpat_T *ci;
/*
* Handle ":syntax sync .." command.
*/
-static void syn_cmd_sync(eap, syncing)
-exarg_T *eap;
-int syncing UNUSED;
+static void syn_cmd_sync(exarg_T *eap, int syncing)
{
char_u *arg_start = eap->arg;
char_u *arg_end;
@@ -5239,11 +5189,13 @@ int syncing UNUSED;
* Careful: the argument is modified (NULs added).
* returns FAIL for some error, OK for success.
*/
-static int get_id_list(arg, keylen, list)
-char_u **arg;
-int keylen; /* length of keyword */
-short **list; /* where to store the resulting list, if not
+static int
+get_id_list (
+ char_u **arg,
+ int keylen, /* length of keyword */
+ short **list /* where to store the resulting list, if not
NULL, the list is silently skipped! */
+)
{
char_u *p = NULL;
char_u *end;
@@ -5409,8 +5361,7 @@ short **list; /* where to store the resulting list, if not
/*
* Make a copy of an ID list.
*/
-static short * copy_id_list(list)
-short *list;
+static short *copy_id_list(short *list)
{
int len;
int count;
@@ -5436,11 +5387,13 @@ short *list;
* the current item.
* This function is called very often, keep it fast!!
*/
-static int in_id_list(cur_si, list, ssp, contained)
-stateitem_T *cur_si; /* current item or NULL */
-short *list; /* id list */
-struct sp_syn *ssp; /* group id and ":syn include" tag of group */
-int contained; /* group id is contained */
+static int
+in_id_list (
+ stateitem_T *cur_si, /* current item or NULL */
+ short *list, /* id list */
+ struct sp_syn *ssp, /* group id and ":syn include" tag of group */
+ int contained /* group id is contained */
+)
{
int retval;
short *scl_list;
@@ -5554,8 +5507,7 @@ static struct subcommand subcommands[] =
* This searches the subcommands[] table for the subcommand name, and calls a
* syntax_subcommand() function to do the rest.
*/
-void ex_syntax(eap)
-exarg_T *eap;
+void ex_syntax(exarg_T *eap)
{
char_u *arg = eap->arg;
char_u *subcmd_end;
@@ -5588,8 +5540,7 @@ exarg_T *eap;
}
}
-void ex_ownsyntax(eap)
-exarg_T *eap;
+void ex_ownsyntax(exarg_T *eap)
{
char_u *old_value;
char_u *new_value;
@@ -5628,8 +5579,7 @@ exarg_T *eap;
}
}
-int syntax_present(win)
-win_T *win;
+int syntax_present(win_T *win)
{
return win->w_s->b_syn_patterns.ga_len != 0
|| win->w_s->b_syn_clusters.ga_len != 0
@@ -5647,7 +5597,7 @@ static enum {
* Reset include_link, include_default, include_none to 0.
* Called when we are done expanding.
*/
-void reset_expand_highlight() {
+void reset_expand_highlight(void) {
include_link = include_default = include_none = 0;
}
@@ -5655,9 +5605,7 @@ void reset_expand_highlight() {
* Handle command line completion for :match and :echohl command: Add "None"
* as highlight group.
*/
-void set_context_in_echohl_cmd(xp, arg)
-expand_T *xp;
-char_u *arg;
+void set_context_in_echohl_cmd(expand_T *xp, char_u *arg)
{
xp->xp_context = EXPAND_HIGHLIGHT;
xp->xp_pattern = arg;
@@ -5667,9 +5615,7 @@ char_u *arg;
/*
* Handle command line completion for :syntax command.
*/
-void set_context_in_syntax_cmd(xp, arg)
-expand_T *xp;
-char_u *arg;
+void set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
{
char_u *p;
@@ -5706,9 +5652,7 @@ static char *(case_args[]) = {"match", "ignore", NULL};
* Function given to ExpandGeneric() to obtain the list syntax names for
* expansion.
*/
-char_u * get_syntax_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_syntax_name(expand_T *xp, int idx)
{
if (expand_what == EXP_SUBCMD)
return (char_u *)subcommands[idx].name;
@@ -5719,13 +5663,15 @@ int idx;
/*
* Function called for expression evaluation: get syntax ID at file position.
*/
-int syn_get_id(wp, lnum, col, trans, spellp, keep_state)
-win_T *wp;
-long lnum;
-colnr_T col;
-int trans; /* remove transparency */
-int *spellp; /* return: can do spell checking */
-int keep_state; /* keep state of char at "col" */
+int
+syn_get_id (
+ win_T *wp,
+ long lnum,
+ colnr_T col,
+ int trans, /* remove transparency */
+ int *spellp, /* return: can do spell checking */
+ int keep_state /* keep state of char at "col" */
+)
{
/* When the position is not after the current position and in the same
* line of the same buffer, need to restart parsing. */
@@ -5745,8 +5691,7 @@ int keep_state; /* keep state of char at "col" */
* Stores the current item sequence nr in "*seqnrp".
* Returns the current flags.
*/
-int get_syntax_info(seqnrp)
-int *seqnrp;
+int get_syntax_info(int *seqnrp)
{
*seqnrp = current_seqnr;
return current_flags;
@@ -5755,7 +5700,7 @@ int *seqnrp;
/*
* Return conceal substitution character
*/
-int syn_get_sub_char() {
+int syn_get_sub_char(void) {
return current_sub_char;
}
@@ -5764,8 +5709,7 @@ int syn_get_sub_char() {
* The caller must have called syn_get_id() before to fill the stack.
* Returns -1 when "i" is out of range.
*/
-int syn_get_stack_item(i)
-int i;
+int syn_get_stack_item(int i)
{
if (i >= current_state.ga_len) {
/* Need to invalidate the state, because we didn't properly finish it
@@ -5780,9 +5724,7 @@ int i;
/*
* Function called to get folding level for line "lnum" in window "wp".
*/
-int syn_get_foldlevel(wp, lnum)
-win_T *wp;
-long lnum;
+int syn_get_foldlevel(win_T *wp, long lnum)
{
int level = 0;
int i;
@@ -5806,8 +5748,7 @@ long lnum;
/*
* ":syntime".
*/
-void ex_syntime(eap)
-exarg_T *eap;
+void ex_syntime(exarg_T *eap)
{
if (STRCMP(eap->arg, "on") == 0)
syn_time_on = TRUE;
@@ -5821,8 +5762,7 @@ exarg_T *eap;
EMSG2(_(e_invarg2), eap->arg);
}
-static void syn_clear_time(st)
-syn_time_T *st;
+static void syn_clear_time(syn_time_T *st)
{
profile_zero(&st->total);
profile_zero(&st->slowest);
@@ -5833,7 +5773,7 @@ syn_time_T *st;
/*
* Clear the syntax timing for the current buffer.
*/
-static void syntime_clear() {
+static void syntime_clear(void) {
int idx;
synpat_T *spp;
@@ -5851,9 +5791,7 @@ static void syntime_clear() {
* Function given to ExpandGeneric() to obtain the possible arguments of the
* ":syntime {on,off,clear,report}" command.
*/
-char_u * get_syntime_arg(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_syntime_arg(expand_T *xp, int idx)
{
switch (idx) {
case 0: return (char_u *)"on";
@@ -5874,9 +5812,7 @@ typedef struct {
char_u *pattern;
} time_entry_T;
-static int syn_compare_syntime(v1, v2)
-const void *v1;
-const void *v2;
+static int syn_compare_syntime(const void *v1, const void *v2)
{
const time_entry_T *s1 = v1;
const time_entry_T *s2 = v2;
@@ -5887,7 +5823,7 @@ const void *v2;
/*
* Clear the syntax timing for the current buffer.
*/
-static void syntime_report() {
+static void syntime_report(void) {
int idx;
synpat_T *spp;
proftime_T tm;
@@ -6151,9 +6087,11 @@ static char *(highlight_init_dark[]) =
NULL
};
-void init_highlight(both, reset)
-int both; /* include groups where 'bg' doesn't matter */
-int reset; /* clear group first */
+void
+init_highlight (
+ int both, /* include groups where 'bg' doesn't matter */
+ int reset /* clear group first */
+)
{
int i;
char **pp;
@@ -6227,8 +6165,7 @@ int reset; /* clear group first */
* Load color file "name".
* Return OK for success, FAIL for failure.
*/
-int load_colors(name)
-char_u *name;
+int load_colors(char_u *name)
{
char_u *buf;
int retval = FAIL;
@@ -6258,10 +6195,12 @@ char_u *name;
* When using ":hi clear" this is called recursively for each group with
* "forceit" and "init" both TRUE.
*/
-void do_highlight(line, forceit, init)
-char_u *line;
-int forceit;
-int init; /* TRUE when called for initializing */
+void
+do_highlight (
+ char_u *line,
+ int forceit,
+ int init /* TRUE when called for initializing */
+)
{
char_u *name_end;
char_u *p;
@@ -6871,7 +6810,7 @@ int init; /* TRUE when called for initializing */
}
#if defined(EXITFREE) || defined(PROTO)
-void free_highlight() {
+void free_highlight(void) {
int i;
for (i = 0; i < highlight_ga.ga_len; ++i) {
@@ -6888,7 +6827,7 @@ void free_highlight() {
* Reset the cterm colors to what they were before Vim was started, if
* possible. Otherwise reset them to zero.
*/
-void restore_cterm_colors() {
+void restore_cterm_colors(void) {
cterm_normal_fg_color = 0;
cterm_normal_fg_bold = 0;
cterm_normal_bg_color = 0;
@@ -6898,9 +6837,7 @@ void restore_cterm_colors() {
* Return TRUE if highlight group "idx" has any settings.
* When "check_link" is TRUE also check for an existing link.
*/
-static int hl_has_settings(idx, check_link)
-int idx;
-int check_link;
+static int hl_has_settings(int idx, int check_link)
{
return HL_TABLE()[idx].sg_term_attr != 0
|| HL_TABLE()[idx].sg_cterm_attr != 0
@@ -6910,8 +6847,7 @@ int check_link;
/*
* Clear highlighting for one group.
*/
-static void highlight_clear(idx)
-int idx;
+static void highlight_clear(int idx)
{
HL_TABLE()[idx].sg_term = 0;
vim_free(HL_TABLE()[idx].sg_start);
@@ -6958,9 +6894,7 @@ static garray_T cterm_attr_table = {0, 0, 0, 0, NULL};
* if the combination is new.
* Return 0 for error (no more room).
*/
-static int get_attr_entry(table, aep)
-garray_T *table;
-attrentry_T *aep;
+static int get_attr_entry(garray_T *table, attrentry_T *aep)
{
int i;
attrentry_T *taep;
@@ -7051,7 +6985,7 @@ attrentry_T *aep;
/*
* Clear all highlight tables.
*/
-void clear_hl_tables() {
+void clear_hl_tables(void) {
int i;
attrentry_T *taep;
@@ -7073,9 +7007,7 @@ void clear_hl_tables() {
* result.
* Return the resulting attributes.
*/
-int hl_combine_attr(char_attr, prim_attr)
-int char_attr;
-int prim_attr;
+int hl_combine_attr(int char_attr, int prim_attr)
{
attrentry_T *char_aep = NULL;
attrentry_T *spell_aep;
@@ -7142,8 +7074,7 @@ int prim_attr;
* Get the highlight attributes (HL_BOLD etc.) from an attribute nr.
* Only to be used when "attr" > HL_ALL.
*/
-int syn_attr2attr(attr)
-int attr;
+int syn_attr2attr(int attr)
{
attrentry_T *aep;
@@ -7158,8 +7089,7 @@ int attr;
}
-attrentry_T * syn_term_attr2entry(attr)
-int attr;
+attrentry_T *syn_term_attr2entry(int attr)
{
attr -= ATTR_OFF;
if (attr >= term_attr_table.ga_len) /* did ":syntax clear" */
@@ -7167,8 +7097,7 @@ int attr;
return &(TERM_ATTR_ENTRY(attr));
}
-attrentry_T * syn_cterm_attr2entry(attr)
-int attr;
+attrentry_T *syn_cterm_attr2entry(int attr)
{
attr -= ATTR_OFF;
if (attr >= cterm_attr_table.ga_len) /* did ":syntax clear" */
@@ -7180,8 +7109,7 @@ int attr;
#define LIST_STRING 2
#define LIST_INT 3
-static void highlight_list_one(id)
-int id;
+static void highlight_list_one(int id)
{
struct hl_group *sgp;
int didh = FALSE;
@@ -7225,13 +7153,7 @@ int id;
last_set_msg(sgp->sg_scriptID);
}
-static int highlight_list_arg(id, didh, type, iarg, sarg, name)
-int id;
-int didh;
-int type;
-int iarg;
-char_u *sarg;
-char *name;
+static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name)
{
char_u buf[100];
char_u *ts;
@@ -7275,10 +7197,12 @@ char *name;
* Return "1" if highlight group "id" has attribute "flag".
* Return NULL otherwise.
*/
-char_u * highlight_has_attr(id, flag, modec)
-int id;
-int flag;
-int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
+char_u *
+highlight_has_attr (
+ int id,
+ int flag,
+ int modec /* 'g' for GUI, 'c' for cterm, 't' for term */
+)
{
int attr;
@@ -7300,10 +7224,12 @@ int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
/*
* Return color name of highlight group "id".
*/
-char_u * highlight_color(id, what, modec)
-int id;
-char_u *what; /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
-int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
+char_u *
+highlight_color (
+ int id,
+ char_u *what, /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
+ int modec /* 'g' for GUI, 'c' for cterm, 't' for term */
+)
{
static char_u name[20];
int n;
@@ -7349,9 +7275,11 @@ int modec; /* 'g' for GUI, 'c' for cterm, 't' for term */
/*
* Return color name of highlight group "id" as RGB value.
*/
-long_u highlight_gui_color_rgb(id, fg)
-int id;
-int fg; /* TRUE = fg, FALSE = bg */
+long_u
+highlight_gui_color_rgb (
+ int id,
+ int fg /* TRUE = fg, FALSE = bg */
+)
{
guicolor_T color;
@@ -7374,10 +7302,12 @@ int fg; /* TRUE = fg, FALSE = bg */
* Output the syntax list header.
* Return TRUE when started a new line.
*/
-static int syn_list_header(did_header, outlen, id)
-int did_header; /* did header already */
-int outlen; /* length of string that comes */
-int id; /* highlight group id */
+static int
+syn_list_header (
+ int did_header, /* did header already */
+ int outlen, /* length of string that comes */
+ int id /* highlight group id */
+)
{
int endcol = 19;
int newline = TRUE;
@@ -7417,8 +7347,10 @@ int id; /* highlight group id */
* Set the attribute numbers for a highlight group.
* Called after one of the attributes has changed.
*/
-static void set_hl_attr(idx)
-int idx; /* index in array */
+static void
+set_hl_attr (
+ int idx /* index in array */
+)
{
attrentry_T at_en;
struct hl_group *sgp = HL_TABLE() + idx;
@@ -7458,8 +7390,7 @@ int idx; /* index in array */
* Lookup a highlight group name and return it's ID.
* If it is not found, 0 is returned.
*/
-int syn_name2id(name)
-char_u *name;
+int syn_name2id(char_u *name)
{
int i;
char_u name_u[200];
@@ -7479,8 +7410,7 @@ char_u *name;
/*
* Return TRUE if highlight group "name" exists.
*/
-int highlight_exists(name)
-char_u *name;
+int highlight_exists(char_u *name)
{
return syn_name2id(name) > 0;
}
@@ -7489,8 +7419,7 @@ char_u *name;
* Return the name of highlight group "id".
* When not a valid ID return an empty string.
*/
-char_u * syn_id2name(id)
-int id;
+char_u *syn_id2name(int id)
{
if (id <= 0 || id > highlight_ga.ga_len)
return (char_u *)"";
@@ -7500,9 +7429,7 @@ int id;
/*
* Like syn_name2id(), but take a pointer + length argument.
*/
-int syn_namen2id(linep, len)
-char_u *linep;
-int len;
+int syn_namen2id(char_u *linep, int len)
{
char_u *name;
int id = 0;
@@ -7521,9 +7448,7 @@ int len;
* If it doesn't exist yet, a new entry is created.
* Return 0 for failure.
*/
-int syn_check_group(pp, len)
-char_u *pp;
-int len;
+int syn_check_group(char_u *pp, int len)
{
int id;
char_u *name;
@@ -7545,8 +7470,7 @@ int len;
* "name" must be an allocated string, it will be consumed.
* Return 0 for failure.
*/
-static int syn_add_group(name)
-char_u *name;
+static int syn_add_group(char_u *name)
{
char_u *p;
@@ -7599,7 +7523,7 @@ char_u *name;
* When, just after calling syn_add_group(), an error is discovered, this
* function deletes the new name.
*/
-static void syn_unadd_group() {
+static void syn_unadd_group(void) {
--highlight_ga.ga_len;
vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name);
vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
@@ -7608,8 +7532,7 @@ static void syn_unadd_group() {
/*
* Translate a group ID to highlight attributes.
*/
-int syn_id2attr(hl_id)
-int hl_id;
+int syn_id2attr(int hl_id)
{
int attr;
struct hl_group *sgp;
@@ -7629,8 +7552,7 @@ int hl_id;
/*
* Translate a group ID to the final group ID (following links).
*/
-int syn_get_final_id(hl_id)
-int hl_id;
+int syn_get_final_id(int hl_id)
{
int count;
struct hl_group *sgp;
@@ -7661,7 +7583,7 @@ int hl_id;
* screen redraw after any :highlight command.
* Return FAIL when an invalid flag is found in 'highlight'. OK otherwise.
*/
-int highlight_changed() {
+int highlight_changed(void) {
int hlf;
int i;
char_u *p;
@@ -7827,9 +7749,7 @@ static void highlight_list_two __ARGS((int cnt, int attr));
/*
* Handle command line completion for :highlight command.
*/
-void set_context_in_highlight_cmd(xp, arg)
-expand_T *xp;
-char_u *arg;
+void set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
{
char_u *p;
@@ -7872,7 +7792,7 @@ char_u *arg;
/*
* List highlighting matches in a nice way.
*/
-static void highlight_list() {
+static void highlight_list(void) {
int i;
for (i = 10; --i >= 0; )
@@ -7881,9 +7801,7 @@ static void highlight_list() {
highlight_list_two(99, 0);
}
-static void highlight_list_two(cnt, attr)
-int cnt;
-int attr;
+static void highlight_list_two(int cnt, int attr)
{
msg_puts_attr((char_u *)&("N \bI \b! \b"[cnt / 11]), attr);
msg_clr_eos();
@@ -7898,9 +7816,7 @@ int attr;
* Function given to ExpandGeneric() to obtain the list of group names.
* Also used for synIDattr() function.
*/
-char_u * get_highlight_name(xp, idx)
-expand_T *xp UNUSED;
-int idx;
+char_u *get_highlight_name(expand_T *xp, int idx)
{
if (idx == highlight_ga.ga_len && include_none != 0)
return (char_u *)"none";
diff --git a/src/proto/syntax.pro b/src/syntax.h
index 0d5f23910f..e05d342927 100644
--- a/src/proto/syntax.pro
+++ b/src/syntax.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_SYNTAX_H
+#define NEOVIM_SYNTAX_H
/* syntax.c */
void syntax_start __ARGS((win_T *wp, linenr_T lnum));
void syn_stack_free_all __ARGS((synblock_T *block));
@@ -56,3 +58,4 @@ void set_context_in_highlight_cmd __ARGS((expand_T *xp, char_u *arg));
char_u *get_highlight_name __ARGS((expand_T *xp, int idx));
void free_highlight_fonts __ARGS((void));
/* vim: set ft=c : */
+#endif /* NEOVIM_SYNTAX_H */
diff --git a/src/tag.c b/src/tag.c
index 3f144936c7..ebdfb6b2a2 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -12,6 +12,33 @@
*/
#include "vim.h"
+#include "tag.h"
+#include "buffer.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "if_cscope.h"
+#include "mark.h"
+#include "mbyte.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "term.h"
+#include "ui.h"
+#include "window.h"
/*
* Structure to hold pointers to various items in a tag line.
@@ -107,12 +134,14 @@ static taggy_T ptag_entry = {NULL, {INIT_POS_T(0, 0, 0), 0}, 0, 0};
*
* for cscope, returns TRUE if we jumped to tag or aborted, FALSE otherwise
*/
-int do_tag(tag, type, count, forceit, verbose)
-char_u *tag; /* tag (pattern) to jump to */
-int type;
-int count;
-int forceit; /* :ta with ! */
-int verbose; /* print "tag not found" message */
+int
+do_tag (
+ char_u *tag, /* tag (pattern) to jump to */
+ int type,
+ int count,
+ int forceit, /* :ta with ! */
+ int verbose /* print "tag not found" message */
+)
{
taggy_T *tagstack = curwin->w_tagstack;
int tagstackidx = curwin->w_tagstackidx;
@@ -910,13 +939,12 @@ end_do_tag:
/*
* Free cached tags.
*/
-void tag_freematch() {
+void tag_freematch(void) {
vim_free(tagmatchname);
tagmatchname = NULL;
}
-static void taglen_advance(l)
-int l;
+static void taglen_advance(int l)
{
if (l == MAXCOL) {
msg_putchar('\n');
@@ -928,8 +956,7 @@ int l;
/*
* Print the tag stack
*/
-void do_tags(eap)
-exarg_T *eap UNUSED;
+void do_tags(exarg_T *eap)
{
int i;
char_u *name;
@@ -978,10 +1005,7 @@ static int tag_strnicmp __ARGS((char_u *s1, char_u *s2, size_t len));
* return 0 for match, < 0 for smaller, > 0 for bigger
* Make sure case is folded to uppercase in comparison (like for 'sort -f')
*/
-static int tag_strnicmp(s1, s2, len)
-char_u *s1;
-char_u *s2;
-size_t len;
+static int tag_strnicmp(char_u *s1, char_u *s2, size_t len)
{
int i;
@@ -1014,9 +1038,7 @@ static void prepare_pats __ARGS((pat_T *pats, int has_re));
/*
* Extract info from the tag search pattern "pats->pat".
*/
-static void prepare_pats(pats, has_re)
-pat_T *pats;
-int has_re;
+static void prepare_pats(pat_T *pats, int has_re)
{
pats->head = pats->pat;
pats->headlen = pats->len;
@@ -1070,14 +1092,16 @@ int has_re;
* TAG_NOIC don't always ignore case
* TAG_KEEP_LANG keep language
*/
-int find_tags(pat, num_matches, matchesp, flags, mincount, buf_ffname)
-char_u *pat; /* pattern to search for */
-int *num_matches; /* return: number of matches found */
-char_u ***matchesp; /* return: array of matches found */
-int flags;
-int mincount; /* MAXCOL: find all matches
+int
+find_tags (
+ char_u *pat, /* pattern to search for */
+ int *num_matches, /* return: number of matches found */
+ char_u ***matchesp, /* return: array of matches found */
+ int flags,
+ int mincount, /* MAXCOL: find all matches
other: minimal number of matches */
-char_u *buf_ffname; /* name of buffer for priority */
+ char_u *buf_ffname /* name of buffer for priority */
+)
{
FILE *fp;
char_u *lbuf; /* line buffer */
@@ -2020,9 +2044,7 @@ static void found_tagfile_cb __ARGS((char_u *fname, void *cookie));
* Callback function for finding all "tags" and "tags-??" files in
* 'runtimepath' doc directories.
*/
-static void found_tagfile_cb(fname, cookie)
-char_u *fname;
-void *cookie UNUSED;
+static void found_tagfile_cb(char_u *fname, void *cookie)
{
if (ga_grow(&tag_fnames, 1) == OK)
((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] =
@@ -2030,7 +2052,7 @@ void *cookie UNUSED;
}
#if defined(EXITFREE) || defined(PROTO)
-void free_tag_stuff() {
+void free_tag_stuff(void) {
ga_clear_strings(&tag_fnames);
do_tag(NULL, DT_FREE, 0, 0, 0);
tag_freematch();
@@ -2049,10 +2071,12 @@ void free_tag_stuff() {
*
* Return FAIL if no more tag file names, OK otherwise.
*/
-int get_tagfname(tnp, first, buf)
-tagname_T *tnp; /* holds status info */
-int first; /* TRUE when first file name is wanted */
-char_u *buf; /* pointer to buffer of MAXPATHL chars */
+int
+get_tagfname (
+ tagname_T *tnp, /* holds status info */
+ int first, /* TRUE when first file name is wanted */
+ char_u *buf /* pointer to buffer of MAXPATHL chars */
+)
{
char_u *fname = NULL;
char_u *r_ptr;
@@ -2152,8 +2176,7 @@ char_u *buf; /* pointer to buffer of MAXPATHL chars */
/*
* Free the contents of a tagname_T that was filled by get_tagfname().
*/
-void tagname_free(tnp)
-tagname_T *tnp;
+void tagname_free(tagname_T *tnp)
{
vim_free(tnp->tn_tags);
vim_findfile_cleanup(tnp->tn_search_ctx);
@@ -2169,10 +2192,11 @@ tagname_T *tnp;
*
* Return FAIL if there is a format error in this line, OK otherwise.
*/
-static int parse_tag_line(lbuf,
- tagp)
-char_u *lbuf; /* line to be parsed */
-tagptrs_T *tagp;
+static int
+parse_tag_line (
+ char_u *lbuf, /* line to be parsed */
+ tagptrs_T *tagp
+)
{
char_u *p;
@@ -2232,8 +2256,7 @@ tagptrs_T *tagp;
* Return TRUE if it is a static tag and adjust *tagname to the real tag.
* Return FALSE if it is not a static tag.
*/
-static int test_for_static(tagp)
-tagptrs_T *tagp;
+static int test_for_static(tagptrs_T *tagp)
{
char_u *p;
@@ -2274,9 +2297,11 @@ tagptrs_T *tagp;
*
* Return OK or FAIL.
*/
-static int parse_match(lbuf, tagp)
-char_u *lbuf; /* input: matching line */
-tagptrs_T *tagp; /* output: pointers into the line */
+static int
+parse_match (
+ char_u *lbuf, /* input: matching line */
+ tagptrs_T *tagp /* output: pointers into the line */
+)
{
int retval;
char_u *p;
@@ -2330,8 +2355,7 @@ tagptrs_T *tagp; /* output: pointers into the line */
* with the matching tag file name.
* Returns an allocated string or NULL (out of memory).
*/
-static char_u * tag_full_fname(tagp)
-tagptrs_T *tagp;
+static char_u *tag_full_fname(tagptrs_T *tagp)
{
char_u *fullname;
int c;
@@ -2352,10 +2376,12 @@ tagptrs_T *tagp;
*
* returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
*/
-static int jumpto_tag(lbuf, forceit, keep_help)
-char_u *lbuf; /* line from the tags file for this tag */
-int forceit; /* :ta with ! */
-int keep_help; /* keep help flag (FALSE for cscope) */
+static int
+jumpto_tag (
+ char_u *lbuf, /* line from the tags file for this tag */
+ int forceit, /* :ta with ! */
+ int keep_help /* keep help flag (FALSE for cscope) */
+)
{
int save_secure;
int save_magic;
@@ -2647,10 +2673,7 @@ erret:
* according to tag_fname (name of tag file containing fname).
* Returns a pointer to allocated memory (or NULL when out of memory).
*/
-static char_u * expand_tag_fname(fname, tag_fname, expand)
-char_u *fname;
-char_u *tag_fname;
-int expand;
+static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand)
{
char_u *p;
char_u *retval;
@@ -2696,8 +2719,7 @@ int expand;
* resulting file name is simplified in place and will either be the same
* length as that supplied, or shorter.
*/
-void simplify_filename(filename)
-char_u *filename;
+void simplify_filename(char_u *filename)
{
int components = 0;
char_u *p, *tail, *start;
@@ -2866,11 +2888,7 @@ char_u *filename;
* Return TRUE if tag for file "fname" if tag file "tag_fname" is for current
* file.
*/
-static int test_for_current(fname, fname_end, tag_fname, buf_ffname)
-char_u *fname;
-char_u *fname_end;
-char_u *tag_fname;
-char_u *buf_ffname;
+static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname, char_u *buf_ffname)
{
int c;
int retval = FALSE;
@@ -2896,8 +2914,7 @@ char_u *buf_ffname;
* Find the end of the tagaddress.
* Return OK if ";\"" is following, FAIL otherwise.
*/
-static int find_extra(pp)
-char_u **pp;
+static int find_extra(char_u **pp)
{
char_u *str = *pp;
@@ -2926,11 +2943,13 @@ char_u **pp;
return FAIL;
}
-int expand_tags(tagnames, pat, num_file, file)
-int tagnames; /* expand tag names */
-char_u *pat;
-int *num_file;
-char_u ***file;
+int
+expand_tags (
+ int tagnames, /* expand tag names */
+ char_u *pat,
+ int *num_file,
+ char_u ***file
+)
{
int i;
int c;
@@ -2978,11 +2997,13 @@ static int add_tag_field __ARGS((dict_T *dict, char *field_name, char_u *start,
* Add a tag field to the dictionary "dict".
* Return OK or FAIL.
*/
-static int add_tag_field(dict, field_name, start, end)
-dict_T *dict;
-char *field_name;
-char_u *start; /* start of the value */
-char_u *end; /* after the value; can be NULL */
+static int
+add_tag_field (
+ dict_T *dict,
+ char *field_name,
+ char_u *start, /* start of the value */
+ char_u *end /* after the value; can be NULL */
+)
{
char_u *buf;
int len = 0;
@@ -3021,9 +3042,7 @@ char_u *end; /* after the value; can be NULL */
* Add the tags matching the specified pattern to the list "list"
* as a dictionary
*/
-int get_tags(list, pat)
-list_T *list;
-char_u *pat;
+int get_tags(list_T *list, char_u *pat)
{
int num_matches, i, ret;
char_u **matches, *p;
diff --git a/src/proto/tag.pro b/src/tag.h
index fedbc93745..829d48ff7b 100644
--- a/src/proto/tag.pro
+++ b/src/tag.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_TAG_H
+#define NEOVIM_TAG_H
/* tag.c */
int do_tag __ARGS((char_u *tag, int type, int count, int forceit, int verbose));
void tag_freematch __ARGS((void));
@@ -13,3 +15,4 @@ int expand_tags __ARGS((int tagnames, char_u *pat, int *num_file,
char_u ***file));
int get_tags __ARGS((list_T *list, char_u *pat));
/* vim: set ft=c : */
+#endif /* NEOVIM_TAG_H */
diff --git a/src/term.c b/src/term.c
index 7525244ca1..8488376a25 100644
--- a/src/term.c
+++ b/src/term.c
@@ -24,6 +24,25 @@
#define tgetstr tgetstr_defined_wrong
#include "vim.h"
+#include "term.h"
+#include "buffer.h"
+#include "charset.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "getchar.h"
+#include "message.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "popupmnu.h"
+#include "screen.h"
+#include "syntax.h"
+#include "ui.h"
+#include "window.h"
#ifdef HAVE_TGETENT
# ifdef HAVE_TERMIOS_H
@@ -1143,8 +1162,7 @@ static int need_gather = FALSE; /* need to fill termleader[] */
static char_u termleader[256 + 1]; /* for check_termcode() */
static int check_for_codes = FALSE; /* check for key code response */
-static struct builtin_term * find_builtin_term(term)
-char_u *term;
+static struct builtin_term *find_builtin_term(char_u *term)
{
struct builtin_term *p;
@@ -1171,8 +1189,7 @@ char_u *term;
* Caller should check if 'name' is a valid builtin term.
* The terminal's name is not set, as this is already done in termcapinit().
*/
-static void parse_builtin_tcap(term)
-char_u *term;
+static void parse_builtin_tcap(char_u *term)
{
struct builtin_term *p;
char_u name[2];
@@ -1222,8 +1239,7 @@ static void set_color_count __ARGS((int nr));
* Store it as a number in t_colors.
* Store it as a string in T_CCO (using nr_colors[]).
*/
-static void set_color_count(nr)
-int nr;
+static void set_color_count(int nr)
{
char_u nr_colors[20]; /* string for number of colors */
@@ -1259,8 +1275,7 @@ static char *(key_names[]) =
*
* While doing this, until ttest(), some options may be NULL, be careful.
*/
-int set_termname(term)
-char_u *term;
+int set_termname(char_u *term)
{
struct builtin_term *termp;
#ifdef HAVE_TGETENT
@@ -1655,9 +1670,11 @@ char_u *term;
# define HMT_SGR 64
static int has_mouse_termcode = 0;
-void set_mouse_termcode(n, s)
-int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
-char_u *s;
+void
+set_mouse_termcode (
+ int n, /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+ char_u *s
+)
{
char_u name[2];
@@ -1683,8 +1700,10 @@ char_u *s;
# if ((defined(UNIX) || defined(VMS) || defined(OS2)) \
&& defined(FEAT_MOUSE_TTY)) || defined(PROTO)
-void del_mouse_termcode(n)
-int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+void
+del_mouse_termcode (
+ int n /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
+)
{
char_u name[2];
@@ -1714,9 +1733,7 @@ int n; /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
* Call tgetent()
* Return error message if it fails, NULL if it's OK.
*/
-static char_u * tgetent_error(tbuf, term)
-char_u *tbuf;
-char_u *term;
+static char_u *tgetent_error(char_u *tbuf, char_u *term)
{
int i;
@@ -1749,9 +1766,7 @@ char_u *term;
* Some versions of tgetstr() have been reported to return -1 instead of NULL.
* Fix that here.
*/
-static char_u * vim_tgetstr(s, pp)
-char *s;
-char_u **pp;
+static char_u *vim_tgetstr(char *s, char_u **pp)
{
char *p;
@@ -1770,9 +1785,11 @@ char_u **pp;
* and "li" entries never change. But on some systems this works.
* Errors while getting the entries are ignored.
*/
-void getlinecol(cp, rp)
-long *cp; /* pointer to columns */
-long *rp; /* pointer to rows */
+void
+getlinecol (
+ long *cp, /* pointer to columns */
+ long *rp /* pointer to rows */
+)
{
char_u tbuf[TBUFSZ];
@@ -1793,9 +1810,7 @@ long *rp; /* pointer to rows */
* If force given, replace an existing entry.
* Return FAIL if the entry was not found, OK if the entry was added.
*/
-int add_termcap_entry(name, force)
-char_u *name;
-int force;
+int add_termcap_entry(char_u *name, int force)
{
char_u *term;
int key;
@@ -1888,8 +1903,7 @@ int force;
return FAIL;
}
-static int term_is_builtin(name)
-char_u *name;
+static int term_is_builtin(char_u *name)
{
return STRNCMP(name, "builtin_", (size_t)8) == 0;
}
@@ -1899,8 +1913,7 @@ char_u *name;
* Assume that the terminal is using 8-bit controls when the name contains
* "8bit", like in "xterm-8bit".
*/
-int term_is_8bit(name)
-char_u *name;
+int term_is_8bit(char_u *name)
{
return detected_8bit || strstr((char *)name, "8bit") != NULL;
}
@@ -1911,8 +1924,7 @@ char_u *name;
* <Esc>] -> <M-C-]>
* <Esc>O -> <M-C-O>
*/
-static int term_7to8bit(p)
-char_u *p;
+static int term_7to8bit(char_u *p)
{
if (*p == ESC) {
if (p[1] == '[')
@@ -1928,8 +1940,7 @@ char_u *p;
#if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)
-char_u * tltoa(i)
-unsigned long i;
+char_u *tltoa(unsigned long i)
{
static char_u buf[16];
char_u *p;
@@ -1953,9 +1964,7 @@ unsigned long i;
*/
static char *tgoto __ARGS((char *, int, int));
-static char * tgoto(cm, x, y)
-char *cm;
-int x, y;
+static char *tgoto(char *cm, int x, int y)
{
static char buf[30];
char *p, *s, *e;
@@ -2001,8 +2010,7 @@ int x, y;
* If "name" is NULL or empty, get the terminal name from the environment.
* If that fails, use the default terminal name.
*/
-void termcapinit(name)
-char_u *name;
+void termcapinit(char_u *name)
{
char_u *term;
@@ -2037,7 +2045,7 @@ static int out_pos = 0; /* number of chars in out_buf */
/*
* out_flush(): flush the output buffer
*/
-void out_flush() {
+void out_flush(void) {
int len;
if (out_pos != 0) {
@@ -2052,7 +2060,7 @@ void out_flush() {
* Sometimes a byte out of a multi-byte character is written with out_char().
* To avoid flushing half of the character, call this function first.
*/
-void out_flush_check() {
+void out_flush_check(void) {
if (enc_dbcs != 0 && out_pos >= OUT_SIZE - MB_MAXBYTES)
out_flush();
}
@@ -2063,8 +2071,7 @@ void out_flush_check() {
* This should not be used for outputting text on the screen (use functions
* like msg_puts() and screen_putchar() for that).
*/
-void out_char(c)
-unsigned c;
+void out_char(unsigned c)
{
#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
if (c == '\n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
@@ -2083,8 +2090,7 @@ static void out_char_nf __ARGS((unsigned));
/*
* out_char_nf(c): like out_char(), but don't flush when p_wd is set
*/
-static void out_char_nf(c)
-unsigned c;
+static void out_char_nf(unsigned c)
{
#if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X_UNIX)
if (c == '\n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
@@ -2108,8 +2114,7 @@ unsigned c;
* This should only be used for writing terminal codes, not for outputting
* normal text (use functions like msg_puts() and screen_putchar() for that).
*/
-void out_str_nf(s)
-char_u *s;
+void out_str_nf(char_u *s)
{
if (out_pos > OUT_SIZE - 20) /* avoid terminal strings being split up */
out_flush();
@@ -2128,8 +2133,7 @@ char_u *s;
* This should only be used for writing terminal codes, not for outputting
* normal text (use functions like msg_puts() and screen_putchar() for that).
*/
-void out_str(s)
-char_u *s;
+void out_str(char_u *s)
{
if (s != NULL && *s) {
/* avoid terminal strings being split up */
@@ -2151,35 +2155,28 @@ char_u *s;
/*
* cursor positioning using termcap parser. (jw)
*/
-void term_windgoto(row, col)
-int row;
-int col;
+void term_windgoto(int row, int col)
{
OUT_STR(tgoto((char *)T_CM, col, row));
}
-void term_cursor_right(i)
-int i;
+void term_cursor_right(int i)
{
OUT_STR(tgoto((char *)T_CRI, 0, i));
}
-void term_append_lines(line_count)
-int line_count;
+void term_append_lines(int line_count)
{
OUT_STR(tgoto((char *)T_CAL, 0, line_count));
}
-void term_delete_lines(line_count)
-int line_count;
+void term_delete_lines(int line_count)
{
OUT_STR(tgoto((char *)T_CDL, 0, line_count));
}
#if defined(HAVE_TGETENT) || defined(PROTO)
-void term_set_winpos(x, y)
-int x;
-int y;
+void term_set_winpos(int x, int y)
{
/* Can't handle a negative value here */
if (x < 0)
@@ -2189,16 +2186,13 @@ int y;
OUT_STR(tgoto((char *)T_CWP, y, x));
}
-void term_set_winsize(width, height)
-int width;
-int height;
+void term_set_winsize(int width, int height)
{
OUT_STR(tgoto((char *)T_CWS, height, width));
}
#endif
-void term_fg_color(n)
-int n;
+void term_fg_color(int n)
{
/* Use "AF" termcap entry if present, "Sf" entry otherwise */
if (*T_CAF)
@@ -2207,8 +2201,7 @@ int n;
term_color(T_CSF, n);
}
-void term_bg_color(n)
-int n;
+void term_bg_color(int n)
{
/* Use "AB" termcap entry if present, "Sb" entry otherwise */
if (*T_CAB)
@@ -2217,9 +2210,7 @@ int n;
term_color(T_CSB, n);
}
-static void term_color(s, n)
-char_u *s;
-int n;
+static void term_color(char_u *s, int n)
{
char buf[20];
int i = 2; /* index in s[] just after <Esc>[ or CSI */
@@ -2252,8 +2243,7 @@ int n;
/*
* Generic function to set window title, using t_ts and t_fs.
*/
-void term_settitle(title)
-char_u *title;
+void term_settitle(char_u *title)
{
/* t_ts takes one argument: column in status line */
OUT_STR(tgoto((char *)T_TS, 0, 0)); /* set title start */
@@ -2267,8 +2257,7 @@ char_u *title;
* Make sure we have a valid set or terminal options.
* Replace all entries that are NULL by empty_option
*/
-void ttest(pairs)
-int pairs;
+void ttest(int pairs)
{
check_options(); /* make sure no options are NULL */
@@ -2360,9 +2349,7 @@ int pairs;
* Represent the given long_u as individual bytes, with the most significant
* byte first, and store them in dst.
*/
-void add_long_to_buf(val, dst)
-long_u val;
-char_u *dst;
+void add_long_to_buf(long_u val, char_u *dst)
{
int i;
int shift;
@@ -2383,9 +2370,7 @@ static int get_long_from_buf __ARGS((char_u *buf, long_u *val));
* (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
* were present.
*/
-static int get_long_from_buf(buf, val)
-char_u *buf;
-long_u *val;
+static int get_long_from_buf(char_u *buf, long_u *val)
{
int len;
char_u bytes[sizeof(long_u)];
@@ -2413,10 +2398,7 @@ long_u *val;
* from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
* available.
*/
-static int get_bytes_from_buf(buf, bytes, num_bytes)
-char_u *buf;
-char_u *bytes;
-int num_bytes;
+static int get_bytes_from_buf(char_u *buf, char_u *bytes, int num_bytes)
{
int len = 0;
int i;
@@ -2449,7 +2431,7 @@ int num_bytes;
* Check if the new shell size is valid, correct it if it's too small or way
* too big.
*/
-void check_shellsize() {
+void check_shellsize(void) {
if (Rows < min_rows()) /* need room for one window and command line */
Rows = min_rows();
limit_screen_size();
@@ -2458,7 +2440,7 @@ void check_shellsize() {
/*
* Limit Rows and Columns to avoid an overflow in Rows * Columns.
*/
-void limit_screen_size() {
+void limit_screen_size(void) {
if (Columns < MIN_COLUMNS)
Columns = MIN_COLUMNS;
else if (Columns > 10000)
@@ -2470,7 +2452,7 @@ void limit_screen_size() {
/*
* Invoked just before the screen structures are going to be (re)allocated.
*/
-void win_new_shellsize() {
+void win_new_shellsize(void) {
static int old_Rows = 0;
static int old_Columns = 0;
@@ -2493,7 +2475,7 @@ void win_new_shellsize() {
* Call this function when the Vim shell has been resized in any way.
* Will obtain the current size and redraw (also when size didn't change).
*/
-void shell_resized() {
+void shell_resized(void) {
set_shellsize(0, 0, FALSE);
}
@@ -2501,7 +2483,7 @@ void shell_resized() {
* Check if the shell size changed. Handle a resize.
* When the size didn't change, nothing happens.
*/
-void shell_resized_check() {
+void shell_resized_check(void) {
int old_Rows = Rows;
int old_Columns = Columns;
@@ -2521,9 +2503,7 @@ void shell_resized_check() {
* If 'mustset' is FALSE, we may try to get the real window size and if
* it fails use 'width' and 'height'.
*/
-void set_shellsize(width, height, mustset)
-int width, height;
-int mustset;
+void set_shellsize(int width, int height, int mustset)
{
static int busy = FALSE;
@@ -2616,8 +2596,7 @@ int mustset;
* Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
* commands and Ex mode).
*/
-void settmode(tmode)
-int tmode;
+void settmode(int tmode)
{
if (full_screen) {
@@ -2652,7 +2631,7 @@ int tmode;
}
}
-void starttermcap() {
+void starttermcap(void) {
if (full_screen && !termcap_active) {
out_str(T_TI); /* start termcap mode */
out_str(T_KS); /* start "keypad transmit" mode */
@@ -2669,7 +2648,7 @@ void starttermcap() {
}
}
-void stoptermcap() {
+void stoptermcap(void) {
screen_stop_highlight();
reset_cterm_colors();
if (termcap_active) {
@@ -2714,7 +2693,7 @@ void stoptermcap() {
* request to terminal while reading from a file).
* The result is caught in check_termcode().
*/
-void may_req_termresponse() {
+void may_req_termresponse(void) {
if (crv_status == CRV_GET
&& cur_tmode == TMODE_RAW
&& starting == 0
@@ -2744,7 +2723,7 @@ void may_req_termresponse() {
* This function has the side effect that changes cursor position, so
* it must be called immediately after entering termcap mode.
*/
-void may_req_ambiguous_char_width() {
+void may_req_ambiguous_char_width(void) {
if (u7_status == U7_GET
&& cur_tmode == TMODE_RAW
&& termcap_active
@@ -2799,14 +2778,14 @@ static void log_tr(char *msg) {
/*
* Return TRUE when saving and restoring the screen.
*/
-int swapping_screen() {
+int swapping_screen(void) {
return full_screen && *T_TI != NUL;
}
/*
* setmouse() - switch mouse on/off depending on current mode and 'mouse'
*/
-void setmouse() {
+void setmouse(void) {
int checkfor;
@@ -2846,8 +2825,7 @@ void setmouse() {
* - the current buffer is a help file and 'h' is in 'mouse' and we are in a
* normal editing mode (not at hit-return message).
*/
-int mouse_has(c)
-int c;
+int mouse_has(int c)
{
char_u *p;
@@ -2867,7 +2845,7 @@ int c;
/*
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
*/
-int mouse_model_popup() {
+int mouse_model_popup(void) {
return p_mousem[0] == 'p';
}
@@ -2876,7 +2854,7 @@ int mouse_model_popup() {
* terminals this makes the screen scrolled to the correct position.
* Used when starting Vim or returning from a shell.
*/
-void scroll_start() {
+void scroll_start(void) {
if (*T_VS != NUL) {
out_str(T_VS);
out_str(T_VE);
@@ -2889,7 +2867,7 @@ static int cursor_is_off = FALSE;
/*
* Enable the cursor.
*/
-void cursor_on() {
+void cursor_on(void) {
if (cursor_is_off) {
out_str(T_VE);
cursor_is_off = FALSE;
@@ -2899,7 +2877,7 @@ void cursor_on() {
/*
* Disable the cursor.
*/
-void cursor_off() {
+void cursor_off(void) {
if (full_screen) {
if (!cursor_is_off)
out_str(T_VI); /* disable cursor */
@@ -2911,7 +2889,7 @@ void cursor_off() {
/*
* Set cursor shape to match Insert mode.
*/
-void term_cursor_shape() {
+void term_cursor_shape(void) {
static int showing_insert_mode = MAYBE;
if (!full_screen || *T_CSI == NUL || *T_CEI == NUL)
@@ -2936,9 +2914,7 @@ void term_cursor_shape() {
* Also set the vertical scroll region for a vertically split window. Always
* the full width of the window, excluding the vertical separator.
*/
-void scroll_region_set(wp, off)
-win_T *wp;
-int off;
+void scroll_region_set(win_T *wp, int off)
{
OUT_STR(tgoto((char *)T_CS, W_WINROW(wp) + wp->w_height - 1,
W_WINROW(wp) + off));
@@ -2951,7 +2927,7 @@ int off;
/*
* Reset scrolling region to the whole screen.
*/
-void scroll_region_reset() {
+void scroll_region_reset(void) {
OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
if (*T_CSV != NUL)
OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0));
@@ -2974,7 +2950,7 @@ static int tc_len = 0; /* current number of entries in termcodes[] */
static int termcode_star __ARGS((char_u *code, int len));
-void clear_termcodes() {
+void clear_termcodes(void) {
while (tc_len > 0)
vim_free(termcodes[--tc_len].code);
vim_free(termcodes);
@@ -2999,10 +2975,7 @@ void clear_termcodes() {
* "flags" is TRUE when replacing 7-bit by 8-bit controls is desired.
* "flags" can also be ATC_FROM_TERM for got_code_from_term().
*/
-void add_termcode(name, string, flags)
-char_u *name;
-char_u *string;
-int flags;
+void add_termcode(char_u *name, char_u *string, int flags)
{
struct termcode *new_tc;
int i, j;
@@ -3107,9 +3080,7 @@ int flags;
* The "X" can be any character.
* Return 0 if not found, 2 for ;*X and 1 for O*X and <M-O>*X.
*/
-static int termcode_star(code, len)
-char_u *code;
-int len;
+static int termcode_star(char_u *code, int len)
{
/* Shortest is <M-O>*X. With ; shortest is <CSI>1;*X */
if (len >= 3 && code[len - 2] == '*') {
@@ -3121,8 +3092,7 @@ int len;
return 0;
}
-char_u * find_termcode(name)
-char_u *name;
+char_u *find_termcode(char_u *name)
{
int i;
@@ -3132,16 +3102,14 @@ char_u *name;
return NULL;
}
-char_u * get_termcode(i)
-int i;
+char_u *get_termcode(int i)
{
if (i >= tc_len)
return NULL;
return &termcodes[i].name[0];
}
-void del_termcode(name)
-char_u *name;
+void del_termcode(char_u *name)
{
int i;
@@ -3158,8 +3126,7 @@ char_u *name;
/* not found. Give error message? */
}
-static void del_termcode_idx(idx)
-int idx;
+static void del_termcode_idx(int idx)
{
int i;
@@ -3173,7 +3140,7 @@ int idx;
* Called when detected that the terminal sends 8-bit codes.
* Convert all 7-bit codes to their 8-bit equivalent.
*/
-static void switch_to_8bit() {
+static void switch_to_8bit(void) {
int i;
int c;
@@ -3206,8 +3173,7 @@ static int orig_topfill = 0;
* Set orig_topline. Used when jumping to another window, so that a double
* click still works.
*/
-void set_mouse_topline(wp)
-win_T *wp;
+void set_mouse_topline(win_T *wp)
{
orig_topline = wp->w_topline;
orig_topfill = wp->w_topfill;
@@ -3227,11 +3193,7 @@ win_T *wp;
* "buflen" is then the length of the string in buf[] and is updated for
* inserts and deletes.
*/
-int check_termcode(max_offset, buf, bufsize, buflen)
-int max_offset;
-char_u *buf;
-int bufsize;
-int *buflen;
+int check_termcode(int max_offset, char_u *buf, int bufsize, int *buflen)
{
char_u *tp;
char_u *p;
@@ -4196,12 +4158,14 @@ int *buflen;
* nothing). When 'cpoptions' does not contain 'B', a backslash can be used
* instead of a CTRL-V.
*/
-char_u * replace_termcodes(from, bufp, from_part, do_lt, special)
-char_u *from;
-char_u **bufp;
-int from_part;
-int do_lt; /* also translate <lt> */
-int special; /* always accept <key> notation */
+char_u *
+replace_termcodes (
+ char_u *from,
+ char_u **bufp,
+ int from_part,
+ int do_lt, /* also translate <lt> */
+ int special /* always accept <key> notation */
+)
{
int i;
int slen;
@@ -4374,8 +4338,7 @@ int special; /* always accept <key> notation */
* Find a termcode with keys 'src' (must be NUL terminated).
* Return the index in termcodes[], or -1 if not found.
*/
-int find_term_bykeys(src)
-char_u *src;
+int find_term_bykeys(char_u *src)
{
int i;
int slen = (int)STRLEN(src);
@@ -4392,7 +4355,7 @@ char_u *src;
* Gather the first characters in the terminal key codes into a string.
* Used to speed up check_termcode().
*/
-static void gather_termleader() {
+static void gather_termleader(void) {
int i;
int len = 0;
@@ -4414,7 +4377,7 @@ static void gather_termleader() {
* Show all termcodes (for ":set termcap")
* This code looks a lot like showoptions(), but is different.
*/
-void show_termcodes() {
+void show_termcodes(void) {
int col;
int *items;
int item_count;
@@ -4492,10 +4455,7 @@ void show_termcodes() {
* Show one termcode entry.
* Output goes into IObuff[]
*/
-int show_one_termcode(name, code, printit)
-char_u *name;
-char_u *code;
-int printit;
+int show_one_termcode(char_u *name, char_u *code, int printit)
{
char_u *p;
int len;
@@ -4546,13 +4506,13 @@ int printit;
static int xt_index_in = 0;
static int xt_index_out = 0;
-static void req_codes_from_term() {
+static void req_codes_from_term(void) {
xt_index_out = 0;
xt_index_in = 0;
req_more_codes_from_term();
}
-static void req_more_codes_from_term() {
+static void req_more_codes_from_term(void) {
char buf[11];
int old_idx = xt_index_out;
@@ -4587,9 +4547,7 @@ static void req_more_codes_from_term() {
* Both <name> and <string> are encoded in hex.
* "code" points to the "0" or "1".
*/
-static void got_code_from_term(code, len)
-char_u *code;
-int len;
+static void got_code_from_term(char_u *code, int len)
{
#define XT_LEN 100
char_u name[3];
@@ -4668,7 +4626,7 @@ int len;
* keyboard input. We don't want responses to be send to that program or
* handled as typed text.
*/
-static void check_for_codes_from_term() {
+static void check_for_codes_from_term(void) {
int c;
/* If no codes requested or all are answered, no need to wait. */
@@ -4714,9 +4672,11 @@ static void check_for_codes_from_term() {
*
* Returns NULL when there is a problem.
*/
-char_u * translate_mapping(str, expmap)
-char_u *str;
-int expmap; /* TRUE when expanding mappings on command-line */
+char_u *
+translate_mapping (
+ char_u *str,
+ int expmap /* TRUE when expanding mappings on command-line */
+)
{
garray_T ga;
int c;
diff --git a/src/term.h b/src/term.h
index 0ba5a19c13..792d9b7484 100644
--- a/src/term.h
+++ b/src/term.h
@@ -1,156 +1,68 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * This file contains the defines for the machine dependent escape sequences
- * that the editor needs to perform various operations. All of the sequences
- * here are optional, except "cm" (cursor motion).
- */
-
-
-/*
- * Index of the termcap codes in the term_strings array.
- */
-enum SpecialKey {
- KS_NAME = 0, /* name of this terminal entry */
- KS_CE, /* clear to end of line */
- KS_AL, /* add new blank line */
- KS_CAL, /* add number of blank lines */
- KS_DL, /* delete line */
- KS_CDL, /* delete number of lines */
- KS_CS, /* scroll region */
- KS_CL, /* clear screen */
- KS_CD, /* clear to end of display */
- KS_UT, /* clearing uses current background color */
- KS_DA, /* text may be scrolled down from up */
- KS_DB, /* text may be scrolled up from down */
- KS_VI, /* cursor invisible */
- KS_VE, /* cursor visible */
- KS_VS, /* cursor very visible */
- KS_ME, /* normal mode */
- KS_MR, /* reverse mode */
- KS_MD, /* bold mode */
- KS_SE, /* normal mode */
- KS_SO, /* standout mode */
- KS_CZH, /* italic mode start */
- KS_CZR, /* italic mode end */
- KS_UE, /* exit underscore (underline) mode */
- KS_US, /* underscore (underline) mode */
- KS_UCE, /* exit undercurl mode */
- KS_UCS, /* undercurl mode */
- KS_MS, /* save to move cur in reverse mode */
- KS_CM, /* cursor motion */
- KS_SR, /* scroll reverse (backward) */
- KS_CRI, /* cursor number of chars right */
- KS_VB, /* visual bell */
- KS_KS, /* put term in "keypad transmit" mode */
- KS_KE, /* out of "keypad transmit" mode */
- KS_TI, /* put terminal in termcap mode */
- KS_TE, /* out of termcap mode */
- KS_BC, /* backspace character (cursor left) */
- KS_CCS, /* cur is relative to scroll region */
- KS_CCO, /* number of colors */
- KS_CSF, /* set foreground color */
- KS_CSB, /* set background color */
- KS_XS, /* standout not erased by overwriting (hpterm) */
- KS_MB, /* blink mode */
- KS_CAF, /* set foreground color (ANSI) */
- KS_CAB, /* set background color (ANSI) */
- KS_LE, /* cursor left (mostly backspace) */
- KS_ND, /* cursor right */
- KS_CIS, /* set icon text start */
- KS_CIE, /* set icon text end */
- KS_TS, /* set window title start (to status line)*/
- KS_FS, /* set window title end (from status line) */
- KS_CWP, /* set window position in pixels */
- KS_CWS, /* set window size in characters */
- KS_CRV, /* request version string */
- KS_CSI, /* start insert mode (bar cursor) */
- KS_CEI, /* end insert mode (block cursor) */
- KS_CSV, /* scroll region vertical */
- KS_OP, /* original color pair */
- KS_U7 /* request cursor position */
-};
-
-#define KS_LAST KS_U7
-
-/*
- * the terminal capabilities are stored in this array
- * IMPORTANT: When making changes, note the following:
- * - there should be an entry for each code in the builtin termcaps
- * - there should be an option for each code in option.c
- * - there should be code in term.c to obtain the value from the termcap
- */
-
-extern char_u *(term_strings[]); /* current terminal strings */
-
-/*
- * strings used for terminal
- */
-#define T_NAME (term_str(KS_NAME)) /* terminal name */
-#define T_CE (term_str(KS_CE)) /* clear to end of line */
-#define T_AL (term_str(KS_AL)) /* add new blank line */
-#define T_CAL (term_str(KS_CAL)) /* add number of blank lines */
-#define T_DL (term_str(KS_DL)) /* delete line */
-#define T_CDL (term_str(KS_CDL)) /* delete number of lines */
-#define T_CS (term_str(KS_CS)) /* scroll region */
-#define T_CSV (term_str(KS_CSV)) /* scroll region vertical */
-#define T_CL (term_str(KS_CL)) /* clear screen */
-#define T_CD (term_str(KS_CD)) /* clear to end of display */
-#define T_UT (term_str(KS_UT)) /* clearing uses background color */
-#define T_DA (term_str(KS_DA)) /* text may be scrolled down from up */
-#define T_DB (term_str(KS_DB)) /* text may be scrolled up from down */
-#define T_VI (term_str(KS_VI)) /* cursor invisible */
-#define T_VE (term_str(KS_VE)) /* cursor visible */
-#define T_VS (term_str(KS_VS)) /* cursor very visible */
-#define T_ME (term_str(KS_ME)) /* normal mode */
-#define T_MR (term_str(KS_MR)) /* reverse mode */
-#define T_MD (term_str(KS_MD)) /* bold mode */
-#define T_SE (term_str(KS_SE)) /* normal mode */
-#define T_SO (term_str(KS_SO)) /* standout mode */
-#define T_CZH (term_str(KS_CZH)) /* italic mode start */
-#define T_CZR (term_str(KS_CZR)) /* italic mode end */
-#define T_UE (term_str(KS_UE)) /* exit underscore (underline) mode */
-#define T_US (term_str(KS_US)) /* underscore (underline) mode */
-#define T_UCE (term_str(KS_UCE)) /* exit undercurl mode */
-#define T_UCS (term_str(KS_UCS)) /* undercurl mode */
-#define T_MS (term_str(KS_MS)) /* save to move cur in reverse mode */
-#define T_CM (term_str(KS_CM)) /* cursor motion */
-#define T_SR (term_str(KS_SR)) /* scroll reverse (backward) */
-#define T_CRI (term_str(KS_CRI)) /* cursor number of chars right */
-#define T_VB (term_str(KS_VB)) /* visual bell */
-#define T_KS (term_str(KS_KS)) /* put term in "keypad transmit" mode */
-#define T_KE (term_str(KS_KE)) /* out of "keypad transmit" mode */
-#define T_TI (term_str(KS_TI)) /* put terminal in termcap mode */
-#define T_TE (term_str(KS_TE)) /* out of termcap mode */
-#define T_BC (term_str(KS_BC)) /* backspace character */
-#define T_CCS (term_str(KS_CCS)) /* cur is relative to scroll region */
-#define T_CCO (term_str(KS_CCO)) /* number of colors */
-#define T_CSF (term_str(KS_CSF)) /* set foreground color */
-#define T_CSB (term_str(KS_CSB)) /* set background color */
-#define T_XS (term_str(KS_XS)) /* standout not erased by overwriting */
-#define T_MB (term_str(KS_MB)) /* blink mode */
-#define T_CAF (term_str(KS_CAF)) /* set foreground color (ANSI) */
-#define T_CAB (term_str(KS_CAB)) /* set background color (ANSI) */
-#define T_LE (term_str(KS_LE)) /* cursor left */
-#define T_ND (term_str(KS_ND)) /* cursor right */
-#define T_CIS (term_str(KS_CIS)) /* set icon text start */
-#define T_CIE (term_str(KS_CIE)) /* set icon text end */
-#define T_TS (term_str(KS_TS)) /* set window title start */
-#define T_FS (term_str(KS_FS)) /* set window title end */
-#define T_CWP (term_str(KS_CWP)) /* window position */
-#define T_CWS (term_str(KS_CWS)) /* window size */
-#define T_CSI (term_str(KS_CSI)) /* start insert mode */
-#define T_CEI (term_str(KS_CEI)) /* end insert mode */
-#define T_CRV (term_str(KS_CRV)) /* request version string */
-#define T_OP (term_str(KS_OP)) /* original color pair */
-#define T_U7 (term_str(KS_U7)) /* request cursor position */
-
-#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
-#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */
-#define TMODE_RAW 2 /* terminal mode for Normal and Insert mode */
+#ifndef NEOVIM_TERM_H
+#define NEOVIM_TERM_H
+/* term.c */
+int set_termname __ARGS((char_u *term));
+void set_mouse_termcode __ARGS((int n, char_u *s));
+void del_mouse_termcode __ARGS((int n));
+void getlinecol __ARGS((long *cp, long *rp));
+int add_termcap_entry __ARGS((char_u *name, int force));
+int term_is_8bit __ARGS((char_u *name));
+int term_is_gui __ARGS((char_u *name));
+char_u *tltoa __ARGS((unsigned long i));
+void termcapinit __ARGS((char_u *name));
+void out_flush __ARGS((void));
+void out_flush_check __ARGS((void));
+void out_trash __ARGS((void));
+void out_char __ARGS((unsigned c));
+void out_str_nf __ARGS((char_u *s));
+void out_str __ARGS((char_u *s));
+void term_windgoto __ARGS((int row, int col));
+void term_cursor_right __ARGS((int i));
+void term_append_lines __ARGS((int line_count));
+void term_delete_lines __ARGS((int line_count));
+void term_set_winpos __ARGS((int x, int y));
+void term_set_winsize __ARGS((int width, int height));
+void term_fg_color __ARGS((int n));
+void term_bg_color __ARGS((int n));
+void term_settitle __ARGS((char_u *title));
+void ttest __ARGS((int pairs));
+void add_long_to_buf __ARGS((long_u val, char_u *dst));
+void check_shellsize __ARGS((void));
+void limit_screen_size __ARGS((void));
+void win_new_shellsize __ARGS((void));
+void shell_resized __ARGS((void));
+void shell_resized_check __ARGS((void));
+void set_shellsize __ARGS((int width, int height, int mustset));
+void settmode __ARGS((int tmode));
+void starttermcap __ARGS((void));
+void stoptermcap __ARGS((void));
+void may_req_termresponse __ARGS((void));
+void may_req_ambiguous_char_width __ARGS((void));
+int swapping_screen __ARGS((void));
+void setmouse __ARGS((void));
+int mouse_has __ARGS((int c));
+int mouse_model_popup __ARGS((void));
+void scroll_start __ARGS((void));
+void cursor_on __ARGS((void));
+void cursor_off __ARGS((void));
+void term_cursor_shape __ARGS((void));
+void scroll_region_set __ARGS((win_T *wp, int off));
+void scroll_region_reset __ARGS((void));
+void clear_termcodes __ARGS((void));
+void add_termcode __ARGS((char_u *name, char_u *string, int flags));
+char_u *find_termcode __ARGS((char_u *name));
+char_u *get_termcode __ARGS((int i));
+void del_termcode __ARGS((char_u *name));
+void set_mouse_topline __ARGS((win_T *wp));
+int check_termcode __ARGS((int max_offset, char_u *buf, int bufsize,
+ int *buflen));
+char_u *replace_termcodes __ARGS((char_u *from, char_u **bufp, int from_part,
+ int do_lt,
+ int special));
+int find_term_bykeys __ARGS((char_u *src));
+void show_termcodes __ARGS((void));
+int show_one_termcode __ARGS((char_u *name, char_u *code, int printit));
+char_u *translate_mapping __ARGS((char_u *str, int expmap));
+void update_tcap __ARGS((int attr));
+/* vim: set ft=c : */
+#endif /* NEOVIM_TERM_H */
diff --git a/src/term_defs.h b/src/term_defs.h
new file mode 100644
index 0000000000..0ba5a19c13
--- /dev/null
+++ b/src/term_defs.h
@@ -0,0 +1,156 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * This file contains the defines for the machine dependent escape sequences
+ * that the editor needs to perform various operations. All of the sequences
+ * here are optional, except "cm" (cursor motion).
+ */
+
+
+/*
+ * Index of the termcap codes in the term_strings array.
+ */
+enum SpecialKey {
+ KS_NAME = 0, /* name of this terminal entry */
+ KS_CE, /* clear to end of line */
+ KS_AL, /* add new blank line */
+ KS_CAL, /* add number of blank lines */
+ KS_DL, /* delete line */
+ KS_CDL, /* delete number of lines */
+ KS_CS, /* scroll region */
+ KS_CL, /* clear screen */
+ KS_CD, /* clear to end of display */
+ KS_UT, /* clearing uses current background color */
+ KS_DA, /* text may be scrolled down from up */
+ KS_DB, /* text may be scrolled up from down */
+ KS_VI, /* cursor invisible */
+ KS_VE, /* cursor visible */
+ KS_VS, /* cursor very visible */
+ KS_ME, /* normal mode */
+ KS_MR, /* reverse mode */
+ KS_MD, /* bold mode */
+ KS_SE, /* normal mode */
+ KS_SO, /* standout mode */
+ KS_CZH, /* italic mode start */
+ KS_CZR, /* italic mode end */
+ KS_UE, /* exit underscore (underline) mode */
+ KS_US, /* underscore (underline) mode */
+ KS_UCE, /* exit undercurl mode */
+ KS_UCS, /* undercurl mode */
+ KS_MS, /* save to move cur in reverse mode */
+ KS_CM, /* cursor motion */
+ KS_SR, /* scroll reverse (backward) */
+ KS_CRI, /* cursor number of chars right */
+ KS_VB, /* visual bell */
+ KS_KS, /* put term in "keypad transmit" mode */
+ KS_KE, /* out of "keypad transmit" mode */
+ KS_TI, /* put terminal in termcap mode */
+ KS_TE, /* out of termcap mode */
+ KS_BC, /* backspace character (cursor left) */
+ KS_CCS, /* cur is relative to scroll region */
+ KS_CCO, /* number of colors */
+ KS_CSF, /* set foreground color */
+ KS_CSB, /* set background color */
+ KS_XS, /* standout not erased by overwriting (hpterm) */
+ KS_MB, /* blink mode */
+ KS_CAF, /* set foreground color (ANSI) */
+ KS_CAB, /* set background color (ANSI) */
+ KS_LE, /* cursor left (mostly backspace) */
+ KS_ND, /* cursor right */
+ KS_CIS, /* set icon text start */
+ KS_CIE, /* set icon text end */
+ KS_TS, /* set window title start (to status line)*/
+ KS_FS, /* set window title end (from status line) */
+ KS_CWP, /* set window position in pixels */
+ KS_CWS, /* set window size in characters */
+ KS_CRV, /* request version string */
+ KS_CSI, /* start insert mode (bar cursor) */
+ KS_CEI, /* end insert mode (block cursor) */
+ KS_CSV, /* scroll region vertical */
+ KS_OP, /* original color pair */
+ KS_U7 /* request cursor position */
+};
+
+#define KS_LAST KS_U7
+
+/*
+ * the terminal capabilities are stored in this array
+ * IMPORTANT: When making changes, note the following:
+ * - there should be an entry for each code in the builtin termcaps
+ * - there should be an option for each code in option.c
+ * - there should be code in term.c to obtain the value from the termcap
+ */
+
+extern char_u *(term_strings[]); /* current terminal strings */
+
+/*
+ * strings used for terminal
+ */
+#define T_NAME (term_str(KS_NAME)) /* terminal name */
+#define T_CE (term_str(KS_CE)) /* clear to end of line */
+#define T_AL (term_str(KS_AL)) /* add new blank line */
+#define T_CAL (term_str(KS_CAL)) /* add number of blank lines */
+#define T_DL (term_str(KS_DL)) /* delete line */
+#define T_CDL (term_str(KS_CDL)) /* delete number of lines */
+#define T_CS (term_str(KS_CS)) /* scroll region */
+#define T_CSV (term_str(KS_CSV)) /* scroll region vertical */
+#define T_CL (term_str(KS_CL)) /* clear screen */
+#define T_CD (term_str(KS_CD)) /* clear to end of display */
+#define T_UT (term_str(KS_UT)) /* clearing uses background color */
+#define T_DA (term_str(KS_DA)) /* text may be scrolled down from up */
+#define T_DB (term_str(KS_DB)) /* text may be scrolled up from down */
+#define T_VI (term_str(KS_VI)) /* cursor invisible */
+#define T_VE (term_str(KS_VE)) /* cursor visible */
+#define T_VS (term_str(KS_VS)) /* cursor very visible */
+#define T_ME (term_str(KS_ME)) /* normal mode */
+#define T_MR (term_str(KS_MR)) /* reverse mode */
+#define T_MD (term_str(KS_MD)) /* bold mode */
+#define T_SE (term_str(KS_SE)) /* normal mode */
+#define T_SO (term_str(KS_SO)) /* standout mode */
+#define T_CZH (term_str(KS_CZH)) /* italic mode start */
+#define T_CZR (term_str(KS_CZR)) /* italic mode end */
+#define T_UE (term_str(KS_UE)) /* exit underscore (underline) mode */
+#define T_US (term_str(KS_US)) /* underscore (underline) mode */
+#define T_UCE (term_str(KS_UCE)) /* exit undercurl mode */
+#define T_UCS (term_str(KS_UCS)) /* undercurl mode */
+#define T_MS (term_str(KS_MS)) /* save to move cur in reverse mode */
+#define T_CM (term_str(KS_CM)) /* cursor motion */
+#define T_SR (term_str(KS_SR)) /* scroll reverse (backward) */
+#define T_CRI (term_str(KS_CRI)) /* cursor number of chars right */
+#define T_VB (term_str(KS_VB)) /* visual bell */
+#define T_KS (term_str(KS_KS)) /* put term in "keypad transmit" mode */
+#define T_KE (term_str(KS_KE)) /* out of "keypad transmit" mode */
+#define T_TI (term_str(KS_TI)) /* put terminal in termcap mode */
+#define T_TE (term_str(KS_TE)) /* out of termcap mode */
+#define T_BC (term_str(KS_BC)) /* backspace character */
+#define T_CCS (term_str(KS_CCS)) /* cur is relative to scroll region */
+#define T_CCO (term_str(KS_CCO)) /* number of colors */
+#define T_CSF (term_str(KS_CSF)) /* set foreground color */
+#define T_CSB (term_str(KS_CSB)) /* set background color */
+#define T_XS (term_str(KS_XS)) /* standout not erased by overwriting */
+#define T_MB (term_str(KS_MB)) /* blink mode */
+#define T_CAF (term_str(KS_CAF)) /* set foreground color (ANSI) */
+#define T_CAB (term_str(KS_CAB)) /* set background color (ANSI) */
+#define T_LE (term_str(KS_LE)) /* cursor left */
+#define T_ND (term_str(KS_ND)) /* cursor right */
+#define T_CIS (term_str(KS_CIS)) /* set icon text start */
+#define T_CIE (term_str(KS_CIE)) /* set icon text end */
+#define T_TS (term_str(KS_TS)) /* set window title start */
+#define T_FS (term_str(KS_FS)) /* set window title end */
+#define T_CWP (term_str(KS_CWP)) /* window position */
+#define T_CWS (term_str(KS_CWS)) /* window size */
+#define T_CSI (term_str(KS_CSI)) /* start insert mode */
+#define T_CEI (term_str(KS_CEI)) /* end insert mode */
+#define T_CRV (term_str(KS_CRV)) /* request version string */
+#define T_OP (term_str(KS_OP)) /* original color pair */
+#define T_U7 (term_str(KS_U7)) /* request cursor position */
+
+#define TMODE_COOK 0 /* terminal mode for external cmds and Ex mode */
+#define TMODE_SLEEP 1 /* terminal mode for sleeping (cooked but no echo) */
+#define TMODE_RAW 2 /* terminal mode for Normal and Insert mode */
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index 5238fda86a..16db2846c2 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -2,7 +2,7 @@
# Makefile to run all tests for Vim
#
-VIMPROG = ../../build/src/vim
+VIMPROG = ../../build/bin/nvim
# Uncomment this line to use valgrind for memory leaks and extra warnings.
# The output goes into a file "valgrind.testN"
diff --git a/src/testdir/test49.vim b/src/testdir/test49.vim
index eaf0cba00b..21c2a0c582 100644
--- a/src/testdir/test49.vim
+++ b/src/testdir/test49.vim
@@ -456,7 +456,7 @@ function! ExtraVim(...)
" messing up the user's viminfo file.
let redirect = a:0 ?
\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
- exec "!echo '" . debug_quits . "q' | ../../build/src/vim -u NONE -N -Xes" . redirect .
+ exec "!echo '" . debug_quits . "q' | ../../build/bin/nvim -u NONE -N -Xes" . redirect .
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
diff --git a/src/ui.c b/src/ui.c
index 7eebee6572..3396f2e6ef 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -17,11 +17,23 @@
*/
#include "vim.h"
-
-
-void ui_write(s, len)
-char_u *s;
-int len;
+#include "ui.h"
+#include "diff.h"
+#include "ex_cmds2.h"
+#include "fold.h"
+#include "main.h"
+#include "mbyte.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "screen.h"
+#include "term.h"
+#include "window.h"
+
+void ui_write(char_u *s, int len)
{
#ifndef NO_CONSOLE
/* Don't output anything in silent mode ("ex -s") unless 'verbose' set */
@@ -53,9 +65,7 @@ static char_u *ta_str = NULL;
static int ta_off; /* offset for next char to use when ta_str != NULL */
static int ta_len; /* length of ta_str when it's not NULL*/
-void ui_inchar_undo(s, len)
-char_u *s;
-int len;
+void ui_inchar_undo(char_u *s, int len)
{
char_u *new;
int newlen;
@@ -91,11 +101,13 @@ int len;
* from a remote client) "buf" can no longer be used. "tb_change_cnt" is NULL
* otherwise.
*/
-int ui_inchar(buf, maxlen, wtime, tb_change_cnt)
-char_u *buf;
-int maxlen;
-long wtime; /* don't use "time", MIPS cannot handle it */
-int tb_change_cnt;
+int
+ui_inchar (
+ char_u *buf,
+ int maxlen,
+ long wtime, /* don't use "time", MIPS cannot handle it */
+ int tb_change_cnt
+)
{
int retval = 0;
@@ -159,7 +171,7 @@ theend:
/*
* return non-zero if a character is available
*/
-int ui_char_avail() {
+int ui_char_avail(void) {
#ifndef NO_CONSOLE
# ifdef NO_CONSOLE_INPUT
if (no_console_input())
@@ -175,9 +187,7 @@ int ui_char_avail() {
* Delay for the given number of milliseconds. If ignoreinput is FALSE then we
* cancel the delay if a key is hit.
*/
-void ui_delay(msec, ignoreinput)
-long msec;
-int ignoreinput;
+void ui_delay(long msec, int ignoreinput)
{
mch_delay(msec, ignoreinput);
}
@@ -187,7 +197,7 @@ int ignoreinput;
* otherwise fake it by starting a new shell.
* When running the GUI iconify the window.
*/
-void ui_suspend() {
+void ui_suspend(void) {
mch_suspend();
}
@@ -196,7 +206,7 @@ void ui_suspend() {
* When the OS can't really suspend, call this function to start a shell.
* This is never called in the GUI.
*/
-void suspend_shell() {
+void suspend_shell(void) {
if (*p_sh == NUL)
EMSG(_(e_shellempty));
else {
@@ -212,7 +222,7 @@ void suspend_shell() {
* Use the new sizes as defaults for 'columns' and 'lines'.
* Return OK when size could be determined, FAIL otherwise.
*/
-int ui_get_shellsize() {
+int ui_get_shellsize(void) {
int retval;
retval = mch_get_shellsize();
@@ -232,8 +242,10 @@ int ui_get_shellsize() {
* The gui_set_shellsize() or mch_set_shellsize() function will try to set the
* new size. If this is not possible, it will adjust Rows and Columns.
*/
-void ui_set_shellsize(mustset)
-int mustset UNUSED; /* set by the user */
+void
+ui_set_shellsize (
+ int mustset /* set by the user */
+)
{
mch_set_shellsize();
}
@@ -242,13 +254,13 @@ int mustset UNUSED; /* set by the user */
* Called when Rows and/or Columns changed. Adjust scroll region and mouse
* region.
*/
-void ui_new_shellsize() {
+void ui_new_shellsize(void) {
if (full_screen && !exiting) {
mch_new_shellsize();
}
}
-void ui_breakcheck() {
+void ui_breakcheck(void) {
mch_breakcheck();
}
@@ -305,16 +317,16 @@ static int inbufcount = 0; /* number of chars in inbuf[] */
* are used by the gui_* calls when a GUI is used to handle keyboard input.
*/
-int vim_is_input_buf_full() {
+int vim_is_input_buf_full(void) {
return inbufcount >= INBUFLEN;
}
-int vim_is_input_buf_empty() {
+int vim_is_input_buf_empty(void) {
return inbufcount == 0;
}
#if defined(FEAT_OLE) || defined(PROTO)
-int vim_free_in_input_buf() {
+int vim_free_in_input_buf(void) {
return INBUFLEN - inbufcount;
}
@@ -325,7 +337,7 @@ int vim_free_in_input_buf() {
* Return the current contents of the input buffer and make it empty.
* The returned pointer must be passed to set_input_buf() later.
*/
-char_u * get_input_buf() {
+char_u *get_input_buf(void) {
garray_T *gap;
/* We use a growarray to store the data pointer and the length. */
@@ -345,8 +357,7 @@ char_u * get_input_buf() {
* Restore the input buffer with a pointer returned from get_input_buf().
* The allocated memory is freed, this only works once!
*/
-void set_input_buf(p)
-char_u *p;
+void set_input_buf(char_u *p)
{
garray_T *gap = (garray_T *)p;
@@ -370,9 +381,7 @@ char_u *p;
* Special keys start with CSI. A real CSI must have been translated to
* CSI KS_EXTRA KE_CSI. K_SPECIAL doesn't require translation.
*/
-void add_to_input_buf(s, len)
-char_u *s;
-int len;
+void add_to_input_buf(char_u *s, int len)
{
if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
return; /* Shouldn't ever happen! */
@@ -413,9 +422,7 @@ void add_to_input_buf_csi(char_u *str, int len) {
#endif
-void push_raw_key(s, len)
-char_u *s;
-int len;
+void push_raw_key(char_u *s, int len)
{
while (len--)
inbuf[inbufcount++] = *s++;
@@ -424,7 +431,7 @@ int len;
#if defined(FEAT_GUI) || defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) \
|| defined(PROTO)
/* Remove everything from the input buffer. Called when ^C is found */
-void trash_input_buf() {
+void trash_input_buf(void) {
inbufcount = 0;
}
@@ -435,9 +442,7 @@ void trash_input_buf() {
* it in buf.
* Note: this function used to be Read() in unix.c
*/
-int read_from_input_buf(buf, maxlen)
-char_u *buf;
-long maxlen;
+int read_from_input_buf(char_u *buf, long maxlen)
{
if (inbufcount == 0) /* if the buffer is empty, fill it */
fill_input_buf(TRUE);
@@ -450,8 +455,7 @@ long maxlen;
return (int)maxlen;
}
-void fill_input_buf(exit_on_error)
-int exit_on_error UNUSED;
+void fill_input_buf(int exit_on_error)
{
#if defined(UNIX) || defined(OS2) || defined(VMS) || defined(MACOS_X_UNIX)
int len;
@@ -567,7 +571,7 @@ int exit_on_error UNUSED;
/*
* Exit because of an input read error.
*/
-void read_error_exit() {
+void read_error_exit(void) {
if (silent_mode) /* Normal way to exit for "ex -s" */
getout(0);
STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
@@ -578,7 +582,7 @@ void read_error_exit() {
/*
* May update the shape of the cursor.
*/
-void ui_cursor_shape() {
+void ui_cursor_shape(void) {
term_cursor_shape();
@@ -592,8 +596,7 @@ void ui_cursor_shape() {
/*
* Check bounds for column number
*/
-int check_col(col)
-int col;
+int check_col(int col)
{
if (col < 0)
return 0;
@@ -605,8 +608,7 @@ int col;
/*
* Check bounds for row number
*/
-int check_row(row)
-int row;
+int check_row(int row)
{
if (row < 0)
return 0;
@@ -626,9 +628,7 @@ int row;
/*
* Get the contents of the X CUT_BUFFER0 and put it in "cbd".
*/
-void yank_cut_buffer0(dpy, cbd)
-Display *dpy;
-VimClipboard *cbd;
+void yank_cut_buffer0(Display *dpy, VimClipboard *cbd)
{
int nbytes = 0;
char_u *buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0);
@@ -694,10 +694,12 @@ VimClipboard *cbd;
* If flags has MOUSE_SETPOS, nothing is done, only the current position is
* remembered.
*/
-int jump_to_mouse(flags, inclusive, which_button)
-int flags;
-int *inclusive; /* used for inclusive operator, can be NULL */
-int which_button; /* MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE */
+int
+jump_to_mouse (
+ int flags,
+ int *inclusive, /* used for inclusive operator, can be NULL */
+ int which_button /* MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE */
+)
{
static int on_status_line = 0; /* #lines below bottom of window */
static int on_sep_line = 0; /* on separator right of window */
@@ -986,11 +988,7 @@ retnomove:
* window "win".
* Returns TRUE if the position is below the last line.
*/
-int mouse_comp_pos(win, rowp, colp, lnump)
-win_T *win;
-int *rowp;
-int *colp;
-linenr_T *lnump;
+int mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
{
int col = *colp;
int row = *rowp;
@@ -1056,9 +1054,7 @@ linenr_T *lnump;
* Find the window at screen position "*rowp" and "*colp". The positions are
* updated to become relative to the top-left of the window.
*/
-win_T * mouse_find_win(rowp, colp)
-int *rowp;
-int *colp UNUSED;
+win_T *mouse_find_win(int *rowp, int *colp)
{
frame_T *fp;
@@ -1090,8 +1086,7 @@ int *colp UNUSED;
/*
* Translate window coordinates to buffer position without any side effects
*/
-int get_fpos_of_mouse(mpos)
-pos_T *mpos;
+int get_fpos_of_mouse(pos_T *mpos)
{
win_T *wp;
int row = mouse_row;
@@ -1129,10 +1124,7 @@ pos_T *mpos;
* Convert a virtual (screen) column to a character column.
* The first column is one.
*/
-int vcol2col(wp, lnum, vcol)
-win_T *wp;
-linenr_T lnum;
-int vcol;
+int vcol2col(win_T *wp, linenr_T lnum, int vcol)
{
/* try to advance to the specified column */
int count = 0;
@@ -1154,8 +1146,7 @@ int vcol;
/*
* Save current Input Method status to specified place.
*/
-void im_save_status(psave)
-long *psave;
+void im_save_status(long *psave)
{
/* Don't save when 'imdisable' is set or "xic" is NULL, IM is always
* disabled then (but might start later).
diff --git a/src/proto/ui.pro b/src/ui.h
index 2f37fb9dfe..bcd6afd426 100644
--- a/src/proto/ui.pro
+++ b/src/ui.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_UI_H
+#define NEOVIM_UI_H
/* ui.c */
void ui_write __ARGS((char_u *s, int len));
void ui_inchar_undo __ARGS((char_u *s, int len));
@@ -65,3 +67,4 @@ int vcol2col __ARGS((win_T *wp, linenr_T lnum, int vcol));
void ui_focus_change __ARGS((int in_focus));
void im_save_status __ARGS((long *psave));
/* vim: set ft=c : */
+#endif /* NEOVIM_UI_H */
diff --git a/src/undo.c b/src/undo.c
index 9dfdcbe74c..b63e89458e 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -82,6 +82,21 @@
#define UE_MAGIC 0xabc123 /* value for ue_magic when in use */
#include "vim.h"
+#include "undo.h"
+#include "edit.h"
+#include "eval.h"
+#include "fileio.h"
+#include "fold.h"
+#include "mark.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "screen.h"
+#include "sha256.h"
static long get_undolevel __ARGS((void));
static void u_unch_branch __ARGS((u_header_T *uhp));
@@ -98,9 +113,9 @@ static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp,
static void u_freeentry __ARGS((u_entry_T *, long));
static void corruption_error __ARGS((char *mesg, char_u *file_name));
static void u_free_uhp __ARGS((u_header_T *uhp));
-static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len,
+static size_t fwrite_crypt __ARGS((buf_T *buf, char_u *ptr, size_t len,
FILE *fp));
-static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len));
+static char_u *read_string_decrypt __ARGS((buf_T *buf, FILE *fd, int len));
static int serialize_header __ARGS((FILE *fp, buf_T *buf, char_u *hash));
static int serialize_uhp __ARGS((FILE *fp, buf_T *buf, u_header_T *uhp));
static u_header_T *unserialize_uhp __ARGS((FILE *fp, char_u *file_name));
@@ -210,7 +225,7 @@ static void u_check(int newhead_may_be_NULL) {
* Careful: may trigger autocommands that reload the buffer.
* Returns OK or FAIL.
*/
-int u_save_cursor() {
+int u_save_cursor(void) {
return u_save((linenr_T)(curwin->w_cursor.lnum - 1),
(linenr_T)(curwin->w_cursor.lnum + 1));
}
@@ -221,8 +236,7 @@ int u_save_cursor() {
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_save(top, bot)
-linenr_T top, bot;
+int u_save(linenr_T top, linenr_T bot)
{
if (undo_off)
return OK;
@@ -244,8 +258,7 @@ linenr_T top, bot;
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savesub(lnum)
-linenr_T lnum;
+int u_savesub(linenr_T lnum)
{
if (undo_off)
return OK;
@@ -259,8 +272,7 @@ linenr_T lnum;
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_inssub(lnum)
-linenr_T lnum;
+int u_inssub(linenr_T lnum)
{
if (undo_off)
return OK;
@@ -275,9 +287,7 @@ linenr_T lnum;
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savedel(lnum, nlines)
-linenr_T lnum;
-long nlines;
+int u_savedel(linenr_T lnum, long nlines)
{
if (undo_off)
return OK;
@@ -290,7 +300,7 @@ long nlines;
* Return TRUE when undo is allowed. Otherwise give an error message and
* return FALSE.
*/
-int undo_allowed() {
+int undo_allowed(void) {
/* Don't allow changes when 'modifiable' is off. */
if (!curbuf->b_p_ma) {
EMSG(_(e_modifiable));
@@ -318,7 +328,7 @@ int undo_allowed() {
/*
* Get the undolevle value for the current buffer.
*/
-static long get_undolevel() {
+static long get_undolevel(void) {
if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
return p_ul;
return curbuf->b_p_ul;
@@ -333,10 +343,7 @@ static long get_undolevel() {
* Careful: may trigger autocommands that reload the buffer.
* Returns FAIL when lines could not be saved, OK otherwise.
*/
-int u_savecommon(top, bot, newbot, reload)
-linenr_T top, bot;
-linenr_T newbot;
-int reload;
+int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
{
linenr_T lnum;
long i;
@@ -647,8 +654,7 @@ static char_u e_not_open[] = N_("E828: Cannot open undo file for writing: %s");
/*
* Compute the hash for the current buffer text into hash[UNDO_HASH_SIZE].
*/
-void u_compute_hash(hash)
-char_u *hash;
+void u_compute_hash(char_u *hash)
{
context_sha256_T ctx;
linenr_T lnum;
@@ -669,9 +675,7 @@ char_u *hash;
* When "reading" is FALSE use the first name where the directory exists.
* Returns NULL when there is no place to write or no file to read.
*/
-char_u * u_get_undo_file_name(buf_ffname, reading)
-char_u *buf_ffname;
-int reading;
+char_u *u_get_undo_file_name(char_u *buf_ffname, int reading)
{
char_u *dirp;
char_u dir_name[IOSIZE + 1];
@@ -738,15 +742,12 @@ int reading;
return undo_file_name;
}
-static void corruption_error(mesg, file_name)
-char *mesg;
-char_u *file_name;
+static void corruption_error(char *mesg, char_u *file_name)
{
EMSG3(_("E825: Corrupted undo file (%s): %s"), mesg, file_name);
}
-static void u_free_uhp(uhp)
-u_header_T *uhp;
+static void u_free_uhp(u_header_T *uhp)
{
u_entry_T *nuep;
u_entry_T *uep;
@@ -764,11 +765,7 @@ u_header_T *uhp;
* Like fwrite() but crypt the bytes when 'key' is set.
* Returns 1 if successful.
*/
-static size_t fwrite_crypt(buf, ptr, len, fp)
-buf_T *buf UNUSED;
-char_u *ptr;
-size_t len;
-FILE *fp;
+static size_t fwrite_crypt(buf_T *buf, char_u *ptr, size_t len, FILE *fp)
{
char_u *copy;
char_u small_buf[100];
@@ -794,10 +791,7 @@ FILE *fp;
* Read a string of length "len" from "fd".
* When 'key' is set decrypt the bytes.
*/
-static char_u * read_string_decrypt(buf, fd, len)
-buf_T *buf UNUSED;
-FILE *fd;
-int len;
+static char_u *read_string_decrypt(buf_T *buf, FILE *fd, int len)
{
char_u *ptr;
@@ -807,10 +801,7 @@ int len;
return ptr;
}
-static int serialize_header(fp, buf, hash)
-FILE *fp;
-buf_T *buf;
-char_u *hash;
+static int serialize_header(FILE *fp, buf_T *buf, char_u *hash)
{
int len;
@@ -872,10 +863,7 @@ char_u *hash;
return OK;
}
-static int serialize_uhp(fp, buf, uhp)
-FILE *fp;
-buf_T *buf;
-u_header_T *uhp;
+static int serialize_uhp(FILE *fp, buf_T *buf, u_header_T *uhp)
{
int i;
u_entry_T *uep;
@@ -914,9 +902,7 @@ u_header_T *uhp;
return OK;
}
-static u_header_T * unserialize_uhp(fp, file_name)
-FILE *fp;
-char_u *file_name;
+static u_header_T *unserialize_uhp(FILE *fp, char_u *file_name)
{
u_header_T *uhp;
int i;
@@ -995,10 +981,7 @@ char_u *file_name;
/*
* Serialize "uep" to "fp".
*/
-static int serialize_uep(fp, buf, uep)
-FILE *fp;
-buf_T *buf;
-u_entry_T *uep;
+static int serialize_uep(FILE *fp, buf_T *buf, u_entry_T *uep)
{
int i;
size_t len;
@@ -1017,10 +1000,7 @@ u_entry_T *uep;
return OK;
}
-static u_entry_T * unserialize_uep(fp, error, file_name)
-FILE *fp;
-int *error;
-char_u *file_name;
+static u_entry_T *unserialize_uep(FILE *fp, int *error, char_u *file_name)
{
int i;
u_entry_T *uep;
@@ -1070,9 +1050,7 @@ char_u *file_name;
/*
* Serialize "pos" to "fp".
*/
-static void serialize_pos(pos, fp)
-pos_T pos;
-FILE *fp;
+static void serialize_pos(pos_T pos, FILE *fp)
{
put_bytes(fp, (long_u)pos.lnum, 4);
put_bytes(fp, (long_u)pos.col, 4);
@@ -1082,9 +1060,7 @@ FILE *fp;
/*
* Unserialize the pos_T at the current position in fp.
*/
-static void unserialize_pos(pos, fp)
-pos_T *pos;
-FILE *fp;
+static void unserialize_pos(pos_T *pos, FILE *fp)
{
pos->lnum = get4c(fp);
if (pos->lnum < 0)
@@ -1100,9 +1076,7 @@ FILE *fp;
/*
* Serialize "info" to "fp".
*/
-static void serialize_visualinfo(info, fp)
-visualinfo_T *info;
-FILE *fp;
+static void serialize_visualinfo(visualinfo_T *info, FILE *fp)
{
serialize_pos(info->vi_start, fp);
serialize_pos(info->vi_end, fp);
@@ -1113,9 +1087,7 @@ FILE *fp;
/*
* Unserialize the visualinfo_T at the current position in fp.
*/
-static void unserialize_visualinfo(info, fp)
-visualinfo_T *info;
-FILE *fp;
+static void unserialize_visualinfo(visualinfo_T *info, FILE *fp)
{
unserialize_pos(&info->vi_start, fp);
unserialize_pos(&info->vi_end, fp);
@@ -1127,9 +1099,7 @@ FILE *fp;
* Write the pointer to an undo header. Instead of writing the pointer itself
* we use the sequence number of the header. This is converted back to
* pointers when reading. */
-static void put_header_ptr(fp, uhp)
-FILE *fp;
-u_header_T *uhp;
+static void put_header_ptr(FILE *fp, u_header_T *uhp)
{
put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
}
@@ -1143,11 +1113,7 @@ u_header_T *uhp;
* "forceit" is TRUE for ":wundo!", FALSE otherwise.
* "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
*/
-void u_write_undo(name, forceit, buf, hash)
-char_u *name;
-int forceit;
-buf_T *buf;
-char_u *hash;
+void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash)
{
u_header_T *uhp;
char_u *file_name;
@@ -1378,10 +1344,7 @@ theend:
* Otherwise use curbuf->b_ffname to generate the undo file name.
* "hash[UNDO_HASH_SIZE]" must be the hash value of the buffer text.
*/
-void u_read_undo(name, hash, orig_name)
-char_u *name;
-char_u *hash;
-char_u *orig_name;
+void u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
{
char_u *file_name;
FILE *fp;
@@ -1684,8 +1647,7 @@ theend:
* If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible).
* If 'cpoptions' does not contain 'u': Always undo.
*/
-void u_undo(count)
-int count;
+void u_undo(int count)
{
/*
* If we get an undo command while executing a macro, we behave like the
@@ -1708,8 +1670,7 @@ int count;
* If 'cpoptions' contains 'u': Repeat the previous undo or redo.
* If 'cpoptions' does not contain 'u': Always redo.
*/
-void u_redo(count)
-int count;
+void u_redo(int count)
{
if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
undo_undoes = FALSE;
@@ -1719,8 +1680,7 @@ int count;
/*
* Undo or redo, depending on 'undo_undoes', 'count' times.
*/
-static void u_doit(startcount)
-int startcount;
+static void u_doit(int startcount)
{
int count = startcount;
@@ -1788,11 +1748,7 @@ int startcount;
* When "absolute" is TRUE use "step" as the sequence number to jump to.
* "sec" must be FALSE then.
*/
-void undo_time(step, sec, file, absolute)
-long step;
-int sec;
-int file;
-int absolute;
+void undo_time(long step, int sec, int file, int absolute)
{
long target;
long closest;
@@ -2099,8 +2055,7 @@ int absolute;
*
* When "undo" is TRUE we go up in the tree, when FALSE we go down.
*/
-static void u_undoredo(undo)
-int undo;
+static void u_undoredo(int undo)
{
char_u **newarray = NULL;
linenr_T oldsize;
@@ -2344,9 +2299,11 @@ int undo;
* Otherwise, report the number of changes (this may be incorrect
* in some cases, but it's better than nothing).
*/
-static void u_undo_end(did_undo, absolute)
-int did_undo; /* just did an undo */
-int absolute; /* used ":undo N" */
+static void
+u_undo_end (
+ int did_undo, /* just did an undo */
+ int absolute /* used ":undo N" */
+)
{
char *msgstr;
u_header_T *uhp;
@@ -2417,8 +2374,10 @@ int absolute; /* used ":undo N" */
/*
* u_sync: stop adding to the current entry list
*/
-void u_sync(force)
-int force; /* Also sync when no_u_sync is set. */
+void
+u_sync (
+ int force /* Also sync when no_u_sync is set. */
+)
{
/* Skip it when already synced or syncing is disabled. */
if (curbuf->b_u_synced || (!force && no_u_sync > 0))
@@ -2434,8 +2393,7 @@ int force; /* Also sync when no_u_sync is set. */
/*
* ":undolist": List the leafs of the undo tree
*/
-void ex_undolist(eap)
-exarg_T *eap UNUSED;
+void ex_undolist(exarg_T *eap)
{
garray_T ga;
u_header_T *uhp;
@@ -2528,10 +2486,7 @@ exarg_T *eap UNUSED;
/*
* Put the timestamp of an undo header in "buf[buflen]" in a nice format.
*/
-static void u_add_time(buf, buflen, tt)
-char_u *buf;
-size_t buflen;
-time_t tt;
+static void u_add_time(char_u *buf, size_t buflen, time_t tt)
{
#ifdef HAVE_STRFTIME
struct tm *curtime;
@@ -2553,8 +2508,7 @@ time_t tt;
/*
* ":undojoin": continue adding to the last entry list
*/
-void ex_undojoin(eap)
-exarg_T *eap UNUSED;
+void ex_undojoin(exarg_T *eap)
{
if (curbuf->b_u_newhead == NULL)
return; /* nothing changed before */
@@ -2577,8 +2531,7 @@ exarg_T *eap UNUSED;
* Called after writing or reloading the file and setting b_changed to FALSE.
* Now an undo means that the buffer is modified.
*/
-void u_unchanged(buf)
-buf_T *buf;
+void u_unchanged(buf_T *buf)
{
u_unch_branch(buf->b_u_oldhead);
buf->b_did_warn = FALSE;
@@ -2588,7 +2541,7 @@ buf_T *buf;
* After reloading a buffer which was saved for 'undoreload': Find the first
* line that was changed and set the cursor there.
*/
-void u_find_first_changed() {
+void u_find_first_changed(void) {
u_header_T *uhp = curbuf->b_u_newhead;
u_entry_T *uep;
linenr_T lnum;
@@ -2620,8 +2573,7 @@ void u_find_first_changed() {
* Increase the write count, store it in the last undo header, what would be
* used for "u".
*/
-void u_update_save_nr(buf)
-buf_T *buf;
+void u_update_save_nr(buf_T *buf)
{
u_header_T *uhp;
@@ -2636,8 +2588,7 @@ buf_T *buf;
uhp->uh_save_nr = buf->b_u_save_nr_last;
}
-static void u_unch_branch(uhp)
-u_header_T *uhp;
+static void u_unch_branch(u_header_T *uhp)
{
u_header_T *uh;
@@ -2652,7 +2603,7 @@ u_header_T *uhp;
* Get pointer to last added entry.
* If it's not valid, give an error message and return NULL.
*/
-static u_entry_T * u_get_headentry() {
+static u_entry_T *u_get_headentry(void) {
if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
EMSG(_("E439: undo list corrupt"));
return NULL;
@@ -2664,7 +2615,7 @@ static u_entry_T * u_get_headentry() {
* u_getbot(): compute the line number of the previous u_save
* It is called only when b_u_synced is FALSE.
*/
-static void u_getbot() {
+static void u_getbot(void) {
u_entry_T *uep;
linenr_T extra;
@@ -2698,10 +2649,12 @@ static void u_getbot() {
/*
* Free one header "uhp" and its entry list and adjust the pointers.
*/
-static void u_freeheader(buf, uhp, uhpp)
-buf_T *buf;
-u_header_T *uhp;
-u_header_T **uhpp; /* if not NULL reset when freeing this header */
+static void
+u_freeheader (
+ buf_T *buf,
+ u_header_T *uhp,
+ u_header_T **uhpp /* if not NULL reset when freeing this header */
+)
{
u_header_T *uhap;
@@ -2732,10 +2685,12 @@ u_header_T **uhpp; /* if not NULL reset when freeing this header */
/*
* Free an alternate branch and any following alternate branches.
*/
-static void u_freebranch(buf, uhp, uhpp)
-buf_T *buf;
-u_header_T *uhp;
-u_header_T **uhpp; /* if not NULL reset when freeing this header */
+static void
+u_freebranch (
+ buf_T *buf,
+ u_header_T *uhp,
+ u_header_T **uhpp /* if not NULL reset when freeing this header */
+)
{
u_header_T *tofree, *next;
@@ -2764,10 +2719,12 @@ u_header_T **uhpp; /* if not NULL reset when freeing this header */
* Free all the undo entries for one header and the header itself.
* This means that "uhp" is invalid when returning.
*/
-static void u_freeentries(buf, uhp, uhpp)
-buf_T *buf;
-u_header_T *uhp;
-u_header_T **uhpp; /* if not NULL reset when freeing this header */
+static void
+u_freeentries (
+ buf_T *buf,
+ u_header_T *uhp,
+ u_header_T **uhpp /* if not NULL reset when freeing this header */
+)
{
u_entry_T *uep, *nuep;
@@ -2794,9 +2751,7 @@ u_header_T **uhpp; /* if not NULL reset when freeing this header */
/*
* free entry 'uep' and 'n' lines in uep->ue_array[]
*/
-static void u_freeentry(uep, n)
-u_entry_T *uep;
-long n;
+static void u_freeentry(u_entry_T *uep, long n)
{
while (n > 0)
vim_free(uep->ue_array[--n]);
@@ -2810,8 +2765,7 @@ long n;
/*
* invalidate the undo buffer; called when storage has already been released
*/
-void u_clearall(buf)
-buf_T *buf;
+void u_clearall(buf_T *buf)
{
buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
buf->b_u_synced = TRUE;
@@ -2823,8 +2777,7 @@ buf_T *buf;
/*
* save the line "lnum" for the "U" command
*/
-void u_saveline(lnum)
-linenr_T lnum;
+void u_saveline(linenr_T lnum)
{
if (lnum == curbuf->b_u_line_lnum) /* line is already saved */
return;
@@ -2844,7 +2797,7 @@ linenr_T lnum;
* clear the line saved for the "U" command
* (this is used externally for crossing a line while in insert mode)
*/
-void u_clearline() {
+void u_clearline(void) {
if (curbuf->b_u_line_ptr != NULL) {
vim_free(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = NULL;
@@ -2858,7 +2811,7 @@ void u_clearline() {
* We also allow the cursor to be in another line.
* Careful: may trigger autocommands that reload the buffer.
*/
-void u_undoline() {
+void u_undoline(void) {
colnr_T t;
char_u *oldp;
@@ -2896,8 +2849,7 @@ void u_undoline() {
/*
* Free all allocated memory blocks for the buffer 'buf'.
*/
-void u_blockfree(buf)
-buf_T *buf;
+void u_blockfree(buf_T *buf)
{
while (buf->b_u_oldhead != NULL)
u_freeheader(buf, buf->b_u_oldhead, NULL);
@@ -2908,8 +2860,7 @@ buf_T *buf;
* u_save_line(): allocate memory and copy line 'lnum' into it.
* Returns NULL when out of memory.
*/
-static char_u * u_save_line(lnum)
-linenr_T lnum;
+static char_u *u_save_line(linenr_T lnum)
{
return vim_strsave(ml_get(lnum));
}
@@ -2919,15 +2870,14 @@ linenr_T lnum;
* check the first character, because it can only be "dos", "unix" or "mac").
* "nofile" and "scratch" type buffers are considered to always be unchanged.
*/
-int bufIsChanged(buf)
-buf_T *buf;
+int bufIsChanged(buf_T *buf)
{
return
!bt_dontwrite(buf) &&
(buf->b_changed || file_ff_differs(buf, TRUE));
}
-int curbufIsChanged() {
+int curbufIsChanged(void) {
return
!bt_dontwrite(curbuf) &&
(curbuf->b_changed || file_ff_differs(curbuf, TRUE));
@@ -2937,9 +2887,7 @@ int curbufIsChanged() {
* For undotree(): Append the list of undo blocks at "first_uhp" to "list".
* Recursive.
*/
-void u_eval_tree(first_uhp, list)
-u_header_T *first_uhp;
-list_T *list;
+void u_eval_tree(u_header_T *first_uhp, list_T *list)
{
u_header_T *uhp = first_uhp;
dict_T *dict;
diff --git a/src/proto/undo.pro b/src/undo.h
index dfbb07ac26..aecab36875 100644
--- a/src/proto/undo.pro
+++ b/src/undo.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_UNDO_H
+#define NEOVIM_UNDO_H
/* undo.c */
int u_save_cursor __ARGS((void));
int u_save __ARGS((linenr_T top, linenr_T bot));
@@ -29,3 +31,4 @@ int bufIsChanged __ARGS((buf_T *buf));
int curbufIsChanged __ARGS((void));
void u_eval_tree __ARGS((u_header_T *first_uhp, list_T *list));
/* vim: set ft=c : */
+#endif /* NEOVIM_UNDO_H */
diff --git a/src/version.c b/src/version.c
index 62a7aa8bc8..e85f7a57ec 100644
--- a/src/version.c
+++ b/src/version.c
@@ -8,7 +8,12 @@
*/
#include "vim.h"
-
+#include "version.h"
+#include "charset.h"
+#include "memline.h"
+#include "message.h"
+#include "misc2.h"
+#include "screen.h"
/*
* Vim originated from Stevie version 3.6 (Fish disk 217) by GRWalter (Fred)
@@ -22,7 +27,7 @@
* interesting.
*/
-#include "version.h"
+#include "version_defs.h"
char *Version = VIM_VERSION_SHORT;
static char *mediumVersion = VIM_VERSION_MEDIUM;
@@ -568,7 +573,7 @@ static char *(extra_patches[]) =
NULL
};
-int highest_patch() {
+int highest_patch(void) {
int i;
int h = 0;
@@ -581,8 +586,7 @@ int highest_patch() {
/*
* Return TRUE if patch "n" has been included.
*/
-int has_patch(n)
-int n;
+int has_patch(int n)
{
int i;
@@ -592,8 +596,7 @@ int n;
return FALSE;
}
-void ex_version(eap)
-exarg_T *eap;
+void ex_version(exarg_T *eap)
{
/*
* Ignore a ":version 9.99" command.
@@ -607,7 +610,7 @@ exarg_T *eap;
/*
* List all features aligned in columns, dictionary style.
*/
-static void list_features() {
+static void list_features(void) {
int i;
int ncol;
int nrow;
@@ -662,7 +665,7 @@ static void list_features() {
}
}
-void list_version() {
+void list_version(void) {
int i;
int first;
char *s = "";
@@ -792,8 +795,7 @@ void list_version() {
* Output a string for the version message. If it's going to wrap, output a
* newline, unless the message is too long to fit on the screen anyway.
*/
-static void version_msg(s)
-char *s;
+static void version_msg(char *s)
{
int len = (int)STRLEN(s);
@@ -810,7 +812,7 @@ static void do_intro_line __ARGS((int row, char_u *mesg, int add_version,
/*
* Show the intro message when not editing a file.
*/
-void maybe_intro_message() {
+void maybe_intro_message(void) {
if (bufempty()
&& curbuf->b_fname == NULL
&& firstwin->w_next == NULL
@@ -823,8 +825,10 @@ void maybe_intro_message() {
* Only used when starting Vim on an empty file, without a file name.
* Or with the ":intro" command (for Sven :-).
*/
-void intro_message(colon)
-int colon; /* TRUE for ":intro" */
+void
+intro_message (
+ int colon /* TRUE for ":intro" */
+)
{
int i;
int row;
@@ -904,11 +908,7 @@ int colon; /* TRUE for ":intro" */
msg_row = row;
}
-static void do_intro_line(row, mesg, add_version, attr)
-int row;
-char_u *mesg;
-int add_version;
-int attr;
+static void do_intro_line(int row, char_u *mesg, int add_version, int attr)
{
char_u vers[20];
int col;
@@ -969,8 +969,7 @@ int attr;
/*
* ":intro": clear screen, display intro screen and wait for return.
*/
-void ex_intro(eap)
-exarg_T *eap UNUSED;
+void ex_intro(exarg_T *eap)
{
screenclear();
intro_message(TRUE);
diff --git a/src/version.h b/src/version.h
index ee49a6d97c..b2828980f3 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,40 +1,13 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * Define the version number, name, etc.
- * The patchlevel is in included_patches[], in version.c.
- *
- * This doesn't use string concatenation, some compilers don't support it.
- */
-
-#define VIM_VERSION_MAJOR 7
-#define VIM_VERSION_MAJOR_STR "7"
-#define VIM_VERSION_MINOR 4
-#define VIM_VERSION_MINOR_STR "4"
-#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
-
-#define VIM_VERSION_BUILD 280
-#define VIM_VERSION_BUILD_BCD 0x118
-#define VIM_VERSION_BUILD_STR "280"
-#define VIM_VERSION_PATCHLEVEL 0
-#define VIM_VERSION_PATCHLEVEL_STR "0"
-/* Used by MacOS port should be one of: development, alpha, beta, final */
-#define VIM_VERSION_RELEASE final
-
-/*
- * VIM_VERSION_NODOT is used for the runtime directory name.
- * VIM_VERSION_SHORT is copied into the swap file (max. length is 6 chars).
- * VIM_VERSION_MEDIUM is used for the startup-screen.
- * VIM_VERSION_LONG is used for the ":version" command and "Vim -h".
- */
-#define VIM_VERSION_NODOT "vim74"
-#define VIM_VERSION_SHORT "7.4"
-#define VIM_VERSION_MEDIUM "7.4"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.4 (2013 Aug 10)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.4 (2013 Aug 10, compiled "
+#ifndef NEOVIM_VERSION_H
+#define NEOVIM_VERSION_H
+/* version.c */
+void make_version __ARGS((void));
+int highest_patch __ARGS((void));
+int has_patch __ARGS((int n));
+void ex_version __ARGS((exarg_T *eap));
+void list_version __ARGS((void));
+void maybe_intro_message __ARGS((void));
+void intro_message __ARGS((int colon));
+void ex_intro __ARGS((exarg_T *eap));
+/* vim: set ft=c : */
+#endif /* NEOVIM_VERSION_H */
diff --git a/src/version_defs.h b/src/version_defs.h
new file mode 100644
index 0000000000..ee49a6d97c
--- /dev/null
+++ b/src/version_defs.h
@@ -0,0 +1,40 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * Define the version number, name, etc.
+ * The patchlevel is in included_patches[], in version.c.
+ *
+ * This doesn't use string concatenation, some compilers don't support it.
+ */
+
+#define VIM_VERSION_MAJOR 7
+#define VIM_VERSION_MAJOR_STR "7"
+#define VIM_VERSION_MINOR 4
+#define VIM_VERSION_MINOR_STR "4"
+#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
+
+#define VIM_VERSION_BUILD 280
+#define VIM_VERSION_BUILD_BCD 0x118
+#define VIM_VERSION_BUILD_STR "280"
+#define VIM_VERSION_PATCHLEVEL 0
+#define VIM_VERSION_PATCHLEVEL_STR "0"
+/* Used by MacOS port should be one of: development, alpha, beta, final */
+#define VIM_VERSION_RELEASE final
+
+/*
+ * VIM_VERSION_NODOT is used for the runtime directory name.
+ * VIM_VERSION_SHORT is copied into the swap file (max. length is 6 chars).
+ * VIM_VERSION_MEDIUM is used for the startup-screen.
+ * VIM_VERSION_LONG is used for the ":version" command and "Vim -h".
+ */
+#define VIM_VERSION_NODOT "vim74"
+#define VIM_VERSION_SHORT "7.4"
+#define VIM_VERSION_MEDIUM "7.4"
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.4 (2013 Aug 10)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.4 (2013 Aug 10, compiled "
diff --git a/src/vim.h b/src/vim.h
index 53706da049..75c2b14d38 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -6,8 +6,8 @@
* Do ":help credits" in Vim to see a list of people who contributed.
*/
-#ifndef VIM__H
-# define VIM__H
+#ifndef NEOVIM_VIM_H
+# define NEOVIM_VIM_H
/* Included when ported to cmake */
/* This is needed to replace TRUE/FALSE macros by true/false from c99 */
#include <stdbool.h>
@@ -62,7 +62,7 @@ Error: configure did not run properly.Check auto/config.log.
# define VIMPACKAGE "vim"
#endif
-#include "os_unix.h" /* bring lots of system header files */
+#include "os_unix_defs.h" /* bring lots of system header files */
#ifndef __ARGS
# if defined(__STDC__) || defined(__GNUC__) || defined(WIN3264)
@@ -72,14 +72,6 @@ Error: configure did not run properly.Check auto/config.log.
# endif
#endif
-/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
- * can be used to check for mistakes. */
-#ifdef HAVE_ATTRIBUTE_UNUSED
-# define UNUSED __attribute__((unused))
-#else
-# define UNUSED
-#endif
-
# ifdef HAVE_LOCALE_H
# include <locale.h>
# endif
@@ -162,7 +154,7 @@ typedef unsigned long u8char_T; /* long should be 32 bits or more */
#include "ascii.h"
#include "keymap.h"
-#include "term.h"
+#include "term_defs.h"
#include "macros.h"
#include <errno.h>
@@ -1268,9 +1260,9 @@ int vim_memcmp __ARGS((void *, void *, size_t));
typedef struct timeval proftime_T;
-/* Include option.h before structs.h, because the number of window-local and
+/* Include option_defs.h before structs.h, because the number of window-local and
* buffer-local options is used there. */
-#include "option.h" /* options and default values */
+#include "option_defs.h" /* options and default values */
/* Note that gui.h is included by structs.h */
@@ -1420,7 +1412,7 @@ typedef struct timeval proftime_T;
typedef int VimClipboard; /* This is required for the prototypes. */
-#include "ex_cmds.h" /* Ex command defines */
+#include "ex_cmds_defs.h" /* Ex command defines */
#include "proto.h" /* function prototypes */
/* This has to go after the include of proto.h, as proto/gui.pro declares
@@ -1602,4 +1594,4 @@ typedef int VimClipboard; /* This is required for the prototypes. */
# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag); set_vim_var_nr( \
VV_HLSEARCH, !no_hlsearch)
-#endif /* VIM__H */
+#endif /* NEOVIM_VIM_H */
diff --git a/src/window.c b/src/window.c
index 336f9dbcca..fb95ec1239 100644
--- a/src/window.c
+++ b/src/window.c
@@ -8,6 +8,39 @@
*/
#include "vim.h"
+#include "window.h"
+#include "buffer.h"
+#include "charset.h"
+#include "diff.h"
+#include "edit.h"
+#include "eval.h"
+#include "ex_cmds.h"
+#include "ex_cmds2.h"
+#include "ex_docmd.h"
+#include "ex_eval.h"
+#include "ex_getln.h"
+#include "fileio.h"
+#include "fold.h"
+#include "getchar.h"
+#include "hashtab.h"
+#include "main.h"
+#include "mark.h"
+#include "memline.h"
+#include "message.h"
+#include "misc1.h"
+#include "misc2.h"
+#include "move.h"
+#include "normal.h"
+#include "option.h"
+#include "os_unix.h"
+#include "quickfix.h"
+#include "regexp.h"
+#include "screen.h"
+#include "search.h"
+#include "syntax.h"
+#include "term.h"
+#include "undo.h"
+#include "os/os.h"
static int path_is_url __ARGS((char_u *p));
static void win_init __ARGS((win_T *newp, win_T *oldp, int flags));
@@ -86,10 +119,12 @@ static char *m_onlyone = N_("Already only one window");
/*
* all CTRL-W window commands are handled here, called from normal_cmd().
*/
-void do_window(nchar, Prenum, xchar)
-int nchar;
-long Prenum;
-int xchar; /* extra char from ":wincmd gx" or NUL */
+void
+do_window (
+ int nchar,
+ long Prenum,
+ int xchar /* extra char from ":wincmd gx" or NUL */
+)
{
long Prenum1;
win_T *wp;
@@ -510,9 +545,7 @@ wingotofile:
*
* return FAIL for failure, OK otherwise
*/
-int win_split(size, flags)
-int size;
-int flags;
+int win_split(int size, int flags)
{
/* When the ":tab" modifier was used open a new tab page instead. */
if (may_open_tabpage() == OK)
@@ -541,11 +574,7 @@ int flags;
* top/left/right/bottom.
* return FAIL for failure, OK otherwise
*/
-int win_split_ins(size, flags, new_wp, dir)
-int size;
-int flags;
-win_T *new_wp;
-int dir;
+int win_split_ins(int size, int flags, win_T *new_wp, int dir)
{
win_T *wp = new_wp;
win_T *oldwin;
@@ -936,10 +965,7 @@ int dir;
* WSP_NEWLOC may be specified in flags to prevent the location list from
* being copied.
*/
-static void win_init(newp, oldp, flags)
-win_T *newp;
-win_T *oldp;
-int flags UNUSED;
+static void win_init(win_T *newp, win_T *oldp, int flags)
{
int i;
@@ -989,9 +1015,7 @@ int flags UNUSED;
* Initialize window "newp" from window"old".
* Only the essential things are copied.
*/
-static void win_init_some(newp, oldp)
-win_T *newp;
-win_T *oldp;
+static void win_init_some(win_T *newp, win_T *oldp)
{
/* Use the same argument list. */
newp->w_alist = oldp->w_alist;
@@ -1006,8 +1030,7 @@ win_T *oldp;
/*
* Check if "win" is a pointer to an existing window.
*/
-int win_valid(win)
-win_T *win;
+int win_valid(win_T *win)
{
win_T *wp;
@@ -1022,7 +1045,7 @@ win_T *win;
/*
* Return the number of windows.
*/
-int win_count() {
+int win_count(void) {
win_T *wp;
int count = 0;
@@ -1037,9 +1060,11 @@ int win_count() {
* Must be called when there is just one window, filling the whole screen
* (excluding the command line).
*/
-int make_windows(count, vertical)
-int count;
-int vertical UNUSED; /* split windows vertically if TRUE */
+int
+make_windows (
+ int count,
+ int vertical /* split windows vertically if TRUE */
+)
{
int maxcount;
int todo;
@@ -1094,8 +1119,7 @@ int vertical UNUSED; /* split windows vertically if TRUE */
/*
* Exchange current and next window
*/
-static void win_exchange(Prenum)
-long Prenum;
+static void win_exchange(long Prenum)
{
frame_T *frp;
frame_T *frp2;
@@ -1185,9 +1209,7 @@ long Prenum;
* rotate windows: if upwards TRUE the second window becomes the first one
* if upwards FALSE the first window becomes the second one
*/
-static void win_rotate(upwards, count)
-int upwards;
-int count;
+static void win_rotate(int upwards, int count)
{
win_T *wp1;
win_T *wp2;
@@ -1260,9 +1282,7 @@ int count;
/*
* Move the current window to the very top/bottom/left/right of the screen.
*/
-static void win_totop(size, flags)
-int size;
-int flags;
+static void win_totop(int size, int flags)
{
int dir;
int height = curwin->w_height;
@@ -1292,8 +1312,7 @@ int flags;
* Move window "win1" to below/right of "win2" and make "win1" the current
* window. Only works within the same frame!
*/
-void win_move_after(win1, win2)
-win_T *win1, *win2;
+void win_move_after(win_T *win1, win_T *win2)
{
int height;
@@ -1346,11 +1365,13 @@ win_T *win1, *win2;
* 'next_curwin' will soon be the current window, make sure it has enough
* rows.
*/
-void win_equal(next_curwin, current, dir)
-win_T *next_curwin; /* pointer to current window to be or NULL */
-int current; /* do only frame with current window */
-int dir; /* 'v' for vertically, 'h' for horizontally,
+void
+win_equal (
+ win_T *next_curwin, /* pointer to current window to be or NULL */
+ int current, /* do only frame with current window */
+ int dir /* 'v' for vertically, 'h' for horizontally,
'b' for both, 0 for using p_ead */
+)
{
if (dir == 0)
dir = *p_ead;
@@ -1365,16 +1386,17 @@ int dir; /* 'v' for vertically, 'h' for horizontally,
* The window "next_curwin" (if not NULL) should at least get the size from
* 'winheight' and 'winwidth' if possible.
*/
-static void win_equal_rec(next_curwin, current, topfr, dir, col, row, width,
- height)
-win_T *next_curwin; /* pointer to current window to be or NULL */
-int current; /* do only frame with current window */
-frame_T *topfr; /* frame to set size off */
-int dir; /* 'v', 'h' or 'b', see win_equal() */
-int col; /* horizontal position for frame */
-int row; /* vertical position for frame */
-int width; /* new width of frame */
-int height; /* new height of frame */
+static void
+win_equal_rec (
+ win_T *next_curwin, /* pointer to current window to be or NULL */
+ int current, /* do only frame with current window */
+ frame_T *topfr, /* frame to set size off */
+ int dir, /* 'v', 'h' or 'b', see win_equal() */
+ int col, /* horizontal position for frame */
+ int row, /* vertical position for frame */
+ int width, /* new width of frame */
+ int height /* new height of frame */
+)
{
int n, m;
int extra_sep = 0;
@@ -1646,9 +1668,11 @@ int height; /* new height of frame */
/*
* close all windows for buffer 'buf'
*/
-void close_windows(buf, keep_curwin)
-buf_T *buf;
-int keep_curwin; /* don't close "curwin" */
+void
+close_windows (
+ buf_T *buf,
+ int keep_curwin /* don't close "curwin" */
+)
{
win_T *wp;
tabpage_T *tp, *nexttp;
@@ -1697,7 +1721,7 @@ int keep_curwin; /* don't close "curwin" */
* "aucmd_win").
* Returns FALSE if there is a window, possibly in another tab page.
*/
-static int last_window() {
+static int last_window(void) {
return one_window() && first_tabpage->tp_next == NULL;
}
@@ -1705,7 +1729,7 @@ static int last_window() {
* Return TRUE if there is only one window other than "aucmd_win" in the
* current tab page.
*/
-int one_window() {
+int one_window(void) {
win_T *wp;
int seen_one = FALSE;
@@ -1724,10 +1748,7 @@ int one_window() {
* Close the possibly last window in a tab page.
* Returns TRUE when the window was closed already.
*/
-static int close_last_window_tabpage(win, free_buf, prev_curtab)
-win_T *win;
-int free_buf;
-tabpage_T *prev_curtab;
+static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_curtab)
{
if (firstwin == lastwin) {
buf_T *old_curbuf = curbuf;
@@ -1770,9 +1791,7 @@ tabpage_T *prev_curtab;
* Called by :quit, :close, :xit, :wq and findtag().
* Returns FAIL when the window was not closed.
*/
-int win_close(win, free_buf)
-win_T *win;
-int free_buf;
+int win_close(win_T *win, int free_buf)
{
win_T *wp;
int other_buffer = FALSE;
@@ -1941,10 +1960,7 @@ int free_buf;
* Caller must check if buffer is hidden and whether the tabline needs to be
* updated.
*/
-void win_close_othertab(win, free_buf, tp)
-win_T *win;
-int free_buf;
-tabpage_T *tp;
+void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
{
win_T *wp;
int dir;
@@ -1998,10 +2014,12 @@ tabpage_T *tp;
* Free the memory used for a window.
* Returns a pointer to the window that got the freed up space.
*/
-static win_T * win_free_mem(win, dirp, tp)
-win_T *win;
-int *dirp; /* set to 'v' or 'h' for direction if 'ea' */
-tabpage_T *tp; /* tab page "win" is in, NULL for current */
+static win_T *
+win_free_mem (
+ win_T *win,
+ int *dirp, /* set to 'v' or 'h' for direction if 'ea' */
+ tabpage_T *tp /* tab page "win" is in, NULL for current */
+)
{
frame_T *frp;
win_T *wp;
@@ -2021,7 +2039,7 @@ tabpage_T *tp; /* tab page "win" is in, NULL for current */
}
#if defined(EXITFREE) || defined(PROTO)
-void win_free_all() {
+void win_free_all(void) {
int dummy;
while (first_tabpage->tp_next != NULL)
@@ -2042,10 +2060,12 @@ void win_free_all() {
* Remove a window and its frame from the tree of frames.
* Returns a pointer to the window that got the freed up space.
*/
-win_T * winframe_remove(win, dirp, tp)
-win_T *win;
-int *dirp UNUSED; /* set to 'v' or 'h' for direction if 'ea' */
-tabpage_T *tp; /* tab page "win" is in, NULL for current */
+win_T *
+winframe_remove (
+ win_T *win,
+ int *dirp, /* set to 'v' or 'h' for direction if 'ea' */
+ tabpage_T *tp /* tab page "win" is in, NULL for current */
+)
{
frame_T *frp, *frp2, *frp3;
frame_T *frp_close = win->w_frame;
@@ -2181,9 +2201,11 @@ tabpage_T *tp; /* tab page "win" is in, NULL for current */
* This makes opening a window and closing it immediately keep the same window
* layout.
*/
-static frame_T * win_altframe(win, tp)
-win_T *win;
-tabpage_T *tp; /* tab page "win" is in, NULL for current */
+static frame_T *
+win_altframe (
+ win_T *win,
+ tabpage_T *tp /* tab page "win" is in, NULL for current */
+)
{
frame_T *frp;
int b;
@@ -2205,7 +2227,7 @@ tabpage_T *tp; /* tab page "win" is in, NULL for current */
/*
* Return the tabpage that will be used if the current one is closed.
*/
-static tabpage_T * alt_tabpage() {
+static tabpage_T *alt_tabpage(void) {
tabpage_T *tp;
/* Use the next tab page if possible. */
@@ -2221,8 +2243,7 @@ static tabpage_T * alt_tabpage() {
/*
* Find the left-upper window in frame "frp".
*/
-static win_T * frame2win(frp)
-frame_T *frp;
+static win_T *frame2win(frame_T *frp)
{
while (frp->fr_win == NULL)
frp = frp->fr_child;
@@ -2232,9 +2253,7 @@ frame_T *frp;
/*
* Return TRUE if frame "frp" contains window "wp".
*/
-static int frame_has_win(frp, wp)
-frame_T *frp;
-win_T *wp;
+static int frame_has_win(frame_T *frp, win_T *wp)
{
frame_T *p;
@@ -2251,12 +2270,14 @@ win_T *wp;
* Set a new height for a frame. Recursively sets the height for contained
* frames and windows. Caller must take care of positions.
*/
-static void frame_new_height(topfrp, height, topfirst, wfh)
-frame_T *topfrp;
-int height;
-int topfirst; /* resize topmost contained frame first */
-int wfh; /* obey 'winfixheight' when there is a choice;
+static void
+frame_new_height (
+ frame_T *topfrp,
+ int height,
+ int topfirst, /* resize topmost contained frame first */
+ int wfh /* obey 'winfixheight' when there is a choice;
may cause the height not to be set */
+)
{
frame_T *frp;
int extra_lines;
@@ -2338,8 +2359,7 @@ int wfh; /* obey 'winfixheight' when there is a choice;
* Return TRUE if height of frame "frp" should not be changed because of
* the 'winfixheight' option.
*/
-static int frame_fixed_height(frp)
-frame_T *frp;
+static int frame_fixed_height(frame_T *frp)
{
/* frame with one window: fixed height if 'winfixheight' set. */
if (frp->fr_win != NULL)
@@ -2366,8 +2386,7 @@ frame_T *frp;
* Return TRUE if width of frame "frp" should not be changed because of
* the 'winfixwidth' option.
*/
-static int frame_fixed_width(frp)
-frame_T *frp;
+static int frame_fixed_width(frame_T *frp)
{
/* frame with one window: fixed width if 'winfixwidth' set. */
if (frp->fr_win != NULL)
@@ -2394,8 +2413,7 @@ frame_T *frp;
* Add a status line to windows at the bottom of "frp".
* Note: Does not check if there is room!
*/
-static void frame_add_statusline(frp)
-frame_T *frp;
+static void frame_add_statusline(frame_T *frp)
{
win_T *wp;
@@ -2422,12 +2440,14 @@ frame_T *frp;
* Set width of a frame. Handles recursively going through contained frames.
* May remove separator line for windows at the right side (for win_close()).
*/
-static void frame_new_width(topfrp, width, leftfirst, wfw)
-frame_T *topfrp;
-int width;
-int leftfirst; /* resize leftmost contained frame first */
-int wfw; /* obey 'winfixwidth' when there is a choice;
+static void
+frame_new_width (
+ frame_T *topfrp,
+ int width,
+ int leftfirst, /* resize leftmost contained frame first */
+ int wfw /* obey 'winfixwidth' when there is a choice;
may cause the width not to be set */
+)
{
frame_T *frp;
int extra_cols;
@@ -2516,8 +2536,7 @@ int wfw; /* obey 'winfixwidth' when there is a choice;
* Add the vertical separator to windows at the right side of "frp".
* Note: Does not check if there is room!
*/
-static void frame_add_vsep(frp)
-frame_T *frp;
+static void frame_add_vsep(frame_T *frp)
{
win_T *wp;
@@ -2544,8 +2563,7 @@ frame_T *frp;
/*
* Set frame width from the window it contains.
*/
-static void frame_fix_width(wp)
-win_T *wp;
+static void frame_fix_width(win_T *wp)
{
wp->w_frame->fr_width = wp->w_width + wp->w_vsep_width;
}
@@ -2553,8 +2571,7 @@ win_T *wp;
/*
* Set frame height from the window it contains.
*/
-static void frame_fix_height(wp)
-win_T *wp;
+static void frame_fix_height(win_T *wp)
{
wp->w_frame->fr_height = wp->w_height + wp->w_status_height;
}
@@ -2566,9 +2583,7 @@ win_T *wp;
* When "next_curwin" is NOWIN, don't use at least one line for the current
* window.
*/
-static int frame_minheight(topfrp, next_curwin)
-frame_T *topfrp;
-win_T *next_curwin;
+static int frame_minheight(frame_T *topfrp, win_T *next_curwin)
{
frame_T *frp;
int m;
@@ -2608,9 +2623,11 @@ win_T *next_curwin;
* When "next_curwin" is NOWIN, don't use at least one column for the current
* window.
*/
-static int frame_minwidth(topfrp, next_curwin)
-frame_T *topfrp;
-win_T *next_curwin; /* use p_wh and p_wiw for next_curwin */
+static int
+frame_minwidth (
+ frame_T *topfrp,
+ win_T *next_curwin /* use p_wh and p_wiw for next_curwin */
+)
{
frame_T *frp;
int m, n;
@@ -2651,9 +2668,11 @@ win_T *next_curwin; /* use p_wh and p_wiw for next_curwin */
*
* Used by ":bdel" and ":only".
*/
-void close_others(message, forceit)
-int message;
-int forceit; /* always hide all other windows */
+void
+close_others (
+ int message,
+ int forceit /* always hide all other windows */
+)
{
win_T *wp;
win_T *nextwp;
@@ -2702,12 +2721,11 @@ int forceit; /* always hide all other windows */
* Init the current window "curwin".
* Called when a new file is being edited.
*/
-void curwin_init() {
+void curwin_init(void) {
win_init_empty(curwin);
}
-void win_init_empty(wp)
-win_T *wp;
+void win_init_empty(win_T *wp)
{
redraw_win_later(wp, NOT_VALID);
wp->w_lines_valid = 0;
@@ -2733,7 +2751,7 @@ win_T *wp;
* Called from main().
* Return FAIL when something goes wrong (out of memory).
*/
-int win_alloc_first() {
+int win_alloc_first(void) {
if (win_alloc_firstwin(NULL) == FAIL)
return FAIL;
@@ -2750,7 +2768,7 @@ int win_alloc_first() {
* Init "aucmd_win". This can only be done after the first
* window is fully initialized, thus it can't be in win_alloc_first().
*/
-void win_alloc_aucmd_win() {
+void win_alloc_aucmd_win(void) {
aucmd_win = win_alloc(NULL, TRUE);
if (aucmd_win != NULL) {
win_init_some(aucmd_win, curwin);
@@ -2766,8 +2784,7 @@ void win_alloc_aucmd_win() {
* FEAT_WINDOWS).
* Return FAIL when something goes wrong (out of memory).
*/
-static int win_alloc_firstwin(oldwin)
-win_T *oldwin;
+static int win_alloc_firstwin(win_T *oldwin)
{
curwin = win_alloc(NULL, FALSE);
if (oldwin == NULL) {
@@ -2816,7 +2833,7 @@ static void new_frame(win_T *wp) {
/*
* Initialize the window and frame size to the maximum.
*/
-void win_init_size() {
+void win_init_size(void) {
firstwin->w_height = ROWS_AVAIL;
topframe->fr_height = ROWS_AVAIL;
firstwin->w_width = Columns;
@@ -2827,7 +2844,7 @@ void win_init_size() {
* Allocate a new tabpage_T and init the values.
* Returns NULL when out of memory.
*/
-static tabpage_T * alloc_tabpage() {
+static tabpage_T *alloc_tabpage(void) {
tabpage_T *tp;
@@ -2849,8 +2866,7 @@ static tabpage_T * alloc_tabpage() {
return tp;
}
-void free_tabpage(tp)
-tabpage_T *tp;
+void free_tabpage(tabpage_T *tp)
{
int idx;
@@ -2873,8 +2889,7 @@ tabpage_T *tp;
* Otherwise put it just before tab page "after".
* Return FAIL or OK.
*/
-int win_new_tabpage(after)
-int after;
+int win_new_tabpage(int after)
{
tabpage_T *tp = curtab;
tabpage_T *newtp;
@@ -2933,7 +2948,7 @@ int after;
* like with ":split".
* Returns OK if a new tab page was created, FAIL otherwise.
*/
-int may_open_tabpage() {
+int may_open_tabpage(void) {
int n = (cmdmod.tab == 0) ? postponed_split_tab : cmdmod.tab;
if (n != 0) {
@@ -2948,8 +2963,7 @@ int may_open_tabpage() {
* Create up to "maxcount" tabpages with empty windows.
* Returns the number of resulting tab pages.
*/
-int make_tabpages(maxcount)
-int maxcount;
+int make_tabpages(int maxcount)
{
int count = maxcount;
int todo;
@@ -2977,8 +2991,7 @@ int maxcount;
/*
* Return TRUE when "tpc" points to a valid tab page.
*/
-int valid_tabpage(tpc)
-tabpage_T *tpc;
+int valid_tabpage(tabpage_T *tpc)
{
tabpage_T *tp;
@@ -2991,8 +3004,7 @@ tabpage_T *tpc;
/*
* Find tab page "n" (first one is 1). Returns NULL when not found.
*/
-tabpage_T * find_tabpage(n)
-int n;
+tabpage_T *find_tabpage(int n)
{
tabpage_T *tp;
int i = 1;
@@ -3006,8 +3018,7 @@ int n;
* Get index of tab page "tp". First one has index 1.
* When not found returns number of tab pages plus one.
*/
-int tabpage_index(ftp)
-tabpage_T *ftp;
+int tabpage_index(tabpage_T *ftp)
{
int i = 1;
tabpage_T *tp;
@@ -3023,10 +3034,12 @@ tabpage_T *ftp;
* FAIL.
* Careful: When OK is returned need to get a new tab page very very soon!
*/
-static int leave_tabpage(new_curbuf, trigger_leave_autocmds)
-buf_T *new_curbuf UNUSED; /* what is going to be the new curbuf,
+static int
+leave_tabpage (
+ buf_T *new_curbuf, /* what is going to be the new curbuf,
NULL if unknown */
-int trigger_leave_autocmds UNUSED;
+ int trigger_leave_autocmds
+)
{
tabpage_T *tp = curtab;
@@ -3061,12 +3074,7 @@ int trigger_leave_autocmds UNUSED;
* Only trigger *Enter autocommands when trigger_enter_autocmds is TRUE.
* Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
*/
-static void enter_tabpage(tp, old_curbuf, trigger_enter_autocmds,
- trigger_leave_autocmds)
-tabpage_T *tp;
-buf_T *old_curbuf UNUSED;
-int trigger_enter_autocmds UNUSED;
-int trigger_leave_autocmds UNUSED;
+static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_autocmds, int trigger_leave_autocmds)
{
int old_off = tp->tp_firstwin->w_winrow;
win_T *next_prevwin = tp->tp_prevwin;
@@ -3115,8 +3123,7 @@ int trigger_leave_autocmds UNUSED;
* Go to tab page "n". For ":tab N" and "Ngt".
* When "n" is 9999 go to the last tab page.
*/
-void goto_tabpage(n)
-int n;
+void goto_tabpage(int n)
{
tabpage_T *tp;
tabpage_T *ttp;
@@ -3177,10 +3184,7 @@ int n;
* Only trigger *Leave autocommands when trigger_leave_autocmds is TRUE.
* Note: doesn't update the GUI tab.
*/
-void goto_tabpage_tp(tp, trigger_enter_autocmds, trigger_leave_autocmds)
-tabpage_T *tp;
-int trigger_enter_autocmds;
-int trigger_leave_autocmds;
+void goto_tabpage_tp(tabpage_T *tp, int trigger_enter_autocmds, int trigger_leave_autocmds)
{
/* Don't repeat a message in another tab page. */
set_keep_msg(NULL, 0);
@@ -3200,9 +3204,7 @@ int trigger_leave_autocmds;
* Enter window "wp" in tab page "tp".
* Also updates the GUI tab.
*/
-void goto_tabpage_win(tp, wp)
-tabpage_T *tp;
-win_T *wp;
+void goto_tabpage_win(tabpage_T *tp, win_T *wp)
{
goto_tabpage_tp(tp, TRUE, TRUE);
if (curtab == tp && win_valid(wp)) {
@@ -3213,8 +3215,7 @@ win_T *wp;
/*
* Move the current tab page to before tab page "nr".
*/
-void tabpage_move(nr)
-int nr;
+void tabpage_move(int nr)
{
int n = nr;
tabpage_T *tp;
@@ -3257,8 +3258,7 @@ int nr;
* When jumping to another window on the same buffer, adjust its cursor
* position to keep the same Visual area.
*/
-void win_goto(wp)
-win_T *wp;
+void win_goto(win_T *wp)
{
win_T *owp = curwin;
@@ -3290,8 +3290,7 @@ win_T *wp;
/*
* Find the tabpage for window "win".
*/
-tabpage_T * win_find_tabpage(win)
-win_T *win;
+tabpage_T *win_find_tabpage(win_T *win)
{
win_T *wp;
tabpage_T *tp;
@@ -3308,9 +3307,11 @@ win_T *win;
/*
* Move to window above or below "count" times.
*/
-static void win_goto_ver(up, count)
-int up; /* TRUE to go to win above */
-long count;
+static void
+win_goto_ver (
+ int up, /* TRUE to go to win above */
+ long count
+)
{
frame_T *fr;
frame_T *nfr;
@@ -3365,9 +3366,11 @@ end:
/*
* Move to left or right window.
*/
-static void win_goto_hor(left, count)
-int left; /* TRUE to go to left win */
-long count;
+static void
+win_goto_hor (
+ int left, /* TRUE to go to left win */
+ long count
+)
{
frame_T *fr;
frame_T *nfr;
@@ -3422,9 +3425,7 @@ end:
/*
* Make window "wp" the current window.
*/
-void win_enter(wp, undo_sync)
-win_T *wp;
-int undo_sync;
+void win_enter(win_T *wp, int undo_sync)
{
win_enter_ext(wp, undo_sync, FALSE, TRUE, TRUE);
}
@@ -3434,13 +3435,7 @@ int undo_sync;
* Can be called with "curwin_invalid" TRUE, which means that curwin has just
* been closed and isn't valid.
*/
-static void win_enter_ext(wp, undo_sync, curwin_invalid, trigger_enter_autocmds,
- trigger_leave_autocmds)
-win_T *wp;
-int undo_sync;
-int curwin_invalid;
-int trigger_enter_autocmds UNUSED;
-int trigger_leave_autocmds UNUSED;
+static void win_enter_ext(win_T *wp, int undo_sync, int curwin_invalid, int trigger_enter_autocmds, int trigger_leave_autocmds)
{
int other_buffer = FALSE;
@@ -3536,8 +3531,7 @@ int trigger_leave_autocmds UNUSED;
* Jump to the first open window that contains buffer "buf", if one exists.
* Returns a pointer to the window found, otherwise NULL.
*/
-win_T * buf_jump_open_win(buf)
-buf_T *buf;
+win_T *buf_jump_open_win(buf_T *buf)
{
win_T *wp;
@@ -3554,8 +3548,7 @@ buf_T *buf;
* if one exists.
* Returns a pointer to the window found, otherwise NULL.
*/
-win_T * buf_jump_open_tab(buf)
-buf_T *buf;
+win_T *buf_jump_open_tab(buf_T *buf)
{
win_T *wp;
tabpage_T *tp;
@@ -3585,9 +3578,7 @@ buf_T *buf;
* Allocate a window structure and link it in the window list when "hidden" is
* FALSE.
*/
-static win_T * win_alloc(after, hidden)
-win_T *after UNUSED;
-int hidden UNUSED;
+static win_T *win_alloc(win_T *after, int hidden)
{
win_T *new_wp;
@@ -3646,9 +3637,11 @@ int hidden UNUSED;
/*
* Remove window 'wp' from the window list and free the structure.
*/
-static void win_free(wp, tp)
-win_T *wp;
-tabpage_T *tp; /* tab page "win" is in, NULL for current */
+static void
+win_free (
+ win_T *wp,
+ tabpage_T *tp /* tab page "win" is in, NULL for current */
+)
{
int i;
buf_T *buf;
@@ -3712,8 +3705,7 @@ tabpage_T *tp; /* tab page "win" is in, NULL for current */
/*
* Append window "wp" in the window list after window "after".
*/
-void win_append(after, wp)
-win_T *after, *wp;
+void win_append(win_T *after, win_T *wp)
{
win_T *before;
@@ -3737,9 +3729,11 @@ win_T *after, *wp;
/*
* Remove a window from the window list.
*/
-void win_remove(wp, tp)
-win_T *wp;
-tabpage_T *tp; /* tab page "win" is in, NULL for current */
+void
+win_remove (
+ win_T *wp,
+ tabpage_T *tp /* tab page "win" is in, NULL for current */
+)
{
if (wp->w_prev != NULL)
wp->w_prev->w_next = wp->w_next;
@@ -3758,8 +3752,7 @@ tabpage_T *tp; /* tab page "win" is in, NULL for current */
/*
* Append frame "frp" in a frame list after frame "after".
*/
-static void frame_append(after, frp)
-frame_T *after, *frp;
+static void frame_append(frame_T *after, frame_T *frp)
{
frp->fr_next = after->fr_next;
after->fr_next = frp;
@@ -3771,8 +3764,7 @@ frame_T *after, *frp;
/*
* Insert frame "frp" in a frame list before frame "before".
*/
-static void frame_insert(before, frp)
-frame_T *before, *frp;
+static void frame_insert(frame_T *before, frame_T *frp)
{
frp->fr_next = before;
frp->fr_prev = before->fr_prev;
@@ -3786,8 +3778,7 @@ frame_T *before, *frp;
/*
* Remove a frame from a frame list.
*/
-static void frame_remove(frp)
-frame_T *frp;
+static void frame_remove(frame_T *frp)
{
if (frp->fr_prev != NULL)
frp->fr_prev->fr_next = frp->fr_next;
@@ -3802,8 +3793,7 @@ frame_T *frp;
* Allocate w_lines[] for window "wp".
* Return FAIL for failure, OK for success.
*/
-int win_alloc_lines(wp)
-win_T *wp;
+int win_alloc_lines(win_T *wp)
{
wp->w_lines_valid = 0;
wp->w_lines = (wline_T *)alloc_clear((unsigned)(Rows * sizeof(wline_T)));
@@ -3815,8 +3805,7 @@ win_T *wp;
/*
* free lsize arrays for a window
*/
-void win_free_lsize(wp)
-win_T *wp;
+void win_free_lsize(win_T *wp)
{
vim_free(wp->w_lines);
wp->w_lines = NULL;
@@ -3826,7 +3815,7 @@ win_T *wp;
* Called from win_new_shellsize() after Rows changed.
* This only does the current tab page, others must be done when made active.
*/
-void shell_new_rows() {
+void shell_new_rows(void) {
int h = (int)ROWS_AVAIL;
if (firstwin == NULL) /* not initialized yet */
@@ -3849,7 +3838,7 @@ void shell_new_rows() {
/*
* Called from win_new_shellsize() after Columns changed.
*/
-void shell_new_columns() {
+void shell_new_columns(void) {
if (firstwin == NULL) /* not initialized yet */
return;
@@ -3865,8 +3854,7 @@ void shell_new_columns() {
/*
* Save the size of all windows in "gap".
*/
-void win_size_save(gap)
-garray_T *gap;
+void win_size_save(garray_T *gap)
{
win_T *wp;
@@ -3884,8 +3872,7 @@ garray_T *gap;
* Restore window sizes, but only if the number of windows is still the same.
* Does not free the growarray.
*/
-void win_size_restore(gap)
-garray_T *gap;
+void win_size_restore(garray_T *gap)
{
win_T *wp;
int i;
@@ -3906,7 +3893,7 @@ garray_T *gap;
* frames.
* Returns the row just after the last window.
*/
-int win_comp_pos() {
+int win_comp_pos(void) {
int row = tabline_height();
int col = 0;
@@ -3920,10 +3907,7 @@ int win_comp_pos() {
* "*row" and "*col" are the top-left position of the frame. They are updated
* to the bottom-right position plus one.
*/
-static void frame_comp_pos(topfrp, row, col)
-frame_T *topfrp;
-int *row;
-int *col;
+static void frame_comp_pos(frame_T *topfrp, int *row, int *col)
{
win_T *wp;
frame_T *frp;
@@ -3961,8 +3945,7 @@ int *col;
* Set current window height and take care of repositioning other windows to
* fit around it.
*/
-void win_setheight(height)
-int height;
+void win_setheight(int height)
{
win_setheight_win(height, curwin);
}
@@ -3971,9 +3954,7 @@ int height;
* Set the window height of window "win" and take care of repositioning other
* windows to fit around it.
*/
-void win_setheight_win(height, win)
-int height;
-win_T *win;
+void win_setheight_win(int height, win_T *win)
{
int row;
@@ -4018,9 +3999,7 @@ win_T *win;
* Check for the minimal height of the FR_ROW frame.
* At the top level we can also use change the command line height.
*/
-static void frame_setheight(curfrp, height)
-frame_T *curfrp;
-int height;
+static void frame_setheight(frame_T *curfrp, int height)
{
int room; /* total number of lines available */
int take; /* number of lines taken from other windows */
@@ -4168,15 +4147,12 @@ int height;
* Set current window width and take care of repositioning other windows to
* fit around it.
*/
-void win_setwidth(width)
-int width;
+void win_setwidth(int width)
{
win_setwidth_win(width, curwin);
}
-void win_setwidth_win(width, wp)
-int width;
-win_T *wp;
+void win_setwidth_win(int width, win_T *wp)
{
/* Always keep current window at least one column wide, even when
* 'winminwidth' is zero. */
@@ -4202,9 +4178,7 @@ win_T *wp;
*
* Strategy is similar to frame_setheight().
*/
-static void frame_setwidth(curfrp, width)
-frame_T *curfrp;
-int width;
+static void frame_setwidth(frame_T *curfrp, int width)
{
int room; /* total number of lines available */
int take; /* number of lines taken from other windows */
@@ -4328,7 +4302,7 @@ int width;
/*
* Check 'winminheight' for a valid value.
*/
-void win_setminheight() {
+void win_setminheight(void) {
int room;
int first = TRUE;
win_T *wp;
@@ -4352,9 +4326,7 @@ void win_setminheight() {
/*
* Status line of dragwin is dragged "offset" lines down (negative is up).
*/
-void win_drag_status_line(dragwin, offset)
-win_T *dragwin;
-int offset;
+void win_drag_status_line(win_T *dragwin, int offset)
{
frame_T *curfr;
frame_T *fr;
@@ -4468,9 +4440,7 @@ int offset;
/*
* Separator line of dragwin is dragged "offset" lines right (negative is left).
*/
-void win_drag_vsep_line(dragwin, offset)
-win_T *dragwin;
-int offset;
+void win_drag_vsep_line(win_T *dragwin, int offset)
{
frame_T *curfr;
frame_T *fr;
@@ -4562,8 +4532,7 @@ int offset;
/*
* Set wp->w_fraction for the current w_wrow and w_height.
*/
-static void set_fraction(wp)
-win_T *wp;
+static void set_fraction(win_T *wp)
{
wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT
+ FRACTION_MULT / 2) / (long)wp->w_height;
@@ -4574,9 +4543,7 @@ win_T *wp;
* This takes care of the things inside the window, not what happens to the
* window position, the frame or to other windows.
*/
-void win_new_height(wp, height)
-win_T *wp;
-int height;
+void win_new_height(win_T *wp, int height)
{
linenr_T lnum;
int sline, line_size;
@@ -4688,9 +4655,7 @@ int height;
/*
* Set the width of a window.
*/
-void win_new_width(wp, width)
-win_T *wp;
-int width;
+void win_new_width(win_T *wp, int width)
{
wp->w_width = width;
wp->w_lines_valid = 0;
@@ -4704,8 +4669,7 @@ int width;
wp->w_redr_status = TRUE;
}
-void win_comp_scroll(wp)
-win_T *wp;
+void win_comp_scroll(win_T *wp)
{
wp->w_p_scr = ((unsigned)wp->w_height >> 1);
if (wp->w_p_scr == 0)
@@ -4715,7 +4679,7 @@ win_T *wp;
/*
* command_height: called whenever p_ch has been changed
*/
-void command_height() {
+void command_height(void) {
int h;
frame_T *frp;
int old_p_ch = curtab->tp_ch_used;
@@ -4782,9 +4746,7 @@ void command_height() {
* Resize frame "frp" to be "n" lines higher (negative for less high).
* Also resize the frames it is contained in.
*/
-static void frame_add_height(frp, n)
-frame_T *frp;
-int n;
+static void frame_add_height(frame_T *frp, int n)
{
frame_new_height(frp, frp->fr_height + n, FALSE, FALSE);
for (;; ) {
@@ -4799,17 +4761,17 @@ int n;
* Add or remove a status line for the bottom window(s), according to the
* value of 'laststatus'.
*/
-void last_status(morewin)
-int morewin; /* pretend there are two or more windows */
+void
+last_status (
+ int morewin /* pretend there are two or more windows */
+)
{
/* Don't make a difference between horizontal or vertical split. */
last_status_rec(topframe, (p_ls == 2
|| (p_ls == 1 && (morewin || lastwin != firstwin))));
}
-static void last_status_rec(fr, statusline)
-frame_T *fr;
-int statusline;
+static void last_status_rec(frame_T *fr, int statusline)
{
frame_T *fp;
win_T *wp;
@@ -4861,7 +4823,7 @@ int statusline;
/*
* Return the number of lines used by the tab page line.
*/
-int tabline_height() {
+int tabline_height(void) {
switch (p_stal) {
case 0: return 0;
case 1: return (first_tabpage->tp_next == NULL) ? 0 : 1;
@@ -4874,9 +4836,7 @@ int tabline_height() {
* If Visual mode is active, use the selected text if it's in one line.
* Returns the name in allocated memory, NULL for failure.
*/
-char_u * grab_file_name(count, file_lnum)
-long count;
-linenr_T *file_lnum;
+char_u *grab_file_name(long count, linenr_T *file_lnum)
{
if (VIsual_active) {
int len;
@@ -4905,10 +4865,7 @@ linenr_T *file_lnum;
* FNAME_HYP check for hypertext link
* FNAME_INCL apply "includeexpr"
*/
-char_u * file_name_at_cursor(options, count, file_lnum)
-int options;
-long count;
-linenr_T *file_lnum;
+char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum)
{
return file_name_in_line(ml_get_curline(),
curwin->w_cursor.col, options, count, curbuf->b_ffname,
@@ -4919,13 +4876,15 @@ linenr_T *file_lnum;
* Return the name of the file under or after ptr[col].
* Otherwise like file_name_at_cursor().
*/
-char_u * file_name_in_line(line, col, options, count, rel_fname, file_lnum)
-char_u *line;
-int col;
-int options;
-long count;
-char_u *rel_fname; /* file we are searching relative to */
-linenr_T *file_lnum; /* line number after the file name */
+char_u *
+file_name_in_line (
+ char_u *line,
+ int col,
+ int options,
+ long count,
+ char_u *rel_fname, /* file we are searching relative to */
+ linenr_T *file_lnum /* line number after the file name */
+)
{
char_u *ptr;
int len;
@@ -4996,9 +4955,7 @@ linenr_T *file_lnum; /* line number after the file name */
static char_u *eval_includeexpr __ARGS((char_u *ptr, int len));
-static char_u * eval_includeexpr(ptr, len)
-char_u *ptr;
-int len;
+static char_u *eval_includeexpr(char_u *ptr, int len)
{
char_u *res;
@@ -5013,12 +4970,14 @@ int len;
* Return the name of the file ptr[len] in 'path'.
* Otherwise like file_name_at_cursor().
*/
-char_u * find_file_name_in_path(ptr, len, options, count, rel_fname)
-char_u *ptr;
-int len;
-int options;
-long count;
-char_u *rel_fname; /* file we are searching relative to */
+char_u *
+find_file_name_in_path (
+ char_u *ptr,
+ int len,
+ int options,
+ long count,
+ char_u *rel_fname /* file we are searching relative to */
+)
{
char_u *file_name;
int c;
@@ -5076,8 +5035,7 @@ char_u *rel_fname; /* file we are searching relative to */
* Also check for ":\\", which MS Internet Explorer accepts, return
* URL_BACKSLASH.
*/
-static int path_is_url(p)
-char_u *p;
+static int path_is_url(char_u *p)
{
if (STRNCMP(p, "://", (size_t)3) == 0)
return URL_SLASH;
@@ -5091,8 +5049,7 @@ char_u *p;
* Return URL_BACKSLASH for "name:\\".
* Return zero otherwise.
*/
-int path_with_url(fname)
-char_u *fname;
+int path_with_url(char_u *fname)
{
char_u *p;
@@ -5104,8 +5061,7 @@ char_u *fname;
/*
* Return TRUE if "name" is a full (absolute) path name or URL.
*/
-int vim_isAbsName(name)
-char_u *name;
+int vim_isAbsName(char_u *name)
{
return path_with_url(name) != 0 || mch_isFullName(name);
}
@@ -5115,10 +5071,13 @@ char_u *name;
*
* return FAIL for failure, OK otherwise
*/
-int vim_FullName(fname, buf, len, force)
-char_u *fname, *buf;
-int len;
-int force; /* force expansion even when already absolute */
+int
+vim_FullName (
+ char_u *fname,
+ char_u *buf,
+ int len,
+ int force /* force expansion even when already absolute */
+)
{
int retval = OK;
int url;
@@ -5141,7 +5100,7 @@ int force; /* force expansion even when already absolute */
* Return the minimal number of rows that is needed on the screen to display
* the current number of windows.
*/
-int min_rows() {
+int min_rows(void) {
int total;
tabpage_T *tp;
int n;
@@ -5165,7 +5124,7 @@ int min_rows() {
* counting a help or preview window, unless it is the current window.
* Does not count "aucmd_win".
*/
-int only_one_window() {
+int only_one_window(void) {
int count = 0;
win_T *wp;
@@ -5189,8 +5148,7 @@ int only_one_window() {
* current buffer, and before applying autocommands.
* When "do_curwin" is TRUE, also check current window.
*/
-void check_lnums(do_curwin)
-int do_curwin;
+void check_lnums(int do_curwin)
{
win_T *wp;
@@ -5221,16 +5179,13 @@ int do_curwin;
/*
* Create a snapshot of the current frame sizes.
*/
-void make_snapshot(idx)
-int idx;
+void make_snapshot(int idx)
{
clear_snapshot(curtab, idx);
make_snapshot_rec(topframe, &curtab->tp_snapshot[idx]);
}
-static void make_snapshot_rec(fr, frp)
-frame_T *fr;
-frame_T **frp;
+static void make_snapshot_rec(frame_T *fr, frame_T **frp)
{
*frp = (frame_T *)alloc_clear((unsigned)sizeof(frame_T));
if (*frp == NULL)
@@ -5249,16 +5204,13 @@ frame_T **frp;
/*
* Remove any existing snapshot.
*/
-static void clear_snapshot(tp, idx)
-tabpage_T *tp;
-int idx;
+static void clear_snapshot(tabpage_T *tp, int idx)
{
clear_snapshot_rec(tp->tp_snapshot[idx]);
tp->tp_snapshot[idx] = NULL;
}
-static void clear_snapshot_rec(fr)
-frame_T *fr;
+static void clear_snapshot_rec(frame_T *fr)
{
if (fr != NULL) {
clear_snapshot_rec(fr->fr_next);
@@ -5272,9 +5224,11 @@ frame_T *fr;
* This is only done if the screen size didn't change and the window layout is
* still the same.
*/
-void restore_snapshot(idx, close_curwin)
-int idx;
-int close_curwin; /* closing current window */
+void
+restore_snapshot (
+ int idx,
+ int close_curwin /* closing current window */
+)
{
win_T *wp;
@@ -5295,9 +5249,7 @@ int close_curwin; /* closing current window */
* Check if frames "sn" and "fr" have the same layout, same following frames
* and same children.
*/
-static int check_snapshot_rec(sn, fr)
-frame_T *sn;
-frame_T *fr;
+static int check_snapshot_rec(frame_T *sn, frame_T *fr)
{
if (sn->fr_layout != fr->fr_layout
|| (sn->fr_next == NULL) != (fr->fr_next == NULL)
@@ -5315,9 +5267,7 @@ frame_T *fr;
* following frames and children.
* Returns a pointer to the old current window, or NULL.
*/
-static win_T * restore_snapshot_rec(sn, fr)
-frame_T *sn;
-frame_T *fr;
+static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr)
{
win_T *wp = NULL;
win_T *wp2;
@@ -5353,12 +5303,7 @@ frame_T *fr;
* triggered, another tabpage access is limited.
* Returns FAIL if switching to "win" failed.
*/
-int switch_win(save_curwin, save_curtab, win, tp, no_display)
-win_T **save_curwin UNUSED;
-tabpage_T **save_curtab UNUSED;
-win_T *win UNUSED;
-tabpage_T *tp UNUSED;
-int no_display UNUSED;
+int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display)
{
block_autocmds();
*save_curwin = curwin;
@@ -5387,10 +5332,7 @@ int no_display UNUSED;
* When "no_display" is TRUE the display won't be affected, no redraw is
* triggered.
*/
-void restore_win(save_curwin, save_curtab, no_display)
-win_T *save_curwin UNUSED;
-tabpage_T *save_curtab UNUSED;
-int no_display UNUSED;
+void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
{
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
if (no_display) {
@@ -5413,9 +5355,7 @@ int no_display UNUSED;
* Make "buf" the current buffer. restore_buffer() MUST be called to undo.
* No autocommands will be executed. Use aucmd_prepbuf() if there are any.
*/
-void switch_buffer(save_curbuf, buf)
-buf_T *buf;
-buf_T **save_curbuf;
+void switch_buffer(buf_T **save_curbuf, buf_T *buf)
{
block_autocmds();
*save_curbuf = curbuf;
@@ -5428,8 +5368,7 @@ buf_T **save_curbuf;
/*
* Restore the current buffer after using switch_buffer().
*/
-void restore_buffer(save_curbuf)
-buf_T *save_curbuf;
+void restore_buffer(buf_T *save_curbuf)
{
unblock_autocmds();
/* Check for valid buffer, just in case. */
@@ -5450,12 +5389,7 @@ buf_T *save_curbuf;
* If no particular ID is desired, -1 must be specified for 'id'.
* Return ID of added match, -1 on failure.
*/
-int match_add(wp, grp, pat, prio, id)
-win_T *wp;
-char_u *grp;
-char_u *pat;
-int prio;
-int id;
+int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id)
{
matchitem_T *cur;
matchitem_T *prev;
@@ -5530,10 +5464,7 @@ int id;
* Delete match with ID 'id' in the match list of window 'wp'.
* Print error messages if 'perr' is TRUE.
*/
-int match_delete(wp, id, perr)
-win_T *wp;
-int id;
-int perr;
+int match_delete(win_T *wp, int id, int perr)
{
matchitem_T *cur = wp->w_match_head;
matchitem_T *prev = cur;
@@ -5567,8 +5498,7 @@ int perr;
/*
* Delete all matches in the match list of window 'wp'.
*/
-void clear_matches(wp)
-win_T *wp;
+void clear_matches(win_T *wp)
{
matchitem_T *m;
@@ -5586,9 +5516,7 @@ win_T *wp;
* Get match from ID 'id' in window 'wp'.
* Return NULL if match not found.
*/
-matchitem_T * get_match(wp, id)
-win_T *wp;
-int id;
+matchitem_T *get_match(win_T *wp, int id)
{
matchitem_T *cur = wp->w_match_head;
@@ -5601,9 +5529,7 @@ int id;
/*
* Return TRUE if "topfrp" and its children are at the right height.
*/
-static int frame_check_height(topfrp, height)
-frame_T *topfrp;
-int height;
+static int frame_check_height(frame_T *topfrp, int height)
{
frame_T *frp;
@@ -5621,9 +5547,7 @@ int height;
/*
* Return TRUE if "topfrp" and its children are at the right width.
*/
-static int frame_check_width(topfrp, width)
-frame_T *topfrp;
-int width;
+static int frame_check_width(frame_T *topfrp, int width)
{
frame_T *frp;
diff --git a/src/proto/window.pro b/src/window.h
index bf82ca1982..1fa7c302fd 100644
--- a/src/proto/window.pro
+++ b/src/window.h
@@ -1,3 +1,5 @@
+#ifndef NEOVIM_WINDOW_H
+#define NEOVIM_WINDOW_H
/* window.c */
void do_window __ARGS((int nchar, long Prenum, int xchar));
int win_split __ARGS((int size, int flags));
@@ -91,3 +93,4 @@ matchitem_T *get_match __ARGS((win_T *wp, int id));
int get_win_number __ARGS((win_T *wp, win_T *first_win));
int get_tab_number __ARGS((tabpage_T *tp));
/* vim: set ft=c : */
+#endif /* NEOVIM_WINDOW_H */
diff --git a/third-party/README.md b/third-party/README.md
new file mode 100644
index 0000000000..0d4c521e87
--- /dev/null
+++ b/third-party/README.md
@@ -0,0 +1,9 @@
+# Third party dependencies for neovim
+
+This directory contains any third party dependencies for neovim which, for one
+reason or another, we cannot rely on the system to supply.
+
+Ideally commits within this directory will only be merge commits from upstream
+projects. The "git subtree" tool is a good choice for managing such merge
+commits. In order to avoid needlessly inflating the bandwidth required to clone
+neovim, the ``--squash`` option for git subtree should be used.
diff --git a/third-party/libuv/.gitignore b/third-party/libuv/.gitignore
new file mode 100644
index 0000000000..d11c90bbf0
--- /dev/null
+++ b/third-party/libuv/.gitignore
@@ -0,0 +1,62 @@
+*.swp
+*.[oa]
+*.l[oa]
+*.opensdf
+*.orig
+*.pyc
+*.sdf
+*.suo
+core
+vgcore.*
+.buildstamp
+.dirstamp
+.deps/
+/.libs/
+/aclocal.m4
+/ar-lib
+/autom4te.cache/
+/compile
+/config.guess
+/config.log
+/config.status
+/config.sub
+/configure
+/depcomp
+/install-sh
+/libtool
+/libuv.a
+/libuv.dylib
+/libuv.pc
+/libuv.so
+/ltmain.sh
+/missing
+/test-driver
+Makefile
+Makefile.in
+
+# Generated by dtrace(1) when doing an in-tree build.
+/include/uv-dtrace.h
+
+# Generated by gyp for android
+*.target.mk
+
+/out/
+/build/gyp
+
+/run-tests
+/run-tests.exe
+/run-tests.dSYM
+/run-benchmarks
+/run-benchmarks.exe
+/run-benchmarks.dSYM
+
+*.sln
+*.vcproj
+*.vcxproj
+*.vcxproj.filters
+*.vcxproj.user
+_UpgradeReport_Files/
+UpgradeLog*.XML
+Debug
+Release
+ipch
diff --git a/third-party/libuv/.mailmap b/third-party/libuv/.mailmap
new file mode 100644
index 0000000000..0f1d843ce8
--- /dev/null
+++ b/third-party/libuv/.mailmap
@@ -0,0 +1,24 @@
+Alan Gutierrez <alan@prettyrobots.com> <alan@blogometer.com>
+Andrius Bentkus <andrius.bentkus@gmail.com> <toxedvirus@gmail.com>
+Bert Belder <bertbelder@gmail.com> <info@2bs.nl>
+Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
+Brandon Philips <brandon.philips@rackspace.com> <brandon@ifup.org>
+Brian White <mscdex@mscdex.net>
+Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Frank Denis <github@pureftpd.org>
+Isaac Z. Schlueter <i@izs.me>
+Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
+Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
+Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
+Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
+Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
+Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
+Ryan Emery <seebees@gmail.com>
+San-Tai Hsu <vanilla@fatpipi.com>
+Saúl Ibarra Corretgé <saghul@gmail.com>
+Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
+Timothy J. Fontaine <tjfontaine@gmail.com>
+Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
+Yuki Okumura <mjt@cltn.org>
diff --git a/third-party/libuv/AUTHORS b/third-party/libuv/AUTHORS
new file mode 100644
index 0000000000..6633f0651e
--- /dev/null
+++ b/third-party/libuv/AUTHORS
@@ -0,0 +1,114 @@
+# Authors ordered by first contribution.
+Ryan Dahl <ryan@joyent.com>
+Bert Belder <bertbelder@gmail.com>
+Josh Roesslein <jroesslein@gmail.com>
+Alan Gutierrez <alan@prettyrobots.com>
+Joshua Peek <josh@joshpeek.com>
+Igor Zinkovsky <igorzi@microsoft.com>
+San-Tai Hsu <vanilla@fatpipi.com>
+Ben Noordhuis <info@bnoordhuis.nl>
+Henry Rawas <henryr@schakra.com>
+Robert Mustacchi <rm@joyent.com>
+Matt Stevens <matt@alloysoft.com>
+Paul Querna <pquerna@apache.org>
+Shigeki Ohtsu <ohtsu@iij.ad.jp>
+Tom Hughes <tom.hughes@palm.com>
+Peter Bright <drpizza@quiscalusmexicanus.org>
+Jeroen Janssen <jeroen.janssen@gmail.com>
+Andrea Lattuada <ndr.lattuada@gmail.com>
+Augusto Henrique Hentz <ahhentz@gmail.com>
+Clifford Heath <clifford.heath@gmail.com>
+Jorge Chamorro Bieling <jorge@jorgechamorro.com>
+Luis Lavena <luislavena@gmail.com>
+Matthew Sporleder <msporleder@gmail.com>
+Erick Tryzelaar <erick.tryzelaar@gmail.com>
+Isaac Z. Schlueter <i@izs.me>
+Pieter Noordhuis <pcnoordhuis@gmail.com>
+Marek Jelen <marek@jelen.biz>
+Fedor Indutny <fedor.indutny@gmail.com>
+Saúl Ibarra Corretgé <saghul@gmail.com>
+Felix Geisendörfer <felix@debuggable.com>
+Yuki Okumura <mjt@cltn.org>
+Roman Shtylman <shtylman@gmail.com>
+Frank Denis <github@pureftpd.org>
+Carter Allen <CarterA@opt-6.com>
+Tj Holowaychuk <tj@vision-media.ca>
+Shimon Doodkin <helpmepro1@gmail.com>
+Ryan Emery <seebees@gmail.com>
+Bruce Mitchener <bruce.mitchener@gmail.com>
+Maciej Małecki <maciej.malecki@notimplemented.org>
+Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Daisuke Murase <typester@cpan.org>
+Paddy Byers <paddy.byers@gmail.com>
+Dan VerWeire <dverweire@gmail.com>
+Brandon Benvie <brandon@bbenvie.com>
+Brandon Philips <brandon.philips@rackspace.com>
+Nathan Rajlich <nathan@tootallnate.net>
+Charlie McConnell <charlie@charlieistheman.com>
+Vladimir Dronnikov <dronnikov@gmail.com>
+Aaron Bieber <qbit@deftly.net>
+Bulat Shakirzyanov <mallluhuct@gmail.com>
+Brian White <mscdex@mscdex.net>
+Erik Dubbelboer <erik@dubbelboer.com>
+Keno Fischer <kenof@stanford.edu>
+Ira Cooper <Ira.Cooper@mathworks.com>
+Andrius Bentkus <andrius.bentkus@gmail.com>
+Iñaki Baz Castillo <ibc@aliax.net>
+Mark Cavage <mark.cavage@joyent.com>
+George Yohng <georgegh@oss3d.com>
+Xidorn Quan <quanxunzhen@gmail.com>
+Roman Neuhauser <rneuhauser@suse.cz>
+Shuhei Tanuma <shuhei.tanuma@gmail.com>
+Bryan Cantrill <bcantrill@acm.org>
+Trond Norbye <trond.norbye@gmail.com>
+Tim Holy <holy@wustl.edu>
+Prancesco Pertugio <meh@schizofreni.co>
+Leonard Hecker <leonard.hecker91@gmail.com>
+Andrew Paprocki <andrew@ishiboo.com>
+Luigi Grilli <luigi.grilli@gmail.com>
+Shannen Saez <shannenlaptop@gmail.com>
+Artur Adib <arturadib@gmail.com>
+Hiroaki Nakamura <hnakamur@gmail.com>
+Ting-Yu Lin <ph.minamo@cytisan.com>
+Stephen Gallagher <sgallagh@redhat.com>
+Shane Holloway <shane.holloway@ieee.org>
+Andrew Shaffer <darawk@gmail.com>
+Vlad Tudose <vlad.tudose@intel.com>
+Ben Leslie <benno@benno.id.au>
+Tim Bradshaw <tfb@cley.com>
+Timothy J. Fontaine <tjfontaine@gmail.com>
+Marc Schlaich <marc.schlaich@googlemail.com>
+Brian Mazza <louseman@gmail.com>
+Elliot Saba <staticfloat@gmail.com>
+Ben Kelly <ben@wanderview.com>
+Kristian Evensen <kristian.evensen@gmail.com>
+Nils Maier <maierman@web.de>
+Nicholas Vavilov <vvnicholas@gmail.com>
+Miroslav Bajtoš <miro.bajtos@gmail.com>
+Sean Silva <chisophugis@gmail.com>
+Wynn Wilkes <wynnw@movenetworks.com>
+Linus MÃ¥rtensson <linus.martensson@sonymobile.com>
+Andrei Sedoi <bsnote@gmail.com>
+Navaneeth Kedaram Nambiathan <navaneethkn@gmail.com>
+Alex Crichton <alex@alexcrichton.com>
+Brent Cook <brent@boundary.com>
+Brian Kaisner <bkize1@gmail.com>
+Luca Bruno <lucab@debian.org>
+Reini Urban <rurban@cpanel.net>
+Maks Naumov <maksqwe1@ukr.net>
+Sean Farrell <sean.farrell@rioki.org>
+Chris Bank <cbank@adobe.com>
+Geert Jansen <geertj@gmail.com>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+huxingyi <huxingyi@msn.com>
+Tenor Biel <tenorbiel@gmail.com>
+Andrej Manduch <AManduch@gmail.com>
+Joshua Neuheisel <joshua@neuheisel.us>
+Alexis Campailla <alexis@janeasystems.com>
+Yazhong Liu <yorkiefixer@gmail.com>
+Sam Roberts <vieuxtech@gmail.com>
+River Tarnell <river@loreley.flyingparchment.org.uk>
+Nathan Sweet <nathanjsweet@gmail.com>
+Trevor Norris <trev.norris@gmail.com>
diff --git a/third-party/libuv/CONTRIBUTING.md b/third-party/libuv/CONTRIBUTING.md
new file mode 100644
index 0000000000..960a9450ae
--- /dev/null
+++ b/third-party/libuv/CONTRIBUTING.md
@@ -0,0 +1,177 @@
+# CONTRIBUTING
+
+The libuv project welcomes new contributors. This document will guide you
+through the process.
+
+
+### FORK
+
+Fork the project [on GitHub](https://github.com/joyent/libuv) and check out
+your copy.
+
+```
+$ git clone https://github.com/username/libuv.git
+$ cd libuv
+$ git remote add upstream https://github.com/joyent/libuv.git
+```
+
+Now decide if you want your feature or bug fix to go into the master branch
+or the stable branch. As a rule of thumb, bug fixes go into the stable branch
+while new features go into the master branch.
+
+The stable branch is effectively frozen; patches that change the libuv
+API/ABI or affect the run-time behavior of applications get rejected.
+
+In case of doubt, open an issue in the [issue tracker][], post your question
+to the [libuv mailing list], or contact one of project maintainers
+(@bnoordhuis, @piscisaureus, @indutny or @saghul) on [IRC][].
+
+Especially do so if you plan to work on something big. Nothing is more
+frustrating than seeing your hard work go to waste because your vision
+does not align with that of a project maintainers.
+
+
+### BRANCH
+
+Okay, so you have decided on the proper branch. Create a feature branch
+and start hacking:
+
+```
+$ git checkout -b my-feature-branch -t origin/v0.10
+```
+
+(Where v0.10 is the latest stable branch as of this writing.)
+
+### CODE
+
+Please adhere to libuv's code style. In general it follows the conventions from
+the [Google C/C++ style guide]. Some of the key points, as well as some
+additional guidelines, are enumerated below.
+
+* Code that is specific to unix-y platforms should be placed in `src/unix`, and
+ declarations go into `src/uv-unix.h`.
+
+* Source code that is Windows-specific goes into `src/win`, and related
+ publicly exported types, functions and macro declarations should generally
+ be declared in `include/uv-win.h`.
+
+* Names should be descriptive and concise.
+
+* All the symbols and types that libuv makes available publicly should be
+ prefixed with `uv_` (or `UV_` in case of macros).
+
+* Internal, non-static functions should be prefixed with `uv__`.
+
+* Use two spaces and no tabs.
+
+* Lines should be wrapped at 80 characters.
+
+* Ensure that lines have no trailing whitespace, and use unix-style (LF) line
+ endings.
+
+* Use C89-compliant syntax. In other words, variables can only be declared at
+ the top of a scope (function, if/for/while-block).
+
+* When writing comments, use properly constructed sentences, including
+ punctuation.
+
+* When documenting APIs and/or source code, don't make assumptions or make
+ implications about race, gender, religion, political orientation or anything
+ else that isn't relevant to the project.
+
+* Remember that source code usually gets written once and read often: ensure
+ the reader doesn't have to make guesses. Make sure that the purpose and inner
+ logic are either obvious to a reasonably skilled professional, or add a
+ comment that explains it.
+
+
+### COMMIT
+
+Make sure git knows your name and email address:
+
+```
+$ git config --global user.name "J. Random User"
+$ git config --global user.email "j.random.user@example.com"
+```
+
+Writing good commit logs is important. A commit log should describe what
+changed and why. Follow these guidelines when writing one:
+
+1. The first line should be 50 characters or less and contain a short
+ description of the change prefixed with the name of the changed
+ subsystem (e.g. "net: add localAddress and localPort to Socket").
+2. Keep the second line blank.
+3. Wrap all other lines at 72 columns.
+
+A good commit log looks like this:
+
+```
+subsystem: explaining the commit in one line
+
+Body of commit message is a few lines of text, explaining things
+in more detail, possibly giving some background about the issue
+being fixed, etc etc.
+
+The body of the commit message can be several paragraphs, and
+please do proper word-wrap and keep columns shorter than about
+72 characters or so. That way `git log` will show things
+nicely even when it is indented.
+```
+
+The header line should be meaningful; it is what other people see when they
+run `git shortlog` or `git log --oneline`.
+
+Check the output of `git log --oneline files_that_you_changed` to find out
+what subsystem (or subsystems) your changes touch.
+
+
+### REBASE
+
+Use `git rebase` (not `git merge`) to sync your work from time to time.
+
+```
+$ git fetch upstream
+$ git rebase upstream/v0.10 # or upstream/master
+```
+
+
+### TEST
+
+Bug fixes and features should come with tests. Add your tests in the
+`test/` directory. Tests also need to be registered in `test/test-list.h`.
+Look at other tests to see how they should be structured (license boilerplate,
+the way entry points are declared, etc.).
+
+```
+$ make test
+```
+
+Make sure that there are no test regressions.
+
+### PUSH
+
+```
+$ git push origin my-feature-branch
+```
+
+Go to https://github.com/username/libuv and select your feature branch. Click
+the 'Pull Request' button and fill out the form.
+
+Pull requests are usually reviewed within a few days. If there are comments
+to address, apply your changes in a separate commit and push that to your
+feature branch. Post a comment in the pull request afterwards; GitHub does
+not send out notifications when you add commits.
+
+
+### CONTRIBUTOR LICENSE AGREEMENT
+
+The current state of affairs is that, in order to get a patch accepted, you need
+to sign Node.js's [contributor license agreement][]. You only need to do that
+once.
+
+
+[issue tracker]: https://github.com/joyent/libuv/issues
+[libuv mailing list]: http://groups.google.com/group/libuv
+[IRC]: http://webchat.freelibuv.net/?channels=libuv
+[Google C/C++ style guide]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
+[contributor license agreement]: http://nodejs.org/cla.html
diff --git a/third-party/libuv/ChangeLog b/third-party/libuv/ChangeLog
new file mode 100644
index 0000000000..ad3cbb504c
--- /dev/null
+++ b/third-party/libuv/ChangeLog
@@ -0,0 +1,1012 @@
+2014.01.30, Version 0.11.19 (Unstable)
+
+Changes since version 0.11.18:
+
+* linux: move sscanf() out of the assert() (Trevor Norris)
+
+* linux: fix C99/C++ comment (Fedor Indutny)
+
+
+2014.01.23, Version 0.11.18 (Unstable), d47962e9d93d4a55a9984623feaf546406c9cdbb
+
+Changes since version 0.11.17:
+
+* osx: Fix a possible segfault in uv__io_poll (Alex Crichton)
+
+* windows: improved handling of invalid FDs (Alexis Campailla)
+
+* doc: adding ARCHS flag to OS X build command (Nathan Sweet)
+
+* tcp: reveal bind-time errors before listen (Alexis Campailla)
+
+* tcp: uv_tcp_dualstack() (Fedor Indutny)
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+* linux: move sscanf() out of the assert() (Trevor Norris)
+
+
+2014.01.23, Version 0.10.23 (Stable), dbd218e699fec8be311d85e4788be9e28ae884f8
+
+Changes since version 0.10.22:
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+
+2014.01.08, Version 0.10.22 (Stable), f526c90eeff271d9323a9107b9a64a4671fd3103
+
+Changes since version 0.10.21:
+
+* windows: avoid assertion failure when pipe server is closed (Bert Belder)
+
+
+2013.12.32, Version 0.11.17 (Unstable), 589c224d4c2e79fec65db01d361948f1e4976858
+
+Changes since version 0.11.16:
+
+* stream: allow multiple buffers for uv_try_write (Fedor Indutny)
+
+* unix: fix a possible memory leak in uv_fs_readdir (Alex Crichton)
+
+* unix, windows: add uv_loop_alive() function (Sam Roberts)
+
+* windows: avoid assertion failure when pipe server is closed (Bert Belder)
+
+* osx: Fix a possible segfault in uv__io_poll (Alex Crichton)
+
+* stream: fix uv__stream_osx_select (Fedor Indutny)
+
+
+2013.12.14, Version 0.11.16 (Unstable), ae0ed8c49d0d313c935c22077511148b6e8408a4
+
+Changes since version 0.11.15:
+
+* fsevents: remove kFSEventStreamCreateFlagNoDefer polyfill (ci-innoq)
+
+* libuv: add more getaddrinfo errors (Steven Kabbes)
+
+* unix: fix accept() EMFILE error handling (Ben Noordhuis)
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fsevents: fix subfolder check (Fedor Indutny)
+
+* fsevents: fix invalid memory access (huxingyi)
+
+* windows/timer: fix uv_hrtime discontinuity (Bert Belder)
+
+* unix: fix various memory leaks and undef behavior (Fedor Indutny)
+
+* unix, windows: always update loop time (Saúl Ibarra Corretgé)
+
+* windows: translate system errors in uv_spawn (Alexis Campailla)
+
+* windows: uv_spawn code refactor (Alexis Campailla)
+
+* unix, windows: detect errors in uv_ip4/6_addr (Yorkie)
+
+* stream: introduce uv_try_write(...) (Fedor Indutny)
+
+
+2013.12.13, Version 0.10.20 (Stable), 04141464dd0fba90ace9aa6f7003ce139b888a40
+
+Changes since version 0.10.19:
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fs-event: fix invalid memory access (huxingyi)
+
+
+2013.11.21, Version 0.11.15 (Unstable), bfe645ed7e99ca5670d9279ad472b604c129d2e5
+
+Changes since version 0.11.14:
+
+* fsevents: report errors to user (Fedor Indutny)
+
+* include: UV_FS_EVENT_RECURSIVE is a flag (Fedor Indutny)
+
+* linux: use CLOCK_MONOTONIC_COARSE if available (Ben Noordhuis)
+
+* build: make systemtap probes work with gyp build (Ben Noordhuis)
+
+* unix: update events from pevents between polls (Fedor Indutny)
+
+* fsevents: support japaneese characters in path (Chris Bank)
+
+* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis)
+
+* queue: strengthen type checks (Ben Noordhuis)
+
+* include: remove uv_strlcat() and uv_strlcpy() (Ben Noordhuis)
+
+* build: fix windows smp build with gyp (Geert Jansen)
+
+* unix: return exec errors from uv_spawn, not async (Alex Crichton)
+
+* fsevents: use native character encoding file paths (Ben Noordhuis)
+
+* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis)
+
+* windows: use _snwprintf(), not swprintf() (Ben Noordhuis)
+
+* fsevents: use FlagNoDefer for FSEventStreamCreate (Fedor Indutny)
+
+* unix: fix reopened fd bug (Fedor Indutny)
+
+* core: fix fake watcher list and count preservation (Fedor Indutny)
+
+* unix: set close-on-exec flag on received fds (Ben Noordhuis)
+
+* netbsd, openbsd: enable futimes() wrapper (Ben Noordhuis)
+
+* unix: nicer error message when kqueue() fails (Ben Noordhuis)
+
+* samples: add socks5 proxy sample application (Ben Noordhuis)
+
+
+2013.11.13, Version 0.10.19 (Stable), 33959f7524090b8d2c6c41e2400ca77e31755059
+
+Changes since version 0.10.18:
+
+* darwin: avoid calling GetCurrentProcess (Fedor Indutny)
+
+* unix: update events from pevents between polls (Fedor Indutny)
+
+* fsevents: support japaneese characters in path (Chris Bank)
+
+* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis)
+
+* build: fix windows smp build with gyp (Geert Jansen)
+
+* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis)
+
+* unix: fix reopened fd bug (Fedor Indutny)
+
+* core: fix fake watcher list and count preservation (Fedor Indutny)
+
+
+2013.10.30, Version 0.11.14 (Unstable), d7a6482f45c1b4eb4a853dbe1a9ce8090a35633a
+
+Changes since version 0.11.13:
+
+* darwin: create fsevents thread on demand (Ben Noordhuis)
+
+* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny)
+
+* fsevents: use shared FSEventStream (Fedor Indutny)
+
+* windows: make uv_fs_chmod() report errors correctly (Bert Belder)
+
+* windows: make uv_shutdown() for write-only pipes work (Bert Belder)
+
+* windows/fs: wrap multi-statement macros in do..while block (Bert Belder)
+
+* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder)
+
+* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder)
+
+* windows/fs: wrap multi-statement macros in do..while block (Bert Belder)
+
+* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder)
+
+* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder)
+
+* build: clarify instructions for Windows (Brian Kaisner)
+
+* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis)
+
+* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis)
+
+* windows: run close callbacks after polling for i/o (Saúl Ibarra Corretgé)
+
+* include: clarify uv_tcp_bind() behavior (Ben Noordhuis)
+
+* include: clean up includes in uv.h (Ben Noordhuis)
+
+* include: remove UV_IO_PRIVATE_FIELDS macro (Ben Noordhuis)
+
+* include: fix typo in comment in uv.h (Ben Noordhuis)
+
+* include: update uv_is_active() documentation (Ben Noordhuis)
+
+* include: make uv_process_options_t.cwd const (Ben Noordhuis)
+
+* unix: wrap long lines at 80 columns (Ben Noordhuis)
+
+* unix, windows: make uv_is_*() always return 0 or 1 (Ben Noordhuis)
+
+* bench: measure total/init/dispatch/cleanup times (Ben Noordhuis)
+
+* build: use -pthread on sunos (Timothy J. Fontaine)
+
+* windows: remove duplicate check in stream.c (Ben Noordhuis)
+
+* unix: sanity-check fds before closing (Ben Noordhuis)
+
+* unix: remove uv__pipe_accept() (Ben Noordhuis)
+
+* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis)
+
+* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis)
+
+* unix: revert recent FSEvent changes (Ben Noordhuis)
+
+* fsevents: fix clever rescheduling (Fedor Indutny)
+
+* linux: ignore fractional time in uv_uptime() (Ben Noordhuis)
+
+* unix: fix SIGCHLD waitpid() race in process.c (Ben Noordhuis)
+
+* unix, windows: add uv_fs_event_start/stop functions (Saúl Ibarra Corretgé)
+
+* unix: fix non-synchronized access in signal.c (Ben Noordhuis)
+
+* unix: add atomic-ops.h (Ben Noordhuis)
+
+* unix: add spinlock.h (Ben Noordhuis)
+
+* unix: clean up uv_tty_set_mode() a little (Ben Noordhuis)
+
+* unix: make uv_tty_reset_mode() async signal-safe (Ben Noordhuis)
+
+* include: add E2BIG status code mapping (Ben Noordhuis)
+
+* windows: fix duplicate case build error (Ben Noordhuis)
+
+* windows: remove unneeded check (Saúl Ibarra Corretgé)
+
+* include: document pipe path truncation behavior (Ben Noordhuis)
+
+* fsevents: increase stack size for OSX 10.9 (Fedor Indutny)
+
+* windows: _snprintf expected wrong parameter type in string (Maks Naumov)
+
+* windows: "else" keyword is missing (Maks Naumov)
+
+* windows: incorrect check for SOCKET_ERROR (Maks Naumov)
+
+* windows: add stdlib.h to satisfy reference to abort (Sean Farrell)
+
+* build: fix check target for mingw (Sean Farrell)
+
+* unix: move uv_shutdown() assertion (Keno Fischer)
+
+* darwin: avoid calling GetCurrentProcess (Fedor Indutny)
+
+
+2013.10.19, Version 0.10.18 (Stable), 9ec52963b585e822e87bdc5de28d6143aff0d2e5
+
+Changes since version 0.10.17:
+
+* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis)
+
+* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis)
+
+* unix: revert recent FSEvent changes (Ben Noordhuis)
+
+* unix: fix non-synchronized access in signal.c (Ben Noordhuis)
+
+
+2013.09.25, Version 0.10.17 (Stable), 9670e0a93540c2f0d86c84a375f2303383c11e7e
+
+Changes since version 0.10.16:
+
+* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis)
+
+* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis)
+
+
+2013.09.06, Version 0.10.16 (Stable), 2bce230d81f4853a23662cbeb26fe98010b1084b
+
+Changes since version 0.10.15:
+
+* windows: make uv_shutdown() for write-only pipes work (Bert Belder)
+
+* windows: make uv_fs_open() report EINVAL when invalid arguments are passed
+ (Bert Belder)
+
+* windows: make uv_fs_open() report _open_osfhandle() failure correctly (Bert
+ Belder)
+
+* windows: make uv_fs_chmod() report errors correctly (Bert Belder)
+
+* windows: wrap multi-statement macros in do..while block (Bert Belder)
+
+
+2013.09.05, Version 0.11.13 (Unstable), f5b6db6c1d7f93d28281207fd47c3841c9a9792e
+
+Changes since version 0.11.12:
+
+* unix: define _GNU_SOURCE, exposes glibc-isms (Ben Noordhuis)
+
+* windows: check for nonconforming swprintf arguments (Brent Cook)
+
+* build: include internal headers in source list (Brent Cook)
+
+* include: merge uv_tcp_bind and uv_tcp_bind6 (Ben Noordhuis)
+
+* include: merge uv_tcp_connect and uv_tcp_connect6 (Ben Noordhuis)
+
+* include: merge uv_udp_bind and uv_udp_bind6 (Ben Noordhuis)
+
+* include: merge uv_udp_send and uv_udp_send6 (Ben Noordhuis)
+
+
+2013.09.03, Version 0.11.12 (Unstable), 82d01d5f6780d178f5176a01425ec297583c0811
+
+Changes since version 0.11.11:
+
+* test: fix epoll_wait() usage in test-embed.c (Ben Noordhuis)
+
+* include: uv_alloc_cb now takes uv_buf_t* (Ben Noordhuis)
+
+* include: uv_read{2}_cb now takes const uv_buf_t* (Ben Noordhuis)
+
+* include: uv_ip[46]_addr now takes sockaddr_in* (Ben Noordhuis)
+
+* include: uv_tcp_bind{6} now takes sockaddr_in* (Ben Noordhuis)
+
+* include: uv_tcp_connect{6} now takes sockaddr_in* (Ben Noordhuis)
+
+* include: uv_udp_recv_cb now takes const uv_buf_t* (Ben Noordhuis)
+
+* include: uv_udp_bind{6} now takes sockaddr_in* (Ben Noordhuis)
+
+* include: uv_udp_send{6} now takes sockaddr_in* (Ben Noordhuis)
+
+* include: uv_spawn takes const uv_process_options_t* (Ben Noordhuis)
+
+* include: make uv_write{2} const correct (Ben Noordhuis)
+
+* windows: fix flags assignment in uv_fs_readdir() (Ben Noordhuis)
+
+* windows: fix stray comments (Ben Noordhuis)
+
+* windows: remove unused is_path_dir() function (Ben Noordhuis)
+
+
+2013.08.30, Version 0.11.11 (Unstable), ba876d53539ed0427c52039012419cd9374c6f0d
+
+Changes since version 0.11.10:
+
+* unix, windows: add thread-local storage API (Ben Noordhuis)
+
+* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis)
+
+* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis)
+
+* windows: make uv_shutdown() for write-only pipes work (Bert Belder)
+
+* include: update uv_udp_open() / uv_udp_bind() docs (Ben Noordhuis)
+
+* unix: req queue must be empty when destroying loop (Ben Noordhuis)
+
+* unix: move loop functions from core.c to loop.c (Ben Noordhuis)
+
+* darwin: remove CoreFoundation dependency (Ben Noordhuis)
+
+* windows: make autotools build system work with mingw (Keno Fischer)
+
+* windows: fix mingw build (Alex Crichton)
+
+* windows: tweak Makefile.mingw for easier usage (Alex Crichton)
+
+* build: remove _GNU_SOURCE macro definition (Ben Noordhuis)
+
+
+2013.08.25, Version 0.11.10 (Unstable), 742dadcb7154cc7bb89c0c228a223b767a36cf0d
+
+* windows: Re-implement uv_fs_stat. The st_ctime field now contains the change
+ time, not the creation time, like on unix systems. st_dev, st_ino, st_blocks
+ and st_blksize are now also filled out. (Bert Belder)
+
+* linux: fix setsockopt(SO_REUSEPORT) error handling (Ben Noordhuis)
+
+* windows: report uv_process_t exit code correctly (Bert Belder)
+
+* windows: make uv_fs_chmod() report errors correctly (Bert Belder)
+
+* windows: make some more NT apis available for libuv's internal use (Bert
+ Belder)
+
+* windows: squelch some compiler warnings (Bert Belder)
+
+
+2013.08.24, Version 0.11.9 (Unstable), a2d29b5b068cbac93dc16138fb30a74e2669daad
+
+Changes since version 0.11.8:
+
+* fsevents: share FSEventStream between multiple FS watchers, which removes a
+ limit on the maximum number of file watchers that can be created on OS X.
+ (Fedor Indutny)
+
+* process: the `exit_status` parameter for a uv_process_t's exit callback now
+ is an int64_t, and no longer an int. (Bert Belder)
+
+* process: make uv_spawn() return some types of errors immediately on windows,
+ instead of passing the error code the the exit callback. This brings it on
+ par with libuv's behavior on unix. (Bert Belder)
+
+
+2013.08.24, Version 0.10.15 (Stable), 221078a8fdd9b853c6b557b3d9a5dd744b4fdd6b
+
+Changes since version 0.10.14:
+
+* fsevents: create FSEvents thread on demand (Ben Noordhuis)
+
+* fsevents: use a single thread for interacting with FSEvents, because it's not
+ thread-safe. (Fedor Indutny)
+
+* fsevents: share FSEventStream between multiple FS watchers, which removes a
+ limit on the maximum number of file watchers that can be created on OS X.
+ (Fedor Indutny)
+
+
+2013.08.22, Version 0.11.8 (Unstable), a5260462db80ab0deab6b9e6a8991dd8f5a9a2f8
+
+Changes since version 0.11.7:
+
+* unix: fix missing return value warning in stream.c (Ben Noordhuis)
+
+* build: serial-tests was added in automake v1.12 (Ben Noordhuis)
+
+* windows: fix uninitialized local variable warning (Ben Noordhuis)
+
+* windows: fix missing return value warning (Ben Noordhuis)
+
+* build: fix string comparisons in autogen.sh (Ben Noordhuis)
+
+* windows: move INLINE macro, remove UNUSED (Ben Noordhuis)
+
+* unix: clean up __attribute__((quux)) usage (Ben Noordhuis)
+
+* sunos: remove futimes() macro (Ben Noordhuis)
+
+* unix: fix uv__signal_unlock() prototype (Ben Noordhuis)
+
+* unix, windows: allow NULL async callback (Ben Noordhuis)
+
+* build: apply dtrace -G to all object files (Timothy J. Fontaine)
+
+* darwin: fix indentation in uv__hrtime() (Ben Noordhuis)
+
+* darwin: create fsevents thread on demand (Ben Noordhuis)
+
+* darwin: reduce fsevents thread stack size (Ben Noordhuis)
+
+* darwin: call pthread_setname_np() if available (Ben Noordhuis)
+
+* build: fix automake serial-tests check again (Ben Noordhuis)
+
+* unix: retry waitpid() on EINTR (Ben Noordhuis)
+
+* darwin: fix ios build error (Ben Noordhuis)
+
+* darwin: fix ios compiler warning (Ben Noordhuis)
+
+* test: simplify test-ip6-addr.c (Ben Noordhuis)
+
+* unix, windows: fix ipv6 link-local address parsing (Ben Noordhuis)
+
+* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny)
+
+* windows: omit stdint.h, fix msvc 2008 build error (Ben Noordhuis)
+
+
+2013.08.22, Version 0.10.14 (Stable), 15d64132151c18b26346afa892444b95e2addad0
+
+Changes since version 0.10.13:
+
+* unix: retry waitpid() on EINTR (Ben Noordhuis)
+
+
+2013.08.07, Version 0.11.7 (Unstable), 3cad361f8776f70941b39d65bd9426bcb1aa817b
+
+Changes since version 0.11.6:
+
+* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis)
+
+* unix, windows: remove unused variables (Brian White)
+
+* test: fix signed/unsigned comparison warnings (Ben Noordhuis)
+
+* build: dtrace shouldn't break out of tree builds (Timothy J. Fontaine)
+
+* unix, windows: don't read/recv if buf.len==0 (Ben Noordhuis)
+
+* build: add mingw makefile (Ben Noordhuis)
+
+* unix, windows: add MAC to uv_interface_addresses() (Brian White)
+
+* build: enable AM_INIT_AUTOMAKE([subdir-objects]) (Ben Noordhuis)
+
+* unix, windows: make buf arg to uv_fs_write const (Ben Noordhuis)
+
+* sunos: fix build breakage introduced in e3a657c (Ben Noordhuis)
+
+* aix: fix build breakage introduced in 3ee4d3f (Ben Noordhuis)
+
+* windows: fix mingw32 build, define JOB_OBJECT_XXX (Yasuhiro Matsumoto)
+
+* windows: fix mingw32 build, include limits.h (Yasuhiro Matsumoto)
+
+* test: replace sprintf() with snprintf() (Ben Noordhuis)
+
+* test: replace strcpy() with strncpy() (Ben Noordhuis)
+
+* openbsd: fix uv_ip6_addr() unused variable warnings (Ben Noordhuis)
+
+* openbsd: fix dlerror() const correctness warning (Ben Noordhuis)
+
+* openbsd: fix uv_fs_sendfile() unused variable warnings (Ben Noordhuis)
+
+* build: disable parallel automake tests (Ben Noordhuis)
+
+* test: add windows-only snprintf() function (Ben Noordhuis)
+
+* build: add automake serial-tests version check (Ben Noordhuis)
+
+
+2013.07.26, Version 0.10.13 (Stable), 381312e1fe6fecbabc943ccd56f0e7d114b3d064
+
+Changes since version 0.10.12:
+
+* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis)
+
+
+2013.07.21, Version 0.11.6 (Unstable), 6645b93273e0553d23823c576573b82b129bf28c
+
+Changes since version 0.11.5:
+
+* test: open stdout fd in write-only mode (Ben Noordhuis)
+
+* windows: uv_spawn shouldn't reject reparse points (Bert Belder)
+
+* windows: use WSAGetLastError(), not errno (Ben Noordhuis)
+
+* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis)
+
+* test: fix signed/unsigned compiler warning (Ben Noordhuis)
+
+* test: add 'start timer from check handle' test (Ben Noordhuis)
+
+* build: `all` now builds static and dynamic lib (Ben Noordhuis)
+
+* unix, windows: add extra fields to uv_stat_t (Saúl Ibarra Corretgé)
+
+* build: add install target to the makefile (Navaneeth Kedaram Nambiathan)
+
+* build: switch to autotools (Ben Noordhuis)
+
+* build: use AM_PROG_AR conditionally (Ben Noordhuis)
+
+* test: fix fs_fstat test on sunos (Ben Noordhuis)
+
+* test: fix fs_chown when running as root (Ben Noordhuis)
+
+* test: fix spawn_setgid_fails and spawn_setuid_fails (Ben Noordhuis)
+
+* build: use AM_SILENT_RULES conditionally (Ben Noordhuis)
+
+* build: add DTrace detection for autotools (Timothy J. Fontaine)
+
+* linux,darwin,win: link-local IPv6 addresses (Miroslav Bajtoš)
+
+* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis)
+
+* unix, windows: return error codes directly (Ben Noordhuis)
+
+
+2013.07.10, Version 0.10.12 (Stable), 58a46221bba726746887a661a9f36fe9ff204209
+
+Changes since version 0.10.11:
+
+* linux: add support for MIPS (Andrei Sedoi)
+
+* windows: uv_spawn shouldn't reject reparse points (Bert Belder)
+
+* windows: use WSAGetLastError(), not errno (Ben Noordhuis)
+
+* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis)
+
+* build: `all` now builds static and dynamic lib (Ben Noordhuis)
+
+* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis)
+
+
+2013.06.27, Version 0.11.5 (Unstable), e3c63ff1627a14e96f54c1c62b0d68b446d8425b
+
+Changes since version 0.11.4:
+
+* build: remove CSTDFLAG, use only CFLAGS (Ben Noordhuis)
+
+* unix: support for android builds (Linus MÃ¥rtensson)
+
+* unix: avoid extra read, short-circuit on POLLHUP (Ben Noordhuis)
+
+* uv: support android libuv standalone build (Linus MÃ¥rtensson)
+
+* src: make queue.h c++ compatible (Ben Noordhuis)
+
+* unix: s/ngx-queue.h/queue.h/ in checksparse.sh (Ben Noordhuis)
+
+* unix: unconditionally stop handle on close (Ben Noordhuis)
+
+* freebsd: don't enable dtrace if it's not available (Brian White)
+
+* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine)
+
+* unix: remove overzealous assert (Ben Noordhuis)
+
+* unix: remove unused function uv_fatal_error() (Ben Noordhuis)
+
+* unix, windows: clean up uv_thread_create() (Ben Noordhuis)
+
+* queue: fix pointer truncation on LLP64 platforms (Bert Belder)
+
+* build: set OS=="android" for android builds (Linus MÃ¥rtensson)
+
+* windows: don't use uppercase in include filename (Ben Noordhuis)
+
+* stream: add an API to make streams do blocking writes (Henry Rawas)
+
+* windows: use WSAGetLastError(), not errno (Ben Noordhuis)
+
+
+2013.06.13, Version 0.10.11 (Stable), c3b75406a66a10222a589cb173e8f469e9665c7e
+
+Changes since version 0.10.10:
+
+* unix: unconditionally stop handle on close (Ben Noordhuis)
+
+* freebsd: don't enable dtrace if it's not available (Brian White)
+
+* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine)
+
+* unix: remove overzealous assert (Ben Noordhuis)
+
+* unix: clear UV_STREAM_SHUTTING after shutdown() (Ben Noordhuis)
+
+* unix: fix busy loop, write if POLLERR or POLLHUP (Ben Noordhuis)
+
+
+2013.06.05, Version 0.10.10 (Stable), 0d95a88bd35fce93863c57a460be613aea34d2c5
+
+Changes since version 0.10.9:
+
+* include: document uv_update_time() and uv_now() (Ben Noordhuis)
+
+* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis)
+
+* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis)
+
+* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis)
+
+* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis)
+
+* test: fix a compilation problem in test-osx-select.c that was caused by the
+ use of c-style comments (Bert Belder)
+
+* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes)
+
+
+2013.05.30, Version 0.11.4 (Unstable), e43e5b3d954a0989db5588aa110e1fe4fe6e0219
+
+Changes since version 0.11.3:
+
+* windows: make uv_spawn not fail when the libuv embedding application is run
+ under external job control (Bert Belder)
+
+* darwin: assume CFRunLoopStop() isn't thread-safe, fixing a race condition
+ when stopping the 'stdin select hack' thread (Fedor Indutny)
+
+* win: fix UV_EALREADY not being reported correctly to the libuv user in some
+ cases (Bert Belder)
+
+* darwin: make the uv__cf_loop_runner and uv__cf_loop_cb functions static (Ben
+ Noordhuis)
+
+* darwin: task_info() cannot fail (Ben Noordhuis)
+
+* unix: add error mapping for ENETDOWN (Ben Noordhuis)
+
+* unix: implicitly signal write errors to the libuv user (Ben Noordhuis)
+
+* unix: fix assertion error on signal pipe overflow (Bert Belder)
+
+* unix: turn off POLLOUT after stream connect (Ben Noordhuis)
+
+* unix: fix stream refcounting buglet (Ben Noordhuis)
+
+* unix: remove assert statements that are no longer correct (Ben Noordhuis)
+
+* unix: appease warning about non-standard `inline` (Sean Silva)
+
+* unix: add uv__is_closing() macro (Ben Noordhuis)
+
+* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis)
+
+* include: document uv_update_time() and uv_now() (Ben Noordhuis)
+
+* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis)
+
+* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis)
+
+* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis)
+
+* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis)
+
+* test: fix a compilation problem in test-osx-select.c that was caused by the
+ use of c-style comments (Bert Belder)
+
+* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes)
+
+* windows: call idle handles on every loop iteration, something the unix
+ implementation already did (Bert Belder)
+
+* test: update the idle-starvation test to verify that idle handles are called
+ in every loop iteration (Bert Belder)
+
+* unix, windows: ensure that uv_run() in RUN_ONCE mode calls timers that expire
+ after blocking (Ben Noordhuis)
+
+
+2013.05.29, Version 0.10.9 (Stable), a195f9ace23d92345baf57582678bfc3017e6632
+
+Changes since version 0.10.8:
+
+* unix: fix stream refcounting buglet (Ben Noordhuis)
+
+* unix: remove erroneous asserts (Ben Noordhuis)
+
+* unix: add uv__is_closing() macro (Ben Noordhuis)
+
+* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis)
+
+
+2013.05.25, Version 0.10.8 (Stable), 0f39be12926fe2d8766a9f025797a473003e6504
+
+Changes since version 0.10.7:
+
+* windows: make uv_spawn not fail under job control (Bert Belder)
+
+* darwin: assume CFRunLoopStop() isn't thread-safe (Fedor Indutny)
+
+* win: fix UV_EALREADY incorrectly set (Bert Belder)
+
+* darwin: make two uv__cf_*() functions static (Ben Noordhuis)
+
+* darwin: task_info() cannot fail (Ben Noordhuis)
+
+* unix: add mapping for ENETDOWN (Ben Noordhuis)
+
+* unix: implicitly signal write errors to libuv user (Ben Noordhuis)
+
+* unix: fix assert on signal pipe overflow (Bert Belder)
+
+* unix: turn off POLLOUT after stream connect (Ben Noordhuis)
+
+
+2013.05.16, Version 0.11.3 (Unstable), 0a48c05b5988aea84c605751900926fa25443b34
+
+Changes since version 0.11.2:
+
+* unix: clean up uv_accept() (Ben Noordhuis)
+
+* unix: remove errno preserving code (Ben Noordhuis)
+
+* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis)
+
+* windows: kill child processes when the parent dies (Bert Belder)
+
+* build: set soname in shared library (Ben Noordhuis)
+
+* build: make `make test` link against .a again (Ben Noordhuis)
+
+* build: only set soname on shared object builds (Timothy J. Fontaine)
+
+* build: convert predefined $PLATFORM to lower case (Elliot Saba)
+
+* test: fix process_title failing on linux (Miroslav Bajtoš)
+
+* test, sunos: disable process_title test (Miroslav Bajtoš)
+
+* test: add error logging to tty unit test (Miroslav Bajtoš)
+
+
+2013.05.15, Version 0.10.7 (Stable), 028baaf0846b686a81e992cb2f2f5a9b8e841fcf
+
+Changes since version 0.10.6:
+
+* windows: kill child processes when the parent dies (Bert Belder)
+
+
+2013.05.15, Version 0.10.6 (Stable), 11e6613e6260d95c8cf11bf89a2759c24649319a
+
+Changes since version 0.10.5:
+
+* stream: fix osx select hack (Fedor Indutny)
+
+* stream: fix small nit in select hack, add test (Fedor Indutny)
+
+* build: link with libkvm on openbsd (Ben Noordhuis)
+
+* stream: use harder sync restrictions for osx-hack (Fedor Indutny)
+
+* unix: fix EMFILE error handling (Ben Noordhuis)
+
+* darwin: fix unnecessary include headers (Daisuke Murase)
+
+* darwin: rename darwin-getproctitle.m (Ben Noordhuis)
+
+* build: convert predefined $PLATFORM to lower case (Elliot Saba)
+
+* build: set soname in shared library (Ben Noordhuis)
+
+* build: make `make test` link against .a again (Ben Noordhuis)
+
+* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis)
+
+* build: only set soname on shared object builds (Timothy J. Fontaine)
+
+
+2013.05.11, Version 0.11.2 (Unstable), 3fba0bf65f091b91a9760530c05c6339c658d88b
+
+Changes since version 0.11.1:
+
+* darwin: look up file path with F_GETPATH (Ben Noordhuis)
+
+* unix, windows: add uv_has_ref() function (Saúl Ibarra Corretgé)
+
+* build: avoid double / in paths for dtrace (Timothy J. Fontaine)
+
+* unix: remove src/unix/cygwin.c (Ben Noordhuis)
+
+* windows: deal with the fact that GetTickCount might lag (Bert Belder)
+
+* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
+
+* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)
+
+
+2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67
+
+Changes since version 0.10.4:
+
+* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
+
+* windows: make timers handle large timeouts (Miroslav Bajtoš)
+
+* windows: remove superfluous assert statement (Bert Belder)
+
+* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)
+
+* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)
+
+
+2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833
+
+Changes since version 0.10.3:
+
+* include: update uv_backend_fd() documentation (Ben Noordhuis)
+
+* unix: include uv.h in src/version.c (Ben Noordhuis)
+
+* unix: don't write more than IOV_MAX iovecs (Fedor Indutny)
+
+* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
+
+* build: gyp disable thin archives (Timothy J. Fontaine)
+
+* sunos: re-export entire library when static (Timothy J. Fontaine)
+
+* unix: dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
+
+* windows: fix memory leak in fs__sendfile (Shannen Saez)
+
+* windows: remove double initialization in uv_tty_init (Shannen Saez)
+
+* build: fix dtrace-enabled out of tree build (Ben Noordhuis)
+
+* build: squelch -Wdollar-in-identifier-extension warnings (Ben Noordhuis)
+
+* inet: snprintf returns int, not size_t (Brian White)
+
+* win: refactor uv_cpu_info (Bert Belder)
+
+* build: add support for Visual Studio 2012 (Nicholas Vavilov)
+
+* build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis)
+
+
+2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a
+
+This is the first versioned release from the current unstable libuv branch.
+
+Changes since Node.js v0.11.0:
+
+* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J.
+ Fontaine)
+
+* all platforms: add netmask to uv_interface_address (Ben Kelly)
+
+* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or
+ -1 (Ben Noordhuis)
+
+* unix: limit the number of iovecs written in a single `writev` syscall to
+ IOV_MAX (Fedor Indutny)
+
+* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine)
+
+* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier)
+
+* windows: fix memory leak in fs__sendfile (Shannen Saez)
+
+* windows: fix edge case bugs in uv_cpu_info (Bert Belder)
+
+* include: no longer ship with / include ngx-queue.h (Ben Noordhuis)
+
+* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis)
+
+* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis)
+
+* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine)
+
+* build: gyp disable thin archives (Timothy J. Fontaine)
+
+* build: add support for Visual Studio 2012 (Nicholas Vavilov)
+
+
+2013.03.28, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0
+
+Changes since version 0.10.2:
+
+* include: remove extraneous const from uv_version() (Ben Noordhuis)
+
+* doc: update README, replace `OS` by `PLATFORM` (Ben Noordhuis)
+
+* build: simplify .buildstamp rule (Ben Noordhuis)
+
+* build: disable -Wstrict-aliasing on darwin (Ben Noordhuis)
+
+* darwin: don't select(&exceptfds) in fallback path (Ben Noordhuis)
+
+* unix: don't clear flags after closing UDP handle (Saúl Ibarra Corretgé)
+
+
+2013.03.25, Version 0.10.2 (Stable), 0f36a00568f3e7608f97f6c6cdb081f4800a50c9
+
+This is the first officially versioned release of libuv. Starting now
+libuv will make releases independently of Node.js.
+
+Changes since Node.js v0.10.0:
+
+* test: add tap output for windows (Timothy J. Fontaine)
+
+* unix: fix uv_tcp_simultaneous_accepts() logic (Ben Noordhuis)
+
+* include: bump UV_VERSION_MINOR (Ben Noordhuis)
+
+* unix: improve uv_guess_handle() implementation (Ben Noordhuis)
+
+* stream: run try_select only for pipes and ttys (Fedor Indutny)
+
+Changes since Node.js v0.10.1:
+
+* build: rename OS to PLATFORM (Ben Noordhuis)
+
+* unix: make uv_timer_init() initialize repeat (Brian Mazza)
+
+* unix: make timers handle large timeouts (Ben Noordhuis)
+
+* build: add OBJC makefile var (Ben Noordhuis)
+
+* Add `uv_version()` and `uv_version_string()` APIs (Bert Belder)
diff --git a/third-party/libuv/LICENSE b/third-party/libuv/LICENSE
new file mode 100644
index 0000000000..8db13acf2c
--- /dev/null
+++ b/third-party/libuv/LICENSE
@@ -0,0 +1,42 @@
+libuv is part of the Node project: http://nodejs.org/
+libuv may be distributed alone under Node's license:
+
+====
+
+Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+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.
+
+====
+
+This license applies to all parts of libuv that are not externally
+maintained libraries.
+
+The externally maintained libraries used by libuv are:
+
+ - tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license.
+
+ - inet_pton and inet_ntop implementations, contained in src/inet.c, are
+ copyright the Internet Systems Consortium, Inc., and licensed under the ISC
+ license.
+
+ - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
+ clause BSD license.
+
+ - pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile
+ Communications AB. Three clause BSD license.
diff --git a/third-party/libuv/Makefile.am b/third-party/libuv/Makefile.am
new file mode 100644
index 0000000000..c1eae8cea0
--- /dev/null
+++ b/third-party/libuv/Makefile.am
@@ -0,0 +1,302 @@
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CPPFLAGS = -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src
+
+include_HEADERS=include/uv.h include/uv-errno.h
+
+CLEANFILES =
+
+lib_LTLIBRARIES = libuv.la
+libuv_la_CFLAGS = @CFLAGS@
+libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
+libuv_la_SOURCES = src/fs-poll.c \
+ src/inet.c \
+ src/queue.h \
+ src/uv-common.c \
+ src/uv-common.h \
+ src/version.c
+
+if SUNOS
+libuv_la_CFLAGS += -pthread
+endif
+
+if WINNT
+
+include_HEADERS += include/uv-win.h include/tree.h
+AM_CPPFLAGS += -I$(top_srcdir)/src/win \
+ -DWIN32_LEAN_AND_MEAN \
+ -D_WIN32_WINNT=0x0600
+LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32
+libuv_la_SOURCES += src/win/async.c \
+ src/win/atomicops-inl.h \
+ src/win/core.c \
+ src/win/dl.c \
+ src/win/error.c \
+ src/win/fs-event.c \
+ src/win/fs.c \
+ src/win/getaddrinfo.c \
+ src/win/handle.c \
+ src/win/handle-inl.h \
+ src/win/internal.h \
+ src/win/loop-watcher.c \
+ src/win/pipe.c \
+ src/win/poll.c \
+ src/win/process-stdio.c \
+ src/win/process.c \
+ src/win/req.c \
+ src/win/req-inl.h \
+ src/win/signal.c \
+ src/win/stream.c \
+ src/win/stream-inl.h \
+ src/win/tcp.c \
+ src/win/thread.c \
+ src/win/threadpool.c \
+ src/win/timer.c \
+ src/win/tty.c \
+ src/win/udp.c \
+ src/win/util.c \
+ src/win/winapi.c \
+ src/win/winapi.h \
+ src/win/winsock.c \
+ src/win/winsock.h
+
+else # WINNT
+
+include_HEADERS += include/uv-unix.h
+AM_CPPFLAGS += -I$(top_srcdir)/src/unix
+libuv_la_SOURCES += src/unix/async.c \
+ src/unix/atomic-ops.h \
+ src/unix/core.c \
+ src/unix/dl.c \
+ src/unix/fs.c \
+ src/unix/getaddrinfo.c \
+ src/unix/internal.h \
+ src/unix/loop-watcher.c \
+ src/unix/loop.c \
+ src/unix/pipe.c \
+ src/unix/poll.c \
+ src/unix/process.c \
+ src/unix/signal.c \
+ src/unix/spinlock.h \
+ src/unix/stream.c \
+ src/unix/tcp.c \
+ src/unix/thread.c \
+ src/unix/threadpool.c \
+ src/unix/timer.c \
+ src/unix/tty.c \
+ src/unix/udp.c
+
+endif # WINNT
+
+TESTS = test/run-tests
+check_PROGRAMS = test/run-tests
+test_run_tests_SOURCES = test/blackhole-server.c \
+ test/dns-server.c \
+ test/echo-server.c \
+ test/run-tests.c \
+ test/runner.c \
+ test/runner.h \
+ test/task.h \
+ test/test-active.c \
+ test/test-async.c \
+ test/test-async-null-cb.c \
+ test/test-barrier.c \
+ test/test-callback-order.c \
+ test/test-callback-stack.c \
+ test/test-close-fd.c \
+ test/test-close-order.c \
+ test/test-condvar.c \
+ test/test-connection-fail.c \
+ test/test-cwd-and-chdir.c \
+ test/test-delayed-accept.c \
+ test/test-dlerror.c \
+ test/test-embed.c \
+ test/test-emfile.c \
+ test/test-error.c \
+ test/test-fail-always.c \
+ test/test-fs-event.c \
+ test/test-fs-poll.c \
+ test/test-fs.c \
+ test/test-get-currentexe.c \
+ test/test-get-loadavg.c \
+ test/test-get-memory.c \
+ test/test-getaddrinfo.c \
+ test/test-getsockname.c \
+ test/test-hrtime.c \
+ test/test-idle.c \
+ test/test-ip4-addr.c \
+ test/test-ip6-addr.c \
+ test/test-ipc-send-recv.c \
+ test/test-ipc.c \
+ test/test-list.h \
+ test/test-loop-handles.c \
+ test/test-loop-alive.c \
+ test/test-loop-stop.c \
+ test/test-loop-time.c \
+ test/test-multiple-listen.c \
+ test/test-mutexes.c \
+ test/test-osx-select.c \
+ test/test-pass-always.c \
+ test/test-ping-pong.c \
+ test/test-pipe-bind-error.c \
+ test/test-pipe-connect-error.c \
+ test/test-pipe-server-close.c \
+ test/test-platform-output.c \
+ test/test-poll-close.c \
+ test/test-poll.c \
+ test/test-process-title.c \
+ test/test-ref.c \
+ test/test-run-nowait.c \
+ test/test-run-once.c \
+ test/test-semaphore.c \
+ test/test-shutdown-close.c \
+ test/test-shutdown-eof.c \
+ test/test-signal-multiple-loops.c \
+ test/test-signal.c \
+ test/test-spawn.c \
+ test/test-stdio-over-pipes.c \
+ test/test-tcp-bind-error.c \
+ test/test-tcp-bind6-error.c \
+ test/test-tcp-close-accept.c \
+ test/test-tcp-close-while-connecting.c \
+ test/test-tcp-close.c \
+ test/test-tcp-connect-error-after-write.c \
+ test/test-tcp-connect-error.c \
+ test/test-tcp-connect-timeout.c \
+ test/test-tcp-connect6-error.c \
+ test/test-tcp-flags.c \
+ test/test-tcp-open.c \
+ test/test-tcp-read-stop.c \
+ test/test-tcp-shutdown-after-write.c \
+ test/test-tcp-unexpected-read.c \
+ test/test-tcp-write-to-half-open-connection.c \
+ test/test-tcp-writealot.c \
+ test/test-tcp-try-write.c \
+ test/test-thread.c \
+ test/test-threadpool-cancel.c \
+ test/test-threadpool.c \
+ test/test-timer-again.c \
+ test/test-timer-from-check.c \
+ test/test-timer.c \
+ test/test-tty.c \
+ test/test-udp-dgram-too-big.c \
+ test/test-udp-ipv6.c \
+ test/test-udp-multicast-join.c \
+ test/test-udp-multicast-ttl.c \
+ test/test-udp-open.c \
+ test/test-udp-options.c \
+ test/test-udp-send-and-recv.c \
+ test/test-walk-handles.c \
+ test/test-watcher-cross-stop.c
+test_run_tests_LDADD = libuv.la
+
+if WINNT
+test_run_tests_SOURCES += test/runner-win.c \
+ test/runner-win.h
+else
+test_run_tests_SOURCES += test/runner-unix.c \
+ test/runner-unix.h
+endif
+
+
+
+if AIX
+libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500
+libuv_la_SOURCES += src/unix/aix.c
+endif
+
+if DARWIN
+include_HEADERS += include/uv-darwin.h
+libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
+libuv_la_SOURCES += src/unix/darwin.c \
+ src/unix/darwin-proctitle.c \
+ src/unix/fsevents.c \
+ src/unix/kqueue.c \
+ src/unix/proctitle.c
+endif
+
+if FREEBSD
+include_HEADERS += include/uv-bsd.h
+libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c
+endif
+
+if LINUX
+include_HEADERS += include/uv-linux.h
+libuv_la_SOURCES += src/unix/linux-core.c \
+ src/unix/linux-inotify.c \
+ src/unix/linux-syscalls.c \
+ src/unix/linux-syscalls.h \
+ src/unix/proctitle.c
+endif
+
+if NETBSD
+include_HEADERS += include/uv-bsd.h
+libuv_la_SOURCES += src/unix/kqueue.c src/unix/netbsd.c
+endif
+
+if OPENBSD
+include_HEADERS += include/uv-bsd.h
+libuv_la_SOURCES += src/unix/kqueue.c src/unix/openbsd.c
+endif
+
+if SUNOS
+include_HEADERS += include/uv-sunos.h
+libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
+libuv_la_SOURCES += src/unix/sunos.c
+endif
+
+if HAVE_DTRACE
+BUILT_SOURCES = include/uv-dtrace.h
+CLEANFILES += include/uv-dtrace.h
+endif
+
+if DTRACE_NEEDS_OBJECTS
+libuv_la_SOURCES += src/unix/uv-dtrace.d
+libuv_la_DEPENDENCIES = src/unix/uv-dtrace.o
+libuv_la_LIBADD = uv-dtrace.lo
+CLEANFILES += src/unix/uv-dtrace.o src/unix/uv-dtrace.lo
+endif
+
+if HAVE_PKG_CONFIG
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = @PACKAGE_NAME@.pc
+endif
+
+if HAVE_DTRACE
+include/uv-dtrace.h: src/unix/uv-dtrace.d
+ $(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -h -xnolibs -s $< -o $(top_srcdir)/$@
+endif
+
+if DTRACE_NEEDS_OBJECTS
+SUFFIXES = .d
+
+src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
+
+# It's ok to specify the output here, because we have 1 .d file, and we process
+# every created .o, most projects don't need to include more than one .d
+.d.o:
+ $(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -G -o $(top_builddir)/uv-dtrace.o -s $< \
+ `find ${top_builddir}/src -name "*.o"`
+ $(AM_V_GEN)printf %s\\n \
+ '# ${top_builddir}/uv-dtrace.lo - a libtool object file' \
+ '# Generated by libtool (GNU libtool) 2.4' \
+ '# libtool wants a .lo not a .o' \
+ "pic_object='uv-dtrace.o'" \
+ "non_pic_object='uv-dtrace.o'" \
+ > ${top_builddir}/uv-dtrace.lo
+endif
diff --git a/third-party/libuv/Makefile.mingw b/third-party/libuv/Makefile.mingw
new file mode 100644
index 0000000000..28a1e274d5
--- /dev/null
+++ b/third-party/libuv/Makefile.mingw
@@ -0,0 +1,77 @@
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+CC = gcc
+
+CFLAGS += -Wall \
+ -Wextra \
+ -Wno-unused-parameter \
+ -Iinclude \
+ -Isrc \
+ -Isrc/win \
+ -DWIN32_LEAN_AND_MEAN \
+ -D_WIN32_WINNT=0x0600
+
+INCLUDES = include/stdint-msvc2008.h \
+ include/tree.h \
+ include/uv-errno.h \
+ include/uv-win.h \
+ include/uv.h \
+ src/queue.h \
+ src/uv-common.h \
+ src/win/atomicops-inl.h \
+ src/win/handle-inl.h \
+ src/win/internal.h \
+ src/win/req-inl.h \
+ src/win/stream-inl.h \
+ src/win/winapi.h \
+ src/win/winsock.h
+
+OBJS = src/fs-poll.o \
+ src/inet.o \
+ src/uv-common.o \
+ src/version.o \
+ src/win/async.o \
+ src/win/core.o \
+ src/win/dl.o \
+ src/win/error.o \
+ src/win/fs-event.o \
+ src/win/fs.o \
+ src/win/getaddrinfo.o \
+ src/win/handle.o \
+ src/win/loop-watcher.o \
+ src/win/pipe.o \
+ src/win/poll.o \
+ src/win/process-stdio.o \
+ src/win/process.o \
+ src/win/req.o \
+ src/win/signal.o \
+ src/win/stream.o \
+ src/win/tcp.o \
+ src/win/thread.o \
+ src/win/threadpool.o \
+ src/win/timer.o \
+ src/win/tty.o \
+ src/win/udp.o \
+ src/win/util.o \
+ src/win/winapi.o \
+ src/win/winsock.o
+
+all: libuv.a
+
+libuv.a: $(OBJS)
+ $(AR) crs $@ $^
+
+# FIXME(bnoordhuis) Don't rebuild everything when a source file changes.
+$(OBJS): $(OBJS:.o=.c) $(INCLUDES)
diff --git a/third-party/libuv/README.md b/third-party/libuv/README.md
new file mode 100644
index 0000000000..5704c39e27
--- /dev/null
+++ b/third-party/libuv/README.md
@@ -0,0 +1,143 @@
+# libuv
+
+libuv is a multi-platform support library with a focus on asynchronous I/O. It
+was primarily developed for use by [Node.js](http://nodejs.org), but it's also
+used by Mozilla's [Rust language](http://www.rust-lang.org/),
+[Luvit](http://luvit.io/), [Julia](http://julialang.org/),
+[pyuv](https://crate.io/packages/pyuv/), and [others](https://github.com/joyent/libuv/wiki/Projects-that-use-libuv).
+
+## Feature highlights
+
+ * Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
+
+ * Asynchronous TCP and UDP sockets
+
+ * Asynchronous DNS resolution
+
+ * Asynchronous file and file system operations
+
+ * File system events
+
+ * ANSI escape code controlled TTY
+
+ * IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
+
+ * Child processes
+
+ * Thread pool
+
+ * Signal handling
+
+ * High resolution clock
+
+ * Threading and synchronization primitives
+
+
+## Community
+
+ * [Mailing list](http://groups.google.com/group/libuv)
+
+## Documentation
+
+ * [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
+ &mdash; API documentation in the form of detailed header comments.
+ * [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
+ &mdash; An overview of libuv with tutorials.
+ * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
+ &mdash; High-level introductory talk about libuv.
+ * [Tests and benchmarks](https://github.com/joyent/libuv/tree/master/test)
+ &mdash; API specification and usage examples.
+ * [libuv-dox](https://github.com/thlorenz/libuv-dox)
+ &mdash; Documenting types and methods of libuv, mostly by reading uv.h.
+
+## Build Instructions
+
+For GCC there are two methods building: via autotools or via [GYP][].
+GYP is a meta-build system which can generate MSVS, Makefile, and XCode
+backends. It is best used for integration into other projects.
+
+To build with autotools:
+
+ $ sh autogen.sh
+ $ ./configure
+ $ make
+ $ make check
+ $ make install
+
+### Windows
+
+First, Python 2.6 or 2.7 must be installed as it is required by [GYP][].
+
+Also, the directory for the preferred Python executable must be specified
+by the `PYTHON` or `Path` environment variables.
+
+To build with Visual Studio, launch a git shell (e.g. Cmd or PowerShell)
+and run vcbuild.bat which will checkout the GYP code into build/gyp and
+generate uv.sln as well as related project files.
+
+To have GYP generate build script for another system, checkout GYP into the
+project tree manually:
+
+ $ mkdir -p build
+ $ git clone https://git.chromium.org/external/gyp.git build/gyp
+
+### Unix
+
+Run:
+
+ $ ./gyp_uv.py -f make
+ $ make -C out
+
+### OS X
+
+Run:
+
+ $ ./gyp_uv.py -f xcode
+ $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \
+ -configuration Release -target All
+
+Note to OS X users:
+
+Make sure that you specify the architecture you wish to build for in the
+"ARCHS" flag. You can specify more than one by delimiting with a space
+(e.g. "x86_64 i386").
+
+### Android
+
+Run:
+
+ $ source ./android-configure NDK_PATH gyp
+ $ make -C out
+
+Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
+`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
+
+### Running tests
+
+Run:
+
+ $ ./gyp_uv.py -f make
+ $ make -C out
+ $ ./out/Debug/run-tests
+
+## Supported Platforms
+
+Microsoft Windows operating systems since Windows XP SP2. It can be built
+with either Visual Studio or MinGW. Consider using
+[Visual Studio Express 2010][] or later if you do not have a full Visual
+Studio license.
+
+Linux using the GCC toolchain.
+
+OS X using the GCC or XCode toolchain.
+
+Solaris 121 and later using GCC toolchain.
+
+## patches
+
+See the [guidelines for contributing][].
+
+[node.js]: http://nodejs.org/
+[GYP]: http://code.google.com/p/gyp/
+[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
+[guidelines for contributing]: https://github.com/joyent/libuv/blob/master/CONTRIBUTING.md
diff --git a/third-party/libuv/android-configure b/third-party/libuv/android-configure
new file mode 100755
index 0000000000..56625761fd
--- /dev/null
+++ b/third-party/libuv/android-configure
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+export TOOLCHAIN=$PWD/android-toolchain
+mkdir -p $TOOLCHAIN
+$1/build/tools/make-standalone-toolchain.sh \
+ --toolchain=arm-linux-androideabi-4.7 \
+ --arch=arm \
+ --install-dir=$TOOLCHAIN \
+ --platform=android-9
+export PATH=$TOOLCHAIN/bin:$PATH
+export AR=arm-linux-androideabi-ar
+export CC=arm-linux-androideabi-gcc
+export CXX=arm-linux-androideabi-g++
+export LINK=arm-linux-androideabi-g++
+export PLATFORM=android
+
+if [ $2 -a $2 == 'gyp' ]
+ then
+ ./gyp_uv.py -Dtarget_arch=arm -DOS=android
+fi
diff --git a/third-party/libuv/autogen.sh b/third-party/libuv/autogen.sh
new file mode 100755
index 0000000000..751b4f5562
--- /dev/null
+++ b/third-party/libuv/autogen.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+cd `dirname "$0"`
+
+if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then
+ LIBTOOLIZE=glibtoolize
+fi
+
+ACLOCAL=${ACLOCAL:-aclocal}
+AUTOCONF=${AUTOCONF:-autoconf}
+AUTOMAKE=${AUTOMAKE:-automake}
+LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
+
+automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'`
+automake_version_major=`echo "$automake_version" | cut -d. -f1`
+automake_version_minor=`echo "$automake_version" | cut -d. -f2`
+
+UV_EXTRA_AUTOMAKE_FLAGS=
+if test "$automake_version_major" -gt 1 || \
+ test "$automake_version_major" -eq 1 && \
+ test "$automake_version_minor" -gt 11; then
+ # serial-tests is available in v0.12 and newer.
+ UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests"
+fi
+echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
+ > m4/libuv-extra-automake-flags.m4
+
+set -ex
+"$LIBTOOLIZE"
+"$ACLOCAL" -I m4
+"$AUTOCONF"
+"$AUTOMAKE" --add-missing --copy
diff --git a/third-party/libuv/checksparse.sh b/third-party/libuv/checksparse.sh
new file mode 100755
index 0000000000..54cd5805a8
--- /dev/null
+++ b/third-party/libuv/checksparse.sh
@@ -0,0 +1,231 @@
+#!/bin/sh
+
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+SPARSE=${SPARSE:-sparse}
+
+SPARSE_FLAGS=${SPARSE_FLAGS:-"
+-D__POSIX__
+-Wsparse-all
+-Wno-do-while
+-Wno-transparent-union
+-Iinclude
+-Isrc
+"}
+
+SOURCES="
+include/tree.h
+include/uv-unix.h
+include/uv.h
+src/fs-poll.c
+src/inet.c
+src/queue.h
+src/unix/async.c
+src/unix/core.c
+src/unix/dl.c
+src/unix/fs.c
+src/unix/getaddrinfo.c
+src/unix/internal.h
+src/unix/loop-watcher.c
+src/unix/loop.c
+src/unix/pipe.c
+src/unix/poll.c
+src/unix/process.c
+src/unix/signal.c
+src/unix/stream.c
+src/unix/tcp.c
+src/unix/thread.c
+src/unix/threadpool.c
+src/unix/timer.c
+src/unix/tty.c
+src/unix/udp.c
+src/uv-common.c
+src/uv-common.h
+"
+
+TESTS="
+test/benchmark-async-pummel.c
+test/benchmark-async.c
+test/benchmark-fs-stat.c
+test/benchmark-getaddrinfo.c
+test/benchmark-loop-count.c
+test/benchmark-million-async.c
+test/benchmark-million-timers.c
+test/benchmark-multi-accept.c
+test/benchmark-ping-pongs.c
+test/benchmark-pound.c
+test/benchmark-pump.c
+test/benchmark-sizes.c
+test/benchmark-spawn.c
+test/benchmark-tcp-write-batch.c
+test/benchmark-thread.c
+test/benchmark-udp-pummel.c
+test/blackhole-server.c
+test/dns-server.c
+test/echo-server.c
+test/run-benchmarks.c
+test/run-tests.c
+test/runner-unix.c
+test/runner-unix.h
+test/runner.c
+test/runner.h
+test/task.h
+test/test-active.c
+test/test-async.c
+test/test-barrier.c
+test/test-callback-order.c
+test/test-callback-stack.c
+test/test-condvar.c
+test/test-connection-fail.c
+test/test-cwd-and-chdir.c
+test/test-delayed-accept.c
+test/test-dlerror.c
+test/test-embed.c
+test/test-error.c
+test/test-fail-always.c
+test/test-fs-event.c
+test/test-fs-poll.c
+test/test-fs.c
+test/test-get-currentexe.c
+test/test-get-loadavg.c
+test/test-get-memory.c
+test/test-getaddrinfo.c
+test/test-getsockname.c
+test/test-hrtime.c
+test/test-idle.c
+test/test-ip6-addr.c
+test/test-ipc-send-recv.c
+test/test-ipc.c
+test/test-loop-handles.c
+test/test-multiple-listen.c
+test/test-mutexes.c
+test/test-pass-always.c
+test/test-ping-pong.c
+test/test-pipe-bind-error.c
+test/test-pipe-connect-error.c
+test/test-pipe-server-close.c
+test/test-platform-output.c
+test/test-poll-close.c
+test/test-poll.c
+test/test-process-title.c
+test/test-ref.c
+test/test-run-nowait.c
+test/test-run-once.c
+test/test-semaphore.c
+test/test-shutdown-close.c
+test/test-shutdown-eof.c
+test/test-signal-multiple-loops.c
+test/test-signal.c
+test/test-spawn.c
+test/test-stdio-over-pipes.c
+test/test-tcp-bind-error.c
+test/test-tcp-bind6-error.c
+test/test-tcp-close-while-connecting.c
+test/test-tcp-close-accept.c
+test/test-tcp-close.c
+test/test-tcp-connect-error-after-write.c
+test/test-tcp-connect-error.c
+test/test-tcp-connect-timeout.c
+test/test-tcp-connect6-error.c
+test/test-tcp-flags.c
+test/test-tcp-open.c
+test/test-tcp-read-stop.c
+test/test-tcp-shutdown-after-write.c
+test/test-tcp-unexpected-read.c
+test/test-tcp-write-error.c
+test/test-tcp-write-to-half-open-connection.c
+test/test-tcp-writealot.c
+test/test-thread.c
+test/test-threadpool-cancel.c
+test/test-threadpool.c
+test/test-timer-again.c
+test/test-timer.c
+test/test-tty.c
+test/test-udp-dgram-too-big.c
+test/test-udp-ipv6.c
+test/test-udp-multicast-join.c
+test/test-udp-multicast-ttl.c
+test/test-udp-open.c
+test/test-udp-options.c
+test/test-udp-send-and-recv.c
+test/test-walk-handles.c
+test/test-watcher-cross-stop.c
+"
+
+case `uname -s` in
+AIX)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D_AIX=1"
+ SOURCES="$SOURCES
+ src/unix/aix.c"
+ ;;
+Darwin)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
+ SOURCES="$SOURCES
+ include/uv-bsd.h
+ src/unix/darwin.c
+ src/unix/kqueue.c
+ src/unix/fsevents.c"
+ ;;
+DragonFly)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1"
+ SOURCES="$SOURCES
+ include/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/freebsd.c"
+ ;;
+FreeBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/freebsd.c"
+ ;;
+Linux)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1"
+ SOURCES="$SOURCES
+ include/uv-linux.h
+ src/unix/linux-inotify.c
+ src/unix/linux-core.c
+ src/unix/linux-syscalls.c
+ src/unix/linux-syscalls.h"
+ ;;
+NetBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/netbsd.c"
+ ;;
+OpenBSD)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1"
+ SOURCES="$SOURCES
+ include/uv-bsd.h
+ src/unix/kqueue.c
+ src/unix/openbsd.c"
+ ;;
+SunOS)
+ SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1"
+ SOURCES="$SOURCES
+ include/uv-sunos.h
+ src/unix/sunos.c"
+ ;;
+esac
+
+for ARCH in __i386__ __x86_64__ __arm__ __mips__; do
+ $SPARSE $SPARSE_FLAGS -D$ARCH=1 $SOURCES
+done
+
+# Tests are architecture independent.
+$SPARSE $SPARSE_FLAGS -Itest $TESTS
diff --git a/third-party/libuv/common.gypi b/third-party/libuv/common.gypi
new file mode 100644
index 0000000000..7adbbbdcc9
--- /dev/null
+++ b/third-party/libuv/common.gypi
@@ -0,0 +1,208 @@
+{
+ 'variables': {
+ 'visibility%': 'hidden', # V8's visibility setting
+ 'target_arch%': 'ia32', # set v8's target architecture
+ 'host_arch%': 'ia32', # set v8's host architecture
+ 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
+ 'component%': 'static_library', # NB. these names match with what V8 expects
+ 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
+ 'gcc_version%': 'unknown',
+ 'clang%': 0,
+ },
+
+ 'target_defaults': {
+ 'default_configuration': 'Debug',
+ 'configurations': {
+ 'Debug': {
+ 'defines': [ 'DEBUG', '_DEBUG' ],
+ 'cflags': [ '-g', '-O0', '-fwrapv' ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 1, # static debug
+ }, {
+ 'RuntimeLibrary': 3, # DLL debug
+ }],
+ ],
+ 'Optimization': 0, # /Od, no optimization
+ 'MinimalRebuild': 'false',
+ 'OmitFramePointers': 'false',
+ 'BasicRuntimeChecks': 3, # /RTC1
+ },
+ 'VCLinkerTool': {
+ 'LinkIncremental': 2, # enable incremental linking
+ },
+ },
+ 'xcode_settings': {
+ 'GCC_OPTIMIZATION_LEVEL': '0',
+ 'OTHER_CFLAGS': [ '-Wno-strict-aliasing' ],
+ },
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [ 'EV_VERIFY=2' ],
+ }],
+ ]
+ },
+ 'Release': {
+ 'defines': [ 'NDEBUG' ],
+ 'cflags': [
+ '-O3',
+ '-fstrict-aliasing',
+ '-fomit-frame-pointer',
+ '-fdata-sections',
+ '-ffunction-sections',
+ ],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'target_conditions': [
+ ['library=="static_library"', {
+ 'RuntimeLibrary': 0, # static release
+ }, {
+ 'RuntimeLibrary': 2, # debug release
+ }],
+ ],
+ 'Optimization': 3, # /Ox, full optimization
+ 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
+ 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
+ 'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
+ 'OmitFramePointers': 'true',
+ 'EnableFunctionLevelLinking': 'true',
+ 'EnableIntrinsicFunctions': 'true',
+ },
+ 'VCLibrarianTool': {
+ 'AdditionalOptions': [
+ '/LTCG', # link time code generation
+ ],
+ },
+ 'VCLinkerTool': {
+ 'LinkTimeCodeGeneration': 1, # link-time code generation
+ 'OptimizeReferences': 2, # /OPT:REF
+ 'EnableCOMDATFolding': 2, # /OPT:ICF
+ 'LinkIncremental': 1, # disable incremental linking
+ },
+ },
+ }
+ },
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ 'StringPooling': 'true', # pool string literals
+ 'DebugInformationFormat': 3, # Generate a PDB
+ 'WarningLevel': 3,
+ 'BufferSecurityCheck': 'true',
+ 'ExceptionHandling': 1, # /EHsc
+ 'SuppressStartupBanner': 'true',
+ 'WarnAsError': 'false',
+ 'AdditionalOptions': [
+ '/MP', # compile across multiple CPUs
+ ],
+ },
+ 'VCLibrarianTool': {
+ },
+ 'VCLinkerTool': {
+ 'GenerateDebugInformation': 'true',
+ 'RandomizedBaseAddress': 2, # enable ASLR
+ 'DataExecutionPrevention': 2, # enable DEP
+ 'AllowIsolation': 'true',
+ 'SuppressStartupBanner': 'true',
+ 'target_conditions': [
+ ['_type=="executable"', {
+ 'SubSystem': 1, # console executable
+ }],
+ ],
+ },
+ },
+ 'conditions': [
+ ['OS == "win"', {
+ 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
+ 'defines': [
+ 'WIN32',
+ # we don't really want VC++ warning us about
+ # how dangerous C functions are...
+ '_CRT_SECURE_NO_DEPRECATE',
+ # ... or that C implementations shouldn't use
+ # POSIX names
+ '_CRT_NONSTDC_NO_DEPRECATE',
+ ],
+ 'target_conditions': [
+ ['target_arch=="x64"', {
+ 'msvs_configuration_platform': 'x64'
+ }]
+ ]
+ }],
+ ['OS in "freebsd linux openbsd solaris android"', {
+ 'cflags': [ '-Wall' ],
+ 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
+ 'target_conditions': [
+ ['_type=="static_library"', {
+ 'standalone_static_library': 1, # disable thin archive which needs binutils >= 2.19
+ }],
+ ],
+ 'conditions': [
+ [ 'host_arch != target_arch and target_arch=="ia32"', {
+ 'cflags': [ '-m32' ],
+ 'ldflags': [ '-m32' ],
+ }],
+ [ 'OS=="linux"', {
+ 'cflags': [ '-ansi' ],
+ }],
+ [ 'OS=="solaris"', {
+ 'cflags': [ '-pthreads' ],
+ 'ldflags': [ '-pthreads' ],
+ }],
+ [ 'OS not in "solaris android"', {
+ 'cflags': [ '-pthread' ],
+ 'ldflags': [ '-pthread' ],
+ }],
+ [ 'visibility=="hidden" and (clang==1 or gcc_version >= 40)', {
+ 'cflags': [ '-fvisibility=hidden' ],
+ }],
+ ],
+ }],
+ ['OS=="mac"', {
+ 'xcode_settings': {
+ 'ALWAYS_SEARCH_USER_PATHS': 'NO',
+ 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
+ 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
+ # (Equivalent to -fPIC)
+ 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
+ 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
+ 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
+ # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
+ 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
+ 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
+ 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
+ 'PREBINDING': 'NO', # No -Wl,-prebind
+ 'USE_HEADERMAP': 'NO',
+ 'OTHER_CFLAGS': [
+ '-fstrict-aliasing',
+ ],
+ 'WARNING_CFLAGS': [
+ '-Wall',
+ '-Wendif-labels',
+ '-W',
+ '-Wno-unused-parameter',
+ ],
+ },
+ 'conditions': [
+ ['target_arch=="ia32"', {
+ 'xcode_settings': {'ARCHS': ['i386']},
+ }],
+ ['target_arch=="x64"', {
+ 'xcode_settings': {'ARCHS': ['x86_64']},
+ }],
+ ],
+ 'target_conditions': [
+ ['_type!="static_library"', {
+ 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
+ }],
+ ],
+ }],
+ ['OS=="solaris"', {
+ 'cflags': [ '-fno-omit-frame-pointer' ],
+ # pull in V8's postmortem metadata
+ 'ldflags': [ '-Wl,-z,allextract' ]
+ }],
+ ],
+ },
+}
diff --git a/third-party/libuv/configure.ac b/third-party/libuv/configure.ac
new file mode 100644
index 0000000000..ffa09b45c2
--- /dev/null
+++ b/third-party/libuv/configure.ac
@@ -0,0 +1,55 @@
+# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+AC_PREREQ(2.57)
+AC_INIT([libuv], [0.11.19], [https://github.com/joyent/libuv/issues])
+AC_CONFIG_MACRO_DIR([m4])
+m4_include([m4/libuv-extra-automake-flags.m4])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
+AC_CANONICAL_HOST
+AC_ENABLE_SHARED
+AC_ENABLE_STATIC
+AC_PROG_CC
+AM_PROG_CC_C_O
+# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+LT_INIT
+# TODO(bnoordhuis) Check for -pthread vs. -pthreads
+AC_CHECK_LIB([dl], [dlopen])
+AC_CHECK_LIB([kstat], [kstat_lookup])
+AC_CHECK_LIB([kvm], [kvm_open])
+AC_CHECK_LIB([nsl], [gethostbyname])
+AC_CHECK_LIB([perfstat], [perfstat_cpu])
+AC_CHECK_LIB([pthread], [pthread_mutex_init])
+AC_CHECK_LIB([rt], [clock_gettime])
+AC_CHECK_LIB([sendfile], [sendfile])
+AC_CHECK_LIB([socket], [socket])
+AC_SYS_LARGEFILE
+AM_CONDITIONAL([AIX], [AS_CASE([$host_os], [aix*], [true], [false])])
+AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os], [darwin*], [true], [false])])
+AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os], [freebsd*], [true], [false])])
+AM_CONDITIONAL([LINUX], [AS_CASE([$host_os], [linux*], [true], [false])])
+AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os], [netbsd*], [true], [false])])
+AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os], [openbsd*], [true], [false])])
+AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os], [solaris*], [true], [false])])
+AM_CONDITIONAL([WINNT], [AS_CASE([$host_os], [mingw*], [true], [false])])
+PANDORA_ENABLE_DTRACE
+AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes)
+AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" = "xyes"])
+AS_IF([test "x$PKG_CONFIG" = "xyes"], [
+ AC_CONFIG_FILES([libuv.pc])
+])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/third-party/libuv/gyp_uv.py b/third-party/libuv/gyp_uv.py
new file mode 100755
index 0000000000..4ba69167d9
--- /dev/null
+++ b/third-party/libuv/gyp_uv.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+import glob
+import platform
+import os
+import subprocess
+import sys
+
+CC = os.environ.get('CC', 'cc')
+script_dir = os.path.dirname(__file__)
+uv_root = os.path.normpath(script_dir)
+output_dir = os.path.join(os.path.abspath(uv_root), 'out')
+
+sys.path.insert(0, os.path.join(uv_root, 'build', 'gyp', 'pylib'))
+try:
+ import gyp
+except ImportError:
+ print('You need to install gyp in build/gyp first. See the README.')
+ sys.exit(42)
+
+
+def host_arch():
+ machine = platform.machine()
+ if machine == 'i386': return 'ia32'
+ if machine == 'x86_64': return 'x64'
+ if machine.startswith('arm'): return 'arm'
+ if machine.startswith('mips'): return 'mips'
+ return machine # Return as-is and hope for the best.
+
+
+def compiler_version():
+ proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
+ is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
+ proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
+ version = proc.communicate()[0].split('.')
+ version = map(int, version[:2])
+ version = tuple(version)
+ return (version, is_clang)
+
+
+def run_gyp(args):
+ rc = gyp.main(args)
+ if rc != 0:
+ print 'Error running GYP'
+ sys.exit(rc)
+
+
+if __name__ == '__main__':
+ args = sys.argv[1:]
+
+ # GYP bug.
+ # On msvs it will crash if it gets an absolute path.
+ # On Mac/make it will crash if it doesn't get an absolute path.
+ if sys.platform == 'win32':
+ args.append(os.path.join(uv_root, 'uv.gyp'))
+ common_fn = os.path.join(uv_root, 'common.gypi')
+ options_fn = os.path.join(uv_root, 'options.gypi')
+ # we force vs 2010 over 2008 which would otherwise be the default for gyp
+ if not os.environ.get('GYP_MSVS_VERSION'):
+ os.environ['GYP_MSVS_VERSION'] = '2010'
+ else:
+ args.append(os.path.join(os.path.abspath(uv_root), 'uv.gyp'))
+ common_fn = os.path.join(os.path.abspath(uv_root), 'common.gypi')
+ options_fn = os.path.join(os.path.abspath(uv_root), 'options.gypi')
+
+ if os.path.exists(common_fn):
+ args.extend(['-I', common_fn])
+
+ if os.path.exists(options_fn):
+ args.extend(['-I', options_fn])
+
+ args.append('--depth=' + uv_root)
+
+ # There's a bug with windows which doesn't allow this feature.
+ if sys.platform != 'win32':
+ if '-f' not in args:
+ args.extend('-f make'.split())
+ if 'eclipse' not in args and 'ninja' not in args:
+ args.extend(['-Goutput_dir=' + output_dir])
+ args.extend(['--generator-output', output_dir])
+ (major, minor), is_clang = compiler_version()
+ args.append('-Dgcc_version=%d' % (10 * major + minor))
+ args.append('-Dclang=%d' % int(is_clang))
+
+ if not any(a.startswith('-Dhost_arch=') for a in args):
+ args.append('-Dhost_arch=%s' % host_arch())
+
+ if not any(a.startswith('-Dtarget_arch=') for a in args):
+ args.append('-Dtarget_arch=%s' % host_arch())
+
+ if not any(a.startswith('-Dlibrary=') for a in args):
+ args.append('-Dlibrary=static_library')
+
+ if not any(a.startswith('-Dcomponent=') for a in args):
+ args.append('-Dcomponent=static_library')
+
+ gyp_args = list(args)
+ print gyp_args
+ run_gyp(gyp_args)
diff --git a/third-party/libuv/include/pthread-fixes.h b/third-party/libuv/include/pthread-fixes.h
new file mode 100644
index 0000000000..230ce3178d
--- /dev/null
+++ b/third-party/libuv/include/pthread-fixes.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2013, Sony Mobile Communications AB
+ * Copyright (c) 2012, Google Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER 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.
+*/
+
+#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
+#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
+
+#include <pthread.h>
+
+
+/*Android doesn't provide pthread_barrier_t for now.*/
+#ifndef PTHREAD_BARRIER_SERIAL_THREAD
+
+/* Anything except 0 will do here.*/
+#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345
+
+typedef struct {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ unsigned count;
+} pthread_barrier_t;
+
+int pthread_barrier_init(pthread_barrier_t* barrier,
+ const void* barrier_attr,
+ unsigned count);
+
+int pthread_barrier_wait(pthread_barrier_t* barrier);
+int pthread_barrier_destroy(pthread_barrier_t *barrier);
+#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */
+
+int pthread_yield(void);
+#endif /* GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H */
diff --git a/third-party/libuv/include/stdint-msvc2008.h b/third-party/libuv/include/stdint-msvc2008.h
new file mode 100644
index 0000000000..d02608a597
--- /dev/null
+++ b/third-party/libuv/include/stdint-msvc2008.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/third-party/libuv/include/tree.h b/third-party/libuv/include/tree.h
new file mode 100644
index 0000000000..f936416e3d
--- /dev/null
+++ b/third-party/libuv/include/tree.h
@@ -0,0 +1,768 @@
+/*-
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UV_TREE_H_
+#define UV_TREE_H_
+
+#ifndef UV__UNUSED
+# if __GNUC__
+# define UV__UNUSED __attribute__((unused))
+# else
+# define UV__UNUSED
+# endif
+#endif
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure. Every operation
+ * on the tree causes a splay to happen. The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree. On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n). The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute. It fulfills a set of conditions:
+ * - every search path from the root to a leaf consists of the
+ * same number of black nodes,
+ * - each red node (except for the root) has a black parent,
+ * - each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#define SPLAY_HEAD(name, type) \
+struct name { \
+ struct type *sph_root; /* root of the tree */ \
+}
+
+#define SPLAY_INITIALIZER(root) \
+ { NULL }
+
+#define SPLAY_INIT(root) do { \
+ (root)->sph_root = NULL; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ENTRY(type) \
+struct { \
+ struct type *spe_left; /* left element */ \
+ struct type *spe_right; /* right element */ \
+}
+
+#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
+#define SPLAY_ROOT(head) (head)->sph_root
+#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) do { \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) do { \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+} while (/*CONSTCOND*/ 0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
+ SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp) \
+void name##_SPLAY(struct name *, struct type *); \
+void name##_SPLAY_MINMAX(struct name *, int); \
+struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
+struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
+ \
+/* Finds the node with the same key as elm */ \
+static __inline struct type * \
+name##_SPLAY_FIND(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) \
+ return(NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) \
+ return (head->sph_root); \
+ return (NULL); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_NEXT(struct name *head, struct type *elm) \
+{ \
+ name##_SPLAY(head, elm); \
+ if (SPLAY_RIGHT(elm, field) != NULL) { \
+ elm = SPLAY_RIGHT(elm, field); \
+ while (SPLAY_LEFT(elm, field) != NULL) { \
+ elm = SPLAY_LEFT(elm, field); \
+ } \
+ } else \
+ elm = NULL; \
+ return (elm); \
+} \
+ \
+static __inline struct type * \
+name##_SPLAY_MIN_MAX(struct name *head, int val) \
+{ \
+ name##_SPLAY_MINMAX(head, val); \
+ return (SPLAY_ROOT(head)); \
+}
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp) \
+struct type * \
+name##_SPLAY_INSERT(struct name *head, struct type *elm) \
+{ \
+ if (SPLAY_EMPTY(head)) { \
+ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
+ } else { \
+ int __comp; \
+ name##_SPLAY(head, elm); \
+ __comp = (cmp)(elm, (head)->sph_root); \
+ if(__comp < 0) { \
+ SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_RIGHT(elm, field) = (head)->sph_root; \
+ SPLAY_LEFT((head)->sph_root, field) = NULL; \
+ } else if (__comp > 0) { \
+ SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT(elm, field) = (head)->sph_root; \
+ SPLAY_RIGHT((head)->sph_root, field) = NULL; \
+ } else \
+ return ((head)->sph_root); \
+ } \
+ (head)->sph_root = (elm); \
+ return (NULL); \
+} \
+ \
+struct type * \
+name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *__tmp; \
+ if (SPLAY_EMPTY(head)) \
+ return (NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) { \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+ } else { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+ name##_SPLAY(head, elm); \
+ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
+ } \
+ return (elm); \
+ } \
+ return (NULL); \
+} \
+ \
+void \
+name##_SPLAY(struct name *head, struct type *elm) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+ int __comp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
+ __left = __right = &__node; \
+ \
+ while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) > 0){ \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+} \
+ \
+/* Splay with either the minimum or the maximum element \
+ * Used to find minimum or maximum element in tree. \
+ */ \
+void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+{ \
+ struct type __node, *__left, *__right, *__tmp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
+ __left = __right = &__node; \
+ \
+ while (1) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp < 0){ \
+ SPLAY_ROTATE_RIGHT(head, __tmp, field); \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp > 0) { \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+}
+
+#define SPLAY_NEGINF -1
+#define SPLAY_INF 1
+
+#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
+ : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head) \
+ for ((x) = SPLAY_MIN(name, head); \
+ (x) != NULL; \
+ (x) = SPLAY_NEXT(name, head, x))
+
+/* Macros that define a red-black tree */
+#define RB_HEAD(name, type) \
+struct name { \
+ struct type *rbh_root; /* root of the tree */ \
+}
+
+#define RB_INITIALIZER(root) \
+ { NULL }
+
+#define RB_INIT(root) do { \
+ (root)->rbh_root = NULL; \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_BLACK 0
+#define RB_RED 1
+#define RB_ENTRY(type) \
+struct { \
+ struct type *rbe_left; /* left element */ \
+ struct type *rbe_right; /* right element */ \
+ struct type *rbe_parent; /* parent element */ \
+ int rbe_color; /* node color */ \
+}
+
+#define RB_LEFT(elm, field) (elm)->field.rbe_left
+#define RB_RIGHT(elm, field) (elm)->field.rbe_right
+#define RB_PARENT(elm, field) (elm)->field.rbe_parent
+#define RB_COLOR(elm, field) (elm)->field.rbe_color
+#define RB_ROOT(head) (head)->rbh_root
+#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
+
+#define RB_SET(elm, parent, field) do { \
+ RB_PARENT(elm, field) = parent; \
+ RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
+ RB_COLOR(elm, field) = RB_RED; \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_SET_BLACKRED(black, red, field) do { \
+ RB_COLOR(black, field) = RB_BLACK; \
+ RB_COLOR(red, field) = RB_RED; \
+} while (/*CONSTCOND*/ 0)
+
+#ifndef RB_AUGMENT
+#define RB_AUGMENT(x) do {} while (0)
+#endif
+
+#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
+ (tmp) = RB_RIGHT(elm, field); \
+ if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
+ RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_LEFT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+ if ((RB_PARENT(tmp, field))) \
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
+} while (/*CONSTCOND*/ 0)
+
+#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
+ (tmp) = RB_LEFT(elm, field); \
+ if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
+ RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
+ } \
+ RB_AUGMENT(elm); \
+ if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
+ if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
+ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
+ else \
+ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
+ } else \
+ (head)->rbh_root = (tmp); \
+ RB_RIGHT(tmp, field) = (elm); \
+ RB_PARENT(elm, field) = (tmp); \
+ RB_AUGMENT(tmp); \
+ if ((RB_PARENT(tmp, field))) \
+ RB_AUGMENT(RB_PARENT(tmp, field)); \
+} while (/*CONSTCOND*/ 0)
+
+/* Generates prototypes and inline functions */
+#define RB_PROTOTYPE(name, type, field, cmp) \
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
+#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
+ RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
+#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
+attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
+attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
+attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
+attr struct type *name##_RB_INSERT(struct name *, struct type *); \
+attr struct type *name##_RB_FIND(struct name *, struct type *); \
+attr struct type *name##_RB_NFIND(struct name *, struct type *); \
+attr struct type *name##_RB_NEXT(struct type *); \
+attr struct type *name##_RB_PREV(struct type *); \
+attr struct type *name##_RB_MINMAX(struct name *, int); \
+ \
+
+/* Main rb operation.
+ * Moves node close to the key of elm to top
+ */
+#define RB_GENERATE(name, type, field, cmp) \
+ RB_GENERATE_INTERNAL(name, type, field, cmp,)
+#define RB_GENERATE_STATIC(name, type, field, cmp) \
+ RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
+#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
+attr void \
+name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
+{ \
+ struct type *parent, *gparent, *tmp; \
+ while ((parent = RB_PARENT(elm, field)) != NULL && \
+ RB_COLOR(parent, field) == RB_RED) { \
+ gparent = RB_PARENT(parent, field); \
+ if (parent == RB_LEFT(gparent, field)) { \
+ tmp = RB_RIGHT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_RIGHT(parent, field) == elm) { \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_RIGHT(head, gparent, tmp, field); \
+ } else { \
+ tmp = RB_LEFT(gparent, field); \
+ if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
+ RB_COLOR(tmp, field) = RB_BLACK; \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ elm = gparent; \
+ continue; \
+ } \
+ if (RB_LEFT(parent, field) == elm) { \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ tmp = parent; \
+ parent = elm; \
+ elm = tmp; \
+ } \
+ RB_SET_BLACKRED(parent, gparent, field); \
+ RB_ROTATE_LEFT(head, gparent, tmp, field); \
+ } \
+ } \
+ RB_COLOR(head->rbh_root, field) = RB_BLACK; \
+} \
+ \
+attr void \
+name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
+ struct type *elm) \
+{ \
+ struct type *tmp; \
+ while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
+ elm != RB_ROOT(head)) { \
+ if (RB_LEFT(parent, field) == elm) { \
+ tmp = RB_RIGHT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
+ struct type *oleft; \
+ if ((oleft = RB_LEFT(tmp, field)) \
+ != NULL) \
+ RB_COLOR(oleft, field) = RB_BLACK; \
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_RIGHT(head, tmp, oleft, field); \
+ tmp = RB_RIGHT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_RIGHT(tmp, field)) \
+ RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
+ RB_ROTATE_LEFT(head, parent, tmp, field); \
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } else { \
+ tmp = RB_LEFT(parent, field); \
+ if (RB_COLOR(tmp, field) == RB_RED) { \
+ RB_SET_BLACKRED(tmp, parent, field); \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ tmp = RB_LEFT(parent, field); \
+ } \
+ if ((RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
+ (RB_RIGHT(tmp, field) == NULL || \
+ RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
+ RB_COLOR(tmp, field) = RB_RED; \
+ elm = parent; \
+ parent = RB_PARENT(elm, field); \
+ } else { \
+ if (RB_LEFT(tmp, field) == NULL || \
+ RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
+ struct type *oright; \
+ if ((oright = RB_RIGHT(tmp, field)) \
+ != NULL) \
+ RB_COLOR(oright, field) = RB_BLACK; \
+ RB_COLOR(tmp, field) = RB_RED; \
+ RB_ROTATE_LEFT(head, tmp, oright, field); \
+ tmp = RB_LEFT(parent, field); \
+ } \
+ RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
+ RB_COLOR(parent, field) = RB_BLACK; \
+ if (RB_LEFT(tmp, field)) \
+ RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
+ RB_ROTATE_RIGHT(head, parent, tmp, field); \
+ elm = RB_ROOT(head); \
+ break; \
+ } \
+ } \
+ } \
+ if (elm) \
+ RB_COLOR(elm, field) = RB_BLACK; \
+} \
+ \
+attr struct type * \
+name##_RB_REMOVE(struct name *head, struct type *elm) \
+{ \
+ struct type *child, *parent, *old = elm; \
+ int color; \
+ if (RB_LEFT(elm, field) == NULL) \
+ child = RB_RIGHT(elm, field); \
+ else if (RB_RIGHT(elm, field) == NULL) \
+ child = RB_LEFT(elm, field); \
+ else { \
+ struct type *left; \
+ elm = RB_RIGHT(elm, field); \
+ while ((left = RB_LEFT(elm, field)) != NULL) \
+ elm = left; \
+ child = RB_RIGHT(elm, field); \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+ if (RB_PARENT(elm, field) == old) \
+ parent = elm; \
+ (elm)->field = (old)->field; \
+ if (RB_PARENT(old, field)) { \
+ if (RB_LEFT(RB_PARENT(old, field), field) == old) \
+ RB_LEFT(RB_PARENT(old, field), field) = elm; \
+ else \
+ RB_RIGHT(RB_PARENT(old, field), field) = elm; \
+ RB_AUGMENT(RB_PARENT(old, field)); \
+ } else \
+ RB_ROOT(head) = elm; \
+ RB_PARENT(RB_LEFT(old, field), field) = elm; \
+ if (RB_RIGHT(old, field)) \
+ RB_PARENT(RB_RIGHT(old, field), field) = elm; \
+ if (parent) { \
+ left = parent; \
+ do { \
+ RB_AUGMENT(left); \
+ } while ((left = RB_PARENT(left, field)) != NULL); \
+ } \
+ goto color; \
+ } \
+ parent = RB_PARENT(elm, field); \
+ color = RB_COLOR(elm, field); \
+ if (child) \
+ RB_PARENT(child, field) = parent; \
+ if (parent) { \
+ if (RB_LEFT(parent, field) == elm) \
+ RB_LEFT(parent, field) = child; \
+ else \
+ RB_RIGHT(parent, field) = child; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = child; \
+color: \
+ if (color == RB_BLACK) \
+ name##_RB_REMOVE_COLOR(head, parent, child); \
+ return (old); \
+} \
+ \
+/* Inserts a node into the RB tree */ \
+attr struct type * \
+name##_RB_INSERT(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp; \
+ struct type *parent = NULL; \
+ int comp = 0; \
+ tmp = RB_ROOT(head); \
+ while (tmp) { \
+ parent = tmp; \
+ comp = (cmp)(elm, parent); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ RB_SET(elm, parent, field); \
+ if (parent != NULL) { \
+ if (comp < 0) \
+ RB_LEFT(parent, field) = elm; \
+ else \
+ RB_RIGHT(parent, field) = elm; \
+ RB_AUGMENT(parent); \
+ } else \
+ RB_ROOT(head) = elm; \
+ name##_RB_INSERT_COLOR(head, elm); \
+ return (NULL); \
+} \
+ \
+/* Finds the node with the same key as elm */ \
+attr struct type * \
+name##_RB_FIND(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ int comp; \
+ while (tmp) { \
+ comp = cmp(elm, tmp); \
+ if (comp < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ return (NULL); \
+} \
+ \
+/* Finds the first node greater than or equal to the search key */ \
+attr struct type * \
+name##_RB_NFIND(struct name *head, struct type *elm) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ struct type *res = NULL; \
+ int comp; \
+ while (tmp) { \
+ comp = cmp(elm, tmp); \
+ if (comp < 0) { \
+ res = tmp; \
+ tmp = RB_LEFT(tmp, field); \
+ } \
+ else if (comp > 0) \
+ tmp = RB_RIGHT(tmp, field); \
+ else \
+ return (tmp); \
+ } \
+ return (res); \
+} \
+ \
+/* ARGSUSED */ \
+attr struct type * \
+name##_RB_NEXT(struct type *elm) \
+{ \
+ if (RB_RIGHT(elm, field)) { \
+ elm = RB_RIGHT(elm, field); \
+ while (RB_LEFT(elm, field)) \
+ elm = RB_LEFT(elm, field); \
+ } else { \
+ if (RB_PARENT(elm, field) && \
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ else { \
+ while (RB_PARENT(elm, field) && \
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ elm = RB_PARENT(elm, field); \
+ } \
+ } \
+ return (elm); \
+} \
+ \
+/* ARGSUSED */ \
+attr struct type * \
+name##_RB_PREV(struct type *elm) \
+{ \
+ if (RB_LEFT(elm, field)) { \
+ elm = RB_LEFT(elm, field); \
+ while (RB_RIGHT(elm, field)) \
+ elm = RB_RIGHT(elm, field); \
+ } else { \
+ if (RB_PARENT(elm, field) && \
+ (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ else { \
+ while (RB_PARENT(elm, field) && \
+ (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
+ elm = RB_PARENT(elm, field); \
+ elm = RB_PARENT(elm, field); \
+ } \
+ } \
+ return (elm); \
+} \
+ \
+attr struct type * \
+name##_RB_MINMAX(struct name *head, int val) \
+{ \
+ struct type *tmp = RB_ROOT(head); \
+ struct type *parent = NULL; \
+ while (tmp) { \
+ parent = tmp; \
+ if (val < 0) \
+ tmp = RB_LEFT(tmp, field); \
+ else \
+ tmp = RB_RIGHT(tmp, field); \
+ } \
+ return (parent); \
+}
+
+#define RB_NEGINF -1
+#define RB_INF 1
+
+#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
+#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
+#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
+#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
+#define RB_PREV(name, x, y) name##_RB_PREV(y)
+#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
+#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
+
+#define RB_FOREACH(x, name, head) \
+ for ((x) = RB_MIN(name, head); \
+ (x) != NULL; \
+ (x) = name##_RB_NEXT(x))
+
+#define RB_FOREACH_FROM(x, name, y) \
+ for ((x) = (y); \
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_SAFE(x, name, head, y) \
+ for ((x) = RB_MIN(name, head); \
+ ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_REVERSE(x, name, head) \
+ for ((x) = RB_MAX(name, head); \
+ (x) != NULL; \
+ (x) = name##_RB_PREV(x))
+
+#define RB_FOREACH_REVERSE_FROM(x, name, y) \
+ for ((x) = (y); \
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
+ (x) = (y))
+
+#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
+ for ((x) = RB_MAX(name, head); \
+ ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
+ (x) = (y))
+
+#endif /* UV_TREE_H_ */
diff --git a/third-party/libuv/include/uv-bsd.h b/third-party/libuv/include/uv-bsd.h
new file mode 100644
index 0000000000..2d72b3d771
--- /dev/null
+++ b/third-party/libuv/include/uv-bsd.h
@@ -0,0 +1,34 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_BSD_H
+#define UV_BSD_H
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ uv__io_t event_watcher; \
+
+#define UV_IO_PRIVATE_PLATFORM_FIELDS \
+ int rcount; \
+ int wcount; \
+
+#define UV_HAVE_KQUEUE 1
+
+#endif /* UV_BSD_H */
diff --git a/third-party/libuv/include/uv-darwin.h b/third-party/libuv/include/uv-darwin.h
new file mode 100644
index 0000000000..24bc35b581
--- /dev/null
+++ b/third-party/libuv/include/uv-darwin.h
@@ -0,0 +1,63 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_DARWIN_H
+#define UV_DARWIN_H
+
+#if defined(__APPLE__) && defined(__MACH__)
+# include <mach/mach.h>
+# include <mach/task.h>
+# include <mach/semaphore.h>
+# include <TargetConditionals.h>
+# define UV_PLATFORM_SEM_T semaphore_t
+#endif
+
+#define UV_IO_PRIVATE_PLATFORM_FIELDS \
+ int rcount; \
+ int wcount; \
+
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv_thread_t cf_thread; \
+ void* _cf_reserved; \
+ void* cf_state; \
+ uv_mutex_t cf_mutex; \
+ uv_sem_t cf_sem; \
+ void* cf_signals[2]; \
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ uv__io_t event_watcher; \
+ char* realpath; \
+ int realpath_len; \
+ int cf_flags; \
+ uv_async_t* cf_cb; \
+ void* cf_events[2]; \
+ void* cf_member[2]; \
+ int cf_error; \
+ uv_mutex_t cf_mutex; \
+
+#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
+ void* select; \
+
+#define UV_HAVE_KQUEUE 1
+
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+
+#endif /* UV_DARWIN_H */
diff --git a/third-party/libuv/include/uv-errno.h b/third-party/libuv/include/uv-errno.h
new file mode 100644
index 0000000000..797bcab93b
--- /dev/null
+++ b/third-party/libuv/include/uv-errno.h
@@ -0,0 +1,373 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_ERRNO_H_
+#define UV_ERRNO_H_
+
+#include <errno.h>
+
+#define UV__EOF (-4095)
+#define UV__UNKNOWN (-4094)
+
+#define UV__EAI_ADDRFAMILY (-3000)
+#define UV__EAI_AGAIN (-3001)
+#define UV__EAI_BADFLAGS (-3002)
+#define UV__EAI_CANCELED (-3003)
+#define UV__EAI_FAIL (-3004)
+#define UV__EAI_FAMILY (-3005)
+#define UV__EAI_MEMORY (-3006)
+#define UV__EAI_NODATA (-3007)
+#define UV__EAI_NONAME (-3008)
+#define UV__EAI_OVERFLOW (-3009)
+#define UV__EAI_SERVICE (-3010)
+#define UV__EAI_SOCKTYPE (-3011)
+#define UV__EAI_SYSTEM (-3012) /* TODO(bnoordhuis) Return system error. */
+#define UV__EAI_BADHINTS (-3013)
+#define UV__EAI_PROTOCOL (-3014)
+
+/* Only map to the system errno on non-Windows platforms. It's apparently
+ * a fairly common practice for Windows programmers to redefine errno codes.
+ */
+#if defined(E2BIG) && !defined(_WIN32)
+# define UV__E2BIG (-E2BIG)
+#else
+# define UV__E2BIG (-4093)
+#endif
+
+#if defined(EACCES) && !defined(_WIN32)
+# define UV__EACCES (-EACCES)
+#else
+# define UV__EACCES (-4092)
+#endif
+
+#if defined(EADDRINFO) && !defined(_WIN32)
+# define UV__EADDRINFO EADDRINFO
+#else
+# define UV__EADDRINFO (-4091)
+#endif
+
+#if defined(EADDRINUSE) && !defined(_WIN32)
+# define UV__EADDRINUSE (-EADDRINUSE)
+#else
+# define UV__EADDRINUSE (-4091)
+#endif
+
+#if defined(EADDRNOTAVAIL) && !defined(_WIN32)
+# define UV__EADDRNOTAVAIL (-EADDRNOTAVAIL)
+#else
+# define UV__EADDRNOTAVAIL (-4090)
+#endif
+
+#if defined(EAFNOSUPPORT) && !defined(_WIN32)
+# define UV__EAFNOSUPPORT (-EAFNOSUPPORT)
+#else
+# define UV__EAFNOSUPPORT (-4089)
+#endif
+
+#if defined(EAGAIN) && !defined(_WIN32)
+# define UV__EAGAIN (-EAGAIN)
+#else
+# define UV__EAGAIN (-4088)
+#endif
+
+#if defined(EALREADY) && !defined(_WIN32)
+# define UV__EALREADY (-EALREADY)
+#else
+# define UV__EALREADY (-4084)
+#endif
+
+#if defined(EBADF) && !defined(_WIN32)
+# define UV__EBADF (-EBADF)
+#else
+# define UV__EBADF (-4083)
+#endif
+
+#if defined(EBUSY) && !defined(_WIN32)
+# define UV__EBUSY (-EBUSY)
+#else
+# define UV__EBUSY (-4082)
+#endif
+
+#if defined(ECANCELED) && !defined(_WIN32)
+# define UV__ECANCELED (-ECANCELED)
+#else
+# define UV__ECANCELED (-4081)
+#endif
+
+#if defined(ECHARSET) && !defined(_WIN32)
+# define UV__ECHARSET (-ECHARSET)
+#else
+# define UV__ECHARSET (-4080)
+#endif
+
+#if defined(ECONNABORTED) && !defined(_WIN32)
+# define UV__ECONNABORTED (-ECONNABORTED)
+#else
+# define UV__ECONNABORTED (-4079)
+#endif
+
+#if defined(ECONNREFUSED) && !defined(_WIN32)
+# define UV__ECONNREFUSED (-ECONNREFUSED)
+#else
+# define UV__ECONNREFUSED (-4078)
+#endif
+
+#if defined(ECONNRESET) && !defined(_WIN32)
+# define UV__ECONNRESET (-ECONNRESET)
+#else
+# define UV__ECONNRESET (-4077)
+#endif
+
+#if defined(EDESTADDRREQ) && !defined(_WIN32)
+# define UV__EDESTADDRREQ (-EDESTADDRREQ)
+#else
+# define UV__EDESTADDRREQ (-4076)
+#endif
+
+#if defined(EEXIST) && !defined(_WIN32)
+# define UV__EEXIST (-EEXIST)
+#else
+# define UV__EEXIST (-4075)
+#endif
+
+#if defined(EFAULT) && !defined(_WIN32)
+# define UV__EFAULT (-EFAULT)
+#else
+# define UV__EFAULT (-4074)
+#endif
+
+#if defined(EHOSTUNREACH) && !defined(_WIN32)
+# define UV__EHOSTUNREACH (-EHOSTUNREACH)
+#else
+# define UV__EHOSTUNREACH (-4073)
+#endif
+
+#if defined(EINTR) && !defined(_WIN32)
+# define UV__EINTR (-EINTR)
+#else
+# define UV__EINTR (-4072)
+#endif
+
+#if defined(EINVAL) && !defined(_WIN32)
+# define UV__EINVAL (-EINVAL)
+#else
+# define UV__EINVAL (-4071)
+#endif
+
+#if defined(EIO) && !defined(_WIN32)
+# define UV__EIO (-EIO)
+#else
+# define UV__EIO (-4070)
+#endif
+
+#if defined(EISCONN) && !defined(_WIN32)
+# define UV__EISCONN (-EISCONN)
+#else
+# define UV__EISCONN (-4069)
+#endif
+
+#if defined(EISDIR) && !defined(_WIN32)
+# define UV__EISDIR (-EISDIR)
+#else
+# define UV__EISDIR (-4068)
+#endif
+
+#if defined(ELOOP) && !defined(_WIN32)
+# define UV__ELOOP (-ELOOP)
+#else
+# define UV__ELOOP (-4067)
+#endif
+
+#if defined(EMFILE) && !defined(_WIN32)
+# define UV__EMFILE (-EMFILE)
+#else
+# define UV__EMFILE (-4066)
+#endif
+
+#if defined(EMSGSIZE) && !defined(_WIN32)
+# define UV__EMSGSIZE (-EMSGSIZE)
+#else
+# define UV__EMSGSIZE (-4065)
+#endif
+
+#if defined(ENAMETOOLONG) && !defined(_WIN32)
+# define UV__ENAMETOOLONG (-ENAMETOOLONG)
+#else
+# define UV__ENAMETOOLONG (-4064)
+#endif
+
+#if defined(ENETDOWN) && !defined(_WIN32)
+# define UV__ENETDOWN (-ENETDOWN)
+#else
+# define UV__ENETDOWN (-4063)
+#endif
+
+#if defined(ENETUNREACH) && !defined(_WIN32)
+# define UV__ENETUNREACH (-ENETUNREACH)
+#else
+# define UV__ENETUNREACH (-4062)
+#endif
+
+#if defined(ENFILE) && !defined(_WIN32)
+# define UV__ENFILE (-ENFILE)
+#else
+# define UV__ENFILE (-4061)
+#endif
+
+#if defined(ENOBUFS) && !defined(_WIN32)
+# define UV__ENOBUFS (-ENOBUFS)
+#else
+# define UV__ENOBUFS (-4060)
+#endif
+
+#if defined(ENODEV) && !defined(_WIN32)
+# define UV__ENODEV (-ENODEV)
+#else
+# define UV__ENODEV (-4059)
+#endif
+
+#if defined(ENOENT) && !defined(_WIN32)
+# define UV__ENOENT (-ENOENT)
+#else
+# define UV__ENOENT (-4058)
+#endif
+
+#if defined(ENOMEM) && !defined(_WIN32)
+# define UV__ENOMEM (-ENOMEM)
+#else
+# define UV__ENOMEM (-4057)
+#endif
+
+#if defined(ENONET) && !defined(_WIN32)
+# define UV__ENONET (-ENONET)
+#else
+# define UV__ENONET (-4056)
+#endif
+
+#if defined(ENOSPC) && !defined(_WIN32)
+# define UV__ENOSPC (-ENOSPC)
+#else
+# define UV__ENOSPC (-4055)
+#endif
+
+#if defined(ENOSYS) && !defined(_WIN32)
+# define UV__ENOSYS (-ENOSYS)
+#else
+# define UV__ENOSYS (-4054)
+#endif
+
+#if defined(ENOTCONN) && !defined(_WIN32)
+# define UV__ENOTCONN (-ENOTCONN)
+#else
+# define UV__ENOTCONN (-4053)
+#endif
+
+#if defined(ENOTDIR) && !defined(_WIN32)
+# define UV__ENOTDIR (-ENOTDIR)
+#else
+# define UV__ENOTDIR (-4052)
+#endif
+
+#if defined(ENOTEMPTY) && !defined(_WIN32)
+# define UV__ENOTEMPTY (-ENOTEMPTY)
+#else
+# define UV__ENOTEMPTY (-4051)
+#endif
+
+#if defined(ENOTSOCK) && !defined(_WIN32)
+# define UV__ENOTSOCK (-ENOTSOCK)
+#else
+# define UV__ENOTSOCK (-4050)
+#endif
+
+#if defined(ENOTSUP) && !defined(_WIN32)
+# define UV__ENOTSUP (-ENOTSUP)
+#else
+# define UV__ENOTSUP (-4049)
+#endif
+
+#if defined(EPERM) && !defined(_WIN32)
+# define UV__EPERM (-EPERM)
+#else
+# define UV__EPERM (-4048)
+#endif
+
+#if defined(EPIPE) && !defined(_WIN32)
+# define UV__EPIPE (-EPIPE)
+#else
+# define UV__EPIPE (-4047)
+#endif
+
+#if defined(EPROTO) && !defined(_WIN32)
+# define UV__EPROTO (-EPROTO)
+#else
+# define UV__EPROTO (-4046)
+#endif
+
+#if defined(EPROTONOSUPPORT) && !defined(_WIN32)
+# define UV__EPROTONOSUPPORT (-EPROTONOSUPPORT)
+#else
+# define UV__EPROTONOSUPPORT (-4045)
+#endif
+
+#if defined(EPROTOTYPE) && !defined(_WIN32)
+# define UV__EPROTOTYPE (-EPROTOTYPE)
+#else
+# define UV__EPROTOTYPE (-4044)
+#endif
+
+#if defined(EROFS) && !defined(_WIN32)
+# define UV__EROFS (-EROFS)
+#else
+# define UV__EROFS (-4043)
+#endif
+
+#if defined(ESHUTDOWN) && !defined(_WIN32)
+# define UV__ESHUTDOWN (-ESHUTDOWN)
+#else
+# define UV__ESHUTDOWN (-4042)
+#endif
+
+#if defined(ESPIPE) && !defined(_WIN32)
+# define UV__ESPIPE (-ESPIPE)
+#else
+# define UV__ESPIPE (-4041)
+#endif
+
+#if defined(ESRCH) && !defined(_WIN32)
+# define UV__ESRCH (-ESRCH)
+#else
+# define UV__ESRCH (-4040)
+#endif
+
+#if defined(ETIMEDOUT) && !defined(_WIN32)
+# define UV__ETIMEDOUT (-ETIMEDOUT)
+#else
+# define UV__ETIMEDOUT (-4039)
+#endif
+
+#if defined(EXDEV) && !defined(_WIN32)
+# define UV__EXDEV (-EXDEV)
+#else
+# define UV__EXDEV (-4037)
+#endif
+
+#endif /* UV_ERRNO_H_ */
diff --git a/third-party/libuv/include/uv-linux.h b/third-party/libuv/include/uv-linux.h
new file mode 100644
index 0000000000..62ebfe2a02
--- /dev/null
+++ b/third-party/libuv/include/uv-linux.h
@@ -0,0 +1,36 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_LINUX_H
+#define UV_LINUX_H
+
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv__io_t inotify_read_watcher; \
+ void* inotify_watchers; \
+ int inotify_fd; \
+
+#define UV_PLATFORM_FS_EVENT_FIELDS \
+ void* watchers[2]; \
+ int wd; \
+
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+
+#endif /* UV_LINUX_H */
diff --git a/third-party/libuv/include/uv-sunos.h b/third-party/libuv/include/uv-sunos.h
new file mode 100644
index 0000000000..042166424e
--- /dev/null
+++ b/third-party/libuv/include/uv-sunos.h
@@ -0,0 +1,44 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_SUNOS_H
+#define UV_SUNOS_H
+
+#include <sys/port.h>
+#include <port.h>
+
+/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c,
+ * add the fs_event fields even when this version of SunOS doesn't support
+ * file watching.
+ */
+#define UV_PLATFORM_LOOP_FIELDS \
+ uv__io_t fs_event_watcher; \
+ int fs_fd; \
+
+#if defined(PORT_SOURCE_FILE)
+
+# define UV_PLATFORM_FS_EVENT_FIELDS \
+ file_obj_t fo; \
+ int fd; \
+
+#endif /* defined(PORT_SOURCE_FILE) */
+
+#endif /* UV_SUNOS_H */
diff --git a/third-party/libuv/include/uv-unix.h b/third-party/libuv/include/uv-unix.h
new file mode 100644
index 0000000000..45006092be
--- /dev/null
+++ b/third-party/libuv/include/uv-unix.h
@@ -0,0 +1,329 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_UNIX_H
+#define UV_UNIX_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <termios.h>
+#include <pwd.h>
+
+#include <semaphore.h>
+#include <pthread.h>
+#ifdef __ANDROID__
+#include "pthread-fixes.h"
+#endif
+#include <signal.h>
+
+#if defined(__linux__)
+# include "uv-linux.h"
+#elif defined(__sun)
+# include "uv-sunos.h"
+#elif defined(__APPLE__)
+# include "uv-darwin.h"
+#elif defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# include "uv-bsd.h"
+#endif
+
+#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
+# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
+#endif
+
+struct uv__io_s;
+struct uv__async;
+struct uv_loop_s;
+
+typedef void (*uv__io_cb)(struct uv_loop_s* loop,
+ struct uv__io_s* w,
+ unsigned int events);
+typedef struct uv__io_s uv__io_t;
+
+struct uv__io_s {
+ uv__io_cb cb;
+ void* pending_queue[2];
+ void* watcher_queue[2];
+ unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
+ unsigned int events; /* Current event mask. */
+ int fd;
+ UV_IO_PRIVATE_PLATFORM_FIELDS
+};
+
+typedef void (*uv__async_cb)(struct uv_loop_s* loop,
+ struct uv__async* w,
+ unsigned int nevents);
+
+struct uv__async {
+ uv__async_cb cb;
+ uv__io_t io_watcher;
+ int wfd;
+};
+
+struct uv__work {
+ void (*work)(struct uv__work *w);
+ void (*done)(struct uv__work *w, int status);
+ struct uv_loop_s* loop;
+ void* wq[2];
+};
+
+#ifndef UV_PLATFORM_SEM_T
+# define UV_PLATFORM_SEM_T sem_t
+#endif
+
+#ifndef UV_PLATFORM_LOOP_FIELDS
+# define UV_PLATFORM_LOOP_FIELDS /* empty */
+#endif
+
+#ifndef UV_PLATFORM_FS_EVENT_FIELDS
+# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */
+#endif
+
+#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS
+# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */
+#endif
+
+/* Note: May be cast to struct iovec. See writev(2). */
+typedef struct {
+ char* base;
+ size_t len;
+} uv_buf_t;
+
+typedef int uv_file;
+typedef int uv_os_sock_t;
+
+#define UV_ONCE_INIT PTHREAD_ONCE_INIT
+
+typedef pthread_once_t uv_once_t;
+typedef pthread_t uv_thread_t;
+typedef pthread_mutex_t uv_mutex_t;
+typedef pthread_rwlock_t uv_rwlock_t;
+typedef UV_PLATFORM_SEM_T uv_sem_t;
+typedef pthread_cond_t uv_cond_t;
+typedef pthread_key_t uv_key_t;
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+typedef struct {
+ unsigned int n;
+ unsigned int count;
+ uv_mutex_t mutex;
+ uv_sem_t turnstile1;
+ uv_sem_t turnstile2;
+} uv_barrier_t;
+
+#else /* defined(__APPLE__) && defined(__MACH__) */
+
+typedef pthread_barrier_t uv_barrier_t;
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+/* Platform-specific definitions for uv_spawn support. */
+typedef gid_t uv_gid_t;
+typedef uid_t uv_uid_t;
+
+/* Platform-specific definitions for uv_dlopen support. */
+#define UV_DYNAMIC /* empty */
+
+typedef struct {
+ void* handle;
+ char* errmsg;
+} uv_lib_t;
+
+#define UV_LOOP_PRIVATE_FIELDS \
+ unsigned long flags; \
+ int backend_fd; \
+ void* pending_queue[2]; \
+ void* watcher_queue[2]; \
+ uv__io_t** watchers; \
+ unsigned int nwatchers; \
+ unsigned int nfds; \
+ void* wq[2]; \
+ uv_mutex_t wq_mutex; \
+ uv_async_t wq_async; \
+ uv_handle_t* closing_handles; \
+ void* process_handles[1][2]; \
+ void* prepare_handles[2]; \
+ void* check_handles[2]; \
+ void* idle_handles[2]; \
+ void* async_handles[2]; \
+ struct uv__async async_watcher; \
+ /* RB_HEAD(uv__timers, uv_timer_s) */ \
+ struct uv__timers { \
+ struct uv_timer_s* rbh_root; \
+ } timer_handles; \
+ uint64_t time; \
+ int signal_pipefd[2]; \
+ uv__io_t signal_io_watcher; \
+ uv_signal_t child_watcher; \
+ int emfile_fd; \
+ uint64_t timer_counter; \
+ UV_PLATFORM_LOOP_FIELDS \
+
+#define UV_REQ_TYPE_PRIVATE /* empty */
+
+#define UV_REQ_PRIVATE_FIELDS /* empty */
+
+#define UV_PRIVATE_REQ_TYPES /* empty */
+
+#define UV_WRITE_PRIVATE_FIELDS \
+ void* queue[2]; \
+ unsigned int write_index; \
+ uv_buf_t* bufs; \
+ unsigned int nbufs; \
+ int error; \
+ uv_buf_t bufsml[4]; \
+
+#define UV_CONNECT_PRIVATE_FIELDS \
+ void* queue[2]; \
+
+#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
+
+#define UV_UDP_SEND_PRIVATE_FIELDS \
+ void* queue[2]; \
+ struct sockaddr_in6 addr; \
+ unsigned int nbufs; \
+ uv_buf_t* bufs; \
+ ssize_t status; \
+ uv_udp_send_cb send_cb; \
+ uv_buf_t bufsml[4]; \
+
+#define UV_HANDLE_PRIVATE_FIELDS \
+ int flags; \
+ uv_handle_t* next_closing; \
+
+#define UV_STREAM_PRIVATE_FIELDS \
+ uv_connect_t *connect_req; \
+ uv_shutdown_t *shutdown_req; \
+ uv__io_t io_watcher; \
+ void* write_queue[2]; \
+ void* write_completed_queue[2]; \
+ uv_connection_cb connection_cb; \
+ int delayed_error; \
+ int accepted_fd; \
+ UV_STREAM_PRIVATE_PLATFORM_FIELDS \
+
+#define UV_TCP_PRIVATE_FIELDS /* empty */
+
+#define UV_UDP_PRIVATE_FIELDS \
+ uv_alloc_cb alloc_cb; \
+ uv_udp_recv_cb recv_cb; \
+ uv__io_t io_watcher; \
+ void* write_queue[2]; \
+ void* write_completed_queue[2]; \
+
+#define UV_PIPE_PRIVATE_FIELDS \
+ const char* pipe_fname; /* strdup'ed */
+
+#define UV_POLL_PRIVATE_FIELDS \
+ uv__io_t io_watcher;
+
+#define UV_PREPARE_PRIVATE_FIELDS \
+ uv_prepare_cb prepare_cb; \
+ void* queue[2]; \
+
+#define UV_CHECK_PRIVATE_FIELDS \
+ uv_check_cb check_cb; \
+ void* queue[2]; \
+
+#define UV_IDLE_PRIVATE_FIELDS \
+ uv_idle_cb idle_cb; \
+ void* queue[2]; \
+
+#define UV_ASYNC_PRIVATE_FIELDS \
+ uv_async_cb async_cb; \
+ void* queue[2]; \
+ int pending; \
+
+#define UV_TIMER_PRIVATE_FIELDS \
+ /* RB_ENTRY(uv_timer_s) tree_entry; */ \
+ struct { \
+ struct uv_timer_s* rbe_left; \
+ struct uv_timer_s* rbe_right; \
+ struct uv_timer_s* rbe_parent; \
+ int rbe_color; \
+ } tree_entry; \
+ uv_timer_cb timer_cb; \
+ uint64_t timeout; \
+ uint64_t repeat; \
+ uint64_t start_id;
+
+#define UV_GETADDRINFO_PRIVATE_FIELDS \
+ struct uv__work work_req; \
+ uv_getaddrinfo_cb cb; \
+ struct addrinfo* hints; \
+ char* hostname; \
+ char* service; \
+ struct addrinfo* res; \
+ int retcode;
+
+#define UV_PROCESS_PRIVATE_FIELDS \
+ void* queue[2]; \
+ int status; \
+
+#define UV_FS_PRIVATE_FIELDS \
+ const char *new_path; \
+ uv_file file; \
+ int flags; \
+ mode_t mode; \
+ void* buf; \
+ size_t len; \
+ off_t off; \
+ uv_uid_t uid; \
+ uv_gid_t gid; \
+ double atime; \
+ double mtime; \
+ struct uv__work work_req; \
+
+#define UV_WORK_PRIVATE_FIELDS \
+ struct uv__work work_req;
+
+#define UV_TTY_PRIVATE_FIELDS \
+ struct termios orig_termios; \
+ int mode;
+
+#define UV_SIGNAL_PRIVATE_FIELDS \
+ /* RB_ENTRY(uv_signal_s) tree_entry; */ \
+ struct { \
+ struct uv_signal_s* rbe_left; \
+ struct uv_signal_s* rbe_right; \
+ struct uv_signal_s* rbe_parent; \
+ int rbe_color; \
+ } tree_entry; \
+ /* Use two counters here so we don have to fiddle with atomics. */ \
+ unsigned int caught_signals; \
+ unsigned int dispatched_signals;
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+ uv_fs_event_cb cb; \
+ UV_PLATFORM_FS_EVENT_FIELDS \
+
+#endif /* UV_UNIX_H */
diff --git a/third-party/libuv/include/uv-win.h b/third-party/libuv/include/uv-win.h
new file mode 100644
index 0000000000..e4e1f839f0
--- /dev/null
+++ b/third-party/libuv/include/uv-win.h
@@ -0,0 +1,589 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x0502
+#endif
+
+#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
+typedef intptr_t ssize_t;
+# define _SSIZE_T_
+# define _SSIZE_T_DEFINED
+#endif
+
+#include <winsock2.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#include <process.h>
+#include <signal.h>
+#include <sys/stat.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#include "tree.h"
+
+#define MAX_PIPENAME_LEN 256
+
+#ifndef S_IFLNK
+# define S_IFLNK 0xA000
+#endif
+
+/* Additional signals supported by uv_signal and or uv_kill. The CRT defines
+ * the following signals already:
+ *
+ * #define SIGINT 2
+ * #define SIGILL 4
+ * #define SIGABRT_COMPAT 6
+ * #define SIGFPE 8
+ * #define SIGSEGV 11
+ * #define SIGTERM 15
+ * #define SIGBREAK 21
+ * #define SIGABRT 22
+ *
+ * The additional signals have values that are common on other Unix
+ * variants (Linux and Darwin)
+ */
+#define SIGHUP 1
+#define SIGKILL 9
+#define SIGWINCH 28
+
+/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */
+/* unix-like platforms. However MinGW doesn't define it, so we do. */
+#ifndef SIGABRT_COMPAT
+# define SIGABRT_COMPAT 6
+#endif
+
+/*
+ * Guids and typedefs for winsock extension functions
+ * Mingw32 doesn't have these :-(
+ */
+#ifndef WSAID_ACCEPTEX
+# define WSAID_ACCEPTEX \
+ {0xb5367df1, 0xcbac, 0x11cf, \
+ {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+# define WSAID_CONNECTEX \
+ {0x25a207b9, 0xddf3, 0x4660, \
+ {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}}
+
+# define WSAID_GETACCEPTEXSOCKADDRS \
+ {0xb5367df2, 0xcbac, 0x11cf, \
+ {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+# define WSAID_DISCONNECTEX \
+ {0x7fda2e11, 0x8630, 0x436f, \
+ {0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}}
+
+# define WSAID_TRANSMITFILE \
+ {0xb5367df0, 0xcbac, 0x11cf, \
+ {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
+
+ typedef BOOL PASCAL (*LPFN_ACCEPTEX)
+ (SOCKET sListenSocket,
+ SOCKET sAcceptSocket,
+ PVOID lpOutputBuffer,
+ DWORD dwReceiveDataLength,
+ DWORD dwLocalAddressLength,
+ DWORD dwRemoteAddressLength,
+ LPDWORD lpdwBytesReceived,
+ LPOVERLAPPED lpOverlapped);
+
+ typedef BOOL PASCAL (*LPFN_CONNECTEX)
+ (SOCKET s,
+ const struct sockaddr* name,
+ int namelen,
+ PVOID lpSendBuffer,
+ DWORD dwSendDataLength,
+ LPDWORD lpdwBytesSent,
+ LPOVERLAPPED lpOverlapped);
+
+ typedef void PASCAL (*LPFN_GETACCEPTEXSOCKADDRS)
+ (PVOID lpOutputBuffer,
+ DWORD dwReceiveDataLength,
+ DWORD dwLocalAddressLength,
+ DWORD dwRemoteAddressLength,
+ LPSOCKADDR* LocalSockaddr,
+ LPINT LocalSockaddrLength,
+ LPSOCKADDR* RemoteSockaddr,
+ LPINT RemoteSockaddrLength);
+
+ typedef BOOL PASCAL (*LPFN_DISCONNECTEX)
+ (SOCKET hSocket,
+ LPOVERLAPPED lpOverlapped,
+ DWORD dwFlags,
+ DWORD reserved);
+
+ typedef BOOL PASCAL (*LPFN_TRANSMITFILE)
+ (SOCKET hSocket,
+ HANDLE hFile,
+ DWORD nNumberOfBytesToWrite,
+ DWORD nNumberOfBytesPerSend,
+ LPOVERLAPPED lpOverlapped,
+ LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
+ DWORD dwFlags);
+
+ typedef PVOID RTL_SRWLOCK;
+ typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+#endif
+
+typedef int (WSAAPI* LPFN_WSARECV)
+ (SOCKET socket,
+ LPWSABUF buffers,
+ DWORD buffer_count,
+ LPDWORD bytes,
+ LPDWORD flags,
+ LPWSAOVERLAPPED overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+
+typedef int (WSAAPI* LPFN_WSARECVFROM)
+ (SOCKET socket,
+ LPWSABUF buffers,
+ DWORD buffer_count,
+ LPDWORD bytes,
+ LPDWORD flags,
+ struct sockaddr* addr,
+ LPINT addr_len,
+ LPWSAOVERLAPPED overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+
+#ifndef _NTDEF_
+ typedef LONG NTSTATUS;
+ typedef NTSTATUS *PNTSTATUS;
+#endif
+
+#ifndef RTL_CONDITION_VARIABLE_INIT
+ typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+#endif
+
+typedef struct _AFD_POLL_HANDLE_INFO {
+ HANDLE Handle;
+ ULONG Events;
+ NTSTATUS Status;
+} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO;
+
+typedef struct _AFD_POLL_INFO {
+ LARGE_INTEGER Timeout;
+ ULONG NumberOfHandles;
+ ULONG Exclusive;
+ AFD_POLL_HANDLE_INFO Handles[1];
+} AFD_POLL_INFO, *PAFD_POLL_INFO;
+
+#define UV_MSAFD_PROVIDER_COUNT 3
+
+
+/**
+ * It should be possible to cast uv_buf_t[] to WSABUF[]
+ * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
+ */
+typedef struct uv_buf_t {
+ ULONG len;
+ char* base;
+} uv_buf_t;
+
+typedef int uv_file;
+
+typedef SOCKET uv_os_sock_t;
+
+typedef HANDLE uv_thread_t;
+
+typedef HANDLE uv_sem_t;
+
+typedef CRITICAL_SECTION uv_mutex_t;
+
+/* This condition variable implementation is based on the SetEvent solution
+ * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * We could not use the SignalObjectAndWait solution (section 3.4) because
+ * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
+ * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
+ */
+
+typedef union {
+ CONDITION_VARIABLE cond_var;
+ struct {
+ unsigned int waiters_count;
+ CRITICAL_SECTION waiters_count_lock;
+ HANDLE signal_event;
+ HANDLE broadcast_event;
+ } fallback;
+} uv_cond_t;
+
+typedef union {
+ /* srwlock_ has type SRWLOCK, but not all toolchains define this type in */
+ /* windows.h. */
+ SRWLOCK srwlock_;
+ struct {
+ uv_mutex_t read_mutex_;
+ uv_mutex_t write_mutex_;
+ unsigned int num_readers_;
+ } fallback_;
+} uv_rwlock_t;
+
+typedef struct {
+ unsigned int n;
+ unsigned int count;
+ uv_mutex_t mutex;
+ uv_sem_t turnstile1;
+ uv_sem_t turnstile2;
+} uv_barrier_t;
+
+typedef struct {
+ DWORD tls_index;
+} uv_key_t;
+
+#define UV_ONCE_INIT { 0, NULL }
+
+typedef struct uv_once_s {
+ unsigned char ran;
+ HANDLE event;
+} uv_once_t;
+
+/* Platform-specific definitions for uv_spawn support. */
+typedef unsigned char uv_uid_t;
+typedef unsigned char uv_gid_t;
+
+/* Platform-specific definitions for uv_dlopen support. */
+#define UV_DYNAMIC FAR WINAPI
+typedef struct {
+ HMODULE handle;
+ char* errmsg;
+} uv_lib_t;
+
+RB_HEAD(uv_timer_tree_s, uv_timer_s);
+
+#define UV_LOOP_PRIVATE_FIELDS \
+ /* The loop's I/O completion port */ \
+ HANDLE iocp; \
+ /* The current time according to the event loop. in msecs. */ \
+ uint64_t time; \
+ /* GetTickCount() result when the event loop time was last updated. */ \
+ DWORD last_tick_count; \
+ /* Tail of a single-linked circular queue of pending reqs. If the queue */ \
+ /* is empty, tail_ is NULL. If there is only one item, */ \
+ /* tail_->next_req == tail_ */ \
+ uv_req_t* pending_reqs_tail; \
+ /* Head of a single-linked list of closed handles */ \
+ uv_handle_t* endgame_handles; \
+ /* The head of the timers tree */ \
+ struct uv_timer_tree_s timers; \
+ /* Lists of active loop (prepare / check / idle) watchers */ \
+ uv_prepare_t* prepare_handles; \
+ uv_check_t* check_handles; \
+ uv_idle_t* idle_handles; \
+ /* This pointer will refer to the prepare/check/idle handle whose */ \
+ /* callback is scheduled to be called next. This is needed to allow */ \
+ /* safe removal from one of the lists above while that list being */ \
+ /* iterated over. */ \
+ uv_prepare_t* next_prepare_handle; \
+ uv_check_t* next_check_handle; \
+ uv_idle_t* next_idle_handle; \
+ /* This handle holds the peer sockets for the fast variant of uv_poll_t */ \
+ SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \
+ /* Counter to keep track of active tcp streams */ \
+ unsigned int active_tcp_streams; \
+ /* Counter to keep track of active udp streams */ \
+ unsigned int active_udp_streams; \
+ /* Counter to started timer */ \
+ uint64_t timer_counter;
+
+#define UV_REQ_TYPE_PRIVATE \
+ /* TODO: remove the req suffix */ \
+ UV_ACCEPT, \
+ UV_FS_EVENT_REQ, \
+ UV_POLL_REQ, \
+ UV_PROCESS_EXIT, \
+ UV_READ, \
+ UV_UDP_RECV, \
+ UV_WAKEUP, \
+ UV_SIGNAL_REQ,
+
+#define UV_REQ_PRIVATE_FIELDS \
+ union { \
+ /* Used by I/O operations */ \
+ struct { \
+ OVERLAPPED overlapped; \
+ size_t queued_bytes; \
+ }; \
+ }; \
+ struct uv_req_s* next_req;
+
+#define UV_WRITE_PRIVATE_FIELDS \
+ int ipc_header; \
+ uv_buf_t write_buffer; \
+ HANDLE event_handle; \
+ HANDLE wait_handle;
+
+#define UV_CONNECT_PRIVATE_FIELDS \
+ /* empty */
+
+#define UV_SHUTDOWN_PRIVATE_FIELDS \
+ /* empty */
+
+#define UV_UDP_SEND_PRIVATE_FIELDS \
+ /* empty */
+
+#define UV_PRIVATE_REQ_TYPES \
+ typedef struct uv_pipe_accept_s { \
+ UV_REQ_FIELDS \
+ HANDLE pipeHandle; \
+ struct uv_pipe_accept_s* next_pending; \
+ } uv_pipe_accept_t; \
+ \
+ typedef struct uv_tcp_accept_s { \
+ UV_REQ_FIELDS \
+ SOCKET accept_socket; \
+ char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
+ HANDLE event_handle; \
+ HANDLE wait_handle; \
+ struct uv_tcp_accept_s* next_pending; \
+ } uv_tcp_accept_t; \
+ \
+ typedef struct uv_read_s { \
+ UV_REQ_FIELDS \
+ HANDLE event_handle; \
+ HANDLE wait_handle; \
+ } uv_read_t;
+
+#define uv_stream_connection_fields \
+ unsigned int write_reqs_pending; \
+ uv_shutdown_t* shutdown_req;
+
+#define uv_stream_server_fields \
+ uv_connection_cb connection_cb;
+
+#define UV_STREAM_PRIVATE_FIELDS \
+ unsigned int reqs_pending; \
+ int activecnt; \
+ uv_read_t read_req; \
+ union { \
+ struct { uv_stream_connection_fields }; \
+ struct { uv_stream_server_fields }; \
+ };
+
+#define uv_tcp_server_fields \
+ uv_tcp_accept_t* accept_reqs; \
+ unsigned int processed_accepts; \
+ uv_tcp_accept_t* pending_accepts; \
+ LPFN_ACCEPTEX func_acceptex;
+
+#define uv_tcp_connection_fields \
+ uv_buf_t read_buffer; \
+ LPFN_CONNECTEX func_connectex;
+
+#define UV_TCP_PRIVATE_FIELDS \
+ SOCKET socket; \
+ int bind_error; \
+ union { \
+ struct { uv_tcp_server_fields }; \
+ struct { uv_tcp_connection_fields }; \
+ };
+
+#define UV_UDP_PRIVATE_FIELDS \
+ SOCKET socket; \
+ unsigned int reqs_pending; \
+ int activecnt; \
+ uv_req_t recv_req; \
+ uv_buf_t recv_buffer; \
+ struct sockaddr_storage recv_from; \
+ int recv_from_len; \
+ uv_udp_recv_cb recv_cb; \
+ uv_alloc_cb alloc_cb; \
+ LPFN_WSARECV func_wsarecv; \
+ LPFN_WSARECVFROM func_wsarecvfrom;
+
+#define uv_pipe_server_fields \
+ int pending_instances; \
+ uv_pipe_accept_t* accept_reqs; \
+ uv_pipe_accept_t* pending_accepts;
+
+#define uv_pipe_connection_fields \
+ uv_timer_t* eof_timer; \
+ uv_write_t ipc_header_write_req; \
+ int ipc_pid; \
+ uint64_t remaining_ipc_rawdata_bytes; \
+ unsigned char reserved[sizeof(void*)]; \
+ struct { \
+ WSAPROTOCOL_INFOW* socket_info; \
+ int tcp_connection; \
+ } pending_ipc_info; \
+ uv_write_t* non_overlapped_writes_tail;
+
+#define UV_PIPE_PRIVATE_FIELDS \
+ HANDLE handle; \
+ WCHAR* name; \
+ union { \
+ struct { uv_pipe_server_fields }; \
+ struct { uv_pipe_connection_fields }; \
+ };
+
+/* TODO: put the parser states in an union - TTY handles are always */
+/* half-duplex so read-state can safely overlap write-state. */
+#define UV_TTY_PRIVATE_FIELDS \
+ HANDLE handle; \
+ union { \
+ struct { \
+ /* Used for readable TTY handles */ \
+ HANDLE read_line_handle; \
+ uv_buf_t read_line_buffer; \
+ HANDLE read_raw_wait; \
+ /* Fields used for translating win keystrokes into vt100 characters */ \
+ char last_key[8]; \
+ unsigned char last_key_offset; \
+ unsigned char last_key_len; \
+ WCHAR last_utf16_high_surrogate; \
+ INPUT_RECORD last_input_record; \
+ }; \
+ struct { \
+ /* Used for writable TTY handles */ \
+ /* utf8-to-utf16 conversion state */ \
+ unsigned int utf8_codepoint; \
+ unsigned char utf8_bytes_left; \
+ /* eol conversion state */ \
+ unsigned char previous_eol; \
+ /* ansi parser state */ \
+ unsigned char ansi_parser_state; \
+ unsigned char ansi_csi_argc; \
+ unsigned short ansi_csi_argv[4]; \
+ COORD saved_position; \
+ WORD saved_attributes; \
+ }; \
+ };
+
+#define UV_POLL_PRIVATE_FIELDS \
+ SOCKET socket; \
+ /* Used in fast mode */ \
+ SOCKET peer_socket; \
+ AFD_POLL_INFO afd_poll_info_1; \
+ AFD_POLL_INFO afd_poll_info_2; \
+ /* Used in fast and slow mode. */ \
+ uv_req_t poll_req_1; \
+ uv_req_t poll_req_2; \
+ unsigned char submitted_events_1; \
+ unsigned char submitted_events_2; \
+ unsigned char mask_events_1; \
+ unsigned char mask_events_2; \
+ unsigned char events;
+
+#define UV_TIMER_PRIVATE_FIELDS \
+ RB_ENTRY(uv_timer_s) tree_entry; \
+ uint64_t due; \
+ uint64_t repeat; \
+ uint64_t start_id; \
+ uv_timer_cb timer_cb;
+
+#define UV_ASYNC_PRIVATE_FIELDS \
+ struct uv_req_s async_req; \
+ uv_async_cb async_cb; \
+ /* char to avoid alignment issues */ \
+ char volatile async_sent;
+
+#define UV_PREPARE_PRIVATE_FIELDS \
+ uv_prepare_t* prepare_prev; \
+ uv_prepare_t* prepare_next; \
+ uv_prepare_cb prepare_cb;
+
+#define UV_CHECK_PRIVATE_FIELDS \
+ uv_check_t* check_prev; \
+ uv_check_t* check_next; \
+ uv_check_cb check_cb;
+
+#define UV_IDLE_PRIVATE_FIELDS \
+ uv_idle_t* idle_prev; \
+ uv_idle_t* idle_next; \
+ uv_idle_cb idle_cb;
+
+#define UV_HANDLE_PRIVATE_FIELDS \
+ uv_handle_t* endgame_next; \
+ unsigned int flags;
+
+#define UV_GETADDRINFO_PRIVATE_FIELDS \
+ uv_getaddrinfo_cb getaddrinfo_cb; \
+ void* alloc; \
+ WCHAR* node; \
+ WCHAR* service; \
+ struct addrinfoW* hints; \
+ struct addrinfoW* res; \
+ int retcode;
+
+#define UV_PROCESS_PRIVATE_FIELDS \
+ struct uv_process_exit_s { \
+ UV_REQ_FIELDS \
+ } exit_req; \
+ BYTE* child_stdio_buffer; \
+ int exit_signal; \
+ HANDLE wait_handle; \
+ HANDLE process_handle; \
+ volatile char exit_cb_pending;
+
+#define UV_FS_PRIVATE_FIELDS \
+ int flags; \
+ DWORD sys_errno_; \
+ union { \
+ /* TODO: remove me in 0.9. */ \
+ WCHAR* pathw; \
+ int fd; \
+ }; \
+ union { \
+ struct { \
+ int mode; \
+ WCHAR* new_pathw; \
+ int file_flags; \
+ int fd_out; \
+ void* buf; \
+ size_t length; \
+ int64_t offset; \
+ }; \
+ struct { \
+ double atime; \
+ double mtime; \
+ }; \
+ };
+
+#define UV_WORK_PRIVATE_FIELDS \
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+ struct uv_fs_event_req_s { \
+ UV_REQ_FIELDS \
+ } req; \
+ HANDLE dir_handle; \
+ int req_pending; \
+ uv_fs_event_cb cb; \
+ WCHAR* filew; \
+ WCHAR* short_filew; \
+ WCHAR* dirw; \
+ char* buffer;
+
+#define UV_SIGNAL_PRIVATE_FIELDS \
+ RB_ENTRY(uv_signal_s) tree_entry; \
+ struct uv_req_s signal_req; \
+ unsigned long pending_signum;
+
+int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
+ char* utf8Buffer, size_t utf8Size);
+int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
+ size_t utf16Size);
+
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
diff --git a/third-party/libuv/include/uv.h b/third-party/libuv/include/uv.h
new file mode 100644
index 0000000000..4eeade74c4
--- /dev/null
+++ b/third-party/libuv/include/uv.h
@@ -0,0 +1,2135 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* See http://nikhilm.github.com/uvbook/ for an introduction. */
+
+#ifndef UV_H
+#define UV_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+ /* Windows - set up dll import/export decorators. */
+# if defined(BUILDING_UV_SHARED)
+ /* Building shared library. */
+# define UV_EXTERN __declspec(dllexport)
+# elif defined(USING_UV_SHARED)
+ /* Using shared library. */
+# define UV_EXTERN __declspec(dllimport)
+# else
+ /* Building static library. */
+# define UV_EXTERN /* nothing */
+# endif
+#elif __GNUC__ >= 4
+# define UV_EXTERN __attribute__((visibility("default")))
+#else
+# define UV_EXTERN /* nothing */
+#endif
+
+#include "uv-errno.h"
+#include <stddef.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#if defined(_WIN32)
+# include "uv-win.h"
+#else
+# include "uv-unix.h"
+#endif
+
+/* Expand this list if necessary. */
+#define UV_ERRNO_MAP(XX) \
+ XX(E2BIG, "argument list too long") \
+ XX(EACCES, "permission denied") \
+ XX(EADDRINUSE, "address already in use") \
+ XX(EADDRNOTAVAIL, "address not available") \
+ XX(EAFNOSUPPORT, "address family not supported") \
+ XX(EAGAIN, "resource temporarily unavailable") \
+ XX(EAI_ADDRFAMILY, "address family not supported") \
+ XX(EAI_AGAIN, "temporary failure") \
+ XX(EAI_BADFLAGS, "bad ai_flags value") \
+ XX(EAI_BADHINTS, "invalid value for hints") \
+ XX(EAI_CANCELED, "request canceled") \
+ XX(EAI_FAIL, "permanent failure") \
+ XX(EAI_FAMILY, "ai_family not supported") \
+ XX(EAI_MEMORY, "out of memory") \
+ XX(EAI_NODATA, "no address") \
+ XX(EAI_NONAME, "unknown node or service") \
+ XX(EAI_OVERFLOW, "argument buffer overflow") \
+ XX(EAI_PROTOCOL, "resolved protocol is unknown") \
+ XX(EAI_SERVICE, "service not available for socket type") \
+ XX(EAI_SOCKTYPE, "socket type not supported") \
+ XX(EAI_SYSTEM, "system error") \
+ XX(EALREADY, "connection already in progress") \
+ XX(EBADF, "bad file descriptor") \
+ XX(EBUSY, "resource busy or locked") \
+ XX(ECANCELED, "operation canceled") \
+ XX(ECHARSET, "invalid Unicode character") \
+ XX(ECONNABORTED, "software caused connection abort") \
+ XX(ECONNREFUSED, "connection refused") \
+ XX(ECONNRESET, "connection reset by peer") \
+ XX(EDESTADDRREQ, "destination address required") \
+ XX(EEXIST, "file already exists") \
+ XX(EFAULT, "bad address in system call argument") \
+ XX(EHOSTUNREACH, "host is unreachable") \
+ XX(EINTR, "interrupted system call") \
+ XX(EINVAL, "invalid argument") \
+ XX(EIO, "i/o error") \
+ XX(EISCONN, "socket is already connected") \
+ XX(EISDIR, "illegal operation on a directory") \
+ XX(ELOOP, "too many symbolic links encountered") \
+ XX(EMFILE, "too many open files") \
+ XX(EMSGSIZE, "message too long") \
+ XX(ENAMETOOLONG, "name too long") \
+ XX(ENETDOWN, "network is down") \
+ XX(ENETUNREACH, "network is unreachable") \
+ XX(ENFILE, "file table overflow") \
+ XX(ENOBUFS, "no buffer space available") \
+ XX(ENODEV, "no such device") \
+ XX(ENOENT, "no such file or directory") \
+ XX(ENOMEM, "not enough memory") \
+ XX(ENONET, "machine is not on the network") \
+ XX(ENOSPC, "no space left on device") \
+ XX(ENOSYS, "function not implemented") \
+ XX(ENOTCONN, "socket is not connected") \
+ XX(ENOTDIR, "not a directory") \
+ XX(ENOTEMPTY, "directory not empty") \
+ XX(ENOTSOCK, "socket operation on non-socket") \
+ XX(ENOTSUP, "operation not supported on socket") \
+ XX(EPERM, "operation not permitted") \
+ XX(EPIPE, "broken pipe") \
+ XX(EPROTO, "protocol error") \
+ XX(EPROTONOSUPPORT, "protocol not supported") \
+ XX(EPROTOTYPE, "protocol wrong type for socket") \
+ XX(EROFS, "read-only file system") \
+ XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \
+ XX(ESPIPE, "invalid seek") \
+ XX(ESRCH, "no such process") \
+ XX(ETIMEDOUT, "connection timed out") \
+ XX(EXDEV, "cross-device link not permitted") \
+ XX(UNKNOWN, "unknown error") \
+ XX(EOF, "end of file") \
+
+#define UV_HANDLE_TYPE_MAP(XX) \
+ XX(ASYNC, async) \
+ XX(CHECK, check) \
+ XX(FS_EVENT, fs_event) \
+ XX(FS_POLL, fs_poll) \
+ XX(HANDLE, handle) \
+ XX(IDLE, idle) \
+ XX(NAMED_PIPE, pipe) \
+ XX(POLL, poll) \
+ XX(PREPARE, prepare) \
+ XX(PROCESS, process) \
+ XX(STREAM, stream) \
+ XX(TCP, tcp) \
+ XX(TIMER, timer) \
+ XX(TTY, tty) \
+ XX(UDP, udp) \
+ XX(SIGNAL, signal) \
+
+#define UV_REQ_TYPE_MAP(XX) \
+ XX(REQ, req) \
+ XX(CONNECT, connect) \
+ XX(WRITE, write) \
+ XX(SHUTDOWN, shutdown) \
+ XX(UDP_SEND, udp_send) \
+ XX(FS, fs) \
+ XX(WORK, work) \
+ XX(GETADDRINFO, getaddrinfo) \
+
+typedef enum {
+#define XX(code, _) UV_ ## code = UV__ ## code,
+ UV_ERRNO_MAP(XX)
+#undef XX
+ UV_ERRNO_MAX = UV__EOF - 1
+} uv_errno_t;
+
+typedef enum {
+ UV_UNKNOWN_HANDLE = 0,
+#define XX(uc, lc) UV_##uc,
+ UV_HANDLE_TYPE_MAP(XX)
+#undef XX
+ UV_FILE,
+ UV_HANDLE_TYPE_MAX
+} uv_handle_type;
+
+typedef enum {
+ UV_UNKNOWN_REQ = 0,
+#define XX(uc, lc) UV_##uc,
+ UV_REQ_TYPE_MAP(XX)
+#undef XX
+ UV_REQ_TYPE_PRIVATE
+ UV_REQ_TYPE_MAX
+} uv_req_type;
+
+
+/* Handle types. */
+typedef struct uv_loop_s uv_loop_t;
+typedef struct uv_handle_s uv_handle_t;
+typedef struct uv_stream_s uv_stream_t;
+typedef struct uv_tcp_s uv_tcp_t;
+typedef struct uv_udp_s uv_udp_t;
+typedef struct uv_pipe_s uv_pipe_t;
+typedef struct uv_tty_s uv_tty_t;
+typedef struct uv_poll_s uv_poll_t;
+typedef struct uv_timer_s uv_timer_t;
+typedef struct uv_prepare_s uv_prepare_t;
+typedef struct uv_check_s uv_check_t;
+typedef struct uv_idle_s uv_idle_t;
+typedef struct uv_async_s uv_async_t;
+typedef struct uv_process_s uv_process_t;
+typedef struct uv_fs_event_s uv_fs_event_t;
+typedef struct uv_fs_poll_s uv_fs_poll_t;
+typedef struct uv_signal_s uv_signal_t;
+
+/* Request types. */
+typedef struct uv_req_s uv_req_t;
+typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
+typedef struct uv_shutdown_s uv_shutdown_t;
+typedef struct uv_write_s uv_write_t;
+typedef struct uv_connect_s uv_connect_t;
+typedef struct uv_udp_send_s uv_udp_send_t;
+typedef struct uv_fs_s uv_fs_t;
+typedef struct uv_work_s uv_work_t;
+
+/* None of the above. */
+typedef struct uv_cpu_info_s uv_cpu_info_t;
+typedef struct uv_interface_address_s uv_interface_address_t;
+
+
+typedef enum {
+ UV_RUN_DEFAULT = 0,
+ UV_RUN_ONCE,
+ UV_RUN_NOWAIT
+} uv_run_mode;
+
+
+/*
+ * Returns the libuv version packed into a single integer. 8 bits are used for
+ * each component, with the patch number stored in the 8 least significant
+ * bits. E.g. for libuv 1.2.3 this would return 0x010203.
+ */
+UV_EXTERN unsigned int uv_version(void);
+
+/*
+ * Returns the libuv version number as a string. For non-release versions
+ * "-pre" is appended, so the version number could be "1.2.3-pre".
+ */
+UV_EXTERN const char* uv_version_string(void);
+
+
+/*
+ * This function must be called before any other functions in libuv.
+ *
+ * All functions besides uv_run() are non-blocking.
+ *
+ * All callbacks in libuv are made asynchronously. That is they are never
+ * made by the function that takes them as a parameter.
+ */
+UV_EXTERN uv_loop_t* uv_loop_new(void);
+UV_EXTERN void uv_loop_delete(uv_loop_t*);
+
+/*
+ * Returns the default loop.
+ */
+UV_EXTERN uv_loop_t* uv_default_loop(void);
+
+/*
+ * This function runs the event loop. It will act differently depending on the
+ * specified mode:
+ * - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
+ * zero. Always returns zero.
+ * - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
+ * there are no pending events. Returns zero when done (no active handles
+ * or requests left), or non-zero if more events are expected (meaning you
+ * should run the event loop again sometime in the future).
+ * - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
+ * pending events.
+ */
+UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
+
+/*
+ * This function checks whether the reference count, the number of active
+ * handles or requests left in the event loop, is non-zero.
+ */
+UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
+
+/*
+ * This function will stop the event loop by forcing uv_run to end
+ * as soon as possible, but not sooner than the next loop iteration.
+ * If this function was called before blocking for i/o, the loop won't
+ * block for i/o on this iteration.
+ */
+UV_EXTERN void uv_stop(uv_loop_t*);
+
+/*
+ * Manually modify the event loop's reference count. Useful if the user wants
+ * to have a handle or timeout that doesn't keep the loop alive.
+ */
+UV_EXTERN void uv_ref(uv_handle_t*);
+UV_EXTERN void uv_unref(uv_handle_t*);
+UV_EXTERN int uv_has_ref(const uv_handle_t*);
+
+/*
+ * Update the event loop's concept of "now". Libuv caches the current time
+ * at the start of the event loop tick in order to reduce the number of
+ * time-related system calls.
+ *
+ * You won't normally need to call this function unless you have callbacks
+ * that block the event loop for longer periods of time, where "longer" is
+ * somewhat subjective but probably on the order of a millisecond or more.
+ */
+UV_EXTERN void uv_update_time(uv_loop_t*);
+
+/*
+ * Return the current timestamp in milliseconds. The timestamp is cached at
+ * the start of the event loop tick, see |uv_update_time()| for details and
+ * rationale.
+ *
+ * The timestamp increases monotonically from some arbitrary point in time.
+ * Don't make assumptions about the starting point, you will only get
+ * disappointed.
+ *
+ * Use uv_hrtime() if you need sub-millisecond granularity.
+ */
+UV_EXTERN uint64_t uv_now(uv_loop_t*);
+
+/*
+ * Get backend file descriptor. Only kqueue, epoll and event ports are
+ * supported.
+ *
+ * This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to
+ * poll in one thread and run the event loop's event callbacks in another.
+ *
+ * Useful for embedding libuv's event loop in another event loop.
+ * See test/test-embed.c for an example.
+ *
+ * Note that embedding a kqueue fd in another kqueue pollset doesn't work on
+ * all platforms. It's not an error to add the fd but it never generates
+ * events.
+ */
+UV_EXTERN int uv_backend_fd(const uv_loop_t*);
+
+/*
+ * Get the poll timeout. The return value is in milliseconds, or -1 for no
+ * timeout.
+ */
+UV_EXTERN int uv_backend_timeout(const uv_loop_t*);
+
+
+/*
+ * Should prepare a buffer that libuv can use to read data into.
+ *
+ * `suggested_size` is a hint. Returning a buffer that is smaller is perfectly
+ * okay as long as `buf.len > 0`.
+ *
+ * If you return a buffer with `buf.len == 0`, libuv skips the read and calls
+ * your read or recv callback with nread=UV_ENOBUFS.
+ *
+ * Note that returning a zero-length buffer does not stop the handle, call
+ * uv_read_stop() or uv_udp_recv_stop() for that.
+ */
+typedef void (*uv_alloc_cb)(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf);
+
+/*
+ * `nread` is > 0 if there is data available, 0 if libuv is done reading for
+ * now, or < 0 on error.
+ *
+ * The callee is responsible for closing the stream when an error happens.
+ * Trying to read from the stream again is undefined.
+ *
+ * The callee is responsible for freeing the buffer, libuv does not reuse it.
+ * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
+ * EOF or error.
+ */
+typedef void (*uv_read_cb)(uv_stream_t* stream,
+ ssize_t nread,
+ const uv_buf_t* buf);
+
+/*
+ * Just like the uv_read_cb except that if the pending parameter is true
+ * then you can use uv_accept() to pull the new handle into the process.
+ * If no handle is pending then pending will be UV_UNKNOWN_HANDLE.
+ */
+typedef void (*uv_read2_cb)(uv_pipe_t* pipe,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type pending);
+
+typedef void (*uv_write_cb)(uv_write_t* req, int status);
+typedef void (*uv_connect_cb)(uv_connect_t* req, int status);
+typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
+typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
+typedef void (*uv_close_cb)(uv_handle_t* handle);
+typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events);
+typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
+/* TODO: do these really need a status argument? */
+typedef void (*uv_async_cb)(uv_async_t* handle, int status);
+typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
+typedef void (*uv_check_cb)(uv_check_t* handle, int status);
+typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
+typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal);
+typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
+typedef void (*uv_fs_cb)(uv_fs_t* req);
+typedef void (*uv_work_cb)(uv_work_t* req);
+typedef void (*uv_after_work_cb)(uv_work_t* req, int status);
+typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,
+ int status,
+ struct addrinfo* res);
+
+typedef struct {
+ long tv_sec;
+ long tv_nsec;
+} uv_timespec_t;
+
+
+typedef struct {
+ uint64_t st_dev;
+ uint64_t st_mode;
+ uint64_t st_nlink;
+ uint64_t st_uid;
+ uint64_t st_gid;
+ uint64_t st_rdev;
+ uint64_t st_ino;
+ uint64_t st_size;
+ uint64_t st_blksize;
+ uint64_t st_blocks;
+ uint64_t st_flags;
+ uint64_t st_gen;
+ uv_timespec_t st_atim;
+ uv_timespec_t st_mtim;
+ uv_timespec_t st_ctim;
+ uv_timespec_t st_birthtim;
+} uv_stat_t;
+
+
+/*
+* This will be called repeatedly after the uv_fs_event_t is initialized.
+* If uv_fs_event_t was initialized with a directory the filename parameter
+* will be a relative path to a file contained in the directory.
+* The events parameter is an ORed mask of enum uv_fs_event elements.
+*/
+typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
+ int events, int status);
+
+typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
+ int status,
+ const uv_stat_t* prev,
+ const uv_stat_t* curr);
+
+typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum);
+
+
+typedef enum {
+ UV_LEAVE_GROUP = 0,
+ UV_JOIN_GROUP
+} uv_membership;
+
+
+/*
+ * Most functions return 0 on success or an error code < 0 on failure.
+ */
+UV_EXTERN const char* uv_strerror(int err);
+UV_EXTERN const char* uv_err_name(int err);
+
+
+#define UV_REQ_FIELDS \
+ /* public */ \
+ void* data; \
+ /* read-only */ \
+ uv_req_type type; \
+ /* private */ \
+ void* active_queue[2]; \
+ UV_REQ_PRIVATE_FIELDS \
+
+/* Abstract base class of all requests. */
+struct uv_req_s {
+ UV_REQ_FIELDS
+};
+
+
+/* Platform-specific request types */
+UV_PRIVATE_REQ_TYPES
+
+
+/*
+ * uv_shutdown_t is a subclass of uv_req_t
+ *
+ * Shutdown the outgoing (write) side of a duplex stream. It waits for
+ * pending write requests to complete. The handle should refer to a
+ * initialized stream. req should be an uninitialized shutdown request
+ * struct. The cb is called after shutdown is complete.
+ */
+UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
+ uv_shutdown_cb cb);
+
+struct uv_shutdown_s {
+ UV_REQ_FIELDS
+ uv_stream_t* handle;
+ uv_shutdown_cb cb;
+ UV_SHUTDOWN_PRIVATE_FIELDS
+};
+
+
+#define UV_HANDLE_FIELDS \
+ /* public */ \
+ uv_close_cb close_cb; \
+ void* data; \
+ /* read-only */ \
+ uv_loop_t* loop; \
+ uv_handle_type type; \
+ /* private */ \
+ void* handle_queue[2]; \
+ UV_HANDLE_PRIVATE_FIELDS \
+
+/* The abstract base class of all handles. */
+struct uv_handle_s {
+ UV_HANDLE_FIELDS
+};
+
+/*
+ * Returns size of various handle types, useful for FFI
+ * bindings to allocate correct memory without copying struct
+ * definitions
+ */
+UV_EXTERN size_t uv_handle_size(uv_handle_type type);
+
+/*
+ * Returns size of request types, useful for dynamic lookup with FFI
+ */
+UV_EXTERN size_t uv_req_size(uv_req_type type);
+
+/*
+ * Returns non-zero if the handle is active, zero if it's inactive.
+ *
+ * What "active" means depends on the type of handle:
+ *
+ * - A uv_async_t handle is always active and cannot be deactivated, except
+ * by closing it with uv_close().
+ *
+ * - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
+ * deals with I/O - is active when it is doing something that involves I/O,
+ * like reading, writing, connecting, accepting new connections, etc.
+ *
+ * - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
+ * been started with a call to uv_check_start(), uv_idle_start(), etc.
+ *
+ * Rule of thumb: if a handle of type uv_foo_t has a uv_foo_start()
+ * function, then it's active from the moment that function is called.
+ * Likewise, uv_foo_stop() deactivates the handle again.
+ *
+ */
+UV_EXTERN int uv_is_active(const uv_handle_t* handle);
+
+/*
+ * Walk the list of open handles.
+ */
+UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
+
+
+/*
+ * Request handle to be closed. close_cb will be called asynchronously after
+ * this call. This MUST be called on each handle before memory is released.
+ *
+ * Note that handles that wrap file descriptors are closed immediately but
+ * close_cb will still be deferred to the next iteration of the event loop.
+ * It gives you a chance to free up any resources associated with the handle.
+ *
+ * In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
+ * have their callbacks called asynchronously with status=UV_ECANCELED.
+ */
+UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
+
+
+/*
+ * Constructor for uv_buf_t.
+ * Due to platform differences the user cannot rely on the ordering of the
+ * base and len members of the uv_buf_t struct. The user is responsible for
+ * freeing base after the uv_buf_t is done. Return struct passed by value.
+ */
+UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
+
+
+#define UV_STREAM_FIELDS \
+ /* number of bytes queued for writing */ \
+ size_t write_queue_size; \
+ uv_alloc_cb alloc_cb; \
+ uv_read_cb read_cb; \
+ uv_read2_cb read2_cb; \
+ /* private */ \
+ UV_STREAM_PRIVATE_FIELDS
+
+/*
+ * uv_stream_t is a subclass of uv_handle_t
+ *
+ * uv_stream is an abstract class.
+ *
+ * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and
+ * soon uv_file_t.
+ */
+struct uv_stream_s {
+ UV_HANDLE_FIELDS
+ UV_STREAM_FIELDS
+};
+
+UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
+
+/*
+ * This call is used in conjunction with uv_listen() to accept incoming
+ * connections. Call uv_accept after receiving a uv_connection_cb to accept
+ * the connection. Before calling uv_accept use uv_*_init() must be
+ * called on the client. Non-zero return value indicates an error.
+ *
+ * When the uv_connection_cb is called it is guaranteed that uv_accept will
+ * complete successfully the first time. If you attempt to use it more than
+ * once, it may fail. It is suggested to only call uv_accept once per
+ * uv_connection_cb call.
+ */
+UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
+
+/*
+ * Read data from an incoming stream. The callback will be made several
+ * times until there is no more data to read or uv_read_stop is called.
+ * When we've reached EOF nread will be set to UV_EOF.
+ *
+ * When nread < 0, the buf parameter might not point to a valid buffer;
+ * in that case buf.len and buf.base are both set to 0.
+ *
+ * Note that nread might also be 0, which does *not* indicate an error or
+ * eof; it happens when libuv requested a buffer through the alloc callback
+ * but then decided that it didn't need that buffer.
+ */
+UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb);
+
+UV_EXTERN int uv_read_stop(uv_stream_t*);
+
+/*
+ * Extended read methods for receiving handles over a pipe. The pipe must be
+ * initialized with ipc == 1.
+ */
+UV_EXTERN int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+ uv_read2_cb read_cb);
+
+
+/*
+ * Write data to stream. Buffers are written in order. Example:
+ *
+ * uv_buf_t a[] = {
+ * { .base = "1", .len = 1 },
+ * { .base = "2", .len = 1 }
+ * };
+ *
+ * uv_buf_t b[] = {
+ * { .base = "3", .len = 1 },
+ * { .base = "4", .len = 1 }
+ * };
+ *
+ * uv_write_t req1;
+ * uv_write_t req2;
+ *
+ * // writes "1234"
+ * uv_write(&req1, stream, a, 2);
+ * uv_write(&req2, stream, b, 2);
+ *
+ */
+UV_EXTERN int uv_write(uv_write_t* req,
+ uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb);
+
+/*
+ * Extended write function for sending handles over a pipe. The pipe must be
+ * initialized with ipc == 1.
+ * send_handle must be a TCP socket or pipe, which is a server or a connection
+ * (listening or connected state). Bound sockets or pipes will be assumed to
+ * be servers.
+ */
+UV_EXTERN int uv_write2(uv_write_t* req,
+ uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb);
+
+/*
+ * Same as `uv_write()`, but won't queue write request if it can't be completed
+ * immediately.
+ * Will return either:
+ * - positive number of bytes written
+ * - zero - if queued write is needed
+ * - negative error code
+ */
+UV_EXTERN int uv_try_write(uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs);
+
+/* uv_write_t is a subclass of uv_req_t */
+struct uv_write_s {
+ UV_REQ_FIELDS
+ uv_write_cb cb;
+ uv_stream_t* send_handle;
+ uv_stream_t* handle;
+ UV_WRITE_PRIVATE_FIELDS
+};
+
+
+/*
+ * Used to determine whether a stream is readable or writable.
+ */
+UV_EXTERN int uv_is_readable(const uv_stream_t* handle);
+UV_EXTERN int uv_is_writable(const uv_stream_t* handle);
+
+
+/*
+ * Enable or disable blocking mode for a stream.
+ *
+ * When blocking mode is enabled all writes complete synchronously. The
+ * interface remains unchanged otherwise, e.g. completion or failure of the
+ * operation will still be reported through a callback which is made
+ * asychronously.
+ *
+ * Relying too much on this API is not recommended. It is likely to change
+ * significantly in the future.
+ *
+ * On windows this currently works only for uv_pipe_t instances. On unix it
+ * works for tcp, pipe and tty instances. Be aware that changing the blocking
+ * mode on unix sets or clears the O_NONBLOCK bit. If you are sharing a handle
+ * with another process, the other process is affected by the change too,
+ * which can lead to unexpected results.
+ *
+ * Also libuv currently makes no ordering guarantee when the blocking mode
+ * is changed after write requests have already been submitted. Therefore it is
+ * recommended to set the blocking mode immediately after opening or creating
+ * the stream.
+ */
+UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking);
+
+
+/*
+ * Used to determine whether a stream is closing or closed.
+ *
+ * N.B. is only valid between the initialization of the handle
+ * and the arrival of the close callback, and cannot be used
+ * to validate the handle.
+ */
+UV_EXTERN int uv_is_closing(const uv_handle_t* handle);
+
+
+/*
+ * uv_tcp_t is a subclass of uv_stream_t
+ *
+ * Represents a TCP stream or TCP server.
+ */
+struct uv_tcp_s {
+ UV_HANDLE_FIELDS
+ UV_STREAM_FIELDS
+ UV_TCP_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
+
+/*
+ * Opens an existing file descriptor or SOCKET as a tcp handle.
+ */
+UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
+
+/* Enable/disable Nagle's algorithm. */
+UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
+
+/*
+ * Enable/disable TCP keep-alive.
+ *
+ * `delay` is the initial delay in seconds, ignored when `enable` is zero.
+ */
+UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
+ int enable,
+ unsigned int delay);
+
+/*
+ * Enable/disable simultaneous asynchronous accept requests that are
+ * queued by the operating system when listening for new tcp connections.
+ * This setting is used to tune a tcp server for the desired performance.
+ * Having simultaneous accepts can significantly improve the rate of
+ * accepting connections (which is why it is enabled by default) but
+ * may lead to uneven load distribution in multi-process setups.
+ */
+UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
+
+enum uv_tcp_flags {
+ /* Used with uv_tcp_bind, when an IPv6 address is used */
+ UV_TCP_IPV6ONLY = 1
+};
+
+/*
+ * Bind the handle to an address and port. `addr` should point to an
+ * initialized struct sockaddr_in or struct sockaddr_in6.
+ *
+ * When the port is already taken, you can expect to see an UV_EADDRINUSE
+ * error from either uv_tcp_bind(), uv_listen() or uv_tcp_connect().
+ *
+ * That is, a successful call to uv_tcp_bind() does not guarantee that
+ * the call to uv_listen() or uv_tcp_connect() will succeed as well.
+ */
+UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags);
+UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
+ int* namelen);
+UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
+ int* namelen);
+
+/*
+ * Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
+ * and an uninitialized uv_connect_t*. `addr` should point to an initialized
+ * struct sockaddr_in or struct sockaddr_in6.
+ *
+ * The callback is made when the connection has been established or when a
+ * connection error happened.
+ */
+UV_EXTERN int uv_tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ uv_connect_cb cb);
+
+/* uv_connect_t is a subclass of uv_req_t */
+struct uv_connect_s {
+ UV_REQ_FIELDS
+ uv_connect_cb cb;
+ uv_stream_t* handle;
+ UV_CONNECT_PRIVATE_FIELDS
+};
+
+
+/*
+ * UDP support.
+ */
+
+enum uv_udp_flags {
+ /* Disables dual stack mode. */
+ UV_UDP_IPV6ONLY = 1,
+ /*
+ * Indicates message was truncated because read buffer was too small. The
+ * remainder was discarded by the OS. Used in uv_udp_recv_cb.
+ */
+ UV_UDP_PARTIAL = 2
+};
+
+/*
+ * Called after a uv_udp_send() or uv_udp_send6(). status 0 indicates
+ * success otherwise error.
+ */
+typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
+
+/*
+ * Callback that is invoked when a new UDP datagram is received.
+ *
+ * handle UDP handle.
+ * nread Number of bytes that have been received.
+ * 0 if there is no more data to read. You may
+ * discard or repurpose the read buffer.
+ * < 0 if a transmission error was detected.
+ * buf uv_buf_t with the received data.
+ * addr struct sockaddr_in or struct sockaddr_in6.
+ * Valid for the duration of the callback only.
+ * flags One or more OR'ed UV_UDP_* constants.
+ * Right now only UV_UDP_PARTIAL is used.
+ */
+typedef void (*uv_udp_recv_cb)(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags);
+
+/* uv_udp_t is a subclass of uv_handle_t */
+struct uv_udp_s {
+ UV_HANDLE_FIELDS
+ UV_UDP_PRIVATE_FIELDS
+};
+
+/* uv_udp_send_t is a subclass of uv_req_t */
+struct uv_udp_send_s {
+ UV_REQ_FIELDS
+ uv_udp_t* handle;
+ uv_udp_send_cb cb;
+ UV_UDP_SEND_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize a new UDP handle. The actual socket is created lazily.
+ * Returns 0 on success.
+ */
+UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
+
+/*
+ * Opens an existing file descriptor or SOCKET as a udp handle.
+ *
+ * Unix only:
+ * The only requirement of the sock argument is that it follows the
+ * datagram contract (works in unconnected mode, supports sendmsg()/recvmsg(),
+ * etc.). In other words, other datagram-type sockets like raw sockets or
+ * netlink sockets can also be passed to this function.
+ *
+ * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
+ * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that
+ * multiple threads or processes can bind to the same address without error
+ * (provided they all set the flag) but only the last one to bind will receive
+ * any traffic, in effect "stealing" the port from the previous listener.
+ * This behavior is something of an anomaly and may be replaced by an explicit
+ * opt-in mechanism in future versions of libuv.
+ */
+UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
+
+/*
+ * Bind to a IPv4 address and port.
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with `uv_udp_init`.
+ * addr struct sockaddr_in or struct sockaddr_in6 with the address and
+ * port to bind to.
+ * flags Unused.
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ *
+ * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
+ * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that
+ * multiple threads or processes can bind to the same address without error
+ * (provided they all set the flag) but only the last one to bind will receive
+ * any traffic, in effect "stealing" the port from the previous listener.
+ * This behavior is something of an anomaly and may be replaced by an explicit
+ * opt-in mechanism in future versions of libuv.
+ */
+UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags);
+
+UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
+ int* namelen);
+
+/*
+ * Set membership for a multicast address
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with
+ * `uv_udp_init`.
+ * multicast_addr multicast address to set membership for
+ * interface_addr interface address
+ * membership Should be UV_JOIN_GROUP or UV_LEAVE_GROUP
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
+ const char* multicast_addr, const char* interface_addr,
+ uv_membership membership);
+
+/*
+ * Set IP multicast loop flag. Makes multicast packets loop back to
+ * local sockets.
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with
+ * `uv_udp_init`.
+ * on 1 for on, 0 for off
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
+
+/*
+ * Set the multicast ttl
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with
+ * `uv_udp_init`.
+ * ttl 1 through 255
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
+
+/*
+ * Set broadcast on or off
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with
+ * `uv_udp_init`.
+ * on 1 for on, 0 for off
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
+
+/*
+ * Set the time to live
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with
+ * `uv_udp_init`.
+ * ttl 1 through 255
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
+
+/*
+ * Send data. If the socket has not previously been bound with `uv_udp_bind`
+ * or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
+ * and a random port number.
+ *
+ * Arguments:
+ * req UDP request handle. Need not be initialized.
+ * handle UDP handle. Should have been initialized with `uv_udp_init`.
+ * bufs List of buffers to send.
+ * nbufs Number of buffers in `bufs`.
+ * addr Address of the remote peer. See `uv_ip4_addr`.
+ * send_cb Callback to invoke when the data has been sent out.
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ uv_udp_send_cb send_cb);
+
+/*
+ * Receive data. If the socket has not previously been bound with `uv_udp_bind`
+ * or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
+ * and a random port number.
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with `uv_udp_init`.
+ * alloc_cb Callback to invoke when temporary storage is needed.
+ * recv_cb Callback to invoke with received data.
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb);
+
+/*
+ * Stop listening for incoming datagrams.
+ *
+ * Arguments:
+ * handle UDP handle. Should have been initialized with `uv_udp_init`.
+ *
+ * Returns:
+ * 0 on success, or an error code < 0 on failure.
+ */
+UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle);
+
+
+/*
+ * uv_tty_t is a subclass of uv_stream_t
+ *
+ * Representing a stream for the console.
+ */
+struct uv_tty_s {
+ UV_HANDLE_FIELDS
+ UV_STREAM_FIELDS
+ UV_TTY_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize a new TTY stream with the given file descriptor. Usually the
+ * file descriptor will be
+ * 0 = stdin
+ * 1 = stdout
+ * 2 = stderr
+ * The last argument, readable, specifies if you plan on calling
+ * uv_read_start with this stream. stdin is readable, stdout is not.
+ *
+ * TTY streams which are not readable have blocking writes.
+ */
+UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
+
+/*
+ * Set mode. 0 for normal, 1 for raw.
+ */
+UV_EXTERN int uv_tty_set_mode(uv_tty_t*, int mode);
+
+/*
+ * To be called when the program exits. Resets TTY settings to default
+ * values for the next process to take over.
+ *
+ * This function is async signal-safe on UNIX platforms but can fail with error
+ * code UV_EBUSY if you call it when execution is inside uv_tty_set_mode().
+ */
+UV_EXTERN int uv_tty_reset_mode(void);
+
+/*
+ * Gets the current Window size. On success zero is returned.
+ */
+UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
+
+/*
+ * Used to detect what type of stream should be used with a given file
+ * descriptor. Usually this will be used during initialization to guess the
+ * type of the stdio streams.
+ * For isatty() functionality use this function and test for UV_TTY.
+ */
+UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
+
+/*
+ * uv_pipe_t is a subclass of uv_stream_t
+ *
+ * Representing a pipe stream or pipe server. On Windows this is a Named
+ * Pipe. On Unix this is a UNIX domain socket.
+ */
+struct uv_pipe_s {
+ UV_HANDLE_FIELDS
+ UV_STREAM_FIELDS
+ int ipc; /* non-zero if this pipe is used for passing handles */
+ UV_PIPE_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize a pipe. The last argument is a boolean to indicate if
+ * this pipe will be used for handle passing between processes.
+ */
+UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
+
+/*
+ * Opens an existing file descriptor or HANDLE as a pipe.
+ */
+UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
+
+/*
+ * Bind the pipe to a file path (UNIX) or a name (Windows.)
+ *
+ * Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
+ * typically between 92 and 108 bytes.
+ */
+UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
+
+/*
+ * Connect to the UNIX domain socket or the named pipe.
+ *
+ * Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
+ * typically between 92 and 108 bytes.
+ */
+UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+ const char* name, uv_connect_cb cb);
+
+/*
+ * This setting applies to Windows only.
+ * Set the number of pending pipe instance handles when the pipe server
+ * is waiting for connections.
+ */
+UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count);
+
+
+/*
+ * uv_poll_t is a subclass of uv_handle_t.
+ *
+ * The uv_poll watcher is used to watch file descriptors for readability and
+ * writability, similar to the purpose of poll(2).
+ *
+ * The purpose of uv_poll is to enable integrating external libraries that
+ * rely on the event loop to signal it about the socket status changes, like
+ * c-ares or libssh2. Using uv_poll_t for any other other purpose is not
+ * recommended; uv_tcp_t, uv_udp_t, etc. provide an implementation that is
+ * much faster and more scalable than what can be achieved with uv_poll_t,
+ * especially on Windows.
+ *
+ * It is possible that uv_poll occasionally signals that a file descriptor is
+ * readable or writable even when it isn't. The user should therefore always
+ * be prepared to handle EAGAIN or equivalent when it attempts to read from or
+ * write to the fd.
+ *
+ * It is not okay to have multiple active uv_poll watchers for the same socket.
+ * This can cause libuv to busyloop or otherwise malfunction.
+ *
+ * The user should not close a file descriptor while it is being polled by an
+ * active uv_poll watcher. This can cause the poll watcher to report an error,
+ * but it might also start polling another socket. However the fd can be safely
+ * closed immediately after a call to uv_poll_stop() or uv_close().
+ *
+ * On windows only sockets can be polled with uv_poll. On unix any file
+ * descriptor that would be accepted by poll(2) can be used with uv_poll.
+ */
+struct uv_poll_s {
+ UV_HANDLE_FIELDS
+ uv_poll_cb poll_cb;
+ UV_POLL_PRIVATE_FIELDS
+};
+
+enum uv_poll_event {
+ UV_READABLE = 1,
+ UV_WRITABLE = 2
+};
+
+/* Initialize the poll watcher using a file descriptor. */
+UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
+
+/* Initialize the poll watcher using a socket descriptor. On unix this is */
+/* identical to uv_poll_init. On windows it takes a SOCKET handle. */
+UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
+ uv_os_sock_t socket);
+
+/*
+ * Starts polling the file descriptor. `events` is a bitmask consisting made up
+ * of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback
+ * will be called with `status` set to 0, and the detected events set en the
+ * `events` field.
+ *
+ * If an error happens while polling status, `status` < 0 and corresponds
+ * with one of the UV_E* error codes. The user should not close the socket
+ * while uv_poll is active. If the user does that anyway, the callback *may*
+ * be called reporting an error status, but this is not guaranteed.
+ *
+ * Calling uv_poll_start on an uv_poll watcher that is already active is fine.
+ * Doing so will update the events mask that is being watched for.
+ */
+UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb);
+
+/* Stops polling the file descriptor. */
+UV_EXTERN int uv_poll_stop(uv_poll_t* handle);
+
+
+/*
+ * uv_prepare_t is a subclass of uv_handle_t.
+ *
+ * Every active prepare handle gets its callback called exactly once per loop
+ * iteration, just before the system blocks to wait for completed i/o.
+ */
+struct uv_prepare_s {
+ UV_HANDLE_FIELDS
+ UV_PREPARE_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
+
+UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
+
+UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
+
+
+/*
+ * uv_check_t is a subclass of uv_handle_t.
+ *
+ * Every active check handle gets its callback called exactly once per loop
+ * iteration, just after the system returns from blocking.
+ */
+struct uv_check_s {
+ UV_HANDLE_FIELDS
+ UV_CHECK_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check);
+
+UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb);
+
+UV_EXTERN int uv_check_stop(uv_check_t* check);
+
+
+/*
+ * uv_idle_t is a subclass of uv_handle_t.
+ *
+ * Every active idle handle gets its callback called repeatedly until it is
+ * stopped. This happens after all other types of callbacks are processed.
+ * When there are multiple "idle" handles active, their callbacks are called
+ * in turn.
+ */
+struct uv_idle_s {
+ UV_HANDLE_FIELDS
+ UV_IDLE_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
+
+UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
+
+UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
+
+
+/*
+ * uv_async_t is a subclass of uv_handle_t.
+ *
+ * uv_async_send wakes up the event loop and calls the async handle's callback.
+ * There is no guarantee that every uv_async_send call leads to exactly one
+ * invocation of the callback; the only guarantee is that the callback function
+ * is called at least once after the call to async_send. Unlike all other
+ * libuv functions, uv_async_send can be called from another thread.
+ */
+struct uv_async_s {
+ UV_HANDLE_FIELDS
+ UV_ASYNC_PRIVATE_FIELDS
+};
+
+/*
+ * Initialize the uv_async_t handle. A NULL callback is allowed.
+ *
+ * Note that uv_async_init(), unlike other libuv functions, immediately
+ * starts the handle. To stop the handle again, close it with uv_close().
+ */
+UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
+ uv_async_cb async_cb);
+
+/*
+ * This can be called from other threads to wake up a libuv thread.
+ *
+ * libuv is single threaded at the moment.
+ */
+UV_EXTERN int uv_async_send(uv_async_t* async);
+
+
+/*
+ * uv_timer_t is a subclass of uv_handle_t.
+ *
+ * Used to get woken up at a specified time in the future.
+ */
+struct uv_timer_s {
+ UV_HANDLE_FIELDS
+ UV_TIMER_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
+
+/*
+ * Start the timer. `timeout` and `repeat` are in milliseconds.
+ *
+ * If timeout is zero, the callback fires on the next tick of the event loop.
+ *
+ * If repeat is non-zero, the callback fires first after timeout milliseconds
+ * and then repeatedly after repeat milliseconds.
+ */
+UV_EXTERN int uv_timer_start(uv_timer_t* handle,
+ uv_timer_cb cb,
+ uint64_t timeout,
+ uint64_t repeat);
+
+UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
+
+/*
+ * Stop the timer, and if it is repeating restart it using the repeat value
+ * as the timeout. If the timer has never been started before it returns
+ * UV_EINVAL.
+ */
+UV_EXTERN int uv_timer_again(uv_timer_t* handle);
+
+/*
+ * Set the repeat value in milliseconds. Note that if the repeat value is set
+ * from a timer callback it does not immediately take effect. If the timer was
+ * non-repeating before, it will have been stopped. If it was repeating, then
+ * the old repeat value will have been used to schedule the next timeout.
+ */
+UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
+
+UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);
+
+
+/*
+ * uv_getaddrinfo_t is a subclass of uv_req_t
+ *
+ * Request object for uv_getaddrinfo.
+ */
+struct uv_getaddrinfo_s {
+ UV_REQ_FIELDS
+ /* read-only */
+ uv_loop_t* loop;
+ UV_GETADDRINFO_PRIVATE_FIELDS
+};
+
+
+/*
+ * Asynchronous getaddrinfo(3).
+ *
+ * Either node or service may be NULL but not both.
+ *
+ * hints is a pointer to a struct addrinfo with additional address type
+ * constraints, or NULL. Consult `man -s 3 getaddrinfo` for details.
+ *
+ * Returns 0 on success or an error code < 0 on failure.
+ *
+ * If successful, your callback gets called sometime in the future with the
+ * lookup result, which is either:
+ *
+ * a) err == 0, the res argument points to a valid struct addrinfo, or
+ * b) err < 0, the res argument is NULL. See the UV_EAI_* constants.
+ *
+ * Call uv_freeaddrinfo() to free the addrinfo structure.
+ */
+UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop,
+ uv_getaddrinfo_t* req,
+ uv_getaddrinfo_cb getaddrinfo_cb,
+ const char* node,
+ const char* service,
+ const struct addrinfo* hints);
+
+/*
+ * Free the struct addrinfo. Passing NULL is allowed and is a no-op.
+ */
+UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
+
+
+/* uv_spawn() options */
+typedef enum {
+ UV_IGNORE = 0x00,
+ UV_CREATE_PIPE = 0x01,
+ UV_INHERIT_FD = 0x02,
+ UV_INHERIT_STREAM = 0x04,
+
+ /* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
+ * determine the direction of flow, from the child process' perspective. Both
+ * flags may be specified to create a duplex data stream.
+ */
+ UV_READABLE_PIPE = 0x10,
+ UV_WRITABLE_PIPE = 0x20
+} uv_stdio_flags;
+
+typedef struct uv_stdio_container_s {
+ uv_stdio_flags flags;
+
+ union {
+ uv_stream_t* stream;
+ int fd;
+ } data;
+} uv_stdio_container_t;
+
+typedef struct uv_process_options_s {
+ uv_exit_cb exit_cb; /* Called after the process exits. */
+ const char* file; /* Path to program to execute. */
+ /*
+ * Command line arguments. args[0] should be the path to the program. On
+ * Windows this uses CreateProcess which concatenates the arguments into a
+ * string this can cause some strange errors. See the note at
+ * windows_verbatim_arguments.
+ */
+ char** args;
+ /*
+ * This will be set as the environ variable in the subprocess. If this is
+ * NULL then the parents environ will be used.
+ */
+ char** env;
+ /*
+ * If non-null this represents a directory the subprocess should execute
+ * in. Stands for current working directory.
+ */
+ const char* cwd;
+ /*
+ * Various flags that control how uv_spawn() behaves. See the definition of
+ * `enum uv_process_flags` below.
+ */
+ unsigned int flags;
+ /*
+ * The `stdio` field points to an array of uv_stdio_container_t structs that
+ * describe the file descriptors that will be made available to the child
+ * process. The convention is that stdio[0] points to stdin, fd 1 is used for
+ * stdout, and fd 2 is stderr.
+ *
+ * Note that on windows file descriptors greater than 2 are available to the
+ * child process only if the child processes uses the MSVCRT runtime.
+ */
+ int stdio_count;
+ uv_stdio_container_t* stdio;
+ /*
+ * Libuv can change the child process' user/group id. This happens only when
+ * the appropriate bits are set in the flags fields. This is not supported on
+ * windows; uv_spawn() will fail and set the error to UV_ENOTSUP.
+ */
+ uv_uid_t uid;
+ uv_gid_t gid;
+} uv_process_options_t;
+
+/*
+ * These are the flags that can be used for the uv_process_options.flags field.
+ */
+enum uv_process_flags {
+ /*
+ * Set the child process' user id. The user id is supplied in the `uid` field
+ * of the options struct. This does not work on windows; setting this flag
+ * will cause uv_spawn() to fail.
+ */
+ UV_PROCESS_SETUID = (1 << 0),
+ /*
+ * Set the child process' group id. The user id is supplied in the `gid`
+ * field of the options struct. This does not work on windows; setting this
+ * flag will cause uv_spawn() to fail.
+ */
+ UV_PROCESS_SETGID = (1 << 1),
+ /*
+ * Do not wrap any arguments in quotes, or perform any other escaping, when
+ * converting the argument list into a command line string. This option is
+ * only meaningful on Windows systems. On unix it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
+ /*
+ * Spawn the child process in a detached state - this will make it a process
+ * group leader, and will effectively enable the child to keep running after
+ * the parent exits. Note that the child process will still keep the
+ * parent's event loop alive unless the parent process calls uv_unref() on
+ * the child's process handle.
+ */
+ UV_PROCESS_DETACHED = (1 << 3),
+ /*
+ * Hide the subprocess console window that would normally be created. This
+ * option is only meaningful on Windows systems. On unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4)
+};
+
+/*
+ * uv_process_t is a subclass of uv_handle_t
+ */
+struct uv_process_s {
+ UV_HANDLE_FIELDS
+ uv_exit_cb exit_cb;
+ int pid;
+ UV_PROCESS_PRIVATE_FIELDS
+};
+
+/*
+ * Initializes the uv_process_t and starts the process. If the process is
+ * successfully spawned, then this function will return 0. Otherwise, the
+ * negative error code corresponding to the reason it couldn't spawn is
+ * returned.
+ *
+ * Possible reasons for failing to spawn would include (but not be limited to)
+ * the file to execute not existing, not having permissions to use the setuid or
+ * setgid specified, or not having enough memory to allocate for the new
+ * process.
+ */
+UV_EXTERN int uv_spawn(uv_loop_t* loop,
+ uv_process_t* handle,
+ const uv_process_options_t* options);
+
+
+/*
+ * Kills the process with the specified signal. The user must still
+ * call uv_close on the process.
+ */
+UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
+
+
+/* Kills the process with the specified signal. */
+UV_EXTERN int uv_kill(int pid, int signum);
+
+
+/*
+ * uv_work_t is a subclass of uv_req_t
+ */
+struct uv_work_s {
+ UV_REQ_FIELDS
+ uv_loop_t* loop;
+ uv_work_cb work_cb;
+ uv_after_work_cb after_work_cb;
+ UV_WORK_PRIVATE_FIELDS
+};
+
+/* Queues a work request to execute asynchronously on the thread pool. */
+UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
+ uv_work_cb work_cb, uv_after_work_cb after_work_cb);
+
+/* Cancel a pending request. Fails if the request is executing or has finished
+ * executing.
+ *
+ * Returns 0 on success, or an error code < 0 on failure.
+ *
+ * Only cancellation of uv_fs_t, uv_getaddrinfo_t and uv_work_t requests is
+ * currently supported.
+ *
+ * Cancelled requests have their callbacks invoked some time in the future.
+ * It's _not_ safe to free the memory associated with the request until your
+ * callback is called.
+ *
+ * Here is how cancellation is reported to your callback:
+ *
+ * - A uv_fs_t request has its req->result field set to UV_ECANCELED.
+ *
+ * - A uv_work_t or uv_getaddrinfo_t request has its callback invoked with
+ * status == UV_ECANCELED.
+ *
+ * This function is currently only implemented on UNIX platforms. On Windows,
+ * it always returns UV_ENOSYS.
+ */
+UV_EXTERN int uv_cancel(uv_req_t* req);
+
+
+struct uv_cpu_info_s {
+ char* model;
+ int speed;
+ struct uv_cpu_times_s {
+ uint64_t user;
+ uint64_t nice;
+ uint64_t sys;
+ uint64_t idle;
+ uint64_t irq;
+ } cpu_times;
+};
+
+struct uv_interface_address_s {
+ char* name;
+ char phys_addr[6];
+ int is_internal;
+ union {
+ struct sockaddr_in address4;
+ struct sockaddr_in6 address6;
+ } address;
+ union {
+ struct sockaddr_in netmask4;
+ struct sockaddr_in6 netmask6;
+ } netmask;
+};
+
+UV_EXTERN char** uv_setup_args(int argc, char** argv);
+UV_EXTERN int uv_get_process_title(char* buffer, size_t size);
+UV_EXTERN int uv_set_process_title(const char* title);
+UV_EXTERN int uv_resident_set_memory(size_t* rss);
+UV_EXTERN int uv_uptime(double* uptime);
+
+/*
+ * This allocates cpu_infos array, and sets count. The array
+ * is freed using uv_free_cpu_info().
+ */
+UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
+UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
+
+/*
+ * This allocates addresses array, and sets count. The array
+ * is freed using uv_free_interface_addresses().
+ */
+UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count);
+UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count);
+
+/*
+ * File System Methods.
+ *
+ * The uv_fs_* functions execute a blocking system call asynchronously (in a
+ * thread pool) and call the specified callback in the specified loop after
+ * completion. If the user gives NULL as the callback the blocking system
+ * call will be called synchronously. req should be a pointer to an
+ * uninitialized uv_fs_t object.
+ *
+ * uv_fs_req_cleanup() must be called after completion of the uv_fs_
+ * function to free any internal memory allocations associated with the
+ * request.
+ */
+
+typedef enum {
+ UV_FS_UNKNOWN = -1,
+ UV_FS_CUSTOM,
+ UV_FS_OPEN,
+ UV_FS_CLOSE,
+ UV_FS_READ,
+ UV_FS_WRITE,
+ UV_FS_SENDFILE,
+ UV_FS_STAT,
+ UV_FS_LSTAT,
+ UV_FS_FSTAT,
+ UV_FS_FTRUNCATE,
+ UV_FS_UTIME,
+ UV_FS_FUTIME,
+ UV_FS_CHMOD,
+ UV_FS_FCHMOD,
+ UV_FS_FSYNC,
+ UV_FS_FDATASYNC,
+ UV_FS_UNLINK,
+ UV_FS_RMDIR,
+ UV_FS_MKDIR,
+ UV_FS_RENAME,
+ UV_FS_READDIR,
+ UV_FS_LINK,
+ UV_FS_SYMLINK,
+ UV_FS_READLINK,
+ UV_FS_CHOWN,
+ UV_FS_FCHOWN
+} uv_fs_type;
+
+/* uv_fs_t is a subclass of uv_req_t */
+struct uv_fs_s {
+ UV_REQ_FIELDS
+ uv_fs_type fs_type;
+ uv_loop_t* loop;
+ uv_fs_cb cb;
+ ssize_t result;
+ void* ptr;
+ const char* path;
+ uv_stat_t statbuf; /* Stores the result of uv_fs_stat and uv_fs_fstat. */
+ UV_FS_PRIVATE_FIELDS
+};
+
+UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req);
+
+UV_EXTERN int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ int flags, int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ void* buf, size_t length, int64_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ const void* buf, size_t length, int64_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req,
+ const char* path, int flags, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ int64_t offset, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
+ uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ double atime, double mtime, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ double atime, double mtime, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, uv_fs_cb cb);
+
+/*
+ * This flag can be used with uv_fs_symlink on Windows
+ * to specify whether path argument points to a directory.
+ */
+#define UV_FS_SYMLINK_DIR 0x0001
+
+/*
+ * This flag can be used with uv_fs_symlink on Windows
+ * to specify whether the symlink is to be created using junction points.
+ */
+#define UV_FS_SYMLINK_JUNCTION 0x0002
+
+UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, int flags, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ int mode, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
+
+UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+ uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
+
+
+enum uv_fs_event {
+ UV_RENAME = 1,
+ UV_CHANGE = 2
+};
+
+
+struct uv_fs_event_s {
+ UV_HANDLE_FIELDS
+ char* filename;
+ UV_FS_EVENT_PRIVATE_FIELDS
+};
+
+
+/*
+ * uv_fs_stat() based polling file watcher.
+ */
+struct uv_fs_poll_s {
+ UV_HANDLE_FIELDS
+ /* Private, don't touch. */
+ void* poll_ctx;
+};
+
+UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle);
+
+/*
+ * Check the file at `path` for changes every `interval` milliseconds.
+ *
+ * Your callback is invoked with `status < 0` if `path` does not exist
+ * or is inaccessible. The watcher is *not* stopped but your callback is
+ * not called again until something changes (e.g. when the file is created
+ * or the error reason changes).
+ *
+ * When `status == 0`, your callback receives pointers to the old and new
+ * `uv_stat_t` structs. They are valid for the duration of the callback
+ * only!
+ *
+ * For maximum portability, use multi-second intervals. Sub-second intervals
+ * will not detect all changes on many file systems.
+ */
+UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
+ uv_fs_poll_cb poll_cb,
+ const char* path,
+ unsigned int interval);
+
+UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
+
+
+/*
+ * UNIX signal handling on a per-event loop basis. The implementation is not
+ * ultra efficient so don't go creating a million event loops with a million
+ * signal watchers.
+ *
+ * Note to Linux users: SIGRT0 and SIGRT1 (signals 32 and 33) are used by the
+ * NPTL pthreads library to manage threads. Installing watchers for those
+ * signals will lead to unpredictable behavior and is strongly discouraged.
+ * Future versions of libuv may simply reject them.
+ *
+ * Some signal support is available on Windows:
+ *
+ * SIGINT is normally delivered when the user presses CTRL+C. However, like
+ * on Unix, it is not generated when terminal raw mode is enabled.
+ *
+ * SIGBREAK is delivered when the user pressed CTRL+BREAK.
+ *
+ * SIGHUP is generated when the user closes the console window. On SIGHUP the
+ * program is given approximately 10 seconds to perform cleanup. After that
+ * Windows will unconditionally terminate it.
+ *
+ * SIGWINCH is raised whenever libuv detects that the console has been
+ * resized. SIGWINCH is emulated by libuv when the program uses an uv_tty_t
+ * handle to write to the console. SIGWINCH may not always be delivered in a
+ * timely manner; libuv will only detect size changes when the cursor is
+ * being moved. When a readable uv_tty_handle is used in raw mode, resizing
+ * the console buffer will also trigger a SIGWINCH signal.
+ *
+ * Watchers for other signals can be successfully created, but these signals
+ * are never generated. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
+ * SIGTERM and SIGKILL.
+ *
+ * Note that calls to raise() or abort() to programmatically raise a signal are
+ * not detected by libuv; these will not trigger a signal watcher.
+ */
+struct uv_signal_s {
+ UV_HANDLE_FIELDS
+ uv_signal_cb signal_cb;
+ int signum;
+ UV_SIGNAL_PRIVATE_FIELDS
+};
+
+UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
+
+UV_EXTERN int uv_signal_start(uv_signal_t* handle,
+ uv_signal_cb signal_cb,
+ int signum);
+
+UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
+
+
+/*
+ * Gets load average.
+ * See: http://en.wikipedia.org/wiki/Load_(computing)
+ * Returns [0,0,0] on Windows.
+ */
+UV_EXTERN void uv_loadavg(double avg[3]);
+
+
+/*
+ * Flags to be passed to uv_fs_event_start.
+ */
+enum uv_fs_event_flags {
+ /*
+ * By default, if the fs event watcher is given a directory name, we will
+ * watch for all events in that directory. This flags overrides this behavior
+ * and makes fs_event report only changes to the directory entry itself. This
+ * flag does not affect individual files watched.
+ * This flag is currently not implemented yet on any backend.
+ */
+ UV_FS_EVENT_WATCH_ENTRY = 1,
+
+ /*
+ * By default uv_fs_event will try to use a kernel interface such as inotify
+ * or kqueue to detect events. This may not work on remote filesystems such
+ * as NFS mounts. This flag makes fs_event fall back to calling stat() on a
+ * regular interval.
+ * This flag is currently not implemented yet on any backend.
+ */
+ UV_FS_EVENT_STAT = 2,
+
+ /*
+ * By default, event watcher, when watching directory, is not registering
+ * (is ignoring) changes in it's subdirectories.
+ * This flag will override this behaviour on platforms that support it.
+ */
+ UV_FS_EVENT_RECURSIVE = 4
+};
+
+
+UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle);
+
+UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags);
+
+UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle);
+
+
+/* Utility */
+
+/* Convert string ip addresses to binary structures */
+UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr);
+UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr);
+
+/* Convert binary addresses to strings */
+UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
+UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+
+/* Cross-platform IPv6-capable implementation of the 'standard' inet_ntop */
+/* and inet_pton functions. On success they return 0. If an error */
+/* the target of the `dst` pointer is unmodified. */
+UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size);
+UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst);
+
+/* Gets the executable path */
+UV_EXTERN int uv_exepath(char* buffer, size_t* size);
+
+/* Gets the current working directory */
+UV_EXTERN int uv_cwd(char* buffer, size_t size);
+
+/* Changes the current working directory */
+UV_EXTERN int uv_chdir(const char* dir);
+
+/* Gets memory info in bytes */
+UV_EXTERN uint64_t uv_get_free_memory(void);
+UV_EXTERN uint64_t uv_get_total_memory(void);
+
+/*
+ * Returns the current high-resolution real time. This is expressed in
+ * nanoseconds. It is relative to an arbitrary time in the past. It is not
+ * related to the time of day and therefore not subject to clock drift. The
+ * primary use is for measuring performance between intervals.
+ *
+ * Note not every platform can support nanosecond resolution; however, this
+ * value will always be in nanoseconds.
+ */
+UV_EXTERN extern uint64_t uv_hrtime(void);
+
+
+/*
+ * Disables inheritance for file descriptors / handles that this process
+ * inherited from its parent. The effect is that child processes spawned by
+ * this process don't accidentally inherit these handles.
+ *
+ * It is recommended to call this function as early in your program as possible,
+ * before the inherited file descriptors can be closed or duplicated.
+ *
+ * Note that this function works on a best-effort basis: there is no guarantee
+ * that libuv can discover all file descriptors that were inherited. In general
+ * it does a better job on Windows than it does on unix.
+ */
+UV_EXTERN void uv_disable_stdio_inheritance(void);
+
+/*
+ * Opens a shared library. The filename is in utf-8. Returns 0 on success and
+ * -1 on error. Call `uv_dlerror(uv_lib_t*)` to get the error message.
+ */
+UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib);
+
+/*
+ * Close the shared library.
+ */
+UV_EXTERN void uv_dlclose(uv_lib_t* lib);
+
+/*
+ * Retrieves a data pointer from a dynamic library. It is legal for a symbol to
+ * map to NULL. Returns 0 on success and -1 if the symbol was not found.
+ */
+UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr);
+
+/*
+ * Returns the last uv_dlopen() or uv_dlsym() error message.
+ */
+UV_EXTERN const char* uv_dlerror(uv_lib_t* lib);
+
+/*
+ * The mutex functions return 0 on success or an error code < 0
+ * (unless the return type is void, of course).
+ */
+UV_EXTERN int uv_mutex_init(uv_mutex_t* handle);
+UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle);
+UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle);
+UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle);
+UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle);
+
+/*
+ * Same goes for the read/write lock functions.
+ */
+UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock);
+UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock);
+UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock);
+UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock);
+UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock);
+UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
+UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
+UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
+
+/*
+ * Same goes for the semaphore functions.
+ */
+UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value);
+UV_EXTERN void uv_sem_destroy(uv_sem_t* sem);
+UV_EXTERN void uv_sem_post(uv_sem_t* sem);
+UV_EXTERN void uv_sem_wait(uv_sem_t* sem);
+UV_EXTERN int uv_sem_trywait(uv_sem_t* sem);
+
+/*
+ * Same goes for the condition variable functions.
+ */
+UV_EXTERN int uv_cond_init(uv_cond_t* cond);
+UV_EXTERN void uv_cond_destroy(uv_cond_t* cond);
+UV_EXTERN void uv_cond_signal(uv_cond_t* cond);
+UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond);
+/* Waits on a condition variable without a timeout.
+ *
+ * Note:
+ * 1. callers should be prepared to deal with spurious wakeups.
+ */
+UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+/* Waits on a condition variable with a timeout in nano seconds.
+ * Returns 0 for success or UV_ETIMEDOUT on timeout, It aborts when other
+ * errors happen.
+ *
+ * Note:
+ * 1. callers should be prepared to deal with spurious wakeups.
+ * 2. the granularity of timeout on Windows is never less than one millisecond.
+ * 3. uv_cond_timedwait takes a relative timeout, not an absolute time.
+ */
+UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
+ uint64_t timeout);
+
+UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
+UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
+UV_EXTERN void uv_barrier_wait(uv_barrier_t* barrier);
+
+/* Runs a function once and only once. Concurrent calls to uv_once() with the
+ * same guard will block all callers except one (it's unspecified which one).
+ * The guard should be initialized statically with the UV_ONCE_INIT macro.
+ */
+UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
+
+/* Thread-local storage. These functions largely follow the semantics of
+ * pthread_key_create(), pthread_key_delete(), pthread_getspecific() and
+ * pthread_setspecific().
+ *
+ * Note that the total thread-local storage size may be limited.
+ * That is, it may not be possible to create many TLS keys.
+ */
+UV_EXTERN int uv_key_create(uv_key_t* key);
+UV_EXTERN void uv_key_delete(uv_key_t* key);
+UV_EXTERN void* uv_key_get(uv_key_t* key);
+UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
+
+UV_EXTERN int uv_thread_create(uv_thread_t *tid,
+ void (*entry)(void *arg), void *arg);
+UV_EXTERN unsigned long uv_thread_self(void);
+UV_EXTERN int uv_thread_join(uv_thread_t *tid);
+
+/* The presence of these unions force similar struct layout. */
+#define XX(_, name) uv_ ## name ## _t name;
+union uv_any_handle {
+ UV_HANDLE_TYPE_MAP(XX)
+};
+
+union uv_any_req {
+ UV_REQ_TYPE_MAP(XX)
+};
+#undef XX
+
+
+struct uv_loop_s {
+ /* User data - use this for whatever. */
+ void* data;
+ /* Loop reference counting */
+ unsigned int active_handles;
+ void* handle_queue[2];
+ void* active_reqs[2];
+ /* Internal flag to signal loop stop */
+ unsigned int stop_flag;
+ UV_LOOP_PRIVATE_FIELDS
+};
+
+
+/* Don't export the private CPP symbols. */
+#undef UV_HANDLE_TYPE_PRIVATE
+#undef UV_REQ_TYPE_PRIVATE
+#undef UV_REQ_PRIVATE_FIELDS
+#undef UV_STREAM_PRIVATE_FIELDS
+#undef UV_TCP_PRIVATE_FIELDS
+#undef UV_PREPARE_PRIVATE_FIELDS
+#undef UV_CHECK_PRIVATE_FIELDS
+#undef UV_IDLE_PRIVATE_FIELDS
+#undef UV_ASYNC_PRIVATE_FIELDS
+#undef UV_TIMER_PRIVATE_FIELDS
+#undef UV_GETADDRINFO_PRIVATE_FIELDS
+#undef UV_FS_REQ_PRIVATE_FIELDS
+#undef UV_WORK_PRIVATE_FIELDS
+#undef UV_FS_EVENT_PRIVATE_FIELDS
+#undef UV_SIGNAL_PRIVATE_FIELDS
+#undef UV_LOOP_PRIVATE_FIELDS
+#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* UV_H */
diff --git a/third-party/libuv/libuv.pc.in b/third-party/libuv/libuv.pc.in
new file mode 100644
index 0000000000..86c1a126cd
--- /dev/null
+++ b/third-party/libuv/libuv.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Description: multi-platform support library with a focus on asynchronous I/O.
+
+Libs: -L${libdir} -luv
+Cflags: -I${includedir}
diff --git a/third-party/libuv/m4/.gitignore b/third-party/libuv/m4/.gitignore
new file mode 100644
index 0000000000..bde78f43f9
--- /dev/null
+++ b/third-party/libuv/m4/.gitignore
@@ -0,0 +1,2 @@
+# Ignore libtoolize-generated files.
+*.m4
diff --git a/third-party/libuv/m4/dtrace.m4 b/third-party/libuv/m4/dtrace.m4
new file mode 100644
index 0000000000..4060af3181
--- /dev/null
+++ b/third-party/libuv/m4/dtrace.m4
@@ -0,0 +1,58 @@
+dnl Copyright (C) 2009 Sun Microsystems
+dnl This file is free software; Sun Microsystems
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl ---------------------------------------------------------------------------
+dnl Macro: PANDORA_ENABLE_DTRACE
+dnl ---------------------------------------------------------------------------
+AC_DEFUN([PANDORA_ENABLE_DTRACE],[
+ AC_ARG_ENABLE([dtrace],
+ [AS_HELP_STRING([--disable-dtrace],
+ [enable DTrace USDT probes. @<:@default=yes@:>@])],
+ [ac_cv_enable_dtrace="$enableval"],
+ [ac_cv_enable_dtrace="yes"])
+
+ AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[
+ AC_CHECK_PROGS([DTRACE], [dtrace])
+ AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[
+
+ AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[
+ cat >conftest.d <<_ACEOF
+provider Example {
+ probe increment(int);
+};
+_ACEOF
+ $DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
+ AS_IF([test $? -eq 0],[ac_cv_dtrace_works=yes],
+ [ac_cv_dtrace_works=no])
+ rm -f conftest.h conftest.d
+ ])
+ AS_IF([test "x$ac_cv_dtrace_works" = "xyes"],[
+ AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support])
+ ])
+ AC_CACHE_CHECK([if dtrace should instrument object files],
+ [ac_cv_dtrace_needs_objects],[
+ dnl DTrace on MacOSX does not use -G option
+ cat >conftest.d <<_ACEOF
+provider Example {
+ probe increment(int);
+};
+_ACEOF
+ $DTRACE -G -o conftest.d.o -s conftest.d 2>/dev/zero
+ AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes],
+ [ac_cv_dtrace_needs_objects=no])
+ rm -f conftest.d.o conftest.d
+ ])
+ AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX
+ ac_cv_have_dtrace=yes
+ ])])
+
+AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_dtrace_works" = "xyes"])
+AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS],
+ [test "x$ac_cv_dtrace_needs_objects" = "xyes"])
+
+])
+dnl ---------------------------------------------------------------------------
+dnl End Macro: PANDORA_ENABLE_DTRACE
+dnl ---------------------------------------------------------------------------
diff --git a/third-party/libuv/samples/.gitignore b/third-party/libuv/samples/.gitignore
new file mode 100644
index 0000000000..f868091ba3
--- /dev/null
+++ b/third-party/libuv/samples/.gitignore
@@ -0,0 +1,22 @@
+# Copyright StrongLoop, Inc. All rights reserved.
+#
+# 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.
+
+*.mk
+*.Makefile
diff --git a/third-party/libuv/samples/socks5-proxy/.gitignore b/third-party/libuv/samples/socks5-proxy/.gitignore
new file mode 100644
index 0000000000..c177f37451
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/.gitignore
@@ -0,0 +1,21 @@
+# Copyright StrongLoop, Inc. All rights reserved.
+#
+# 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.
+
+/build/
diff --git a/third-party/libuv/samples/socks5-proxy/LICENSE b/third-party/libuv/samples/socks5-proxy/LICENSE
new file mode 100644
index 0000000000..63c1447fc5
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/LICENSE
@@ -0,0 +1,53 @@
+Files: *
+========
+
+Copyright StrongLoop, Inc. All rights reserved.
+
+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.
+
+
+Files: getopt.c
+===============
+
+Copyright (c) 1987, 1993, 1994
+The Regents of the University of California. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/third-party/libuv/samples/socks5-proxy/Makefile b/third-party/libuv/samples/socks5-proxy/Makefile
new file mode 100644
index 0000000000..268dc55b1a
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/Makefile
@@ -0,0 +1,46 @@
+# Copyright StrongLoop, Inc. All rights reserved.
+#
+# 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.
+
+BUILDTYPE ?= Debug
+BUILDDIR ?= build
+GYP ?= gyp
+V ?=
+
+SOURCES := client.c defs.h getopt.c main.c s5.c s5.h server.c util.c
+
+.PHONY: all clean
+
+all: $(BUILDDIR)/$(BUILDTYPE)/s5-proxy
+
+clean:
+ $(RM) $(BUILDDIR)
+
+$(BUILDDIR)/$(BUILDTYPE)/s5-proxy: $(BUILDDIR)/Makefile $(SOURCES)
+ $(MAKE) -C $(BUILDDIR) V=$(V)
+
+$(BUILDDIR)/Makefile: ../../common.gypi build.gyp
+ $(GYP) \
+ -Dlibrary=static_library \
+ -Goutput_dir=. \
+ -I../../common.gypi \
+ -f make \
+ --depth=. \
+ --generator-output=$(BUILDDIR) \
+ build.gyp
diff --git a/third-party/libuv/samples/socks5-proxy/build.gyp b/third-party/libuv/samples/socks5-proxy/build.gyp
new file mode 100644
index 0000000000..771a1e146d
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/build.gyp
@@ -0,0 +1,46 @@
+# Copyright StrongLoop, Inc. All rights reserved.
+#
+# 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.
+
+{
+ 'targets': [
+ {
+ 'dependencies': ['../../uv.gyp:libuv'],
+ 'target_name': 's5-proxy',
+ 'type': 'executable',
+ 'sources': [
+ 'client.c',
+ 'defs.h',
+ 'main.c',
+ 's5.c',
+ 's5.h',
+ 'server.c',
+ 'util.c',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'defines': ['HAVE_UNISTD_H=0'],
+ 'sources': ['getopt.c']
+ }, {
+ 'defines': ['HAVE_UNISTD_H=1']
+ }]
+ ]
+ }
+ ]
+}
diff --git a/third-party/libuv/samples/socks5-proxy/client.c b/third-party/libuv/samples/socks5-proxy/client.c
new file mode 100644
index 0000000000..ae9913a1c6
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/client.c
@@ -0,0 +1,737 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "defs.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* A connection is modeled as an abstraction on top of two simple state
+ * machines, one for reading and one for writing. Either state machine
+ * is, when active, in one of three states: busy, done or stop; the fourth
+ * and final state, dead, is an end state and only relevant when shutting
+ * down the connection. A short overview:
+ *
+ * busy done stop
+ * ----------|---------------------------|--------------------|------|
+ * readable | waiting for incoming data | have incoming data | idle |
+ * writable | busy writing out data | completed write | idle |
+ *
+ * We could remove the done state from the writable state machine. For our
+ * purposes, it's functionally equivalent to the stop state.
+ *
+ * When the connection with upstream has been established, the client_ctx
+ * moves into a state where incoming data from the client is sent upstream
+ * and vice versa, incoming data from upstream is sent to the client. In
+ * other words, we're just piping data back and forth. See conn_cycle()
+ * for details.
+ *
+ * An interesting deviation from libuv's I/O model is that reads are discrete
+ * rather than continuous events. In layman's terms, when a read operation
+ * completes, the connection stops reading until further notice.
+ *
+ * The rationale for this approach is that we have to wait until the data
+ * has been sent out again before we can reuse the read buffer.
+ *
+ * It also pleasingly unifies with the request model that libuv uses for
+ * writes and everything else; libuv may switch to a request model for
+ * reads in the future.
+ */
+enum conn_state {
+ c_busy, /* Busy; waiting for incoming data or for a write to complete. */
+ c_done, /* Done; read incoming data or write finished. */
+ c_stop, /* Stopped. */
+ c_dead
+};
+
+/* Session states. */
+enum sess_state {
+ s_handshake, /* Wait for client handshake. */
+ s_handshake_auth, /* Wait for client authentication data. */
+ s_req_start, /* Start waiting for request data. */
+ s_req_parse, /* Wait for request data. */
+ s_req_lookup, /* Wait for upstream hostname DNS lookup to complete. */
+ s_req_connect, /* Wait for uv_tcp_connect() to complete. */
+ s_proxy_start, /* Connected. Start piping data. */
+ s_proxy, /* Connected. Pipe data back and forth. */
+ s_kill, /* Tear down session. */
+ s_almost_dead_0, /* Waiting for finalizers to complete. */
+ s_almost_dead_1, /* Waiting for finalizers to complete. */
+ s_almost_dead_2, /* Waiting for finalizers to complete. */
+ s_almost_dead_3, /* Waiting for finalizers to complete. */
+ s_almost_dead_4, /* Waiting for finalizers to complete. */
+ s_dead /* Dead. Safe to free now. */
+};
+
+static void do_next(client_ctx *cx);
+static int do_handshake(client_ctx *cx);
+static int do_handshake_auth(client_ctx *cx);
+static int do_req_start(client_ctx *cx);
+static int do_req_parse(client_ctx *cx);
+static int do_req_lookup(client_ctx *cx);
+static int do_req_connect_start(client_ctx *cx);
+static int do_req_connect(client_ctx *cx);
+static int do_proxy_start(client_ctx *cx);
+static int do_proxy(client_ctx *cx);
+static int do_kill(client_ctx *cx);
+static int do_almost_dead(client_ctx *cx);
+static int conn_cycle(const char *who, conn *a, conn *b);
+static void conn_timer_reset(conn *c);
+static void conn_timer_expire(uv_timer_t *handle, int status);
+static void conn_getaddrinfo(conn *c, const char *hostname);
+static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
+ int status,
+ struct addrinfo *ai);
+static int conn_connect(conn *c);
+static void conn_connect_done(uv_connect_t *req, int status);
+static void conn_read(conn *c);
+static void conn_read_done(uv_stream_t *handle,
+ ssize_t nread,
+ const uv_buf_t *buf);
+static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf);
+static void conn_write(conn *c, const void *data, unsigned int len);
+static void conn_write_done(uv_write_t *req, int status);
+static void conn_close(conn *c);
+static void conn_close_done(uv_handle_t *handle);
+
+/* |incoming| has been initialized by server.c when this is called. */
+void client_finish_init(server_ctx *sx, client_ctx *cx) {
+ conn *incoming;
+ conn *outgoing;
+
+ cx->sx = sx;
+ cx->state = s_handshake;
+ s5_init(&cx->parser);
+
+ incoming = &cx->incoming;
+ incoming->client = cx;
+ incoming->result = 0;
+ incoming->rdstate = c_stop;
+ incoming->wrstate = c_stop;
+ incoming->idle_timeout = sx->idle_timeout;
+ CHECK(0 == uv_timer_init(sx->loop, &incoming->timer_handle));
+
+ outgoing = &cx->outgoing;
+ outgoing->client = cx;
+ outgoing->result = 0;
+ outgoing->rdstate = c_stop;
+ outgoing->wrstate = c_stop;
+ outgoing->idle_timeout = sx->idle_timeout;
+ CHECK(0 == uv_tcp_init(cx->sx->loop, &outgoing->handle.tcp));
+ CHECK(0 == uv_timer_init(cx->sx->loop, &outgoing->timer_handle));
+
+ /* Wait for the initial packet. */
+ conn_read(incoming);
+}
+
+/* This is the core state machine that drives the client <-> upstream proxy.
+ * We move through the initial handshake and authentication steps first and
+ * end up (if all goes well) in the proxy state where we're just proxying
+ * data between the client and upstream.
+ */
+static void do_next(client_ctx *cx) {
+ int new_state;
+
+ ASSERT(cx->state != s_dead);
+ switch (cx->state) {
+ case s_handshake:
+ new_state = do_handshake(cx);
+ break;
+ case s_handshake_auth:
+ new_state = do_handshake_auth(cx);
+ break;
+ case s_req_start:
+ new_state = do_req_start(cx);
+ break;
+ case s_req_parse:
+ new_state = do_req_parse(cx);
+ break;
+ case s_req_lookup:
+ new_state = do_req_lookup(cx);
+ break;
+ case s_req_connect:
+ new_state = do_req_connect(cx);
+ break;
+ case s_proxy_start:
+ new_state = do_proxy_start(cx);
+ break;
+ case s_proxy:
+ new_state = do_proxy(cx);
+ break;
+ case s_kill:
+ new_state = do_kill(cx);
+ break;
+ case s_almost_dead_0:
+ case s_almost_dead_1:
+ case s_almost_dead_2:
+ case s_almost_dead_3:
+ case s_almost_dead_4:
+ new_state = do_almost_dead(cx);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ cx->state = new_state;
+
+ if (cx->state == s_dead) {
+ if (DEBUG_CHECKS) {
+ memset(cx, -1, sizeof(*cx));
+ }
+ free(cx);
+ }
+}
+
+static int do_handshake(client_ctx *cx) {
+ unsigned int methods;
+ conn *incoming;
+ s5_ctx *parser;
+ uint8_t *data;
+ size_t size;
+ int err;
+
+ parser = &cx->parser;
+ incoming = &cx->incoming;
+ ASSERT(incoming->rdstate == c_done);
+ ASSERT(incoming->wrstate == c_stop);
+ incoming->rdstate = c_stop;
+
+ if (incoming->result < 0) {
+ pr_err("read error: %s", uv_strerror(incoming->result));
+ return do_kill(cx);
+ }
+
+ data = (uint8_t *) incoming->t.buf;
+ size = (size_t) incoming->result;
+ err = s5_parse(parser, &data, &size);
+ if (err == s5_ok) {
+ conn_read(incoming);
+ return s_handshake; /* Need more data. */
+ }
+
+ if (size != 0) {
+ /* Could allow a round-trip saving shortcut here if the requested auth
+ * method is S5_AUTH_NONE (provided unauthenticated traffic is allowed.)
+ * Requires client support however.
+ */
+ pr_err("junk in handshake");
+ return do_kill(cx);
+ }
+
+ if (err != s5_auth_select) {
+ pr_err("handshake error: %s", s5_strerror(err));
+ return do_kill(cx);
+ }
+
+ methods = s5_auth_methods(parser);
+ if ((methods & S5_AUTH_NONE) && can_auth_none(cx->sx, cx)) {
+ s5_select_auth(parser, S5_AUTH_NONE);
+ conn_write(incoming, "\5\0", 2); /* No auth required. */
+ return s_req_start;
+ }
+
+ if ((methods & S5_AUTH_PASSWD) && can_auth_passwd(cx->sx, cx)) {
+ /* TODO(bnoordhuis) Implement username/password auth. */
+ }
+
+ conn_write(incoming, "\5\377", 2); /* No acceptable auth. */
+ return s_kill;
+}
+
+/* TODO(bnoordhuis) Implement username/password auth. */
+static int do_handshake_auth(client_ctx *cx) {
+ UNREACHABLE();
+ return do_kill(cx);
+}
+
+static int do_req_start(client_ctx *cx) {
+ conn *incoming;
+
+ incoming = &cx->incoming;
+ ASSERT(incoming->rdstate == c_stop);
+ ASSERT(incoming->wrstate == c_done);
+ incoming->wrstate = c_stop;
+
+ if (incoming->result < 0) {
+ pr_err("write error: %s", uv_strerror(incoming->result));
+ return do_kill(cx);
+ }
+
+ conn_read(incoming);
+ return s_req_parse;
+}
+
+static int do_req_parse(client_ctx *cx) {
+ conn *incoming;
+ conn *outgoing;
+ s5_ctx *parser;
+ uint8_t *data;
+ size_t size;
+ int err;
+
+ parser = &cx->parser;
+ incoming = &cx->incoming;
+ outgoing = &cx->outgoing;
+ ASSERT(incoming->rdstate == c_done);
+ ASSERT(incoming->wrstate == c_stop);
+ ASSERT(outgoing->rdstate == c_stop);
+ ASSERT(outgoing->wrstate == c_stop);
+ incoming->rdstate = c_stop;
+
+ if (incoming->result < 0) {
+ pr_err("read error: %s", uv_strerror(incoming->result));
+ return do_kill(cx);
+ }
+
+ data = (uint8_t *) incoming->t.buf;
+ size = (size_t) incoming->result;
+ err = s5_parse(parser, &data, &size);
+ if (err == s5_ok) {
+ conn_read(incoming);
+ return s_req_parse; /* Need more data. */
+ }
+
+ if (size != 0) {
+ pr_err("junk in request %u", (unsigned) size);
+ return do_kill(cx);
+ }
+
+ if (err != s5_exec_cmd) {
+ pr_err("request error: %s", s5_strerror(err));
+ return do_kill(cx);
+ }
+
+ if (parser->cmd == s5_cmd_tcp_bind) {
+ /* Not supported but relatively straightforward to implement. */
+ pr_warn("BIND requests are not supported.");
+ return do_kill(cx);
+ }
+
+ if (parser->cmd == s5_cmd_udp_assoc) {
+ /* Not supported. Might be hard to implement because libuv has no
+ * functionality for detecting the MTU size which the RFC mandates.
+ */
+ pr_warn("UDP ASSOC requests are not supported.");
+ return do_kill(cx);
+ }
+ ASSERT(parser->cmd == s5_cmd_tcp_connect);
+
+ if (parser->atyp == s5_atyp_host) {
+ conn_getaddrinfo(outgoing, (const char *) parser->daddr);
+ return s_req_lookup;
+ }
+
+ if (parser->atyp == s5_atyp_ipv4) {
+ memset(&outgoing->t.addr4, 0, sizeof(outgoing->t.addr4));
+ outgoing->t.addr4.sin_family = AF_INET;
+ outgoing->t.addr4.sin_port = htons(parser->dport);
+ memcpy(&outgoing->t.addr4.sin_addr,
+ parser->daddr,
+ sizeof(outgoing->t.addr4.sin_addr));
+ } else if (parser->atyp == s5_atyp_ipv6) {
+ memset(&outgoing->t.addr6, 0, sizeof(outgoing->t.addr6));
+ outgoing->t.addr6.sin6_family = AF_INET6;
+ outgoing->t.addr6.sin6_port = htons(parser->dport);
+ memcpy(&outgoing->t.addr6.sin6_addr,
+ parser->daddr,
+ sizeof(outgoing->t.addr6.sin6_addr));
+ } else {
+ UNREACHABLE();
+ }
+
+ return do_req_connect_start(cx);
+}
+
+static int do_req_lookup(client_ctx *cx) {
+ s5_ctx *parser;
+ conn *incoming;
+ conn *outgoing;
+
+ parser = &cx->parser;
+ incoming = &cx->incoming;
+ outgoing = &cx->outgoing;
+ ASSERT(incoming->rdstate == c_stop);
+ ASSERT(incoming->wrstate == c_stop);
+ ASSERT(outgoing->rdstate == c_stop);
+ ASSERT(outgoing->wrstate == c_stop);
+
+ if (outgoing->result < 0) {
+ /* TODO(bnoordhuis) Escape control characters in parser->daddr. */
+ pr_err("lookup error for \"%s\": %s",
+ parser->daddr,
+ uv_strerror(outgoing->result));
+ /* Send back a 'Host unreachable' reply. */
+ conn_write(incoming, "\5\4\0\1\0\0\0\0\0\0", 10);
+ return s_kill;
+ }
+
+ /* Don't make assumptions about the offset of sin_port/sin6_port. */
+ switch (outgoing->t.addr.sa_family) {
+ case AF_INET:
+ outgoing->t.addr4.sin_port = htons(parser->dport);
+ break;
+ case AF_INET6:
+ outgoing->t.addr6.sin6_port = htons(parser->dport);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return do_req_connect_start(cx);
+}
+
+/* Assumes that cx->outgoing.t.sa contains a valid AF_INET/AF_INET6 address. */
+static int do_req_connect_start(client_ctx *cx) {
+ conn *incoming;
+ conn *outgoing;
+ int err;
+
+ incoming = &cx->incoming;
+ outgoing = &cx->outgoing;
+ ASSERT(incoming->rdstate == c_stop);
+ ASSERT(incoming->wrstate == c_stop);
+ ASSERT(outgoing->rdstate == c_stop);
+ ASSERT(outgoing->wrstate == c_stop);
+
+ if (!can_access(cx->sx, cx, &outgoing->t.addr)) {
+ pr_warn("connection not allowed by ruleset");
+ /* Send a 'Connection not allowed by ruleset' reply. */
+ conn_write(incoming, "\5\2\0\1\0\0\0\0\0\0", 10);
+ return s_kill;
+ }
+
+ err = conn_connect(outgoing);
+ if (err != 0) {
+ pr_err("connect error: %s\n", uv_strerror(err));
+ return do_kill(cx);
+ }
+
+ return s_req_connect;
+}
+
+static int do_req_connect(client_ctx *cx) {
+ const struct sockaddr_in6 *in6;
+ const struct sockaddr_in *in;
+ char addr_storage[sizeof(*in6)];
+ conn *incoming;
+ conn *outgoing;
+ uint8_t *buf;
+ int addrlen;
+
+ incoming = &cx->incoming;
+ outgoing = &cx->outgoing;
+ ASSERT(incoming->rdstate == c_stop);
+ ASSERT(incoming->wrstate == c_stop);
+ ASSERT(outgoing->rdstate == c_stop);
+ ASSERT(outgoing->wrstate == c_stop);
+
+ /* Build and send the reply. Not very pretty but gets the job done. */
+ buf = (uint8_t *) incoming->t.buf;
+ if (outgoing->result == 0) {
+ /* The RFC mandates that the SOCKS server must include the local port
+ * and address in the reply. So that's what we do.
+ */
+ addrlen = sizeof(addr_storage);
+ CHECK(0 == uv_tcp_getsockname(&outgoing->handle.tcp,
+ (struct sockaddr *) addr_storage,
+ &addrlen));
+ buf[0] = 5; /* Version. */
+ buf[1] = 0; /* Success. */
+ buf[2] = 0; /* Reserved. */
+ if (addrlen == sizeof(*in)) {
+ buf[3] = 1; /* IPv4. */
+ in = (const struct sockaddr_in *) &addr_storage;
+ memcpy(buf + 4, &in->sin_addr, 4);
+ memcpy(buf + 8, &in->sin_port, 2);
+ conn_write(incoming, buf, 10);
+ } else if (addrlen == sizeof(*in6)) {
+ buf[3] = 4; /* IPv6. */
+ in6 = (const struct sockaddr_in6 *) &addr_storage;
+ memcpy(buf + 4, &in6->sin6_addr, 16);
+ memcpy(buf + 20, &in6->sin6_port, 2);
+ conn_write(incoming, buf, 22);
+ } else {
+ UNREACHABLE();
+ }
+ return s_proxy_start;
+ } else {
+ pr_err("upstream connection error: %s\n", uv_strerror(outgoing->result));
+ /* Send a 'Connection refused' reply. */
+ conn_write(incoming, "\5\5\0\1\0\0\0\0\0\0", 10);
+ return s_kill;
+ }
+
+ UNREACHABLE();
+ return s_kill;
+}
+
+static int do_proxy_start(client_ctx *cx) {
+ conn *incoming;
+ conn *outgoing;
+
+ incoming = &cx->incoming;
+ outgoing = &cx->outgoing;
+ ASSERT(incoming->rdstate == c_stop);
+ ASSERT(incoming->wrstate == c_done);
+ ASSERT(outgoing->rdstate == c_stop);
+ ASSERT(outgoing->wrstate == c_stop);
+ incoming->wrstate = c_stop;
+
+ if (incoming->result < 0) {
+ pr_err("write error: %s", uv_strerror(incoming->result));
+ return do_kill(cx);
+ }
+
+ conn_read(incoming);
+ conn_read(outgoing);
+ return s_proxy;
+}
+
+/* Proxy incoming data back and forth. */
+static int do_proxy(client_ctx *cx) {
+ if (conn_cycle("client", &cx->incoming, &cx->outgoing)) {
+ return do_kill(cx);
+ }
+
+ if (conn_cycle("upstream", &cx->outgoing, &cx->incoming)) {
+ return do_kill(cx);
+ }
+
+ return s_proxy;
+}
+
+static int do_kill(client_ctx *cx) {
+ int new_state;
+
+ if (cx->state >= s_almost_dead_0) {
+ return cx->state;
+ }
+
+ /* Try to cancel the request. The callback still runs but if the
+ * cancellation succeeded, it gets called with status=UV_ECANCELED.
+ */
+ new_state = s_almost_dead_1;
+ if (cx->state == s_req_lookup) {
+ new_state = s_almost_dead_0;
+ uv_cancel(&cx->outgoing.t.req);
+ }
+
+ conn_close(&cx->incoming);
+ conn_close(&cx->outgoing);
+ return new_state;
+}
+
+static int do_almost_dead(client_ctx *cx) {
+ ASSERT(cx->state >= s_almost_dead_0);
+ return cx->state + 1; /* Another finalizer completed. */
+}
+
+static int conn_cycle(const char *who, conn *a, conn *b) {
+ if (a->result < 0) {
+ if (a->result != UV_EOF) {
+ pr_err("%s error: %s", who, uv_strerror(a->result));
+ }
+ return -1;
+ }
+
+ if (b->result < 0) {
+ return -1;
+ }
+
+ if (a->wrstate == c_done) {
+ a->wrstate = c_stop;
+ }
+
+ /* The logic is as follows: read when we don't write and write when we don't
+ * read. That gives us back-pressure handling for free because if the peer
+ * sends data faster than we consume it, TCP congestion control kicks in.
+ */
+ if (a->wrstate == c_stop) {
+ if (b->rdstate == c_stop) {
+ conn_read(b);
+ } else if (b->rdstate == c_done) {
+ conn_write(a, b->t.buf, b->result);
+ b->rdstate = c_stop; /* Triggers the call to conn_read() above. */
+ }
+ }
+
+ return 0;
+}
+
+static void conn_timer_reset(conn *c) {
+ CHECK(0 == uv_timer_start(&c->timer_handle,
+ conn_timer_expire,
+ c->idle_timeout,
+ 0));
+}
+
+static void conn_timer_expire(uv_timer_t *handle, int status) {
+ conn *c;
+
+ CHECK(0 == status);
+ c = CONTAINER_OF(handle, conn, timer_handle);
+ c->result = UV_ETIMEDOUT;
+ do_next(c->client);
+}
+
+static void conn_getaddrinfo(conn *c, const char *hostname) {
+ struct addrinfo hints;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ CHECK(0 == uv_getaddrinfo(c->client->sx->loop,
+ &c->t.addrinfo_req,
+ conn_getaddrinfo_done,
+ hostname,
+ NULL,
+ &hints));
+ conn_timer_reset(c);
+}
+
+static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
+ int status,
+ struct addrinfo *ai) {
+ conn *c;
+
+ c = CONTAINER_OF(req, conn, t.addrinfo_req);
+ c->result = status;
+
+ if (status == 0) {
+ /* FIXME(bnoordhuis) Should try all addresses. */
+ if (ai->ai_family == AF_INET) {
+ c->t.addr4 = *(const struct sockaddr_in *) ai->ai_addr;
+ } else if (ai->ai_family == AF_INET6) {
+ c->t.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr;
+ } else {
+ UNREACHABLE();
+ }
+ }
+
+ uv_freeaddrinfo(ai);
+ do_next(c->client);
+}
+
+/* Assumes that c->t.sa contains a valid AF_INET or AF_INET6 address. */
+static int conn_connect(conn *c) {
+ ASSERT(c->t.addr.sa_family == AF_INET ||
+ c->t.addr.sa_family == AF_INET6);
+ conn_timer_reset(c);
+ return uv_tcp_connect(&c->t.connect_req,
+ &c->handle.tcp,
+ &c->t.addr,
+ conn_connect_done);
+}
+
+static void conn_connect_done(uv_connect_t *req, int status) {
+ conn *c;
+
+ if (status == UV_ECANCELED) {
+ return; /* Handle has been closed. */
+ }
+
+ c = CONTAINER_OF(req, conn, t.connect_req);
+ c->result = status;
+ do_next(c->client);
+}
+
+static void conn_read(conn *c) {
+ ASSERT(c->rdstate == c_stop);
+ CHECK(0 == uv_read_start(&c->handle.stream, conn_alloc, conn_read_done));
+ c->rdstate = c_busy;
+ conn_timer_reset(c);
+}
+
+static void conn_read_done(uv_stream_t *handle,
+ ssize_t nread,
+ const uv_buf_t *buf) {
+ conn *c;
+
+ c = CONTAINER_OF(handle, conn, handle);
+ ASSERT(c->t.buf == buf->base);
+ ASSERT(c->rdstate == c_busy);
+ c->rdstate = c_done;
+ c->result = nread;
+
+ uv_read_stop(&c->handle.stream);
+ do_next(c->client);
+}
+
+static void conn_alloc(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
+ conn *c;
+
+ c = CONTAINER_OF(handle, conn, handle);
+ ASSERT(c->rdstate == c_busy);
+ buf->base = c->t.buf;
+ buf->len = sizeof(c->t.buf);
+}
+
+static void conn_write(conn *c, const void *data, unsigned int len) {
+ uv_buf_t buf;
+
+ ASSERT(c->wrstate == c_stop || c->wrstate == c_done);
+ c->wrstate = c_busy;
+
+ /* It's okay to cast away constness here, uv_write() won't modify the
+ * memory.
+ */
+ buf.base = (char *) data;
+ buf.len = len;
+
+ CHECK(0 == uv_write(&c->write_req,
+ &c->handle.stream,
+ &buf,
+ 1,
+ conn_write_done));
+ conn_timer_reset(c);
+}
+
+static void conn_write_done(uv_write_t *req, int status) {
+ conn *c;
+
+ if (status == UV_ECANCELED) {
+ return; /* Handle has been closed. */
+ }
+
+ c = CONTAINER_OF(req, conn, write_req);
+ ASSERT(c->wrstate == c_busy);
+ c->wrstate = c_done;
+ c->result = status;
+ do_next(c->client);
+}
+
+static void conn_close(conn *c) {
+ ASSERT(c->rdstate != c_dead);
+ ASSERT(c->wrstate != c_dead);
+ c->rdstate = c_dead;
+ c->wrstate = c_dead;
+ c->timer_handle.data = c;
+ c->handle.handle.data = c;
+ uv_close(&c->handle.handle, conn_close_done);
+ uv_close((uv_handle_t *) &c->timer_handle, conn_close_done);
+}
+
+static void conn_close_done(uv_handle_t *handle) {
+ conn *c;
+
+ c = handle->data;
+ do_next(c->client);
+}
diff --git a/third-party/libuv/samples/socks5-proxy/defs.h b/third-party/libuv/samples/socks5-proxy/defs.h
new file mode 100644
index 0000000000..99ee8160c8
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/defs.h
@@ -0,0 +1,139 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef DEFS_H_
+#define DEFS_H_
+
+#include "s5.h"
+#include "uv.h"
+
+#include <assert.h>
+#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
+#include <stddef.h> /* size_t, ssize_t */
+#include <stdint.h>
+#include <sys/socket.h> /* sockaddr */
+
+struct client_ctx;
+
+typedef struct {
+ const char *bind_host;
+ unsigned short bind_port;
+ unsigned int idle_timeout;
+} server_config;
+
+typedef struct {
+ unsigned int idle_timeout; /* Connection idle timeout in ms. */
+ uv_tcp_t tcp_handle;
+ uv_loop_t *loop;
+} server_ctx;
+
+typedef struct {
+ unsigned char rdstate;
+ unsigned char wrstate;
+ unsigned int idle_timeout;
+ struct client_ctx *client; /* Backlink to owning client context. */
+ ssize_t result;
+ union {
+ uv_handle_t handle;
+ uv_stream_t stream;
+ uv_tcp_t tcp;
+ uv_udp_t udp;
+ } handle;
+ uv_timer_t timer_handle; /* For detecting timeouts. */
+ uv_write_t write_req;
+ /* We only need one of these at a time so make them share memory. */
+ union {
+ uv_getaddrinfo_t addrinfo_req;
+ uv_connect_t connect_req;
+ uv_req_t req;
+ struct sockaddr_in6 addr6;
+ struct sockaddr_in addr4;
+ struct sockaddr addr;
+ char buf[2048]; /* Scratch space. Used to read data into. */
+ } t;
+} conn;
+
+typedef struct client_ctx {
+ unsigned int state;
+ server_ctx *sx; /* Backlink to owning server context. */
+ s5_ctx parser; /* The SOCKS protocol parser. */
+ conn incoming; /* Connection with the SOCKS client. */
+ conn outgoing; /* Connection with upstream. */
+} client_ctx;
+
+/* server.c */
+int server_run(const server_config *cf, uv_loop_t *loop);
+int can_auth_none(const server_ctx *sx, const client_ctx *cx);
+int can_auth_passwd(const server_ctx *sx, const client_ctx *cx);
+int can_access(const server_ctx *sx,
+ const client_ctx *cx,
+ const struct sockaddr *addr);
+
+/* client.c */
+void client_finish_init(server_ctx *sx, client_ctx *cx);
+
+/* util.c */
+#if defined(__GNUC__)
+# define ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__((format(printf, a, b)))
+#else
+# define ATTRIBUTE_FORMAT_PRINTF(a, b)
+#endif
+void pr_info(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void pr_warn(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void pr_err(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void *xmalloc(size_t size);
+
+/* main.c */
+const char *_getprogname(void);
+
+/* getopt.c */
+#if !HAVE_UNISTD_H
+extern char *optarg;
+int getopt(int argc, char **argv, const char *options);
+#endif
+
+/* ASSERT() is for debug checks, CHECK() for run-time sanity checks.
+ * DEBUG_CHECKS is for expensive debug checks that we only want to
+ * enable in debug builds but still want type-checked by the compiler
+ * in release builds.
+ */
+#if defined(NDEBUG)
+# define ASSERT(exp)
+# define CHECK(exp) do { if (!(exp)) abort(); } while (0)
+# define DEBUG_CHECKS (0)
+#else
+# define ASSERT(exp) assert(exp)
+# define CHECK(exp) assert(exp)
+# define DEBUG_CHECKS (1)
+#endif
+
+#define UNREACHABLE() CHECK(!"Unreachable code reached.")
+
+/* This macro looks complicated but it's not: it calculates the address
+ * of the embedding struct through the address of the embedded struct.
+ * In other words, if struct A embeds struct B, then we can obtain
+ * the address of A by taking the address of B and subtracting the
+ * field offset of B in A.
+ */
+#define CONTAINER_OF(ptr, type, field) \
+ ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
+
+#endif /* DEFS_H_ */
diff --git a/third-party/libuv/samples/socks5-proxy/getopt.c b/third-party/libuv/samples/socks5-proxy/getopt.c
new file mode 100644
index 0000000000..8481b2264f
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/getopt.c
@@ -0,0 +1,131 @@
+/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+extern const char *_getprogname(void);
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const nargv[];
+ const char *ostr;
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || *place == 0) { /* update scanning pointer */
+ optreset = 0;
+ place = nargv[optind];
+ if (optind >= nargc || *place++ != '-') {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return (-1);
+ }
+ optopt = *place++;
+ if (optopt == '-' && *place == 0) {
+ /* "--" => end of options */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ if (optopt == 0) {
+ /* Solitary '-', treat as a '-' option
+ if the program (eg su) is looking for it. */
+ place = EMSG;
+ if (strchr(ostr, '-') == NULL)
+ return (-1);
+ optopt = '-';
+ }
+ } else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+ if (*place == 0)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", _getprogname(),
+ optopt);
+ return (BADCH);
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ optarg = NULL;
+ if (*place == 0)
+ ++optind;
+ } else {
+ /* Option-argument is either the rest of this argument or the
+ entire next argument. */
+ if (*place)
+ optarg = place;
+ else if (nargc > ++optind)
+ optarg = nargv[optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ _getprogname(), optopt);
+ return (BADCH);
+ }
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* return option letter */
+}
diff --git a/third-party/libuv/samples/socks5-proxy/main.c b/third-party/libuv/samples/socks5-proxy/main.c
new file mode 100644
index 0000000000..04020cbd3a
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/main.c
@@ -0,0 +1,99 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "defs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h> /* getopt */
+#endif
+
+#define DEFAULT_BIND_HOST "127.0.0.1"
+#define DEFAULT_BIND_PORT 1080
+#define DEFAULT_IDLE_TIMEOUT (60 * 1000)
+
+static void parse_opts(server_config *cf, int argc, char **argv);
+static void usage(void);
+
+static const char *progname = __FILE__; /* Reset in main(). */
+
+int main(int argc, char **argv) {
+ server_config config;
+ int err;
+
+ progname = argv[0];
+ memset(&config, 0, sizeof(config));
+ config.bind_host = DEFAULT_BIND_HOST;
+ config.bind_port = DEFAULT_BIND_PORT;
+ config.idle_timeout = DEFAULT_IDLE_TIMEOUT;
+ parse_opts(&config, argc, argv);
+
+ err = server_run(&config, uv_default_loop());
+ if (err) {
+ exit(1);
+ }
+
+ return 0;
+}
+
+const char *_getprogname(void) {
+ return progname;
+}
+
+static void parse_opts(server_config *cf, int argc, char **argv) {
+ int opt;
+
+ while (-1 != (opt = getopt(argc, argv, "H:hp:"))) {
+ switch (opt) {
+ case 'H':
+ cf->bind_host = optarg;
+ break;
+
+ case 'p':
+ if (1 != sscanf(optarg, "%hu", &cf->bind_port)) {
+ pr_err("bad port number: %s", optarg);
+ usage();
+ }
+ break;
+
+ default:
+ usage();
+ }
+ }
+}
+
+static void usage(void) {
+ printf("Usage:\n"
+ "\n"
+ " %s [-b <address> [-h] [-p <port>]\n"
+ "\n"
+ "Options:\n"
+ "\n"
+ " -b <hostname|address> Bind to this address or hostname.\n"
+ " Default: \"127.0.0.1\"\n"
+ " -h Show this help message.\n"
+ " -p <port> Bind to this port number. Default: 1080\n"
+ "",
+ progname);
+ exit(1);
+}
diff --git a/third-party/libuv/samples/socks5-proxy/s5.c b/third-party/libuv/samples/socks5-proxy/s5.c
new file mode 100644
index 0000000000..4f08e34524
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/s5.c
@@ -0,0 +1,271 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "s5.h"
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h> /* abort() */
+#include <string.h> /* memset() */
+
+enum {
+ s5_version,
+ s5_nmethods,
+ s5_methods,
+ s5_auth_pw_version,
+ s5_auth_pw_userlen,
+ s5_auth_pw_username,
+ s5_auth_pw_passlen,
+ s5_auth_pw_password,
+ s5_req_version,
+ s5_req_cmd,
+ s5_req_reserved,
+ s5_req_atyp,
+ s5_req_atyp_host,
+ s5_req_daddr,
+ s5_req_dport0,
+ s5_req_dport1,
+ s5_dead
+};
+
+void s5_init(s5_ctx *cx) {
+ memset(cx, 0, sizeof(*cx));
+ cx->state = s5_version;
+}
+
+s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size) {
+ s5_err err;
+ uint8_t *p;
+ uint8_t c;
+ size_t i;
+ size_t n;
+
+ p = *data;
+ n = *size;
+ i = 0;
+
+ while (i < n) {
+ c = p[i];
+ i += 1;
+ switch (cx->state) {
+ case s5_version:
+ if (c != 5) {
+ err = s5_bad_version;
+ goto out;
+ }
+ cx->state = s5_nmethods;
+ break;
+
+ case s5_nmethods:
+ cx->arg0 = 0;
+ cx->arg1 = c; /* Number of bytes to read. */
+ cx->state = s5_methods;
+ break;
+
+ case s5_methods:
+ if (cx->arg0 < cx->arg1) {
+ switch (c) {
+ case 0:
+ cx->methods |= S5_AUTH_NONE;
+ break;
+ case 1:
+ cx->methods |= S5_AUTH_GSSAPI;
+ break;
+ case 2:
+ cx->methods |= S5_AUTH_PASSWD;
+ break;
+ /* Ignore everything we don't understand. */
+ }
+ cx->arg0 += 1;
+ }
+ if (cx->arg0 == cx->arg1) {
+ err = s5_auth_select;
+ goto out;
+ }
+ break;
+
+ case s5_auth_pw_version:
+ if (c != 1) {
+ err = s5_bad_version;
+ goto out;
+ }
+ cx->state = s5_auth_pw_userlen;
+ break;
+
+ case s5_auth_pw_userlen:
+ cx->arg0 = 0;
+ cx->userlen = c;
+ cx->state = s5_auth_pw_username;
+ break;
+
+ case s5_auth_pw_username:
+ if (cx->arg0 < cx->userlen) {
+ cx->username[cx->arg0] = c;
+ cx->arg0 += 1;
+ }
+ if (cx->arg0 == cx->userlen) {
+ cx->username[cx->userlen] = '\0';
+ cx->state = s5_auth_pw_passlen;
+ }
+ break;
+
+ case s5_auth_pw_passlen:
+ cx->arg0 = 0;
+ cx->passlen = c;
+ cx->state = s5_auth_pw_password;
+ break;
+
+ case s5_auth_pw_password:
+ if (cx->arg0 < cx->passlen) {
+ cx->password[cx->arg0] = c;
+ cx->arg0 += 1;
+ }
+ if (cx->arg0 == cx->passlen) {
+ cx->password[cx->passlen] = '\0';
+ cx->state = s5_req_version;
+ err = s5_auth_verify;
+ goto out;
+ }
+ break;
+
+ case s5_req_version:
+ if (c != 5) {
+ err = s5_bad_version;
+ goto out;
+ }
+ cx->state = s5_req_cmd;
+ break;
+
+ case s5_req_cmd:
+ switch (c) {
+ case 1: /* TCP connect */
+ cx->cmd = s5_cmd_tcp_connect;
+ break;
+ case 3: /* UDP associate */
+ cx->cmd = s5_cmd_udp_assoc;
+ break;
+ default:
+ err = s5_bad_cmd;
+ goto out;
+ }
+ cx->state = s5_req_reserved;
+ break;
+
+ case s5_req_reserved:
+ cx->state = s5_req_atyp;
+ break;
+
+ case s5_req_atyp:
+ cx->arg0 = 0;
+ switch (c) {
+ case 1: /* IPv4, four octets. */
+ cx->state = s5_req_daddr;
+ cx->atyp = s5_atyp_ipv4;
+ cx->arg1 = 4;
+ break;
+ case 3: /* Hostname. First byte is length. */
+ cx->state = s5_req_atyp_host;
+ cx->atyp = s5_atyp_host;
+ cx->arg1 = 0;
+ break;
+ case 4: /* IPv6, sixteen octets. */
+ cx->state = s5_req_daddr;
+ cx->atyp = s5_atyp_ipv6;
+ cx->arg1 = 16;
+ break;
+ default:
+ err = s5_bad_atyp;
+ goto out;
+ }
+ break;
+
+ case s5_req_atyp_host:
+ cx->arg1 = c;
+ cx->state = s5_req_daddr;
+ break;
+
+ case s5_req_daddr:
+ if (cx->arg0 < cx->arg1) {
+ cx->daddr[cx->arg0] = c;
+ cx->arg0 += 1;
+ }
+ if (cx->arg0 == cx->arg1) {
+ cx->daddr[cx->arg1] = '\0';
+ cx->state = s5_req_dport0;
+ }
+ break;
+
+ case s5_req_dport0:
+ cx->dport = c << 8;
+ cx->state = s5_req_dport1;
+ break;
+
+ case s5_req_dport1:
+ cx->dport |= c;
+ cx->state = s5_dead;
+ err = s5_exec_cmd;
+ goto out;
+
+ case s5_dead:
+ break;
+
+ default:
+ abort();
+ }
+ }
+ err = s5_ok;
+
+out:
+ *data = p + i;
+ *size = n - i;
+ return err;
+}
+
+unsigned int s5_auth_methods(const s5_ctx *cx) {
+ return cx->methods;
+}
+
+int s5_select_auth(s5_ctx *cx, s5_auth_method method) {
+ int err;
+
+ err = 0;
+ switch (method) {
+ case S5_AUTH_NONE:
+ cx->state = s5_req_version;
+ break;
+ case S5_AUTH_PASSWD:
+ cx->state = s5_auth_pw_version;
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+const char *s5_strerror(s5_err err) {
+#define S5_ERR_GEN(_, name, errmsg) case s5_ ## name: return errmsg;
+ switch (err) {
+ S5_ERR_MAP(S5_ERR_GEN)
+ default: ; /* Silence s5_max_errors -Wswitch warning. */
+ }
+#undef S5_ERR_GEN
+ return "Unknown error.";
+}
diff --git a/third-party/libuv/samples/socks5-proxy/s5.h b/third-party/libuv/samples/socks5-proxy/s5.h
new file mode 100644
index 0000000000..715f322287
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/s5.h
@@ -0,0 +1,94 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef S5_H_
+#define S5_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define S5_ERR_MAP(V) \
+ V(-1, bad_version, "Bad protocol version.") \
+ V(-2, bad_cmd, "Bad protocol command.") \
+ V(-3, bad_atyp, "Bad address type.") \
+ V(0, ok, "No error.") \
+ V(1, auth_select, "Select authentication method.") \
+ V(2, auth_verify, "Verify authentication.") \
+ V(3, exec_cmd, "Execute command.") \
+
+typedef enum {
+#define S5_ERR_GEN(code, name, _) s5_ ## name = code,
+ S5_ERR_MAP(S5_ERR_GEN)
+#undef S5_ERR_GEN
+ s5_max_errors
+} s5_err;
+
+typedef enum {
+ S5_AUTH_NONE = 1 << 0,
+ S5_AUTH_GSSAPI = 1 << 1,
+ S5_AUTH_PASSWD = 1 << 2
+} s5_auth_method;
+
+typedef enum {
+ s5_auth_allow,
+ s5_auth_deny
+} s5_auth_result;
+
+typedef enum {
+ s5_atyp_ipv4,
+ s5_atyp_ipv6,
+ s5_atyp_host
+} s5_atyp;
+
+typedef enum {
+ s5_cmd_tcp_connect,
+ s5_cmd_tcp_bind,
+ s5_cmd_udp_assoc
+} s5_cmd;
+
+typedef struct {
+ uint32_t arg0; /* Scratch space for the state machine. */
+ uint32_t arg1; /* Scratch space for the state machine. */
+ uint8_t state;
+ uint8_t methods;
+ uint8_t cmd;
+ uint8_t atyp;
+ uint8_t userlen;
+ uint8_t passlen;
+ uint16_t dport;
+ uint8_t username[257];
+ uint8_t password[257];
+ uint8_t daddr[257]; /* TODO(bnoordhuis) Merge with username/password. */
+} s5_ctx;
+
+void s5_init(s5_ctx *ctx);
+
+s5_err s5_parse(s5_ctx *cx, uint8_t **data, size_t *size);
+
+/* Only call after s5_parse() has returned s5_want_auth_method. */
+unsigned int s5_auth_methods(const s5_ctx *cx);
+
+/* Call after s5_parse() has returned s5_want_auth_method. */
+int s5_select_auth(s5_ctx *cx, s5_auth_method method);
+
+const char *s5_strerror(s5_err err);
+
+#endif /* S5_H_ */
diff --git a/third-party/libuv/samples/socks5-proxy/server.c b/third-party/libuv/samples/socks5-proxy/server.c
new file mode 100644
index 0000000000..3f1ba42c9e
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/server.c
@@ -0,0 +1,241 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "defs.h"
+#include <netinet/in.h> /* INET6_ADDRSTRLEN */
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef INET6_ADDRSTRLEN
+# define INET6_ADDRSTRLEN 63
+#endif
+
+typedef struct {
+ uv_getaddrinfo_t getaddrinfo_req;
+ server_config config;
+ server_ctx *servers;
+ uv_loop_t *loop;
+} server_state;
+
+static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *ai);
+static void on_connection(uv_stream_t *server, int status);
+
+int server_run(const server_config *cf, uv_loop_t *loop) {
+ struct addrinfo hints;
+ server_state state;
+ int err;
+
+ memset(&state, 0, sizeof(state));
+ state.servers = NULL;
+ state.config = *cf;
+ state.loop = loop;
+
+ /* Resolve the address of the interface that we should bind to.
+ * The getaddrinfo callback starts the server and everything else.
+ */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ err = uv_getaddrinfo(loop,
+ &state.getaddrinfo_req,
+ do_bind,
+ cf->bind_host,
+ NULL,
+ &hints);
+ if (err != 0) {
+ pr_err("getaddrinfo: %s", uv_strerror(err));
+ return err;
+ }
+
+ /* Start the event loop. Control continues in do_bind(). */
+ if (uv_run(loop, UV_RUN_DEFAULT)) {
+ abort();
+ }
+
+ /* Please Valgrind. */
+ uv_loop_delete(loop);
+ free(state.servers);
+ return 0;
+}
+
+/* Bind a server to each address that getaddrinfo() reported. */
+static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) {
+ char addrbuf[INET6_ADDRSTRLEN + 1];
+ unsigned int ipv4_naddrs;
+ unsigned int ipv6_naddrs;
+ server_state *state;
+ server_config *cf;
+ struct addrinfo *ai;
+ const void *addrv;
+ const char *what;
+ uv_loop_t *loop;
+ server_ctx *sx;
+ unsigned int n;
+ int err;
+ union {
+ struct sockaddr addr;
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ } s;
+
+ state = CONTAINER_OF(req, server_state, getaddrinfo_req);
+ loop = state->loop;
+ cf = &state->config;
+
+ if (status < 0) {
+ pr_err("getaddrinfo(\"%s\"): %s", cf->bind_host, uv_strerror(status));
+ uv_freeaddrinfo(addrs);
+ return;
+ }
+
+ ipv4_naddrs = 0;
+ ipv6_naddrs = 0;
+ for (ai = addrs; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family == AF_INET) {
+ ipv4_naddrs += 1;
+ } else if (ai->ai_family == AF_INET6) {
+ ipv6_naddrs += 1;
+ }
+ }
+
+ if (ipv4_naddrs == 0 && ipv6_naddrs == 0) {
+ pr_err("%s has no IPv4/6 addresses", cf->bind_host);
+ uv_freeaddrinfo(addrs);
+ return;
+ }
+
+ state->servers =
+ xmalloc((ipv4_naddrs + ipv6_naddrs) * sizeof(state->servers[0]));
+
+ n = 0;
+ for (ai = addrs; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
+ continue;
+ }
+
+ if (ai->ai_family == AF_INET) {
+ s.addr4 = *(const struct sockaddr_in *) ai->ai_addr;
+ s.addr4.sin_port = htons(cf->bind_port);
+ addrv = &s.addr4.sin_addr;
+ } else if (ai->ai_family == AF_INET6) {
+ s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr;
+ s.addr6.sin6_port = htons(cf->bind_port);
+ addrv = &s.addr6.sin6_addr;
+ } else {
+ UNREACHABLE();
+ }
+
+ if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) {
+ UNREACHABLE();
+ }
+
+ sx = state->servers + n;
+ sx->loop = loop;
+ sx->idle_timeout = state->config.idle_timeout;
+ CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle));
+
+ what = "uv_tcp_bind";
+ err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0);
+ if (err == 0) {
+ what = "uv_listen";
+ err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection);
+ }
+
+ if (err != 0) {
+ pr_err("%s(\"%s:%hu\"): %s",
+ what,
+ addrbuf,
+ cf->bind_port,
+ uv_strerror(err));
+ while (n > 0) {
+ n -= 1;
+ uv_close((uv_handle_t *) (state->servers + n), NULL);
+ }
+ break;
+ }
+
+ pr_info("listening on %s:%hu", addrbuf, cf->bind_port);
+ n += 1;
+ }
+
+ uv_freeaddrinfo(addrs);
+}
+
+static void on_connection(uv_stream_t *server, int status) {
+ server_ctx *sx;
+ client_ctx *cx;
+
+ CHECK(status == 0);
+ sx = CONTAINER_OF(server, server_ctx, tcp_handle);
+ cx = xmalloc(sizeof(*cx));
+ CHECK(0 == uv_tcp_init(sx->loop, &cx->incoming.handle.tcp));
+ CHECK(0 == uv_accept(server, &cx->incoming.handle.stream));
+ client_finish_init(sx, cx);
+}
+
+int can_auth_none(const server_ctx *sx, const client_ctx *cx) {
+ return 1;
+}
+
+int can_auth_passwd(const server_ctx *sx, const client_ctx *cx) {
+ return 0;
+}
+
+int can_access(const server_ctx *sx,
+ const client_ctx *cx,
+ const struct sockaddr *addr) {
+ const struct sockaddr_in6 *addr6;
+ const struct sockaddr_in *addr4;
+ const uint32_t *p;
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ uint32_t d;
+
+ /* TODO(bnoordhuis) Implement proper access checks. For now, just reject
+ * traffic to localhost.
+ */
+ if (addr->sa_family == AF_INET) {
+ addr4 = (const struct sockaddr_in *) addr;
+ d = ntohl(addr4->sin_addr.s_addr);
+ return (d >> 24) != 0x7F;
+ }
+
+ if (addr->sa_family == AF_INET6) {
+ addr6 = (const struct sockaddr_in6 *) addr;
+ p = (const uint32_t *) &addr6->sin6_addr.s6_addr;
+ a = ntohl(p[0]);
+ b = ntohl(p[1]);
+ c = ntohl(p[2]);
+ d = ntohl(p[3]);
+ if (a == 0 && b == 0 && c == 0 && d == 1) {
+ return 0; /* "::1" style address. */
+ }
+ if (a == 0 && b == 0 && c == 0xFFFF && (d >> 24) == 0x7F) {
+ return 0; /* "::ffff:127.x.x.x" style address. */
+ }
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/third-party/libuv/samples/socks5-proxy/util.c b/third-party/libuv/samples/socks5-proxy/util.c
new file mode 100644
index 0000000000..af34f05593
--- /dev/null
+++ b/third-party/libuv/samples/socks5-proxy/util.c
@@ -0,0 +1,72 @@
+/* Copyright StrongLoop, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "defs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void pr_do(FILE *stream,
+ const char *label,
+ const char *fmt,
+ va_list ap);
+
+void *xmalloc(size_t size) {
+ void *ptr;
+
+ ptr = malloc(size);
+ if (ptr == NULL) {
+ pr_err("out of memory, need %lu bytes", (unsigned long) size);
+ exit(1);
+ }
+
+ return ptr;
+}
+
+void pr_info(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ pr_do(stdout, "info", fmt, ap);
+ va_end(ap);
+}
+
+void pr_warn(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ pr_do(stderr, "warn", fmt, ap);
+ va_end(ap);
+}
+
+void pr_err(const char *fmt, ...) {
+ va_list ap;
+ va_start(ap, fmt);
+ pr_do(stderr, "error", fmt, ap);
+ va_end(ap);
+}
+
+static void pr_do(FILE *stream,
+ const char *label,
+ const char *fmt,
+ va_list ap) {
+ char fmtbuf[1024];
+ vsnprintf(fmtbuf, sizeof(fmtbuf), fmt, ap);
+ fprintf(stream, "%s:%s: %s\n", _getprogname(), label, fmtbuf);
+}
diff --git a/third-party/libuv/src/fs-poll.c b/third-party/libuv/src/fs-poll.c
new file mode 100644
index 0000000000..7fdaaeb17a
--- /dev/null
+++ b/third-party/libuv/src/fs-poll.c
@@ -0,0 +1,223 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "uv-common.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct poll_ctx {
+ uv_fs_poll_t* parent_handle; /* NULL if parent has been stopped or closed */
+ int busy_polling;
+ unsigned int interval;
+ uint64_t start_time;
+ uv_loop_t* loop;
+ uv_fs_poll_cb poll_cb;
+ uv_timer_t timer_handle;
+ uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */
+ uv_stat_t statbuf;
+ char path[1]; /* variable length */
+};
+
+static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b);
+static void poll_cb(uv_fs_t* req);
+static void timer_cb(uv_timer_t* timer, int status);
+static void timer_close_cb(uv_handle_t* handle);
+
+static uv_stat_t zero_statbuf;
+
+
+int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL);
+ return 0;
+}
+
+
+int uv_fs_poll_start(uv_fs_poll_t* handle,
+ uv_fs_poll_cb cb,
+ const char* path,
+ unsigned int interval) {
+ struct poll_ctx* ctx;
+ uv_loop_t* loop;
+ size_t len;
+
+ if (uv__is_active(handle))
+ return 0;
+
+ loop = handle->loop;
+ len = strlen(path);
+ ctx = calloc(1, sizeof(*ctx) + len);
+
+ if (ctx == NULL)
+ return UV_ENOMEM;
+
+ ctx->loop = loop;
+ ctx->poll_cb = cb;
+ ctx->interval = interval ? interval : 1;
+ ctx->start_time = uv_now(loop);
+ ctx->parent_handle = handle;
+ memcpy(ctx->path, path, len + 1);
+
+ if (uv_timer_init(loop, &ctx->timer_handle))
+ abort();
+
+ ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
+ uv__handle_unref(&ctx->timer_handle);
+
+ if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb))
+ abort();
+
+ handle->poll_ctx = ctx;
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+int uv_fs_poll_stop(uv_fs_poll_t* handle) {
+ struct poll_ctx* ctx;
+
+ if (!uv__is_active(handle))
+ return 0;
+
+ ctx = handle->poll_ctx;
+ assert(ctx != NULL);
+ assert(ctx->parent_handle != NULL);
+ ctx->parent_handle = NULL;
+ handle->poll_ctx = NULL;
+
+ /* Close the timer if it's active. If it's inactive, there's a stat request
+ * in progress and poll_cb will take care of the cleanup.
+ */
+ if (uv__is_active(&ctx->timer_handle))
+ uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
+
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+void uv__fs_poll_close(uv_fs_poll_t* handle) {
+ uv_fs_poll_stop(handle);
+}
+
+
+static void timer_cb(uv_timer_t* timer, int status) {
+ struct poll_ctx* ctx;
+
+ ctx = container_of(timer, struct poll_ctx, timer_handle);
+ assert(ctx->parent_handle != NULL);
+ assert(ctx->parent_handle->poll_ctx == ctx);
+ ctx->start_time = uv_now(ctx->loop);
+
+ if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb))
+ abort();
+}
+
+
+static void poll_cb(uv_fs_t* req) {
+ uv_stat_t* statbuf;
+ struct poll_ctx* ctx;
+ uint64_t interval;
+
+ ctx = container_of(req, struct poll_ctx, fs_req);
+
+ if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */
+ uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
+ uv_fs_req_cleanup(req);
+ return;
+ }
+
+ if (req->result != 0) {
+ if (ctx->busy_polling != req->result) {
+ ctx->poll_cb(ctx->parent_handle,
+ req->result,
+ &ctx->statbuf,
+ &zero_statbuf);
+ ctx->busy_polling = req->result;
+ }
+ goto out;
+ }
+
+ statbuf = &req->statbuf;
+
+ if (ctx->busy_polling != 0)
+ if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf))
+ ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf);
+
+ ctx->statbuf = *statbuf;
+ ctx->busy_polling = 1;
+
+out:
+ uv_fs_req_cleanup(req);
+
+ if (ctx->parent_handle == NULL) { /* handle has been stopped by callback */
+ uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
+ return;
+ }
+
+ /* Reschedule timer, subtract the delay from doing the stat(). */
+ interval = ctx->interval;
+ interval -= (uv_now(ctx->loop) - ctx->start_time) % interval;
+
+ if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0))
+ abort();
+}
+
+
+static void timer_close_cb(uv_handle_t* handle) {
+ free(container_of(handle, struct poll_ctx, timer_handle));
+}
+
+
+static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) {
+ return a->st_ctim.tv_nsec == b->st_ctim.tv_nsec
+ && a->st_mtim.tv_nsec == b->st_mtim.tv_nsec
+ && a->st_birthtim.tv_nsec == b->st_birthtim.tv_nsec
+ && a->st_ctim.tv_sec == b->st_ctim.tv_sec
+ && a->st_mtim.tv_sec == b->st_mtim.tv_sec
+ && a->st_birthtim.tv_sec == b->st_birthtim.tv_sec
+ && a->st_size == b->st_size
+ && a->st_mode == b->st_mode
+ && a->st_uid == b->st_uid
+ && a->st_gid == b->st_gid
+ && a->st_ino == b->st_ino
+ && a->st_dev == b->st_dev
+ && a->st_flags == b->st_flags
+ && a->st_gen == b->st_gen;
+}
+
+
+#if defined(_WIN32)
+
+#include "win/internal.h"
+#include "win/handle-inl.h"
+
+void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) {
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ uv__handle_close(handle);
+}
+
+#endif /* _WIN32 */
diff --git a/third-party/libuv/src/inet.c b/third-party/libuv/src/inet.c
new file mode 100644
index 0000000000..a30c0d1512
--- /dev/null
+++ b/third-party/libuv/src/inet.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#include "uv.h"
+#include "uv-common.h"
+
+
+static int inet_ntop4(const unsigned char *src, char *dst, size_t size);
+static int inet_ntop6(const unsigned char *src, char *dst, size_t size);
+static int inet_pton4(const char *src, unsigned char *dst);
+static int inet_pton6(const char *src, unsigned char *dst);
+
+
+int uv_inet_ntop(int af, const void* src, char* dst, size_t size) {
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ return UV_EAFNOSUPPORT;
+ }
+ /* NOTREACHED */
+}
+
+
+static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+ int l;
+
+#ifndef _WIN32
+ l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
+#else
+ l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
+#endif
+ if (l <= 0 || (size_t) l >= size) {
+ return UV_ENOSPC;
+ }
+ strncpy(dst, tmp, size);
+ dst[size - 1] = '\0';
+ return 0;
+}
+
+
+static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < (int) sizeof(struct in6_addr); i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ best.len = 0;
+ cur.base = -1;
+ cur.len = 0;
+ for (i = 0; i < (int) ARRAY_SIZE(words); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (int) ARRAY_SIZE(words); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 && (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ int err = inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp));
+ if (err)
+ return err;
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%x", words[i]);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ return UV_ENOSPC;
+ }
+ strcpy(dst, tmp);
+ return 0;
+}
+
+
+int uv_inet_pton(int af, const char* src, void* dst) {
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ return UV_EAFNOSUPPORT;
+ }
+ /* NOTREACHED */
+}
+
+
+static int inet_pton4(const char *src, unsigned char *dst) {
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[sizeof(struct in_addr)], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int nw = *tp * 10 + (pch - digits);
+
+ if (saw_digit && *tp == 0)
+ return UV_EINVAL;
+ if (nw > 255)
+ return UV_EINVAL;
+ *tp = nw;
+ if (!saw_digit) {
+ if (++octets > 4)
+ return UV_EINVAL;
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return UV_EINVAL;
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return UV_EINVAL;
+ }
+ if (octets < 4)
+ return UV_EINVAL;
+ memcpy(dst, tmp, sizeof(struct in_addr));
+ return 0;
+}
+
+
+static int inet_pton6(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[sizeof(struct in6_addr)], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, seen_xdigits;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', sizeof tmp);
+ endp = tp + sizeof tmp;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return UV_EINVAL;
+ curtok = src;
+ seen_xdigits = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (++seen_xdigits > 4)
+ return UV_EINVAL;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!seen_xdigits) {
+ if (colonp)
+ return UV_EINVAL;
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return UV_EINVAL;
+ }
+ if (tp + sizeof(uint16_t) > endp)
+ return UV_EINVAL;
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ seen_xdigits = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
+ int err = inet_pton4(curtok, tp);
+ if (err == 0) {
+ tp += sizeof(struct in_addr);
+ seen_xdigits = 0;
+ break; /*%< '\\0' was seen by inet_pton4(). */
+ }
+ }
+ return UV_EINVAL;
+ }
+ if (seen_xdigits) {
+ if (tp + sizeof(uint16_t) > endp)
+ return UV_EINVAL;
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return UV_EINVAL;
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return UV_EINVAL;
+ memcpy(dst, tmp, sizeof tmp);
+ return 0;
+}
diff --git a/third-party/libuv/src/queue.h b/third-party/libuv/src/queue.h
new file mode 100644
index 0000000000..fe02b454ea
--- /dev/null
+++ b/third-party/libuv/src/queue.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef QUEUE_H_
+#define QUEUE_H_
+
+typedef void *QUEUE[2];
+
+/* Private macros. */
+#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0]))
+#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1]))
+#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
+#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
+
+/* Public macros. */
+#define QUEUE_DATA(ptr, type, field) \
+ ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
+
+#define QUEUE_FOREACH(q, h) \
+ for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
+
+#define QUEUE_EMPTY(q) \
+ ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))
+
+#define QUEUE_HEAD(q) \
+ (QUEUE_NEXT(q))
+
+#define QUEUE_INIT(q) \
+ do { \
+ QUEUE_NEXT(q) = (q); \
+ QUEUE_PREV(q) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_ADD(h, n) \
+ do { \
+ QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \
+ QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \
+ QUEUE_PREV(h) = QUEUE_PREV(n); \
+ QUEUE_PREV_NEXT(h) = (h); \
+ } \
+ while (0)
+
+#define QUEUE_SPLIT(h, q, n) \
+ do { \
+ QUEUE_PREV(n) = QUEUE_PREV(h); \
+ QUEUE_PREV_NEXT(n) = (n); \
+ QUEUE_NEXT(n) = (q); \
+ QUEUE_PREV(h) = QUEUE_PREV(q); \
+ QUEUE_PREV_NEXT(h) = (h); \
+ QUEUE_PREV(q) = (n); \
+ } \
+ while (0)
+
+#define QUEUE_INSERT_HEAD(h, q) \
+ do { \
+ QUEUE_NEXT(q) = QUEUE_NEXT(h); \
+ QUEUE_PREV(q) = (h); \
+ QUEUE_NEXT_PREV(q) = (q); \
+ QUEUE_NEXT(h) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_INSERT_TAIL(h, q) \
+ do { \
+ QUEUE_NEXT(q) = (h); \
+ QUEUE_PREV(q) = QUEUE_PREV(h); \
+ QUEUE_PREV_NEXT(q) = (q); \
+ QUEUE_PREV(h) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_REMOVE(q) \
+ do { \
+ QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \
+ QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \
+ } \
+ while (0)
+
+#endif /* QUEUE_H_ */
diff --git a/third-party/libuv/src/unix/aix.c b/third-party/libuv/src/unix/aix.c
new file mode 100644
index 0000000000..2521681305
--- /dev/null
+++ b/third-party/libuv/src/unix/aix.c
@@ -0,0 +1,399 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+#include <sys/protosw.h>
+#include <libperfstat.h>
+#include <sys/proc.h>
+#include <sys/procfs.h>
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ uint64_t G = 1000000000;
+ timebasestruct_t t;
+ read_wall_time(&t, TIMEBASE_SZ);
+ time_base_to_time(&t, TIMEBASE_SZ);
+ return (uint64_t) t.tb_high * G + t.tb_low;
+}
+
+
+/*
+ * We could use a static buffer for the path manipulations that we need outside
+ * of the function, but this function could be called by multiple consumers and
+ * we don't want to potentially create a race condition in the use of snprintf.
+ */
+int uv_exepath(char* buffer, size_t* size) {
+ ssize_t res;
+ char pp[64], cwdl[PATH_MAX];
+ struct psinfo ps;
+ int fd;
+
+ if (buffer == NULL)
+ return (-1);
+
+ if (size == NULL)
+ return (-1);
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/cwd", (unsigned long) getpid());
+
+ res = readlink(pp, cwdl, sizeof(cwdl) - 1);
+ if (res < 0)
+ return res;
+
+ cwdl[res] = '\0';
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
+ fd = open(pp, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ res = read(fd, &ps, sizeof(ps));
+ uv__close(fd);
+ if (res < 0)
+ return res;
+
+ (void) snprintf(buffer, *size, "%s%s", cwdl, ps.pr_fname);
+ *size = strlen(buffer);
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ perfstat_memory_total_t mem_total;
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
+ if (result == -1) {
+ return 0;
+ }
+ return mem_total.real_free * 4096;
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ perfstat_memory_total_t mem_total;
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
+ if (result == -1) {
+ return 0;
+ }
+ return mem_total.real_total * 4096;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ perfstat_cpu_total_t ps_total;
+ int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
+ if (result == -1) {
+ avg[0] = 0.; avg[1] = 0.; avg[2] = 0.;
+ return;
+ }
+ avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS);
+ avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS);
+ avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS);
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ return -ENOSYS;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags) {
+ return -ENOSYS;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ return -ENOSYS;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ UNREACHABLE();
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return 0;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ char pp[64];
+ psinfo_t psinfo;
+ int err;
+ int fd;
+
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
+
+ fd = open(pp, O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ /* FIXME(bnoordhuis) Handle EINTR. */
+ err = -EINVAL;
+ if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
+ *rss = (size_t)psinfo.pr_rssize * 1024;
+ err = 0;
+ }
+ uv__close(fd);
+
+ return err;
+}
+
+
+int uv_uptime(double* uptime) {
+ struct utmp *utmp_buf;
+ size_t entries = 0;
+ time_t boot_time;
+
+ utmpname(UTMP_FILE);
+
+ setutent();
+
+ while ((utmp_buf = getutent()) != NULL) {
+ if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS)
+ ++entries;
+ if (utmp_buf->ut_type == BOOT_TIME)
+ boot_time = utmp_buf->ut_time;
+ }
+
+ endutent();
+
+ if (boot_time == 0)
+ return -ENOSYS;
+
+ *uptime = time(NULL) - boot_time;
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ uv_cpu_info_t* cpu_info;
+ perfstat_cpu_total_t ps_total;
+ perfstat_cpu_t* ps_cpus;
+ perfstat_id_t cpu_id;
+ int result, ncpus, idx = 0;
+
+ result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
+ if (result == -1) {
+ return -ENOSYS;
+ }
+
+ ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
+ if (result == -1) {
+ return -ENOSYS;
+ }
+
+ ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t));
+ if (!ps_cpus) {
+ return -ENOMEM;
+ }
+
+ strcpy(cpu_id.name, FIRST_CPU);
+ result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
+ if (result == -1) {
+ free(ps_cpus);
+ return -ENOSYS;
+ }
+
+ *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t));
+ if (!*cpu_infos) {
+ free(ps_cpus);
+ return -ENOMEM;
+ }
+
+ *count = ncpus;
+
+ cpu_info = *cpu_infos;
+ while (idx < ncpus) {
+ cpu_info->speed = (int)(ps_total.processorHZ / 1000000);
+ cpu_info->model = strdup(ps_total.description);
+ cpu_info->cpu_times.user = ps_cpus[idx].user;
+ cpu_info->cpu_times.sys = ps_cpus[idx].sys;
+ cpu_info->cpu_times.idle = ps_cpus[idx].idle;
+ cpu_info->cpu_times.irq = ps_cpus[idx].wait;
+ cpu_info->cpu_times.nice = 0;
+ cpu_info++;
+ idx++;
+ }
+
+ free(ps_cpus);
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count) {
+ uv_interface_address_t* address;
+ int sockfd, size = 1;
+ struct ifconf ifc;
+ struct ifreq *ifr, *p, flg;
+
+ *count = 0;
+
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+ return -ENOSYS;
+ }
+
+ if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
+ uv__close(sockfd);
+ return -ENOSYS;
+ }
+
+ ifc.ifc_req = (struct ifreq*)malloc(size);
+ ifc.ifc_len = size;
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
+ uv__close(sockfd);
+ return -ENOSYS;
+ }
+
+#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
+
+ /* Count all up and running ipv4/ipv6 addresses */
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
+ p->ifr_addr.sa_family == AF_INET))
+ continue;
+
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
+ uv__close(sockfd);
+ return -ENOSYS;
+ }
+
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+ continue;
+
+ (*count)++;
+ }
+
+ /* Alloc the return interface structs */
+ *addresses = (uv_interface_address_t*)
+ malloc(*count * sizeof(uv_interface_address_t));
+ if (!(*addresses)) {
+ uv__close(sockfd);
+ return -ENOMEM;
+ }
+ address = *addresses;
+
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
+ p->ifr_addr.sa_family == AF_INET))
+ continue;
+
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
+ uv__close(sockfd);
+ return -ENOSYS;
+ }
+
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
+ continue;
+
+ /* All conditions above must match count loop */
+
+ address->name = strdup(p->ifr_name);
+
+ if (p->ifr_addr.sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
+ }
+
+ /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
+
+ address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
+
+ address++;
+ }
+
+#undef ADDR_SIZE
+
+ uv__close(sockfd);
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; ++i) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/async.c b/third-party/libuv/src/unix/async.c
new file mode 100644
index 0000000000..3c23e1d7fd
--- /dev/null
+++ b/third-party/libuv/src/unix/async.c
@@ -0,0 +1,290 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+/* This file contains both the uv__async internal infrastructure and the
+ * user-facing uv_async_t functions.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void uv__async_event(uv_loop_t* loop,
+ struct uv__async* w,
+ unsigned int nevents);
+static int uv__async_make_pending(int* pending);
+static int uv__async_eventfd(void);
+
+
+int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
+ int err;
+
+ err = uv__async_start(loop, &loop->async_watcher, uv__async_event);
+ if (err)
+ return err;
+
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
+ handle->async_cb = async_cb;
+ handle->pending = 0;
+
+ QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue);
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+int uv_async_send(uv_async_t* handle) {
+ if (uv__async_make_pending(&handle->pending) == 0)
+ uv__async_send(&handle->loop->async_watcher);
+
+ return 0;
+}
+
+
+void uv__async_close(uv_async_t* handle) {
+ QUEUE_REMOVE(&handle->queue);
+ uv__handle_stop(handle);
+}
+
+
+static void uv__async_event(uv_loop_t* loop,
+ struct uv__async* w,
+ unsigned int nevents) {
+ QUEUE* q;
+ uv_async_t* h;
+
+ QUEUE_FOREACH(q, &loop->async_handles) {
+ h = QUEUE_DATA(q, uv_async_t, queue);
+
+ if (h->pending == 0)
+ continue;
+ h->pending = 0;
+
+ if (h->async_cb == NULL)
+ continue;
+ h->async_cb(h, 0);
+ }
+}
+
+
+static int uv__async_make_pending(int* pending) {
+ /* Do a cheap read first. */
+ if (ACCESS_ONCE(int, *pending) != 0)
+ return 1;
+
+ /* Micro-optimization: use atomic memory operations to detect if we've been
+ * preempted by another thread and don't have to make an expensive syscall.
+ * This speeds up the heavily contended case by about 1-2% and has little
+ * if any impact on the non-contended case.
+ *
+ * Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits
+ * on x86, it's about 4x faster. It probably makes zero difference in the
+ * grand scheme of things but I'm OCD enough not to let this one pass.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+ {
+ unsigned int val = 1;
+ __asm__ __volatile__ ("xchgl %0, %1"
+ : "+r" (val)
+ : "m" (*pending));
+ return val != 0;
+ }
+#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
+ return __sync_val_compare_and_swap(pending, 0, 1) != 0;
+#else
+ ACCESS_ONCE(int, *pending) = 1;
+ return 0;
+#endif
+}
+
+
+static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ struct uv__async* wa;
+ char buf[1024];
+ unsigned n;
+ ssize_t r;
+
+ n = 0;
+ for (;;) {
+ r = read(w->fd, buf, sizeof(buf));
+
+ if (r > 0)
+ n += r;
+
+ if (r == sizeof(buf))
+ continue;
+
+ if (r != -1)
+ break;
+
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ break;
+
+ if (errno == EINTR)
+ continue;
+
+ abort();
+ }
+
+ wa = container_of(w, struct uv__async, io_watcher);
+
+#if defined(__linux__)
+ if (wa->wfd == -1) {
+ uint64_t val;
+ assert(n == sizeof(val));
+ memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */
+ wa->cb(loop, wa, val);
+ return;
+ }
+#endif
+
+ wa->cb(loop, wa, n);
+}
+
+
+void uv__async_send(struct uv__async* wa) {
+ const void* buf;
+ ssize_t len;
+ int fd;
+ int r;
+
+ buf = "";
+ len = 1;
+ fd = wa->wfd;
+
+#if defined(__linux__)
+ if (fd == -1) {
+ static const uint64_t val = 1;
+ buf = &val;
+ len = sizeof(val);
+ fd = wa->io_watcher.fd; /* eventfd */
+ }
+#endif
+
+ do
+ r = write(fd, buf, len);
+ while (r == -1 && errno == EINTR);
+
+ if (r == len)
+ return;
+
+ if (r == -1)
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return;
+
+ abort();
+}
+
+
+void uv__async_init(struct uv__async* wa) {
+ wa->io_watcher.fd = -1;
+ wa->wfd = -1;
+}
+
+
+int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
+ int pipefd[2];
+ int err;
+
+ if (wa->io_watcher.fd != -1)
+ return 0;
+
+ err = uv__async_eventfd();
+ if (err >= 0) {
+ pipefd[0] = err;
+ pipefd[1] = -1;
+ }
+ else if (err == -ENOSYS)
+ err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
+
+ if (err < 0)
+ return err;
+
+ uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
+ uv__io_start(loop, &wa->io_watcher, UV__POLLIN);
+ wa->wfd = pipefd[1];
+ wa->cb = cb;
+
+ return 0;
+}
+
+
+void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
+ if (wa->io_watcher.fd == -1)
+ return;
+
+ uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
+ uv__close(wa->io_watcher.fd);
+ wa->io_watcher.fd = -1;
+
+ if (wa->wfd != -1) {
+ uv__close(wa->wfd);
+ wa->wfd = -1;
+ }
+}
+
+
+static int uv__async_eventfd() {
+#if defined(__linux__)
+ static int no_eventfd2;
+ static int no_eventfd;
+ int fd;
+
+ if (no_eventfd2)
+ goto skip_eventfd2;
+
+ fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
+ if (fd != -1)
+ return fd;
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_eventfd2 = 1;
+
+skip_eventfd2:
+
+ if (no_eventfd)
+ goto skip_eventfd;
+
+ fd = uv__eventfd(0);
+ if (fd != -1) {
+ uv__cloexec(fd, 1);
+ uv__nonblock(fd, 1);
+ return fd;
+ }
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_eventfd = 1;
+
+skip_eventfd:
+
+#endif
+
+ return -ENOSYS;
+}
diff --git a/third-party/libuv/src/unix/atomic-ops.h b/third-party/libuv/src/unix/atomic-ops.h
new file mode 100644
index 0000000000..7e4e64beda
--- /dev/null
+++ b/third-party/libuv/src/unix/atomic-ops.h
@@ -0,0 +1,60 @@
+/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef UV_ATOMIC_OPS_H_
+#define UV_ATOMIC_OPS_H_
+
+#include "internal.h" /* UV_UNUSED */
+
+UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
+UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
+UV_UNUSED(static void cpu_relax(void));
+
+/* Prefer hand-rolled assembly over the gcc builtins because the latter also
+ * issue full memory barriers.
+ */
+UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
+#if defined(__i386__) || defined(__x86_64__)
+ int out;
+ __asm__ __volatile__ ("lock; cmpxchg %2, %1;"
+ : "=a" (out), "+m" (*(volatile int*) ptr)
+ : "r" (newval), "0" (oldval)
+ : "memory");
+ return out;
+#else
+ return __sync_val_compare_and_swap(ptr, oldval, newval);
+#endif
+}
+
+UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
+#if defined(__i386__) || defined(__x86_64__)
+ long out;
+ __asm__ __volatile__ ("lock; cmpxchg %2, %1;"
+ : "=a" (out), "+m" (*(volatile long*) ptr)
+ : "r" (newval), "0" (oldval)
+ : "memory");
+ return out;
+#else
+ return __sync_val_compare_and_swap(ptr, oldval, newval);
+#endif
+}
+
+UV_UNUSED(static void cpu_relax(void)) {
+#if defined(__i386__) || defined(__x86_64__)
+ __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
+#endif
+}
+
+#endif /* UV_ATOMIC_OPS_H_ */
diff --git a/third-party/libuv/src/unix/core.c b/third-party/libuv/src/unix/core.c
new file mode 100644
index 0000000000..df2a5f8042
--- /dev/null
+++ b/third-party/libuv/src/unix/core.c
@@ -0,0 +1,787 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stddef.h> /* NULL */
+#include <stdio.h> /* printf */
+#include <stdlib.h>
+#include <string.h> /* strerror */
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <limits.h> /* INT_MAX, PATH_MAX */
+#include <sys/uio.h> /* writev */
+
+#ifdef __linux__
+# include <sys/ioctl.h>
+#endif
+
+#ifdef __sun
+# include <sys/types.h>
+# include <sys/wait.h>
+#endif
+
+#ifdef __APPLE__
+# include <mach-o/dyld.h> /* _NSGetExecutablePath */
+# include <sys/filio.h>
+# include <sys/ioctl.h>
+#endif
+
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+# include <sys/filio.h>
+# include <sys/ioctl.h>
+# include <sys/wait.h>
+#endif
+
+static void uv__run_pending(uv_loop_t* loop);
+
+/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
+STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
+STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) ==
+ sizeof(((struct iovec*) 0)->iov_base));
+STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) ==
+ sizeof(((struct iovec*) 0)->iov_len));
+STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base));
+STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len));
+
+
+uint64_t uv_hrtime(void) {
+ return uv__hrtime(UV_CLOCK_PRECISE);
+}
+
+
+void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+
+ handle->flags |= UV_CLOSING;
+ handle->close_cb = close_cb;
+
+ switch (handle->type) {
+ case UV_NAMED_PIPE:
+ uv__pipe_close((uv_pipe_t*)handle);
+ break;
+
+ case UV_TTY:
+ uv__stream_close((uv_stream_t*)handle);
+ break;
+
+ case UV_TCP:
+ uv__tcp_close((uv_tcp_t*)handle);
+ break;
+
+ case UV_UDP:
+ uv__udp_close((uv_udp_t*)handle);
+ break;
+
+ case UV_PREPARE:
+ uv__prepare_close((uv_prepare_t*)handle);
+ break;
+
+ case UV_CHECK:
+ uv__check_close((uv_check_t*)handle);
+ break;
+
+ case UV_IDLE:
+ uv__idle_close((uv_idle_t*)handle);
+ break;
+
+ case UV_ASYNC:
+ uv__async_close((uv_async_t*)handle);
+ break;
+
+ case UV_TIMER:
+ uv__timer_close((uv_timer_t*)handle);
+ break;
+
+ case UV_PROCESS:
+ uv__process_close((uv_process_t*)handle);
+ break;
+
+ case UV_FS_EVENT:
+ uv__fs_event_close((uv_fs_event_t*)handle);
+ break;
+
+ case UV_POLL:
+ uv__poll_close((uv_poll_t*)handle);
+ break;
+
+ case UV_FS_POLL:
+ uv__fs_poll_close((uv_fs_poll_t*)handle);
+ break;
+
+ case UV_SIGNAL:
+ uv__signal_close((uv_signal_t*) handle);
+ /* Signal handles may not be closed immediately. The signal code will */
+ /* itself close uv__make_close_pending whenever appropriate. */
+ return;
+
+ default:
+ assert(0);
+ }
+
+ uv__make_close_pending(handle);
+}
+
+
+void uv__make_close_pending(uv_handle_t* handle) {
+ assert(handle->flags & UV_CLOSING);
+ assert(!(handle->flags & UV_CLOSED));
+ handle->next_closing = handle->loop->closing_handles;
+ handle->loop->closing_handles = handle;
+}
+
+
+static void uv__finish_close(uv_handle_t* handle) {
+ /* Note: while the handle is in the UV_CLOSING state now, it's still possible
+ * for it to be active in the sense that uv__is_active() returns true.
+ * A good example is when the user calls uv_shutdown(), immediately followed
+ * by uv_close(). The handle is considered active at this point because the
+ * completion of the shutdown req is still pending.
+ */
+ assert(handle->flags & UV_CLOSING);
+ assert(!(handle->flags & UV_CLOSED));
+ handle->flags |= UV_CLOSED;
+
+ switch (handle->type) {
+ case UV_PREPARE:
+ case UV_CHECK:
+ case UV_IDLE:
+ case UV_ASYNC:
+ case UV_TIMER:
+ case UV_PROCESS:
+ case UV_FS_EVENT:
+ case UV_FS_POLL:
+ case UV_POLL:
+ case UV_SIGNAL:
+ break;
+
+ case UV_NAMED_PIPE:
+ case UV_TCP:
+ case UV_TTY:
+ uv__stream_destroy((uv_stream_t*)handle);
+ break;
+
+ case UV_UDP:
+ uv__udp_finish_close((uv_udp_t*)handle);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ uv__handle_unref(handle);
+ QUEUE_REMOVE(&handle->handle_queue);
+
+ if (handle->close_cb) {
+ handle->close_cb(handle);
+ }
+}
+
+
+static void uv__run_closing_handles(uv_loop_t* loop) {
+ uv_handle_t* p;
+ uv_handle_t* q;
+
+ p = loop->closing_handles;
+ loop->closing_handles = NULL;
+
+ while (p) {
+ q = p->next_closing;
+ uv__finish_close(p);
+ p = q;
+ }
+}
+
+
+int uv_is_closing(const uv_handle_t* handle) {
+ return uv__is_closing(handle);
+}
+
+
+int uv_backend_fd(const uv_loop_t* loop) {
+ return loop->backend_fd;
+}
+
+
+int uv_backend_timeout(const uv_loop_t* loop) {
+ if (loop->stop_flag != 0)
+ return 0;
+
+ if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
+ return 0;
+
+ if (!QUEUE_EMPTY(&loop->idle_handles))
+ return 0;
+
+ if (loop->closing_handles)
+ return 0;
+
+ return uv__next_timeout(loop);
+}
+
+
+static int uv__loop_alive(const uv_loop_t* loop) {
+ return uv__has_active_handles(loop) ||
+ uv__has_active_reqs(loop) ||
+ loop->closing_handles != NULL;
+}
+
+
+int uv_loop_alive(const uv_loop_t* loop) {
+ return uv__loop_alive(loop);
+}
+
+
+int uv_run(uv_loop_t* loop, uv_run_mode mode) {
+ int timeout;
+ int r;
+
+ r = uv__loop_alive(loop);
+ if (!r)
+ uv__update_time(loop);
+
+ while (r != 0 && loop->stop_flag == 0) {
+ UV_TICK_START(loop, mode);
+
+ uv__update_time(loop);
+ uv__run_timers(loop);
+ uv__run_idle(loop);
+ uv__run_prepare(loop);
+ uv__run_pending(loop);
+
+ timeout = 0;
+ if ((mode & UV_RUN_NOWAIT) == 0)
+ timeout = uv_backend_timeout(loop);
+
+ uv__io_poll(loop, timeout);
+ uv__run_check(loop);
+ uv__run_closing_handles(loop);
+
+ if (mode == UV_RUN_ONCE) {
+ /* UV_RUN_ONCE implies forward progess: at least one callback must have
+ * been invoked when it returns. uv__io_poll() can return without doing
+ * I/O (meaning: no callbacks) when its timeout expires - which means we
+ * have pending timers that satisfy the forward progress constraint.
+ *
+ * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
+ * the check.
+ */
+ uv__update_time(loop);
+ uv__run_timers(loop);
+ }
+
+ r = uv__loop_alive(loop);
+ UV_TICK_STOP(loop, mode);
+
+ if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+ break;
+ }
+
+ /* The if statement lets gcc compile it to a conditional store. Avoids
+ * dirtying a cache line.
+ */
+ if (loop->stop_flag != 0)
+ loop->stop_flag = 0;
+
+ return r;
+}
+
+
+void uv_update_time(uv_loop_t* loop) {
+ uv__update_time(loop);
+}
+
+
+int uv_is_active(const uv_handle_t* handle) {
+ return uv__is_active(handle);
+}
+
+
+/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
+int uv__socket(int domain, int type, int protocol) {
+ int sockfd;
+ int err;
+
+#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
+ sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
+ if (sockfd != -1)
+ return sockfd;
+
+ if (errno != EINVAL)
+ return -errno;
+#endif
+
+ sockfd = socket(domain, type, protocol);
+ if (sockfd == -1)
+ return -errno;
+
+ err = uv__nonblock(sockfd, 1);
+ if (err == 0)
+ err = uv__cloexec(sockfd, 1);
+
+ if (err) {
+ uv__close(sockfd);
+ return err;
+ }
+
+#if defined(SO_NOSIGPIPE)
+ {
+ int on = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
+ }
+#endif
+
+ return sockfd;
+}
+
+
+int uv__accept(int sockfd) {
+ int peerfd;
+ int err;
+
+ assert(sockfd >= 0);
+
+ while (1) {
+#if defined(__linux__)
+ static int no_accept4;
+
+ if (no_accept4)
+ goto skip;
+
+ peerfd = uv__accept4(sockfd,
+ NULL,
+ NULL,
+ UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
+ if (peerfd != -1)
+ return peerfd;
+
+ if (errno == EINTR)
+ continue;
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_accept4 = 1;
+skip:
+#endif
+
+ peerfd = accept(sockfd, NULL, NULL);
+ if (peerfd == -1) {
+ if (errno == EINTR)
+ continue;
+ return -errno;
+ }
+
+ err = uv__cloexec(peerfd, 1);
+ if (err == 0)
+ err = uv__nonblock(peerfd, 1);
+
+ if (err) {
+ uv__close(peerfd);
+ return err;
+ }
+
+ return peerfd;
+ }
+}
+
+
+int uv__close(int fd) {
+ int saved_errno;
+ int rc;
+
+ assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */
+ assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
+
+ saved_errno = errno;
+ rc = close(fd);
+ if (rc == -1) {
+ rc = -errno;
+ if (rc == -EINTR)
+ rc = -EINPROGRESS; /* For platform/libc consistency. */
+ errno = saved_errno;
+ }
+
+ return rc;
+}
+
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
+
+int uv__nonblock(int fd, int set) {
+ int r;
+
+ do
+ r = ioctl(fd, FIONBIO, &set);
+ while (r == -1 && errno == EINTR);
+
+ if (r)
+ return -errno;
+
+ return 0;
+}
+
+
+int uv__cloexec(int fd, int set) {
+ int r;
+
+ do
+ r = ioctl(fd, set ? FIOCLEX : FIONCLEX);
+ while (r == -1 && errno == EINTR);
+
+ if (r)
+ return -errno;
+
+ return 0;
+}
+
+#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) */
+
+int uv__nonblock(int fd, int set) {
+ int flags;
+ int r;
+
+ do
+ r = fcntl(fd, F_GETFL);
+ while (r == -1 && errno == EINTR);
+
+ if (r == -1)
+ return -errno;
+
+ /* Bail out now if already set/clear. */
+ if (!!(r & O_NONBLOCK) == !!set)
+ return 0;
+
+ if (set)
+ flags = r | O_NONBLOCK;
+ else
+ flags = r & ~O_NONBLOCK;
+
+ do
+ r = fcntl(fd, F_SETFL, flags);
+ while (r == -1 && errno == EINTR);
+
+ if (r)
+ return -errno;
+
+ return 0;
+}
+
+
+int uv__cloexec(int fd, int set) {
+ int flags;
+ int r;
+
+ do
+ r = fcntl(fd, F_GETFD);
+ while (r == -1 && errno == EINTR);
+
+ if (r == -1)
+ return -errno;
+
+ /* Bail out now if already set/clear. */
+ if (!!(r & FD_CLOEXEC) == !!set)
+ return 0;
+
+ if (set)
+ flags = r | FD_CLOEXEC;
+ else
+ flags = r & ~FD_CLOEXEC;
+
+ do
+ r = fcntl(fd, F_SETFD, flags);
+ while (r == -1 && errno == EINTR);
+
+ if (r)
+ return -errno;
+
+ return 0;
+}
+
+#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
+
+
+/* This function is not execve-safe, there is a race window
+ * between the call to dup() and fcntl(FD_CLOEXEC).
+ */
+int uv__dup(int fd) {
+ int err;
+
+ fd = dup(fd);
+
+ if (fd == -1)
+ return -errno;
+
+ err = uv__cloexec(fd, 1);
+ if (err) {
+ uv__close(fd);
+ return err;
+ }
+
+ return fd;
+}
+
+
+ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
+ struct cmsghdr* cmsg;
+ ssize_t rc;
+ int* pfd;
+ int* end;
+#if defined(__linux__)
+ static int no_msg_cmsg_cloexec;
+ if (no_msg_cmsg_cloexec == 0) {
+ rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */
+ if (rc != -1)
+ return rc;
+ if (errno != EINVAL)
+ return -errno;
+ rc = recvmsg(fd, msg, flags);
+ if (rc == -1)
+ return -errno;
+ no_msg_cmsg_cloexec = 1;
+ } else {
+ rc = recvmsg(fd, msg, flags);
+ }
+#else
+ rc = recvmsg(fd, msg, flags);
+#endif
+ if (rc == -1)
+ return -errno;
+ if (msg->msg_controllen == 0)
+ return rc;
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
+ if (cmsg->cmsg_type == SCM_RIGHTS)
+ for (pfd = (int*) CMSG_DATA(cmsg),
+ end = (int*) ((char*) cmsg + cmsg->cmsg_len);
+ pfd < end;
+ pfd += 1)
+ uv__cloexec(*pfd, 1);
+ return rc;
+}
+
+
+int uv_cwd(char* buffer, size_t size) {
+ if (buffer == NULL)
+ return -EINVAL;
+
+ if (size == 0)
+ return -EINVAL;
+
+ if (getcwd(buffer, size) == NULL)
+ return -errno;
+
+ return 0;
+}
+
+
+int uv_chdir(const char* dir) {
+ if (chdir(dir))
+ return -errno;
+
+ return 0;
+}
+
+
+void uv_disable_stdio_inheritance(void) {
+ int fd;
+
+ /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the
+ * first 16 file descriptors. After that, bail out after the first error.
+ */
+ for (fd = 0; ; fd++)
+ if (uv__cloexec(fd, 1) && fd > 15)
+ break;
+}
+
+
+static void uv__run_pending(uv_loop_t* loop) {
+ QUEUE* q;
+ uv__io_t* w;
+
+ while (!QUEUE_EMPTY(&loop->pending_queue)) {
+ q = QUEUE_HEAD(&loop->pending_queue);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ w = QUEUE_DATA(q, uv__io_t, pending_queue);
+ w->cb(loop, w, UV__POLLOUT);
+ }
+}
+
+
+static unsigned int next_power_of_two(unsigned int val) {
+ val -= 1;
+ val |= val >> 1;
+ val |= val >> 2;
+ val |= val >> 4;
+ val |= val >> 8;
+ val |= val >> 16;
+ val += 1;
+ return val;
+}
+
+static void maybe_resize(uv_loop_t* loop, unsigned int len) {
+ uv__io_t** watchers;
+ void* fake_watcher_list;
+ void* fake_watcher_count;
+ unsigned int nwatchers;
+ unsigned int i;
+
+ if (len <= loop->nwatchers)
+ return;
+
+ /* Preserve fake watcher list and count at the end of the watchers */
+ if (loop->watchers != NULL) {
+ fake_watcher_list = loop->watchers[loop->nwatchers];
+ fake_watcher_count = loop->watchers[loop->nwatchers + 1];
+ } else {
+ fake_watcher_list = NULL;
+ fake_watcher_count = NULL;
+ }
+
+ nwatchers = next_power_of_two(len + 2) - 2;
+ watchers = realloc(loop->watchers,
+ (nwatchers + 2) * sizeof(loop->watchers[0]));
+
+ if (watchers == NULL)
+ abort();
+ for (i = loop->nwatchers; i < nwatchers; i++)
+ watchers[i] = NULL;
+ watchers[nwatchers] = fake_watcher_list;
+ watchers[nwatchers + 1] = fake_watcher_count;
+
+ loop->watchers = watchers;
+ loop->nwatchers = nwatchers;
+}
+
+
+void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
+ assert(cb != NULL);
+ assert(fd >= -1);
+ QUEUE_INIT(&w->pending_queue);
+ QUEUE_INIT(&w->watcher_queue);
+ w->cb = cb;
+ w->fd = fd;
+ w->events = 0;
+ w->pevents = 0;
+
+#if defined(UV_HAVE_KQUEUE)
+ w->rcount = 0;
+ w->wcount = 0;
+#endif /* defined(UV_HAVE_KQUEUE) */
+}
+
+
+void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+ assert(w->fd >= 0);
+ assert(w->fd < INT_MAX);
+
+ w->pevents |= events;
+ maybe_resize(loop, w->fd + 1);
+
+#if !defined(__sun)
+ /* The event ports backend needs to rearm all file descriptors on each and
+ * every tick of the event loop but the other backends allow us to
+ * short-circuit here if the event mask is unchanged.
+ */
+ if (w->events == w->pevents) {
+ if (w->events == 0 && !QUEUE_EMPTY(&w->watcher_queue)) {
+ QUEUE_REMOVE(&w->watcher_queue);
+ QUEUE_INIT(&w->watcher_queue);
+ }
+ return;
+ }
+#endif
+
+ if (QUEUE_EMPTY(&w->watcher_queue))
+ QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
+
+ if (loop->watchers[w->fd] == NULL) {
+ loop->watchers[w->fd] = w;
+ loop->nfds++;
+ }
+}
+
+
+void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+
+ if (w->fd == -1)
+ return;
+
+ assert(w->fd >= 0);
+
+ /* Happens when uv__io_stop() is called on a handle that was never started. */
+ if ((unsigned) w->fd >= loop->nwatchers)
+ return;
+
+ w->pevents &= ~events;
+
+ if (w->pevents == 0) {
+ QUEUE_REMOVE(&w->watcher_queue);
+ QUEUE_INIT(&w->watcher_queue);
+
+ if (loop->watchers[w->fd] != NULL) {
+ assert(loop->watchers[w->fd] == w);
+ assert(loop->nfds > 0);
+ loop->watchers[w->fd] = NULL;
+ loop->nfds--;
+ w->events = 0;
+ }
+ }
+ else if (QUEUE_EMPTY(&w->watcher_queue))
+ QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
+}
+
+
+void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
+ QUEUE_REMOVE(&w->pending_queue);
+
+ /* Remove stale events for this file descriptor */
+ uv__platform_invalidate_fd(loop, w->fd);
+}
+
+
+void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
+ if (QUEUE_EMPTY(&w->pending_queue))
+ QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue);
+}
+
+
+int uv__io_active(const uv__io_t* w, unsigned int events) {
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 != events);
+ return 0 != (w->pevents & events);
+}
diff --git a/third-party/libuv/src/unix/darwin-proctitle.c b/third-party/libuv/src/unix/darwin-proctitle.c
new file mode 100644
index 0000000000..8cd358bcf0
--- /dev/null
+++ b/third-party/libuv/src/unix/darwin-proctitle.c
@@ -0,0 +1,203 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <TargetConditionals.h>
+
+#if !TARGET_OS_IPHONE
+# include <CoreFoundation/CoreFoundation.h>
+# include <ApplicationServices/ApplicationServices.h>
+#endif
+
+
+static int uv__pthread_setname_np(const char* name) {
+ int (*dynamic_pthread_setname_np)(const char* name);
+ char namebuf[64]; /* MAXTHREADNAMESIZE */
+ int err;
+
+ /* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
+ dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np");
+ if (dynamic_pthread_setname_np == NULL)
+ return -ENOSYS;
+
+ strncpy(namebuf, name, sizeof(namebuf) - 1);
+ namebuf[sizeof(namebuf) - 1] = '\0';
+
+ err = dynamic_pthread_setname_np(namebuf);
+ if (err)
+ return -err;
+
+ return 0;
+}
+
+
+int uv__set_process_title(const char* title) {
+#if TARGET_OS_IPHONE
+ return uv__pthread_setname_np(title);
+#else
+ CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
+ const char*,
+ CFStringEncoding);
+ CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
+ void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
+ void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
+ CFTypeRef (*pLSGetCurrentApplicationASN)(void);
+ OSStatus (*pLSSetApplicationInformationItem)(int,
+ CFTypeRef,
+ CFStringRef,
+ CFStringRef,
+ CFDictionaryRef*);
+ void* application_services_handle;
+ void* core_foundation_handle;
+ CFBundleRef launch_services_bundle;
+ CFStringRef* display_name_key;
+ CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
+ CFBundleRef (*pCFBundleGetMainBundle)(void);
+ CFBundleRef hi_services_bundle;
+ OSStatus (*pSetApplicationIsDaemon)(int);
+ CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
+ void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
+ void*);
+ CFTypeRef asn;
+ int err;
+
+ err = -ENOENT;
+ application_services_handle = dlopen("/System/Library/Frameworks/"
+ "ApplicationServices.framework/"
+ "Versions/A/ApplicationServices",
+ RTLD_LAZY | RTLD_LOCAL);
+ core_foundation_handle = dlopen("/System/Library/Frameworks/"
+ "CoreFoundation.framework/"
+ "Versions/A/CoreFoundation",
+ RTLD_LAZY | RTLD_LOCAL);
+
+ if (application_services_handle == NULL || core_foundation_handle == NULL)
+ goto out;
+
+ pCFStringCreateWithCString =
+ dlsym(core_foundation_handle, "CFStringCreateWithCString");
+ pCFBundleGetBundleWithIdentifier =
+ dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
+ pCFBundleGetDataPointerForName =
+ dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
+ pCFBundleGetFunctionPointerForName =
+ dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
+
+ if (pCFStringCreateWithCString == NULL ||
+ pCFBundleGetBundleWithIdentifier == NULL ||
+ pCFBundleGetDataPointerForName == NULL ||
+ pCFBundleGetFunctionPointerForName == NULL) {
+ goto out;
+ }
+
+#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
+
+ launch_services_bundle =
+ pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
+
+ if (launch_services_bundle == NULL)
+ goto out;
+
+ pLSGetCurrentApplicationASN =
+ pCFBundleGetFunctionPointerForName(launch_services_bundle,
+ S("_LSGetCurrentApplicationASN"));
+
+ if (pLSGetCurrentApplicationASN == NULL)
+ goto out;
+
+ pLSSetApplicationInformationItem =
+ pCFBundleGetFunctionPointerForName(launch_services_bundle,
+ S("_LSSetApplicationInformationItem"));
+
+ if (pLSSetApplicationInformationItem == NULL)
+ goto out;
+
+ display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle,
+ S("_kLSDisplayNameKey"));
+
+ if (display_name_key == NULL || *display_name_key == NULL)
+ goto out;
+
+ pCFBundleGetInfoDictionary = dlsym(core_foundation_handle,
+ "CFBundleGetInfoDictionary");
+ pCFBundleGetMainBundle = dlsym(core_foundation_handle,
+ "CFBundleGetMainBundle");
+ if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
+ goto out;
+
+ /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
+ hi_services_bundle =
+ pCFBundleGetBundleWithIdentifier(S("com.apple.HIServices"));
+ err = -ENOENT;
+ if (hi_services_bundle == NULL)
+ goto out;
+
+ pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName(
+ hi_services_bundle,
+ S("SetApplicationIsDaemon"));
+ pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName(
+ launch_services_bundle,
+ S("_LSApplicationCheckIn"));
+ pLSSetApplicationLaunchServicesServerConnectionStatus =
+ pCFBundleGetFunctionPointerForName(
+ launch_services_bundle,
+ S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
+ if (pSetApplicationIsDaemon == NULL ||
+ pLSApplicationCheckIn == NULL ||
+ pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
+ goto out;
+ }
+
+ if (pSetApplicationIsDaemon(1) != noErr)
+ goto out;
+
+ pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
+
+ /* Check into process manager?! */
+ pLSApplicationCheckIn(-2,
+ pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
+
+ asn = pLSGetCurrentApplicationASN();
+
+ err = -EINVAL;
+ if (pLSSetApplicationInformationItem(-2, /* Magic value. */
+ asn,
+ *display_name_key,
+ S(title),
+ NULL) != noErr) {
+ goto out;
+ }
+
+ uv__pthread_setname_np(title); /* Don't care if it fails. */
+ err = 0;
+
+out:
+ if (core_foundation_handle != NULL)
+ dlclose(core_foundation_handle);
+
+ if (application_services_handle != NULL)
+ dlclose(application_services_handle);
+
+ return err;
+#endif /* !TARGET_OS_IPHONE */
+}
diff --git a/third-party/libuv/src/unix/darwin.c b/third-party/libuv/src/unix/darwin.c
new file mode 100644
index 0000000000..bc282e7912
--- /dev/null
+++ b/third-party/libuv/src/unix/darwin.c
@@ -0,0 +1,324 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <mach-o/dyld.h> /* _NSGetExecutablePath */
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <unistd.h> /* sysconf */
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ loop->cf_state = NULL;
+
+ if (uv__kqueue_init(loop))
+ return -errno;
+
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ uv__fsevents_loop_delete(loop);
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ mach_timebase_info_data_t info;
+
+ if (mach_timebase_info(&info) != KERN_SUCCESS)
+ abort();
+
+ return mach_absolute_time() * info.numer / info.denom;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ uint32_t usize;
+ int result;
+ char* path;
+ char* fullpath;
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+ usize = *size;
+ result = _NSGetExecutablePath(buffer, &usize);
+ if (result) return result;
+
+ path = malloc(2 * PATH_MAX);
+ fullpath = realpath(buffer, path);
+ if (fullpath == NULL) {
+ SAVE_ERRNO(free(path));
+ return -errno;
+ }
+
+ strncpy(buffer, fullpath, *size);
+ free(fullpath);
+ *size = strlen(buffer);
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ vm_statistics_data_t info;
+ mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t);
+
+ if (host_statistics(mach_host_self(), HOST_VM_INFO,
+ (host_info_t)&info, &count) != KERN_SUCCESS) {
+ return -EINVAL; /* FIXME(bnoordhuis) Translate error. */
+ }
+
+ return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ uint64_t info;
+ int which[] = {CTL_HW, HW_MEMSIZE};
+ size_t size = sizeof(info);
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct loadavg info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_LOADAVG};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+
+ avg[0] = (double) info.ldavg[0] / info.fscale;
+ avg[1] = (double) info.ldavg[1] / info.fscale;
+ avg[2] = (double) info.ldavg[2] / info.fscale;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ mach_msg_type_number_t count;
+ task_basic_info_data_t info;
+ kern_return_t err;
+
+ count = TASK_BASIC_INFO_COUNT;
+ err = task_info(mach_task_self(),
+ TASK_BASIC_INFO,
+ (task_info_t) &info,
+ &count);
+ (void) &err;
+ /* task_info(TASK_BASIC_INFO) cannot really fail. Anything other than
+ * KERN_SUCCESS implies a libuv bug.
+ */
+ assert(err == KERN_SUCCESS);
+ *rss = info.resident_size;
+
+ return 0;
+}
+
+
+int uv_uptime(double* uptime) {
+ time_t now;
+ struct timeval info;
+ size_t size = sizeof(info);
+ static int which[] = {CTL_KERN, KERN_BOOTTIME};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ now = time(NULL);
+ *uptime = now - info.tv_sec;
+
+ return 0;
+}
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
+ multiplier = ((uint64_t)1000L / ticks);
+ char model[512];
+ uint64_t cpuspeed;
+ size_t size;
+ unsigned int i;
+ natural_t numcpus;
+ mach_msg_type_number_t msg_type;
+ processor_cpu_load_info_data_t *info;
+ uv_cpu_info_t* cpu_info;
+
+ size = sizeof(model);
+ if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) &&
+ sysctlbyname("hw.model", &model, &size, NULL, 0)) {
+ return -errno;
+ }
+
+ size = sizeof(cpuspeed);
+ if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0))
+ return -errno;
+
+ if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus,
+ (processor_info_array_t*)&info,
+ &msg_type) != KERN_SUCCESS) {
+ return -EINVAL; /* FIXME(bnoordhuis) Translate error. */
+ }
+
+ *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+ if (!(*cpu_infos))
+ return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */
+
+ *count = numcpus;
+
+ for (i = 0; i < numcpus; i++) {
+ cpu_info = &(*cpu_infos)[i];
+
+ cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier;
+ cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier;
+ cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier;
+ cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier;
+ cpu_info->cpu_times.irq = 0;
+
+ cpu_info->model = strdup(model);
+ cpu_info->speed = cpuspeed/1000000;
+ }
+ vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
+
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ struct ifaddrs *addrs, *ent;
+ uv_interface_address_t* address;
+ int i;
+ struct sockaddr_dl *sa_addr;
+
+ if (getifaddrs(&addrs))
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family == AF_LINK)) {
+ continue;
+ }
+
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ /*
+ * On Mac OS X getifaddrs returns information related to Mac Addresses for
+ * various devices, such as firewire, etc. These are not relevant here.
+ */
+ if (ent->ifa_addr->sa_family == AF_LINK)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != AF_LINK)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/dl.c b/third-party/libuv/src/unix/dl.c
new file mode 100644
index 0000000000..cbffe4aa26
--- /dev/null
+++ b/third-party/libuv/src/unix/dl.c
@@ -0,0 +1,83 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
+#include <locale.h>
+
+static int uv__dlerror(uv_lib_t* lib);
+
+
+int uv_dlopen(const char* filename, uv_lib_t* lib) {
+ dlerror(); /* Reset error status. */
+ lib->errmsg = NULL;
+ lib->handle = dlopen(filename, RTLD_LAZY);
+ return lib->handle ? 0 : uv__dlerror(lib);
+}
+
+
+void uv_dlclose(uv_lib_t* lib) {
+ if (lib->errmsg) {
+ free(lib->errmsg);
+ lib->errmsg = NULL;
+ }
+
+ if (lib->handle) {
+ /* Ignore errors. No good way to signal them without leaking memory. */
+ dlclose(lib->handle);
+ lib->handle = NULL;
+ }
+}
+
+
+int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
+ dlerror(); /* Reset error status. */
+ *ptr = dlsym(lib->handle, name);
+ return uv__dlerror(lib);
+}
+
+
+const char* uv_dlerror(uv_lib_t* lib) {
+ return lib->errmsg ? lib->errmsg : "no error";
+}
+
+
+static int uv__dlerror(uv_lib_t* lib) {
+ const char* errmsg;
+
+ if (lib->errmsg)
+ free(lib->errmsg);
+
+ errmsg = dlerror();
+
+ if (errmsg) {
+ lib->errmsg = strdup(errmsg);
+ return -1;
+ }
+ else {
+ lib->errmsg = NULL;
+ return 0;
+ }
+}
diff --git a/third-party/libuv/src/unix/freebsd.c b/third-party/libuv/src/unix/freebsd.c
new file mode 100644
index 0000000000..dcae244bb1
--- /dev/null
+++ b/third-party/libuv/src/unix/freebsd.c
@@ -0,0 +1,425 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include <kvm.h>
+#include <paths.h>
+#include <sys/user.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <vm/vm_param.h> /* VM_LOADAVG */
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h> /* sysconf */
+#include <fcntl.h>
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+#ifndef CPUSTATES
+# define CPUSTATES 5U
+#endif
+#ifndef CP_USER
+# define CP_USER 0
+# define CP_NICE 1
+# define CP_SYS 2
+# define CP_IDLE 3
+# define CP_INTR 4
+#endif
+
+static char *process_title;
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ int mib[4];
+ size_t cb;
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+#ifdef __DragonFly__
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ARGS;
+ mib[3] = getpid();
+#else
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PATHNAME;
+ mib[3] = -1;
+#endif
+
+ cb = *size;
+ if (sysctl(mib, 4, buffer, &cb, NULL, 0))
+ return -errno;
+ *size = strlen(buffer);
+
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ int freecount;
+ size_t size = sizeof(freecount);
+
+ if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) freecount * sysconf(_SC_PAGESIZE);
+
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ unsigned long info;
+ int which[] = {CTL_HW, HW_PHYSMEM};
+
+ size_t size = sizeof(info);
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct loadavg info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_LOADAVG};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+
+ avg[0] = (double) info.ldavg[0] / info.fscale;
+ avg[1] = (double) info.ldavg[1] / info.fscale;
+ avg[2] = (double) info.ldavg[2] / info.fscale;
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc ? strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ int oid[4];
+
+ if (process_title) free(process_title);
+ process_title = strdup(title);
+
+ oid[0] = CTL_KERN;
+ oid[1] = KERN_PROC;
+ oid[2] = KERN_PROC_ARGS;
+ oid[3] = getpid();
+
+ sysctl(oid,
+ ARRAY_SIZE(oid),
+ NULL,
+ NULL,
+ process_title,
+ strlen(process_title) + 1);
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (process_title) {
+ strncpy(buffer, process_title, size);
+ } else {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ kvm_t *kd = NULL;
+ struct kinfo_proc *kinfo = NULL;
+ pid_t pid;
+ int nprocs;
+ size_t page_size = getpagesize();
+
+ pid = getpid();
+
+ kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
+ if (kd == NULL) goto error;
+
+ kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs);
+ if (kinfo == NULL) goto error;
+
+#ifdef __DragonFly__
+ *rss = kinfo->kp_vm_rssize * page_size;
+#else
+ *rss = kinfo->ki_rssize * page_size;
+#endif
+
+ kvm_close(kd);
+
+ return 0;
+
+error:
+ if (kd) kvm_close(kd);
+ return -EPERM;
+}
+
+
+int uv_uptime(double* uptime) {
+ time_t now;
+ struct timeval info;
+ size_t size = sizeof(info);
+ static int which[] = {CTL_KERN, KERN_BOOTTIME};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ now = time(NULL);
+
+ *uptime = (double)(now - info.tv_sec);
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
+ multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus,
+ cur = 0;
+ uv_cpu_info_t* cpu_info;
+ const char* maxcpus_key;
+ const char* cptimes_key;
+ char model[512];
+ long* cp_times;
+ int numcpus;
+ size_t size;
+ int i;
+
+#if defined(__DragonFly__)
+ /* This is not quite correct but DragonFlyBSD doesn't seem to have anything
+ * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total,
+ * not per CPU). At least this stops uv_cpu_info() from failing completely.
+ */
+ maxcpus_key = "hw.ncpu";
+ cptimes_key = "kern.cp_time";
+#else
+ maxcpus_key = "kern.smp.maxcpus";
+ cptimes_key = "kern.cp_times";
+#endif
+
+ size = sizeof(model);
+ if (sysctlbyname("hw.model", &model, &size, NULL, 0))
+ return -errno;
+
+ size = sizeof(numcpus);
+ if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
+ return -errno;
+
+ *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+ if (!(*cpu_infos))
+ return -ENOMEM;
+
+ *count = numcpus;
+
+ size = sizeof(cpuspeed);
+ if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) {
+ SAVE_ERRNO(free(*cpu_infos));
+ return -errno;
+ }
+
+ /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of
+ * ncpu.
+ */
+ size = sizeof(maxcpus);
+ if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) {
+ SAVE_ERRNO(free(*cpu_infos));
+ return -errno;
+ }
+
+ size = maxcpus * CPUSTATES * sizeof(long);
+
+ cp_times = malloc(size);
+ if (cp_times == NULL) {
+ free(*cpu_infos);
+ return -ENOMEM;
+ }
+
+ if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) {
+ SAVE_ERRNO(free(cp_times));
+ SAVE_ERRNO(free(*cpu_infos));
+ return -errno;
+ }
+
+ for (i = 0; i < numcpus; i++) {
+ cpu_info = &(*cpu_infos)[i];
+
+ cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
+ cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
+ cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
+ cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
+ cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
+
+ cpu_info->model = strdup(model);
+ cpu_info->speed = cpuspeed;
+
+ cur+=CPUSTATES;
+ }
+
+ free(cp_times);
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ struct ifaddrs *addrs, *ent;
+ uv_interface_address_t* address;
+ int i;
+ struct sockaddr_dl *sa_addr;
+
+ if (getifaddrs(&addrs))
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family == AF_LINK)) {
+ continue;
+ }
+
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ /*
+ * On FreeBSD getifaddrs returns information related to the raw underlying
+ * devices. We're not interested in this information yet.
+ */
+ if (ent->ifa_addr->sa_family == AF_LINK)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != AF_LINK)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/fs.c b/third-party/libuv/src/unix/fs.c
new file mode 100644
index 0000000000..1aa6539cb4
--- /dev/null
+++ b/third-party/libuv/src/unix/fs.c
@@ -0,0 +1,971 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* Caveat emptor: this file deviates from the libuv convention of returning
+ * negated errno codes. Most uv_fs_*() functions map directly to the system
+ * call of the same name. For more complex wrappers, it's easier to just
+ * return -1 with errno set. The dispatcher in uv__fs_work() takes care of
+ * getting the errno to the right place (req->result or as the return value.)
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utime.h>
+#include <poll.h>
+
+#if defined(__linux__) || defined(__sun)
+# include <sys/sendfile.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+# include <sys/socket.h>
+# include <sys/uio.h>
+#endif
+
+#define INIT(type) \
+ do { \
+ uv__req_init((loop), (req), UV_FS); \
+ (req)->fs_type = UV_FS_ ## type; \
+ (req)->result = 0; \
+ (req)->ptr = NULL; \
+ (req)->loop = loop; \
+ (req)->path = NULL; \
+ (req)->new_path = NULL; \
+ (req)->cb = (cb); \
+ } \
+ while (0)
+
+#define PATH \
+ do { \
+ (req)->path = strdup(path); \
+ if ((req)->path == NULL) \
+ return -ENOMEM; \
+ } \
+ while (0)
+
+#define PATH2 \
+ do { \
+ size_t path_len; \
+ size_t new_path_len; \
+ path_len = strlen((path)) + 1; \
+ new_path_len = strlen((new_path)) + 1; \
+ (req)->path = malloc(path_len + new_path_len); \
+ if ((req)->path == NULL) \
+ return -ENOMEM; \
+ (req)->new_path = (req)->path + path_len; \
+ memcpy((void*) (req)->path, (path), path_len); \
+ memcpy((void*) (req)->new_path, (new_path), new_path_len); \
+ } \
+ while (0)
+
+#define POST \
+ do { \
+ if ((cb) != NULL) { \
+ uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
+ return 0; \
+ } \
+ else { \
+ uv__fs_work(&(req)->work_req); \
+ uv__fs_done(&(req)->work_req, 0); \
+ return (req)->result; \
+ } \
+ } \
+ while (0)
+
+
+static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
+#if defined(__linux__) || defined(__sun) || defined(__NetBSD__)
+ return fdatasync(req->file);
+#elif defined(__APPLE__) && defined(F_FULLFSYNC)
+ return fcntl(req->file, F_FULLFSYNC);
+#else
+ return fsync(req->file);
+#endif
+}
+
+
+static ssize_t uv__fs_futime(uv_fs_t* req) {
+#if defined(__linux__)
+ /* utimesat() has nanosecond resolution but we stick to microseconds
+ * for the sake of consistency with other platforms.
+ */
+ static int no_utimesat;
+ struct timespec ts[2];
+ struct timeval tv[2];
+ char path[sizeof("/proc/self/fd/") + 3 * sizeof(int)];
+ int r;
+
+ if (no_utimesat)
+ goto skip;
+
+ ts[0].tv_sec = req->atime;
+ ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000;
+ ts[1].tv_sec = req->mtime;
+ ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
+
+ r = uv__utimesat(req->file, NULL, ts, 0);
+ if (r == 0)
+ return r;
+
+ if (errno != ENOSYS)
+ return r;
+
+ no_utimesat = 1;
+
+skip:
+
+ tv[0].tv_sec = req->atime;
+ tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[1].tv_sec = req->mtime;
+ tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+ snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file);
+
+ r = utimes(path, tv);
+ if (r == 0)
+ return r;
+
+ switch (errno) {
+ case ENOENT:
+ if (fcntl(req->file, F_GETFL) == -1 && errno == EBADF)
+ break;
+ /* Fall through. */
+
+ case EACCES:
+ case ENOTDIR:
+ errno = ENOSYS;
+ break;
+ }
+
+ return r;
+
+#elif defined(__APPLE__) \
+ || defined(__DragonFly__) \
+ || defined(__FreeBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__OpenBSD__) \
+ || defined(__sun)
+ struct timeval tv[2];
+ tv[0].tv_sec = req->atime;
+ tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[1].tv_sec = req->mtime;
+ tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+# if defined(__sun)
+ return futimesat(req->file, NULL, tv);
+# else
+ return futimes(req->file, tv);
+# endif
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+
+static ssize_t uv__fs_read(uv_fs_t* req) {
+ if (req->off < 0)
+ return read(req->file, req->buf, req->len);
+ else
+ return pread(req->file, req->buf, req->len, req->off);
+}
+
+
+static int uv__fs_readdir_filter(const struct dirent* dent) {
+ return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
+}
+
+
+/* This should have been called uv__fs_scandir(). */
+static ssize_t uv__fs_readdir(uv_fs_t* req) {
+ struct dirent **dents;
+ int saved_errno;
+ size_t off;
+ size_t len;
+ char *buf;
+ int i;
+ int n;
+
+ dents = NULL;
+ n = scandir(req->path, &dents, uv__fs_readdir_filter, alphasort);
+
+ if (n == 0)
+ goto out; /* osx still needs to deallocate some memory */
+ else if (n == -1)
+ return n;
+
+ len = 0;
+
+ for (i = 0; i < n; i++)
+ len += strlen(dents[i]->d_name) + 1;
+
+ buf = malloc(len);
+
+ if (buf == NULL) {
+ errno = ENOMEM;
+ n = -1;
+ goto out;
+ }
+
+ off = 0;
+
+ for (i = 0; i < n; i++) {
+ len = strlen(dents[i]->d_name) + 1;
+ memcpy(buf + off, dents[i]->d_name, len);
+ off += len;
+ }
+
+ req->ptr = buf;
+
+out:
+ saved_errno = errno;
+ if (dents != NULL) {
+ for (i = 0; i < n; i++)
+ free(dents[i]);
+ free(dents);
+ }
+ errno = saved_errno;
+
+ return n;
+}
+
+
+static ssize_t uv__fs_readlink(uv_fs_t* req) {
+ ssize_t len;
+ char* buf;
+
+ len = pathconf(req->path, _PC_PATH_MAX);
+
+ if (len == -1) {
+#if defined(PATH_MAX)
+ len = PATH_MAX;
+#else
+ len = 4096;
+#endif
+ }
+
+ buf = malloc(len + 1);
+
+ if (buf == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ len = readlink(req->path, buf, len);
+
+ if (len == -1) {
+ free(buf);
+ return -1;
+ }
+
+ buf[len] = '\0';
+ req->ptr = buf;
+
+ return 0;
+}
+
+
+static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
+ struct pollfd pfd;
+ int use_pread;
+ off_t offset;
+ ssize_t nsent;
+ ssize_t nread;
+ ssize_t nwritten;
+ size_t buflen;
+ size_t len;
+ ssize_t n;
+ int in_fd;
+ int out_fd;
+ char buf[8192];
+
+ len = req->len;
+ in_fd = req->flags;
+ out_fd = req->file;
+ offset = req->off;
+ use_pread = 1;
+
+ /* Here are the rules regarding errors:
+ *
+ * 1. Read errors are reported only if nsent==0, otherwise we return nsent.
+ * The user needs to know that some data has already been sent, to stop
+ * them from sending it twice.
+ *
+ * 2. Write errors are always reported. Write errors are bad because they
+ * mean data loss: we've read data but now we can't write it out.
+ *
+ * We try to use pread() and fall back to regular read() if the source fd
+ * doesn't support positional reads, for example when it's a pipe fd.
+ *
+ * If we get EAGAIN when writing to the target fd, we poll() on it until
+ * it becomes writable again.
+ *
+ * FIXME: If we get a write error when use_pread==1, it should be safe to
+ * return the number of sent bytes instead of an error because pread()
+ * is, in theory, idempotent. However, special files in /dev or /proc
+ * may support pread() but not necessarily return the same data on
+ * successive reads.
+ *
+ * FIXME: There is no way now to signal that we managed to send *some* data
+ * before a write error.
+ */
+ for (nsent = 0; (size_t) nsent < len; ) {
+ buflen = len - nsent;
+
+ if (buflen > sizeof(buf))
+ buflen = sizeof(buf);
+
+ do
+ if (use_pread)
+ nread = pread(in_fd, buf, buflen, offset);
+ else
+ nread = read(in_fd, buf, buflen);
+ while (nread == -1 && errno == EINTR);
+
+ if (nread == 0)
+ goto out;
+
+ if (nread == -1) {
+ if (use_pread && nsent == 0 && (errno == EIO || errno == ESPIPE)) {
+ use_pread = 0;
+ continue;
+ }
+
+ if (nsent == 0)
+ nsent = -1;
+
+ goto out;
+ }
+
+ for (nwritten = 0; nwritten < nread; ) {
+ do
+ n = write(out_fd, buf + nwritten, nread - nwritten);
+ while (n == -1 && errno == EINTR);
+
+ if (n != -1) {
+ nwritten += n;
+ continue;
+ }
+
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
+ nsent = -1;
+ goto out;
+ }
+
+ pfd.fd = out_fd;
+ pfd.events = POLLOUT;
+ pfd.revents = 0;
+
+ do
+ n = poll(&pfd, 1, -1);
+ while (n == -1 && errno == EINTR);
+
+ if (n == -1 || (pfd.revents & ~POLLOUT) != 0) {
+ errno = EIO;
+ nsent = -1;
+ goto out;
+ }
+ }
+
+ offset += nread;
+ nsent += nread;
+ }
+
+out:
+ if (nsent != -1)
+ req->off = offset;
+
+ return nsent;
+}
+
+
+static ssize_t uv__fs_sendfile(uv_fs_t* req) {
+ int in_fd;
+ int out_fd;
+
+ in_fd = req->flags;
+ out_fd = req->file;
+
+#if defined(__linux__) || defined(__sun)
+ {
+ off_t off;
+ ssize_t r;
+
+ off = req->off;
+ r = sendfile(out_fd, in_fd, &off, req->len);
+
+ /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
+ * it still writes out data. Fortunately, we can detect it by checking if
+ * the offset has been updated.
+ */
+ if (r != -1 || off > req->off) {
+ r = off - req->off;
+ req->off = off;
+ return r;
+ }
+
+ if (errno == EINVAL ||
+ errno == EIO ||
+ errno == ENOTSOCK ||
+ errno == EXDEV) {
+ errno = 0;
+ return uv__fs_sendfile_emul(req);
+ }
+
+ return -1;
+ }
+#elif defined(__FreeBSD__) || defined(__APPLE__)
+ {
+ off_t len;
+ ssize_t r;
+
+ /* sendfile() on FreeBSD and Darwin returns EAGAIN if the target fd is in
+ * non-blocking mode and not all data could be written. If a non-zero
+ * number of bytes have been sent, we don't consider it an error.
+ */
+
+#if defined(__FreeBSD__)
+ len = 0;
+ r = sendfile(in_fd, out_fd, req->off, req->len, NULL, &len, 0);
+#else
+ /* The darwin sendfile takes len as an input for the length to send,
+ * so make sure to initialize it with the caller's value. */
+ len = req->len;
+ r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
+#endif
+
+ if (r != -1 || len != 0) {
+ req->off += len;
+ return (ssize_t) len;
+ }
+
+ if (errno == EINVAL ||
+ errno == EIO ||
+ errno == ENOTSOCK ||
+ errno == EXDEV) {
+ errno = 0;
+ return uv__fs_sendfile_emul(req);
+ }
+
+ return -1;
+ }
+#else
+ /* Squelch compiler warnings. */
+ (void) &in_fd;
+ (void) &out_fd;
+
+ return uv__fs_sendfile_emul(req);
+#endif
+}
+
+
+static ssize_t uv__fs_utime(uv_fs_t* req) {
+ struct utimbuf buf;
+ buf.actime = req->atime;
+ buf.modtime = req->mtime;
+ return utime(req->path, &buf); /* TODO use utimes() where available */
+}
+
+
+static ssize_t uv__fs_write(uv_fs_t* req) {
+ ssize_t r;
+
+ /* Serialize writes on OS X, concurrent write() and pwrite() calls result in
+ * data loss. We can't use a per-file descriptor lock, the descriptor may be
+ * a dup().
+ */
+#if defined(__APPLE__)
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock(&lock);
+#endif
+
+ if (req->off < 0)
+ r = write(req->file, req->buf, req->len);
+ else
+ r = pwrite(req->file, req->buf, req->len, req->off);
+
+#if defined(__APPLE__)
+ pthread_mutex_unlock(&lock);
+#endif
+
+ return r;
+}
+
+static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
+ dst->st_dev = src->st_dev;
+ dst->st_mode = src->st_mode;
+ dst->st_nlink = src->st_nlink;
+ dst->st_uid = src->st_uid;
+ dst->st_gid = src->st_gid;
+ dst->st_rdev = src->st_rdev;
+ dst->st_ino = src->st_ino;
+ dst->st_size = src->st_size;
+ dst->st_blksize = src->st_blksize;
+ dst->st_blocks = src->st_blocks;
+
+#if defined(__APPLE__)
+ dst->st_atim.tv_sec = src->st_atimespec.tv_sec;
+ dst->st_atim.tv_nsec = src->st_atimespec.tv_nsec;
+ dst->st_mtim.tv_sec = src->st_mtimespec.tv_sec;
+ dst->st_mtim.tv_nsec = src->st_mtimespec.tv_nsec;
+ dst->st_ctim.tv_sec = src->st_ctimespec.tv_sec;
+ dst->st_ctim.tv_nsec = src->st_ctimespec.tv_nsec;
+ dst->st_birthtim.tv_sec = src->st_birthtimespec.tv_sec;
+ dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec;
+ dst->st_flags = src->st_flags;
+ dst->st_gen = src->st_gen;
+#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE)
+ dst->st_atim.tv_sec = src->st_atim.tv_sec;
+ dst->st_atim.tv_nsec = src->st_atim.tv_nsec;
+ dst->st_mtim.tv_sec = src->st_mtim.tv_sec;
+ dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec;
+ dst->st_ctim.tv_sec = src->st_ctim.tv_sec;
+ dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec;
+# if defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+ dst->st_birthtim.tv_sec = src->st_birthtim.tv_sec;
+ dst->st_birthtim.tv_nsec = src->st_birthtim.tv_nsec;
+ dst->st_flags = src->st_flags;
+ dst->st_gen = src->st_gen;
+# else
+ dst->st_birthtim.tv_sec = src->st_ctim.tv_sec;
+ dst->st_birthtim.tv_nsec = src->st_ctim.tv_nsec;
+ dst->st_flags = 0;
+ dst->st_gen = 0;
+# endif
+#else
+ dst->st_atim.tv_sec = src->st_atime;
+ dst->st_atim.tv_nsec = 0;
+ dst->st_mtim.tv_sec = src->st_mtime;
+ dst->st_mtim.tv_nsec = 0;
+ dst->st_ctim.tv_sec = src->st_ctime;
+ dst->st_ctim.tv_nsec = 0;
+ dst->st_birthtim.tv_sec = src->st_ctime;
+ dst->st_birthtim.tv_nsec = 0;
+ dst->st_flags = 0;
+ dst->st_gen = 0;
+#endif
+}
+
+
+static int uv__fs_stat(const char *path, uv_stat_t *buf) {
+ struct stat pbuf;
+ int ret;
+ ret = stat(path, &pbuf);
+ uv__to_stat(&pbuf, buf);
+ return ret;
+}
+
+
+static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
+ struct stat pbuf;
+ int ret;
+ ret = lstat(path, &pbuf);
+ uv__to_stat(&pbuf, buf);
+ return ret;
+}
+
+
+static int uv__fs_fstat(int fd, uv_stat_t *buf) {
+ struct stat pbuf;
+ int ret;
+ ret = fstat(fd, &pbuf);
+ uv__to_stat(&pbuf, buf);
+ return ret;
+}
+
+
+static void uv__fs_work(struct uv__work* w) {
+ int retry_on_eintr;
+ uv_fs_t* req;
+ ssize_t r;
+
+ req = container_of(w, uv_fs_t, work_req);
+ retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
+
+ do {
+ errno = 0;
+
+#define X(type, action) \
+ case UV_FS_ ## type: \
+ r = action; \
+ break;
+
+ switch (req->fs_type) {
+ X(CHMOD, chmod(req->path, req->mode));
+ X(CHOWN, chown(req->path, req->uid, req->gid));
+ X(CLOSE, close(req->file));
+ X(FCHMOD, fchmod(req->file, req->mode));
+ X(FCHOWN, fchown(req->file, req->uid, req->gid));
+ X(FDATASYNC, uv__fs_fdatasync(req));
+ X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
+ X(FSYNC, fsync(req->file));
+ X(FTRUNCATE, ftruncate(req->file, req->off));
+ X(FUTIME, uv__fs_futime(req));
+ X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
+ X(LINK, link(req->path, req->new_path));
+ X(MKDIR, mkdir(req->path, req->mode));
+ X(OPEN, open(req->path, req->flags, req->mode));
+ X(READ, uv__fs_read(req));
+ X(READDIR, uv__fs_readdir(req));
+ X(READLINK, uv__fs_readlink(req));
+ X(RENAME, rename(req->path, req->new_path));
+ X(RMDIR, rmdir(req->path));
+ X(SENDFILE, uv__fs_sendfile(req));
+ X(STAT, uv__fs_stat(req->path, &req->statbuf));
+ X(SYMLINK, symlink(req->path, req->new_path));
+ X(UNLINK, unlink(req->path));
+ X(UTIME, uv__fs_utime(req));
+ X(WRITE, uv__fs_write(req));
+ default: abort();
+ }
+
+#undef X
+ }
+ while (r == -1 && errno == EINTR && retry_on_eintr);
+
+ if (r == -1)
+ req->result = -errno;
+ else
+ req->result = r;
+
+ if (r == 0 && (req->fs_type == UV_FS_STAT ||
+ req->fs_type == UV_FS_FSTAT ||
+ req->fs_type == UV_FS_LSTAT)) {
+ req->ptr = &req->statbuf;
+ }
+}
+
+
+static void uv__fs_done(struct uv__work* w, int status) {
+ uv_fs_t* req;
+
+ req = container_of(w, uv_fs_t, work_req);
+ uv__req_unregister(req->loop, req);
+
+ if (status == -ECANCELED) {
+ assert(req->result == 0);
+ req->result = -ECANCELED;
+ }
+
+ if (req->cb != NULL)
+ req->cb(req);
+}
+
+
+int uv_fs_chmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(CHMOD);
+ PATH;
+ req->mode = mode;
+ POST;
+}
+
+
+int uv_fs_chown(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb) {
+ INIT(CHOWN);
+ PATH;
+ req->uid = uid;
+ req->gid = gid;
+ POST;
+}
+
+
+int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(CLOSE);
+ req->file = file;
+ POST;
+}
+
+
+int uv_fs_fchmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(FCHMOD);
+ req->file = file;
+ req->mode = mode;
+ POST;
+}
+
+
+int uv_fs_fchown(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb) {
+ INIT(FCHOWN);
+ req->file = file;
+ req->uid = uid;
+ req->gid = gid;
+ POST;
+}
+
+
+int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FDATASYNC);
+ req->file = file;
+ POST;
+}
+
+
+int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FSTAT);
+ req->file = file;
+ POST;
+}
+
+
+int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
+ INIT(FSYNC);
+ req->file = file;
+ POST;
+}
+
+
+int uv_fs_ftruncate(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(FTRUNCATE);
+ req->file = file;
+ req->off = off;
+ POST;
+}
+
+
+int uv_fs_futime(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ double atime,
+ double mtime,
+ uv_fs_cb cb) {
+ INIT(FUTIME);
+ req->file = file;
+ req->atime = atime;
+ req->mtime = mtime;
+ POST;
+}
+
+
+int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(LSTAT);
+ PATH;
+ POST;
+}
+
+
+int uv_fs_link(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb) {
+ INIT(LINK);
+ PATH2;
+ POST;
+}
+
+
+int uv_fs_mkdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(MKDIR);
+ PATH;
+ req->mode = mode;
+ POST;
+}
+
+
+int uv_fs_open(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ int mode,
+ uv_fs_cb cb) {
+ INIT(OPEN);
+ PATH;
+ req->flags = flags;
+ req->mode = mode;
+ POST;
+}
+
+
+int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
+ uv_file file,
+ void* buf,
+ size_t len,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(READ);
+ req->file = file;
+ req->buf = buf;
+ req->len = len;
+ req->off = off;
+ POST;
+}
+
+
+int uv_fs_readdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ uv_fs_cb cb) {
+ INIT(READDIR);
+ PATH;
+ req->flags = flags;
+ POST;
+}
+
+
+int uv_fs_readlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb) {
+ INIT(READLINK);
+ PATH;
+ POST;
+}
+
+
+int uv_fs_rename(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb) {
+ INIT(RENAME);
+ PATH2;
+ POST;
+}
+
+
+int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(RMDIR);
+ PATH;
+ POST;
+}
+
+
+int uv_fs_sendfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file out_fd,
+ uv_file in_fd,
+ int64_t off,
+ size_t len,
+ uv_fs_cb cb) {
+ INIT(SENDFILE);
+ req->flags = in_fd; /* hack */
+ req->file = out_fd;
+ req->off = off;
+ req->len = len;
+ POST;
+}
+
+
+int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(STAT);
+ PATH;
+ POST;
+}
+
+
+int uv_fs_symlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb) {
+ INIT(SYMLINK);
+ PATH2;
+ req->flags = flags;
+ POST;
+}
+
+
+int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ INIT(UNLINK);
+ PATH;
+ POST;
+}
+
+
+int uv_fs_utime(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ double atime,
+ double mtime,
+ uv_fs_cb cb) {
+ INIT(UTIME);
+ PATH;
+ req->atime = atime;
+ req->mtime = mtime;
+ POST;
+}
+
+
+int uv_fs_write(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ const void* buf,
+ size_t len,
+ int64_t off,
+ uv_fs_cb cb) {
+ INIT(WRITE);
+ req->file = file;
+ req->buf = (void*) buf;
+ req->len = len;
+ req->off = off;
+ POST;
+}
+
+
+void uv_fs_req_cleanup(uv_fs_t* req) {
+ free((void*) req->path);
+ req->path = NULL;
+ req->new_path = NULL;
+
+ if (req->ptr != &req->statbuf)
+ free(req->ptr);
+ req->ptr = NULL;
+}
diff --git a/third-party/libuv/src/unix/fsevents.c b/third-party/libuv/src/unix/fsevents.c
new file mode 100644
index 0000000000..7faa1562a6
--- /dev/null
+++ b/third-party/libuv/src/unix/fsevents.c
@@ -0,0 +1,899 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#if TARGET_OS_IPHONE
+
+/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */
+
+int uv__fsevents_init(uv_fs_event_t* handle) {
+ return 0;
+}
+
+
+int uv__fsevents_close(uv_fs_event_t* handle) {
+ return 0;
+}
+
+
+void uv__fsevents_loop_delete(uv_loop_t* loop) {
+}
+
+#else /* TARGET_OS_IPHONE */
+
+#include <dlfcn.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include <CoreFoundation/CFRunLoop.h>
+#include <CoreServices/CoreServices.h>
+
+/* These are macros to avoid "initializer element is not constant" errors
+ * with old versions of gcc.
+ */
+#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod | \
+ kFSEventStreamEventFlagItemModified | \
+ kFSEventStreamEventFlagItemInodeMetaMod | \
+ kFSEventStreamEventFlagItemChangeOwner | \
+ kFSEventStreamEventFlagItemXattrMod)
+
+#define kFSEventsRenamed (kFSEventStreamEventFlagItemCreated | \
+ kFSEventStreamEventFlagItemRemoved | \
+ kFSEventStreamEventFlagItemRenamed)
+
+#define kFSEventsSystem (kFSEventStreamEventFlagUserDropped | \
+ kFSEventStreamEventFlagKernelDropped | \
+ kFSEventStreamEventFlagEventIdsWrapped | \
+ kFSEventStreamEventFlagHistoryDone | \
+ kFSEventStreamEventFlagMount | \
+ kFSEventStreamEventFlagUnmount | \
+ kFSEventStreamEventFlagRootChanged)
+
+typedef struct uv__fsevents_event_s uv__fsevents_event_t;
+typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
+typedef struct uv__cf_loop_state_s uv__cf_loop_state_t;
+
+struct uv__cf_loop_signal_s {
+ QUEUE member;
+ uv_fs_event_t* handle;
+};
+
+struct uv__fsevents_event_s {
+ QUEUE member;
+ int events;
+ char path[1];
+};
+
+struct uv__cf_loop_state_s {
+ CFRunLoopRef loop;
+ CFRunLoopSourceRef signal_source;
+ int fsevent_need_reschedule;
+ FSEventStreamRef fsevent_stream;
+ uv_sem_t fsevent_sem;
+ uv_mutex_t fsevent_mutex;
+ void* fsevent_handles[2];
+ unsigned int fsevent_handle_count;
+};
+
+/* Forward declarations */
+static void uv__cf_loop_cb(void* arg);
+static void* uv__cf_loop_runner(void* arg);
+static int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle);
+
+/* Lazy-loaded by uv__fsevents_global_init(). */
+static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef,
+ const void**,
+ CFIndex,
+ const CFArrayCallBacks*);
+static void (*pCFRelease)(CFTypeRef);
+static void (*pCFRunLoopAddSource)(CFRunLoopRef,
+ CFRunLoopSourceRef,
+ CFStringRef);
+static CFRunLoopRef (*pCFRunLoopGetCurrent)(void);
+static void (*pCFRunLoopRemoveSource)(CFRunLoopRef,
+ CFRunLoopSourceRef,
+ CFStringRef);
+static void (*pCFRunLoopRun)(void);
+static CFRunLoopSourceRef (*pCFRunLoopSourceCreate)(CFAllocatorRef,
+ CFIndex,
+ CFRunLoopSourceContext*);
+static void (*pCFRunLoopSourceSignal)(CFRunLoopSourceRef);
+static void (*pCFRunLoopStop)(CFRunLoopRef);
+static void (*pCFRunLoopWakeUp)(CFRunLoopRef);
+static CFStringRef (*pCFStringCreateWithFileSystemRepresentation)(
+ CFAllocatorRef,
+ const char*);
+static CFStringEncoding (*pCFStringGetSystemEncoding)(void);
+static CFStringRef (*pkCFRunLoopDefaultMode);
+static FSEventStreamRef (*pFSEventStreamCreate)(CFAllocatorRef,
+ FSEventStreamCallback,
+ FSEventStreamContext*,
+ CFArrayRef,
+ FSEventStreamEventId,
+ CFTimeInterval,
+ FSEventStreamCreateFlags);
+static void (*pFSEventStreamFlushSync)(FSEventStreamRef);
+static void (*pFSEventStreamInvalidate)(FSEventStreamRef);
+static void (*pFSEventStreamRelease)(FSEventStreamRef);
+static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef,
+ CFRunLoopRef,
+ CFStringRef);
+static Boolean (*pFSEventStreamStart)(FSEventStreamRef);
+static void (*pFSEventStreamStop)(FSEventStreamRef);
+
+#define UV__FSEVENTS_PROCESS(handle, block) \
+ do { \
+ QUEUE events; \
+ QUEUE* q; \
+ uv__fsevents_event_t* event; \
+ int err; \
+ uv_mutex_lock(&(handle)->cf_mutex); \
+ /* Split-off all events and empty original queue */ \
+ QUEUE_INIT(&events); \
+ if (!QUEUE_EMPTY(&(handle)->cf_events)) { \
+ q = QUEUE_HEAD(&(handle)->cf_events); \
+ QUEUE_SPLIT(&(handle)->cf_events, q, &events); \
+ } \
+ /* Get error (if any) and zero original one */ \
+ err = (handle)->cf_error; \
+ (handle)->cf_error = 0; \
+ uv_mutex_unlock(&(handle)->cf_mutex); \
+ /* Loop through events, deallocating each after processing */ \
+ while (!QUEUE_EMPTY(&events)) { \
+ q = QUEUE_HEAD(&events); \
+ event = QUEUE_DATA(q, uv__fsevents_event_t, member); \
+ QUEUE_REMOVE(q); \
+ /* NOTE: Checking uv__is_active() is required here, because handle \
+ * callback may close handle and invoking it after it will lead to \
+ * incorrect behaviour */ \
+ if (!uv__is_closing((handle)) && uv__is_active((handle))) \
+ block \
+ /* Free allocated data */ \
+ free(event); \
+ } \
+ if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \
+ (handle)->cb((handle), NULL, 0, err); \
+ } while (0)
+
+
+/* Runs in UV loop's thread, when there're events to report to handle */
+static void uv__fsevents_cb(uv_async_t* cb, int status) {
+ uv_fs_event_t* handle;
+
+ handle = cb->data;
+
+ UV__FSEVENTS_PROCESS(handle, {
+ handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0);
+ });
+}
+
+
+/* Runs in CF thread, pushed event into handle's event list */
+static void uv__fsevents_push_event(uv_fs_event_t* handle,
+ QUEUE* events,
+ int err) {
+ assert(events != NULL || err != 0);
+ uv_mutex_lock(&handle->cf_mutex);
+
+ /* Concatenate two queues */
+ if (events != NULL)
+ QUEUE_ADD(&handle->cf_events, events);
+
+ /* Propagate error */
+ if (err != 0)
+ handle->cf_error = err;
+ uv_mutex_unlock(&handle->cf_mutex);
+
+ uv_async_send(handle->cf_cb);
+}
+
+
+/* Runs in CF thread, when there're events in FSEventStream */
+static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
+ void* info,
+ size_t numEvents,
+ void* eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[]) {
+ size_t i;
+ int len;
+ char** paths;
+ char* path;
+ char* pos;
+ uv_fs_event_t* handle;
+ QUEUE* q;
+ uv_loop_t* loop;
+ uv__cf_loop_state_t* state;
+ uv__fsevents_event_t* event;
+ QUEUE head;
+
+ loop = info;
+ state = loop->cf_state;
+ assert(state != NULL);
+ paths = eventPaths;
+
+ /* For each handle */
+ uv_mutex_lock(&state->fsevent_mutex);
+ QUEUE_FOREACH(q, &state->fsevent_handles) {
+ handle = QUEUE_DATA(q, uv_fs_event_t, cf_member);
+ QUEUE_INIT(&head);
+
+ /* Process and filter out events */
+ for (i = 0; i < numEvents; i++) {
+ /* Ignore system events */
+ if (eventFlags[i] & kFSEventsSystem)
+ continue;
+
+ path = paths[i];
+ len = strlen(path);
+
+ /* Filter out paths that are outside handle's request */
+ if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
+ continue;
+
+ if (handle->realpath_len > 1 || *handle->realpath != '/') {
+ path += handle->realpath_len;
+ len -= handle->realpath_len;
+
+ /* Skip forward slash */
+ if (*path != '\0') {
+ path++;
+ len--;
+ }
+ }
+
+#ifdef MAC_OS_X_VERSION_10_7
+ /* Ignore events with path equal to directory itself */
+ if (len == 0)
+ continue;
+#endif /* MAC_OS_X_VERSION_10_7 */
+
+ /* Do not emit events from subdirectories (without option set) */
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+ pos = strchr(path + 1, '/');
+ if (pos != NULL)
+ continue;
+ }
+
+#ifndef MAC_OS_X_VERSION_10_7
+ path = "";
+ len = 0;
+#endif /* MAC_OS_X_VERSION_10_7 */
+
+ event = malloc(sizeof(*event) + len);
+ if (event == NULL)
+ break;
+
+ memset(event, 0, sizeof(*event));
+ memcpy(event->path, path, len + 1);
+
+ if ((eventFlags[i] & kFSEventsModified) != 0 &&
+ (eventFlags[i] & kFSEventsRenamed) == 0)
+ event->events = UV_CHANGE;
+ else
+ event->events = UV_RENAME;
+
+ QUEUE_INSERT_TAIL(&head, &event->member);
+ }
+
+ if (!QUEUE_EMPTY(&head))
+ uv__fsevents_push_event(handle, &head, 0);
+ }
+ uv_mutex_unlock(&state->fsevent_mutex);
+}
+
+
+/* Runs in CF thread */
+static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
+ uv__cf_loop_state_t* state;
+ FSEventStreamContext ctx;
+ FSEventStreamRef ref;
+ CFAbsoluteTime latency;
+ FSEventStreamCreateFlags flags;
+
+ /* Initialize context */
+ ctx.version = 0;
+ ctx.info = loop;
+ ctx.retain = NULL;
+ ctx.release = NULL;
+ ctx.copyDescription = NULL;
+
+ latency = 0.05;
+
+ /* Explanation of selected flags:
+ * 1. NoDefer - without this flag, events that are happening continuously
+ * (i.e. each event is happening after time interval less than `latency`,
+ * counted from previous event), will be deferred and passed to callback
+ * once they'll either fill whole OS buffer, or when this continuous stream
+ * will stop (i.e. there'll be delay between events, bigger than
+ * `latency`).
+ * Specifying this flag will invoke callback after `latency` time passed
+ * since event.
+ * 2. FileEvents - fire callback for file changes too (by default it is firing
+ * it only for directory changes).
+ */
+ flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents;
+
+ /*
+ * NOTE: It might sound like a good idea to remember last seen StreamEventId,
+ * but in reality one dir might have last StreamEventId less than, the other,
+ * that is being watched now. Which will cause FSEventStream API to report
+ * changes to files from the past.
+ */
+ ref = pFSEventStreamCreate(NULL,
+ &uv__fsevents_event_cb,
+ &ctx,
+ paths,
+ kFSEventStreamEventIdSinceNow,
+ latency,
+ flags);
+ assert(ref != NULL);
+
+ state = loop->cf_state;
+ pFSEventStreamScheduleWithRunLoop(ref,
+ state->loop,
+ *pkCFRunLoopDefaultMode);
+ if (!pFSEventStreamStart(ref)) {
+ pFSEventStreamInvalidate(ref);
+ pFSEventStreamRelease(ref);
+ return -EMFILE;
+ }
+
+ state->fsevent_stream = ref;
+ return 0;
+}
+
+
+/* Runs in CF thread */
+static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
+ uv__cf_loop_state_t* state;
+
+ state = loop->cf_state;
+
+ if (state->fsevent_stream == NULL)
+ return;
+
+ /* Flush all accumulated events */
+ pFSEventStreamFlushSync(state->fsevent_stream);
+
+ /* Stop emitting events */
+ pFSEventStreamStop(state->fsevent_stream);
+
+ /* Release stream */
+ pFSEventStreamInvalidate(state->fsevent_stream);
+ pFSEventStreamRelease(state->fsevent_stream);
+ state->fsevent_stream = NULL;
+}
+
+
+/* Runs in CF thread, when there're new fsevent handles to add to stream */
+static void uv__fsevents_reschedule(uv_fs_event_t* handle) {
+ uv__cf_loop_state_t* state;
+ QUEUE* q;
+ uv_fs_event_t* curr;
+ CFArrayRef cf_paths;
+ CFStringRef* paths;
+ unsigned int i;
+ int err;
+ unsigned int path_count;
+
+ state = handle->loop->cf_state;
+ paths = NULL;
+ cf_paths = NULL;
+ err = 0;
+ /* NOTE: `i` is used in deallocation loop below */
+ i = 0;
+
+ /* Optimization to prevent O(n^2) time spent when starting to watch
+ * many files simultaneously
+ */
+ uv_mutex_lock(&state->fsevent_mutex);
+ if (state->fsevent_need_reschedule == 0) {
+ uv_mutex_unlock(&state->fsevent_mutex);
+ goto final;
+ }
+ state->fsevent_need_reschedule = 0;
+ uv_mutex_unlock(&state->fsevent_mutex);
+
+ /* Destroy previous FSEventStream */
+ uv__fsevents_destroy_stream(handle->loop);
+
+ /* Any failure below will be a memory failure */
+ err = -ENOMEM;
+
+ /* Create list of all watched paths */
+ uv_mutex_lock(&state->fsevent_mutex);
+ path_count = state->fsevent_handle_count;
+ if (path_count != 0) {
+ paths = malloc(sizeof(*paths) * path_count);
+ if (paths == NULL) {
+ uv_mutex_unlock(&state->fsevent_mutex);
+ goto final;
+ }
+
+ q = &state->fsevent_handles;
+ for (; i < path_count; i++) {
+ q = QUEUE_NEXT(q);
+ assert(q != &state->fsevent_handles);
+ curr = QUEUE_DATA(q, uv_fs_event_t, cf_member);
+
+ assert(curr->realpath != NULL);
+ paths[i] =
+ pCFStringCreateWithFileSystemRepresentation(NULL, curr->realpath);
+ if (paths[i] == NULL) {
+ uv_mutex_unlock(&state->fsevent_mutex);
+ goto final;
+ }
+ }
+ }
+ uv_mutex_unlock(&state->fsevent_mutex);
+ err = 0;
+
+ if (path_count != 0) {
+ /* Create new FSEventStream */
+ cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL);
+ if (cf_paths == NULL) {
+ err = -ENOMEM;
+ goto final;
+ }
+ err = uv__fsevents_create_stream(handle->loop, cf_paths);
+ }
+
+final:
+ /* Deallocate all paths in case of failure */
+ if (err != 0) {
+ if (cf_paths == NULL) {
+ while (i != 0)
+ pCFRelease(paths[--i]);
+ free(paths);
+ } else {
+ /* CFArray takes ownership of both strings and original C-array */
+ pCFRelease(cf_paths);
+ }
+
+ /* Broadcast error to all handles */
+ uv_mutex_lock(&state->fsevent_mutex);
+ QUEUE_FOREACH(q, &state->fsevent_handles) {
+ curr = QUEUE_DATA(q, uv_fs_event_t, cf_member);
+ uv__fsevents_push_event(curr, NULL, err);
+ }
+ uv_mutex_unlock(&state->fsevent_mutex);
+ }
+
+ /*
+ * Main thread will block until the removal of handle from the list,
+ * we must tell it when we're ready.
+ *
+ * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close`
+ */
+ if (!uv__is_active(handle))
+ uv_sem_post(&state->fsevent_sem);
+}
+
+
+static int uv__fsevents_global_init(void) {
+ static pthread_mutex_t global_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static void* core_foundation_handle;
+ static void* core_services_handle;
+ int err;
+
+ err = 0;
+ pthread_mutex_lock(&global_init_mutex);
+ if (core_foundation_handle != NULL)
+ goto out;
+
+ /* The libraries are never unloaded because we currently don't have a good
+ * mechanism for keeping a reference count. It's unlikely to be an issue
+ * but if it ever becomes one, we can turn the dynamic library handles into
+ * per-event loop properties and have the dynamic linker keep track for us.
+ */
+ err = -ENOSYS;
+ core_foundation_handle = dlopen("/System/Library/Frameworks/"
+ "CoreFoundation.framework/"
+ "Versions/A/CoreFoundation",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (core_foundation_handle == NULL)
+ goto out;
+
+ core_services_handle = dlopen("/System/Library/Frameworks/"
+ "CoreServices.framework/"
+ "Versions/A/CoreServices",
+ RTLD_LAZY | RTLD_LOCAL);
+ if (core_services_handle == NULL)
+ goto out;
+
+ err = -ENOENT;
+#define V(handle, symbol) \
+ do { \
+ p ## symbol = dlsym((handle), #symbol); \
+ if (p ## symbol == NULL) \
+ goto out; \
+ } \
+ while (0)
+ V(core_foundation_handle, CFArrayCreate);
+ V(core_foundation_handle, CFRelease);
+ V(core_foundation_handle, CFRunLoopAddSource);
+ V(core_foundation_handle, CFRunLoopGetCurrent);
+ V(core_foundation_handle, CFRunLoopRemoveSource);
+ V(core_foundation_handle, CFRunLoopRun);
+ V(core_foundation_handle, CFRunLoopSourceCreate);
+ V(core_foundation_handle, CFRunLoopSourceSignal);
+ V(core_foundation_handle, CFRunLoopStop);
+ V(core_foundation_handle, CFRunLoopWakeUp);
+ V(core_foundation_handle, CFStringCreateWithFileSystemRepresentation);
+ V(core_foundation_handle, CFStringGetSystemEncoding);
+ V(core_foundation_handle, kCFRunLoopDefaultMode);
+ V(core_services_handle, FSEventStreamCreate);
+ V(core_services_handle, FSEventStreamFlushSync);
+ V(core_services_handle, FSEventStreamInvalidate);
+ V(core_services_handle, FSEventStreamRelease);
+ V(core_services_handle, FSEventStreamScheduleWithRunLoop);
+ V(core_services_handle, FSEventStreamStart);
+ V(core_services_handle, FSEventStreamStop);
+#undef V
+ err = 0;
+
+out:
+ if (err && core_services_handle != NULL) {
+ dlclose(core_services_handle);
+ core_services_handle = NULL;
+ }
+
+ if (err && core_foundation_handle != NULL) {
+ dlclose(core_foundation_handle);
+ core_foundation_handle = NULL;
+ }
+
+ pthread_mutex_unlock(&global_init_mutex);
+ return err;
+}
+
+
+/* Runs in UV loop */
+static int uv__fsevents_loop_init(uv_loop_t* loop) {
+ CFRunLoopSourceContext ctx;
+ uv__cf_loop_state_t* state;
+ pthread_attr_t attr_storage;
+ pthread_attr_t* attr;
+ int err;
+
+ if (loop->cf_state != NULL)
+ return 0;
+
+ err = uv__fsevents_global_init();
+ if (err)
+ return err;
+
+ state = calloc(1, sizeof(*state));
+ if (state == NULL)
+ return -ENOMEM;
+
+ err = uv_mutex_init(&loop->cf_mutex);
+ if (err)
+ goto fail_mutex_init;
+
+ err = uv_sem_init(&loop->cf_sem, 0);
+ if (err)
+ goto fail_sem_init;
+
+ QUEUE_INIT(&loop->cf_signals);
+
+ err = uv_sem_init(&state->fsevent_sem, 0);
+ if (err)
+ goto fail_fsevent_sem_init;
+
+ err = uv_mutex_init(&state->fsevent_mutex);
+ if (err)
+ goto fail_fsevent_mutex_init;
+
+ QUEUE_INIT(&state->fsevent_handles);
+ state->fsevent_need_reschedule = 0;
+ state->fsevent_handle_count = 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.info = loop;
+ ctx.perform = uv__cf_loop_cb;
+ state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx);
+ if (state->signal_source == NULL) {
+ err = -ENOMEM;
+ goto fail_signal_source_create;
+ }
+
+ /* In the unlikely event that pthread_attr_init() fails, create the thread
+ * with the default stack size. We'll use a little more address space but
+ * that in itself is not a fatal error.
+ */
+ attr = &attr_storage;
+ if (pthread_attr_init(attr))
+ attr = NULL;
+
+ if (attr != NULL)
+ if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN))
+ abort();
+
+ loop->cf_state = state;
+
+ /* uv_thread_t is an alias for pthread_t. */
+ err = -pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop);
+
+ if (attr != NULL)
+ pthread_attr_destroy(attr);
+
+ if (err)
+ goto fail_thread_create;
+
+ /* Synchronize threads */
+ uv_sem_wait(&loop->cf_sem);
+ return 0;
+
+fail_thread_create:
+ loop->cf_state = NULL;
+
+fail_signal_source_create:
+ uv_mutex_destroy(&state->fsevent_mutex);
+
+fail_fsevent_mutex_init:
+ uv_sem_destroy(&state->fsevent_sem);
+
+fail_fsevent_sem_init:
+ uv_sem_destroy(&loop->cf_sem);
+
+fail_sem_init:
+ uv_mutex_destroy(&loop->cf_mutex);
+
+fail_mutex_init:
+ free(state);
+ return err;
+}
+
+
+/* Runs in UV loop */
+void uv__fsevents_loop_delete(uv_loop_t* loop) {
+ uv__cf_loop_signal_t* s;
+ uv__cf_loop_state_t* state;
+ QUEUE* q;
+
+ if (loop->cf_state == NULL)
+ return;
+
+ if (uv__cf_loop_signal(loop, NULL) != 0)
+ abort();
+
+ uv_thread_join(&loop->cf_thread);
+ uv_sem_destroy(&loop->cf_sem);
+ uv_mutex_destroy(&loop->cf_mutex);
+
+ /* Free any remaining data */
+ while (!QUEUE_EMPTY(&loop->cf_signals)) {
+ q = QUEUE_HEAD(&loop->cf_signals);
+ s = QUEUE_DATA(q, uv__cf_loop_signal_t, member);
+ QUEUE_REMOVE(q);
+ free(s);
+ }
+
+ /* Destroy state */
+ state = loop->cf_state;
+ uv_sem_destroy(&state->fsevent_sem);
+ uv_mutex_destroy(&state->fsevent_mutex);
+ pCFRelease(state->signal_source);
+ free(state);
+ loop->cf_state = NULL;
+}
+
+
+/* Runs in CF thread. This is the CF loop's body */
+static void* uv__cf_loop_runner(void* arg) {
+ uv_loop_t* loop;
+ uv__cf_loop_state_t* state;
+
+ loop = arg;
+ state = loop->cf_state;
+ state->loop = pCFRunLoopGetCurrent();
+
+ pCFRunLoopAddSource(state->loop,
+ state->signal_source,
+ *pkCFRunLoopDefaultMode);
+
+ uv_sem_post(&loop->cf_sem);
+
+ pCFRunLoopRun();
+ pCFRunLoopRemoveSource(state->loop,
+ state->signal_source,
+ *pkCFRunLoopDefaultMode);
+
+ return NULL;
+}
+
+
+/* Runs in CF thread, executed after `uv__cf_loop_signal()` */
+static void uv__cf_loop_cb(void* arg) {
+ uv_loop_t* loop;
+ uv__cf_loop_state_t* state;
+ QUEUE* item;
+ QUEUE split_head;
+ uv__cf_loop_signal_t* s;
+
+ loop = arg;
+ state = loop->cf_state;
+ QUEUE_INIT(&split_head);
+
+ uv_mutex_lock(&loop->cf_mutex);
+ if (!QUEUE_EMPTY(&loop->cf_signals)) {
+ QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals);
+ QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head);
+ }
+ uv_mutex_unlock(&loop->cf_mutex);
+
+ while (!QUEUE_EMPTY(&split_head)) {
+ item = QUEUE_HEAD(&split_head);
+
+ s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
+
+ /* This was a termination signal */
+ if (s->handle == NULL)
+ pCFRunLoopStop(state->loop);
+ else
+ uv__fsevents_reschedule(s->handle);
+
+ QUEUE_REMOVE(item);
+ free(s);
+ }
+}
+
+
+/* Runs in UV loop to notify CF thread */
+int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__cf_loop_signal_t* item;
+ uv__cf_loop_state_t* state;
+
+ item = malloc(sizeof(*item));
+ if (item == NULL)
+ return -ENOMEM;
+
+ item->handle = handle;
+
+ uv_mutex_lock(&loop->cf_mutex);
+ QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
+ uv_mutex_unlock(&loop->cf_mutex);
+
+ state = loop->cf_state;
+ assert(state != NULL);
+ pCFRunLoopSourceSignal(state->signal_source);
+ pCFRunLoopWakeUp(state->loop);
+
+ return 0;
+}
+
+
+/* Runs in UV loop to initialize handle */
+int uv__fsevents_init(uv_fs_event_t* handle) {
+ int err;
+ uv__cf_loop_state_t* state;
+
+ err = uv__fsevents_loop_init(handle->loop);
+ if (err)
+ return err;
+
+ /* Get absolute path to file */
+ handle->realpath = realpath(handle->filename, NULL);
+ if (handle->realpath == NULL)
+ return -errno;
+ handle->realpath_len = strlen(handle->realpath);
+
+ /* Initialize event queue */
+ QUEUE_INIT(&handle->cf_events);
+ handle->cf_error = 0;
+
+ /*
+ * Events will occur in other thread.
+ * Initialize callback for getting them back into event loop's thread
+ */
+ handle->cf_cb = malloc(sizeof(*handle->cf_cb));
+ if (handle->cf_cb == NULL) {
+ err = -ENOMEM;
+ goto fail_cf_cb_malloc;
+ }
+
+ handle->cf_cb->data = handle;
+ uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
+ handle->cf_cb->flags |= UV__HANDLE_INTERNAL;
+ uv_unref((uv_handle_t*) handle->cf_cb);
+
+ err = uv_mutex_init(&handle->cf_mutex);
+ if (err)
+ goto fail_cf_mutex_init;
+
+ /* Insert handle into the list */
+ state = handle->loop->cf_state;
+ uv_mutex_lock(&state->fsevent_mutex);
+ QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member);
+ state->fsevent_handle_count++;
+ state->fsevent_need_reschedule = 1;
+ uv_mutex_unlock(&state->fsevent_mutex);
+
+ /* Reschedule FSEventStream */
+ assert(handle != NULL);
+ err = uv__cf_loop_signal(handle->loop, handle);
+ if (err)
+ goto fail_loop_signal;
+
+ return 0;
+
+fail_loop_signal:
+ uv_mutex_destroy(&handle->cf_mutex);
+
+fail_cf_mutex_init:
+ free(handle->cf_cb);
+ handle->cf_cb = NULL;
+
+fail_cf_cb_malloc:
+ free(handle->realpath);
+ handle->realpath = NULL;
+ handle->realpath_len = 0;
+
+ return err;
+}
+
+
+/* Runs in UV loop to de-initialize handle */
+int uv__fsevents_close(uv_fs_event_t* handle) {
+ int err;
+ uv__cf_loop_state_t* state;
+
+ if (handle->cf_cb == NULL)
+ return -EINVAL;
+
+ /* Remove handle from the list */
+ state = handle->loop->cf_state;
+ uv_mutex_lock(&state->fsevent_mutex);
+ QUEUE_REMOVE(&handle->cf_member);
+ state->fsevent_handle_count--;
+ state->fsevent_need_reschedule = 1;
+ uv_mutex_unlock(&state->fsevent_mutex);
+
+ /* Reschedule FSEventStream */
+ assert(handle != NULL);
+ err = uv__cf_loop_signal(handle->loop, handle);
+ if (err)
+ return -err;
+
+ /* Wait for deinitialization */
+ uv_sem_wait(&state->fsevent_sem);
+
+ uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
+ handle->cf_cb = NULL;
+
+ /* Free data in queue */
+ UV__FSEVENTS_PROCESS(handle, {
+ /* NOP */
+ });
+
+ uv_mutex_destroy(&handle->cf_mutex);
+ free(handle->realpath);
+ handle->realpath = NULL;
+ handle->realpath_len = 0;
+
+ return 0;
+}
+
+#endif /* TARGET_OS_IPHONE */
diff --git a/third-party/libuv/src/unix/getaddrinfo.c b/third-party/libuv/src/unix/getaddrinfo.c
new file mode 100644
index 0000000000..1db00680d1
--- /dev/null
+++ b/third-party/libuv/src/unix/getaddrinfo.c
@@ -0,0 +1,135 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <stddef.h> /* NULL */
+#include <stdlib.h>
+#include <string.h>
+
+
+static void uv__getaddrinfo_work(struct uv__work* w) {
+ uv_getaddrinfo_t* req;
+ int err;
+
+ req = container_of(w, uv_getaddrinfo_t, work_req);
+ err = getaddrinfo(req->hostname, req->service, req->hints, &req->res);
+ req->retcode = uv__getaddrinfo_translate_error(err);
+}
+
+
+static void uv__getaddrinfo_done(struct uv__work* w, int status) {
+ uv_getaddrinfo_t* req;
+ struct addrinfo *res;
+
+ req = container_of(w, uv_getaddrinfo_t, work_req);
+ uv__req_unregister(req->loop, req);
+
+ res = req->res;
+ req->res = NULL;
+
+ /* See initialization in uv_getaddrinfo(). */
+ if (req->hints)
+ free(req->hints);
+ else if (req->service)
+ free(req->service);
+ else if (req->hostname)
+ free(req->hostname);
+ else
+ assert(0);
+
+ req->hints = NULL;
+ req->service = NULL;
+ req->hostname = NULL;
+
+ if (status == -ECANCELED) {
+ assert(req->retcode == 0);
+ req->retcode = UV_EAI_CANCELED;
+ }
+
+ req->cb(req, req->retcode, res);
+}
+
+
+int uv_getaddrinfo(uv_loop_t* loop,
+ uv_getaddrinfo_t* req,
+ uv_getaddrinfo_cb cb,
+ const char* hostname,
+ const char* service,
+ const struct addrinfo* hints) {
+ size_t hostname_len;
+ size_t service_len;
+ size_t hints_len;
+ size_t len;
+ char* buf;
+
+ if (req == NULL || cb == NULL || (hostname == NULL && service == NULL))
+ return -EINVAL;
+
+ hostname_len = hostname ? strlen(hostname) + 1 : 0;
+ service_len = service ? strlen(service) + 1 : 0;
+ hints_len = hints ? sizeof(*hints) : 0;
+ buf = malloc(hostname_len + service_len + hints_len);
+
+ if (buf == NULL)
+ return -ENOMEM;
+
+ uv__req_init(loop, req, UV_GETADDRINFO);
+ req->loop = loop;
+ req->cb = cb;
+ req->res = NULL;
+ req->hints = NULL;
+ req->service = NULL;
+ req->hostname = NULL;
+ req->retcode = 0;
+
+ /* order matters, see uv_getaddrinfo_done() */
+ len = 0;
+
+ if (hints) {
+ req->hints = memcpy(buf + len, hints, sizeof(*hints));
+ len += sizeof(*hints);
+ }
+
+ if (service) {
+ req->service = memcpy(buf + len, service, service_len);
+ len += service_len;
+ }
+
+ if (hostname) {
+ req->hostname = memcpy(buf + len, hostname, hostname_len);
+ len += hostname_len;
+ }
+
+ uv__work_submit(loop,
+ &req->work_req,
+ uv__getaddrinfo_work,
+ uv__getaddrinfo_done);
+
+ return 0;
+}
+
+
+void uv_freeaddrinfo(struct addrinfo* ai) {
+ if (ai)
+ freeaddrinfo(ai);
+}
diff --git a/third-party/libuv/src/unix/internal.h b/third-party/libuv/src/unix/internal.h
new file mode 100644
index 0000000000..0ea82b51a0
--- /dev/null
+++ b/third-party/libuv/src/unix/internal.h
@@ -0,0 +1,296 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_UNIX_INTERNAL_H_
+#define UV_UNIX_INTERNAL_H_
+
+#include "uv-common.h"
+
+#include <assert.h>
+#include <stdlib.h> /* abort */
+#include <string.h> /* strrchr */
+
+#if defined(__STRICT_ANSI__)
+# define inline __inline
+#endif
+
+#if defined(__linux__)
+# include "linux-syscalls.h"
+#endif /* __linux__ */
+
+#if defined(__sun)
+# include <sys/port.h>
+# include <port.h>
+#endif /* __sun */
+
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
+# include <CoreServices/CoreServices.h>
+#endif
+
+#define STATIC_ASSERT(expr) \
+ void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
+
+#define ACCESS_ONCE(type, var) \
+ (*(volatile type*) &(var))
+
+#define UNREACHABLE() \
+ do { \
+ assert(0 && "unreachable code"); \
+ abort(); \
+ } \
+ while (0)
+
+#define SAVE_ERRNO(block) \
+ do { \
+ int _saved_errno = errno; \
+ do { block; } while (0); \
+ errno = _saved_errno; \
+ } \
+ while (0)
+
+/* The __clang__ and __INTEL_COMPILER checks are superfluous because they
+ * define __GNUC__. They are here to convey to you, dear reader, that these
+ * macros are enabled when compiling with clang or icc.
+ */
+#if defined(__clang__) || \
+ defined(__GNUC__) || \
+ defined(__INTEL_COMPILER) || \
+ defined(__SUNPRO_C)
+# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
+# define UV_UNUSED(declaration) __attribute__((unused)) declaration
+#else
+# define UV_DESTRUCTOR(declaration) declaration
+# define UV_UNUSED(declaration) declaration
+#endif
+
+#if defined(__linux__)
+# define UV__POLLIN UV__EPOLLIN
+# define UV__POLLOUT UV__EPOLLOUT
+# define UV__POLLERR UV__EPOLLERR
+# define UV__POLLHUP UV__EPOLLHUP
+#endif
+
+#if defined(__sun)
+# define UV__POLLIN POLLIN
+# define UV__POLLOUT POLLOUT
+# define UV__POLLERR POLLERR
+# define UV__POLLHUP POLLHUP
+#endif
+
+#ifndef UV__POLLIN
+# define UV__POLLIN 1
+#endif
+
+#ifndef UV__POLLOUT
+# define UV__POLLOUT 2
+#endif
+
+#ifndef UV__POLLERR
+# define UV__POLLERR 4
+#endif
+
+#ifndef UV__POLLHUP
+# define UV__POLLHUP 8
+#endif
+
+/* handle flags */
+enum {
+ UV_CLOSING = 0x01, /* uv_close() called but not finished. */
+ UV_CLOSED = 0x02, /* close(2) finished. */
+ UV_STREAM_READING = 0x04, /* uv_read_start() called. */
+ UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
+ UV_STREAM_SHUT = 0x10, /* Write side closed. */
+ UV_STREAM_READABLE = 0x20, /* The stream is readable */
+ UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
+ UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */
+ UV_STREAM_READ_PARTIAL = 0x100, /* read(2) read less than requested. */
+ UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */
+ UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
+ UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
+ UV_TCP_SINGLE_ACCEPT = 0x1000 /* Only accept() when idle. */
+};
+
+typedef enum {
+ UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */
+ UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */
+} uv_clocktype_t;
+
+/* core */
+int uv__nonblock(int fd, int set);
+int uv__close(int fd);
+int uv__cloexec(int fd, int set);
+int uv__socket(int domain, int type, int protocol);
+int uv__dup(int fd);
+ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
+void uv__make_close_pending(uv_handle_t* handle);
+
+void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
+void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+void uv__io_close(uv_loop_t* loop, uv__io_t* w);
+void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
+int uv__io_active(const uv__io_t* w, unsigned int events);
+void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
+
+/* async */
+void uv__async_send(struct uv__async* wa);
+void uv__async_init(struct uv__async* wa);
+int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
+void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
+
+/* loop */
+void uv__run_idle(uv_loop_t* loop);
+void uv__run_check(uv_loop_t* loop);
+void uv__run_prepare(uv_loop_t* loop);
+
+/* stream */
+void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream,
+ uv_handle_type type);
+int uv__stream_open(uv_stream_t*, int fd, int flags);
+void uv__stream_destroy(uv_stream_t* stream);
+#if defined(__APPLE__)
+int uv__stream_try_select(uv_stream_t* stream, int* fd);
+#endif /* defined(__APPLE__) */
+void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+int uv__accept(int sockfd);
+
+/* tcp */
+int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
+int uv__tcp_nodelay(int fd, int on);
+int uv__tcp_keepalive(int fd, int on, unsigned int delay);
+
+/* pipe */
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
+
+/* timer */
+void uv__run_timers(uv_loop_t* loop);
+int uv__next_timeout(const uv_loop_t* loop);
+
+/* signal */
+void uv__signal_close(uv_signal_t* handle);
+void uv__signal_global_once_init(void);
+void uv__signal_loop_cleanup(uv_loop_t* loop);
+
+/* thread pool */
+void uv__work_submit(uv_loop_t* loop,
+ struct uv__work *w,
+ void (*work)(struct uv__work *w),
+ void (*done)(struct uv__work *w, int status));
+void uv__work_done(uv_async_t* handle, int status);
+
+/* platform specific */
+uint64_t uv__hrtime(uv_clocktype_t type);
+int uv__kqueue_init(uv_loop_t* loop);
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
+void uv__platform_loop_delete(uv_loop_t* loop);
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd);
+
+/* various */
+void uv__async_close(uv_async_t* handle);
+void uv__check_close(uv_check_t* handle);
+void uv__fs_event_close(uv_fs_event_t* handle);
+void uv__idle_close(uv_idle_t* handle);
+void uv__pipe_close(uv_pipe_t* handle);
+void uv__poll_close(uv_poll_t* handle);
+void uv__prepare_close(uv_prepare_t* handle);
+void uv__process_close(uv_process_t* handle);
+void uv__stream_close(uv_stream_t* handle);
+void uv__tcp_close(uv_tcp_t* handle);
+void uv__timer_close(uv_timer_t* handle);
+void uv__udp_close(uv_udp_t* handle);
+void uv__udp_finish_close(uv_udp_t* handle);
+
+#if defined(__APPLE__)
+int uv___stream_fd(uv_stream_t* handle);
+#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
+#else
+#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
+#endif /* defined(__APPLE__) */
+
+#ifdef UV__O_NONBLOCK
+# define UV__F_NONBLOCK UV__O_NONBLOCK
+#else
+# define UV__F_NONBLOCK 1
+#endif
+
+int uv__make_socketpair(int fds[2], int flags);
+int uv__make_pipe(int fds[2], int flags);
+
+#if defined(__APPLE__)
+
+int uv__fsevents_init(uv_fs_event_t* handle);
+int uv__fsevents_close(uv_fs_event_t* handle);
+void uv__fsevents_loop_delete(uv_loop_t* loop);
+
+/* OSX < 10.7 has no file events, polyfill them */
+#ifndef MAC_OS_X_VERSION_10_7
+
+static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
+static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
+static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
+static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
+static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
+static const int kFSEventStreamEventFlagItemModified = 0x00001000;
+static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
+static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
+static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
+static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
+static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
+static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
+
+#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
+
+#endif /* defined(__APPLE__) */
+
+UV_UNUSED(static void uv__req_init(uv_loop_t* loop,
+ uv_req_t* req,
+ uv_req_type type)) {
+ req->type = type;
+ uv__req_register(loop, req);
+}
+#define uv__req_init(loop, req, type) \
+ uv__req_init((loop), (uv_req_t*)(req), (type))
+
+UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
+ /* Use a fast time source if available. We only need millisecond precision.
+ */
+ loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
+}
+
+UV_UNUSED(static char* uv__basename_r(const char* path)) {
+ char* s;
+
+ s = strrchr(path, '/');
+ if (s == NULL)
+ return (char*) path;
+
+ return s + 1;
+}
+
+
+#ifdef HAVE_DTRACE
+#include "uv-dtrace.h"
+#else
+#define UV_TICK_START(arg0, arg1)
+#define UV_TICK_STOP(arg0, arg1)
+#endif
+
+#endif /* UV_UNIX_INTERNAL_H_ */
diff --git a/third-party/libuv/src/unix/kqueue.c b/third-party/libuv/src/unix/kqueue.c
new file mode 100644
index 0000000000..f86f291fc0
--- /dev/null
+++ b/third-party/libuv/src/unix/kqueue.c
@@ -0,0 +1,403 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+
+static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
+
+
+int uv__kqueue_init(uv_loop_t* loop) {
+ loop->backend_fd = kqueue();
+ if (loop->backend_fd == -1)
+ return -errno;
+
+ uv__cloexec(loop->backend_fd, 1);
+
+ return 0;
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct kevent events[1024];
+ struct kevent* ev;
+ struct timespec spec;
+ unsigned int nevents;
+ unsigned int revents;
+ QUEUE* q;
+ uint64_t base;
+ uint64_t diff;
+ uv__io_t* w;
+ int filter;
+ int fflags;
+ int count;
+ int nfds;
+ int fd;
+ int op;
+ int i;
+
+ if (loop->nfds == 0) {
+ assert(QUEUE_EMPTY(&loop->watcher_queue));
+ return;
+ }
+
+ nevents = 0;
+
+ while (!QUEUE_EMPTY(&loop->watcher_queue)) {
+ q = QUEUE_HEAD(&loop->watcher_queue);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+ assert(w->fd >= 0);
+ assert(w->fd < (int) loop->nwatchers);
+
+ if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
+ filter = EVFILT_READ;
+ fflags = 0;
+ op = EV_ADD;
+
+ if (w->cb == uv__fs_event) {
+ filter = EVFILT_VNODE;
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
+ op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */
+ }
+
+ EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0);
+
+ if (++nevents == ARRAY_SIZE(events)) {
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
+ abort();
+ nevents = 0;
+ }
+ }
+
+ if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) {
+ EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
+
+ if (++nevents == ARRAY_SIZE(events)) {
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
+ abort();
+ nevents = 0;
+ }
+ }
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;; nevents = 0) {
+ if (timeout != -1) {
+ spec.tv_sec = timeout / 1000;
+ spec.tv_nsec = (timeout % 1000) * 1000000;
+ }
+
+ nfds = kevent(loop->backend_fd,
+ events,
+ nevents,
+ events,
+ ARRAY_SIZE(events),
+ timeout == -1 ? NULL : &spec);
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (nfds == -1) {
+ if (errno != EINTR)
+ abort();
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+ /* Interrupted by a signal. Update timeout and poll again. */
+ goto update_timeout;
+ }
+
+ nevents = 0;
+
+ assert(loop->watchers != NULL);
+ loop->watchers[loop->nwatchers] = (void*) events;
+ loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+ for (i = 0; i < nfds; i++) {
+ ev = events + i;
+ fd = ev->ident;
+ /* Skip invalidated events, see uv__platform_invalidate_fd */
+ if (fd == -1)
+ continue;
+ w = loop->watchers[fd];
+
+ if (w == NULL) {
+ /* File descriptor that we've stopped watching, disarm it. */
+ /* TODO batch up */
+ struct kevent events[1];
+
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != EBADF && errno != ENOENT)
+ abort();
+
+ continue;
+ }
+
+ if (ev->filter == EVFILT_VNODE) {
+ assert(w->events == UV__POLLIN);
+ assert(w->pevents == UV__POLLIN);
+ w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
+ nevents++;
+ continue;
+ }
+
+ revents = 0;
+
+ if (ev->filter == EVFILT_READ) {
+ if (w->pevents & UV__POLLIN) {
+ revents |= UV__POLLIN;
+ w->rcount = ev->data;
+ } else {
+ /* TODO batch up */
+ struct kevent events[1];
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != ENOENT)
+ abort();
+ }
+ }
+
+ if (ev->filter == EVFILT_WRITE) {
+ if (w->pevents & UV__POLLOUT) {
+ revents |= UV__POLLOUT;
+ w->wcount = ev->data;
+ } else {
+ /* TODO batch up */
+ struct kevent events[1];
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != ENOENT)
+ abort();
+ }
+ }
+
+ if (ev->flags & EV_ERROR)
+ revents |= UV__POLLERR;
+
+ if (revents == 0)
+ continue;
+
+ w->cb(loop, w, revents);
+ nevents++;
+ }
+ loop->watchers[loop->nwatchers] = NULL;
+ loop->watchers[loop->nwatchers + 1] = NULL;
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
+}
+
+
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
+ struct kevent* events;
+ uintptr_t i;
+ uintptr_t nfds;
+
+ assert(loop->watchers != NULL);
+
+ events = (struct kevent*) loop->watchers[loop->nwatchers];
+ nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
+ if (events == NULL)
+ return;
+
+ /* Invalidate events with same file descriptor */
+ for (i = 0; i < nfds; i++)
+ if ((int) events[i].ident == fd)
+ events[i].ident = -1;
+}
+
+
+static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
+ uv_fs_event_t* handle;
+ struct kevent ev;
+ int events;
+ const char* path;
+#if defined(F_GETPATH)
+ /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */
+ char pathbuf[MAXPATHLEN];
+#endif
+
+ handle = container_of(w, uv_fs_event_t, event_watcher);
+
+ if (fflags & (NOTE_ATTRIB | NOTE_EXTEND))
+ events = UV_CHANGE;
+ else
+ events = UV_RENAME;
+
+ path = NULL;
+#if defined(F_GETPATH)
+ /* Also works when the file has been unlinked from the file system. Passing
+ * in the path when the file has been deleted is arguably a little strange
+ * but it's consistent with what the inotify backend does.
+ */
+ if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0)
+ path = uv__basename_r(pathbuf);
+#endif
+ handle->cb(handle, path, events, 0);
+
+ if (handle->event_watcher.fd == -1)
+ return;
+
+ /* Watcher operates in one-shot mode, re-arm it. */
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
+
+ EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0);
+
+ if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
+ abort();
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+ return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags) {
+#if defined(__APPLE__)
+ struct stat statbuf;
+#endif /* defined(__APPLE__) */
+ int fd;
+
+ if (uv__is_active(handle))
+ return -EINVAL;
+
+ /* TODO open asynchronously - but how do we report back errors? */
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ uv__handle_start(handle);
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
+ handle->filename = strdup(filename);
+ handle->cb = cb;
+
+#if defined(__APPLE__)
+ /* Nullify field to perform checks later */
+ handle->cf_cb = NULL;
+ handle->realpath = NULL;
+ handle->realpath_len = 0;
+ handle->cf_flags = flags;
+
+ if (fstat(fd, &statbuf))
+ goto fallback;
+ /* FSEvents works only with directories */
+ if (!(statbuf.st_mode & S_IFDIR))
+ goto fallback;
+
+ return uv__fsevents_init(handle);
+
+fallback:
+#endif /* defined(__APPLE__) */
+
+ uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ if (!uv__is_active(handle))
+ return -EINVAL;
+
+ uv__handle_stop(handle);
+
+#if defined(__APPLE__)
+ if (uv__fsevents_close(handle))
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
+#else
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
+#endif /* defined(__APPLE__) */
+
+ free(handle->filename);
+ handle->filename = NULL;
+
+ uv__close(handle->event_watcher.fd);
+ handle->event_watcher.fd = -1;
+
+ return 0;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ uv_fs_event_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/linux-core.c b/third-party/libuv/src/unix/linux-core.c
new file mode 100644
index 0000000000..f71dd2d6b9
--- /dev/null
+++ b/third-party/libuv/src/unix/linux-core.c
@@ -0,0 +1,816 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <net/if.h>
+#include <sys/param.h>
+#include <sys/prctl.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+
+#ifndef __ANDROID__
+#define HAVE_IFADDRS_H 1
+#endif
+
+#ifdef __UCLIBC__
+# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32
+# undef HAVE_IFADDRS_H
+# endif
+#endif
+#ifdef HAVE_IFADDRS_H
+# include <ifaddrs.h>
+# include <sys/socket.h>
+# include <net/ethernet.h>
+# include <linux/if_packet.h>
+#endif
+
+/* Available from 2.6.32 onwards. */
+#ifndef CLOCK_MONOTONIC_COARSE
+# define CLOCK_MONOTONIC_COARSE 6
+#endif
+
+/* This is rather annoying: CLOCK_BOOTTIME lives in <linux/time.h> but we can't
+ * include that file because it conflicts with <time.h>. We'll just have to
+ * define it ourselves.
+ */
+#ifndef CLOCK_BOOTTIME
+# define CLOCK_BOOTTIME 7
+#endif
+
+static int read_models(unsigned int numcpus, uv_cpu_info_t* ci);
+static int read_times(unsigned int numcpus, uv_cpu_info_t* ci);
+static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
+static unsigned long read_cpufreq(unsigned int cpunum);
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ int fd;
+
+ fd = uv__epoll_create1(UV__EPOLL_CLOEXEC);
+
+ /* epoll_create1() can fail either because it's not implemented (old kernel)
+ * or because it doesn't understand the EPOLL_CLOEXEC flag.
+ */
+ if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
+ fd = uv__epoll_create(256);
+
+ if (fd != -1)
+ uv__cloexec(fd, 1);
+ }
+
+ loop->backend_fd = fd;
+ loop->inotify_fd = -1;
+ loop->inotify_watchers = NULL;
+
+ if (fd == -1)
+ return -errno;
+
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ if (loop->inotify_fd == -1) return;
+ uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN);
+ uv__close(loop->inotify_fd);
+ loop->inotify_fd = -1;
+}
+
+
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
+ struct uv__epoll_event* events;
+ uintptr_t i;
+ uintptr_t nfds;
+
+ assert(loop->watchers != NULL);
+
+ events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
+ nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
+ if (events == NULL)
+ return;
+
+ /* Invalidate events with same file descriptor */
+ for (i = 0; i < nfds; i++)
+ if ((int) events[i].data == fd)
+ events[i].data = -1;
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct uv__epoll_event events[1024];
+ struct uv__epoll_event* pe;
+ struct uv__epoll_event e;
+ QUEUE* q;
+ uv__io_t* w;
+ uint64_t base;
+ uint64_t diff;
+ int nevents;
+ int count;
+ int nfds;
+ int fd;
+ int op;
+ int i;
+
+ if (loop->nfds == 0) {
+ assert(QUEUE_EMPTY(&loop->watcher_queue));
+ return;
+ }
+
+ while (!QUEUE_EMPTY(&loop->watcher_queue)) {
+ q = QUEUE_HEAD(&loop->watcher_queue);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+ assert(w->fd >= 0);
+ assert(w->fd < (int) loop->nwatchers);
+
+ e.events = w->pevents;
+ e.data = w->fd;
+
+ if (w->events == 0)
+ op = UV__EPOLL_CTL_ADD;
+ else
+ op = UV__EPOLL_CTL_MOD;
+
+ /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
+ * events, skip the syscall and squelch the events after epoll_wait().
+ */
+ if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
+ if (errno != EEXIST)
+ abort();
+
+ assert(op == UV__EPOLL_CTL_ADD);
+
+ /* We've reactivated a file descriptor that's been watched before. */
+ if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e))
+ abort();
+ }
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;;) {
+ nfds = uv__epoll_wait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout);
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (nfds == -1) {
+ if (errno != EINTR)
+ abort();
+
+ if (timeout == -1)
+ continue;
+
+ if (timeout == 0)
+ return;
+
+ /* Interrupted by a signal. Update timeout and poll again. */
+ goto update_timeout;
+ }
+
+ nevents = 0;
+
+ assert(loop->watchers != NULL);
+ loop->watchers[loop->nwatchers] = (void*) events;
+ loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+ for (i = 0; i < nfds; i++) {
+ pe = events + i;
+ fd = pe->data;
+
+ /* Skip invalidated events, see uv__platform_invalidate_fd */
+ if (fd == -1)
+ continue;
+
+ assert(fd >= 0);
+ assert((unsigned) fd < loop->nwatchers);
+
+ w = loop->watchers[fd];
+
+ if (w == NULL) {
+ /* File descriptor that we've stopped watching, disarm it.
+ *
+ * Ignore all errors because we may be racing with another thread
+ * when the file descriptor is closed.
+ */
+ uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe);
+ continue;
+ }
+
+ /* Give users only events they're interested in. Prevents spurious
+ * callbacks when previous callback invocation in this loop has stopped
+ * the current watcher. Also, filters out events that users has not
+ * requested us to watch.
+ */
+ pe->events &= w->pevents | UV__POLLERR | UV__POLLHUP;
+
+ /* Work around an epoll quirk where it sometimes reports just the
+ * EPOLLERR or EPOLLHUP event. In order to force the event loop to
+ * move forward, we merge in the read/write events that the watcher
+ * is interested in; uv__read() and uv__write() will then deal with
+ * the error or hangup in the usual fashion.
+ *
+ * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
+ * reads the available data, calls uv_read_stop(), then sometime later
+ * calls uv_read_start() again. By then, libuv has forgotten about the
+ * hangup and the kernel won't report EPOLLIN again because there's
+ * nothing left to read. If anything, libuv is to blame here. The
+ * current hack is just a quick bandaid; to properly fix it, libuv
+ * needs to remember the error/hangup event. We should get that for
+ * free when we switch over to edge-triggered I/O.
+ */
+ if (pe->events == UV__EPOLLERR || pe->events == UV__EPOLLHUP)
+ pe->events |= w->pevents & (UV__EPOLLIN | UV__EPOLLOUT);
+
+ if (pe->events != 0) {
+ w->cb(loop, w, pe->events);
+ nevents++;
+ }
+ }
+ loop->watchers[loop->nwatchers] = NULL;
+ loop->watchers[loop->nwatchers + 1] = NULL;
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ static clock_t fast_clock_id = -1;
+ struct timespec t;
+ clock_t clock_id;
+
+ /* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has
+ * millisecond granularity or better. CLOCK_MONOTONIC_COARSE is
+ * serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may
+ * decide to make a costly system call.
+ */
+ /* TODO(bnoordhuis) Use CLOCK_MONOTONIC_COARSE for UV_CLOCK_PRECISE
+ * when it has microsecond granularity or better (unlikely).
+ */
+ if (type == UV_CLOCK_FAST && fast_clock_id == -1) {
+ if (clock_getres(CLOCK_MONOTONIC_COARSE, &t) == 0 &&
+ t.tv_nsec <= 1 * 1000 * 1000) {
+ fast_clock_id = CLOCK_MONOTONIC_COARSE;
+ } else {
+ fast_clock_id = CLOCK_MONOTONIC;
+ }
+ }
+
+ clock_id = CLOCK_MONOTONIC;
+ if (type == UV_CLOCK_FAST)
+ clock_id = fast_clock_id;
+
+ if (clock_gettime(clock_id, &t))
+ return 0; /* Not really possible. */
+
+ return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct sysinfo info;
+
+ if (sysinfo(&info) < 0) return;
+
+ avg[0] = (double) info.loads[0] / 65536.0;
+ avg[1] = (double) info.loads[1] / 65536.0;
+ avg[2] = (double) info.loads[2] / 65536.0;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ ssize_t n;
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+ n = readlink("/proc/self/exe", buffer, *size - 1);
+ if (n == -1)
+ return -errno;
+
+ buffer[n] = '\0';
+ *size = n;
+
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ char buf[1024];
+ const char* s;
+ ssize_t n;
+ long val;
+ int fd;
+ int i;
+
+ do
+ fd = open("/proc/self/stat", O_RDONLY);
+ while (fd == -1 && errno == EINTR);
+
+ if (fd == -1)
+ return -errno;
+
+ do
+ n = read(fd, buf, sizeof(buf) - 1);
+ while (n == -1 && errno == EINTR);
+
+ uv__close(fd);
+ if (n == -1)
+ return -errno;
+ buf[n] = '\0';
+
+ s = strchr(buf, ' ');
+ if (s == NULL)
+ goto err;
+
+ s += 1;
+ if (*s != '(')
+ goto err;
+
+ s = strchr(s, ')');
+ if (s == NULL)
+ goto err;
+
+ for (i = 1; i <= 22; i++) {
+ s = strchr(s + 1, ' ');
+ if (s == NULL)
+ goto err;
+ }
+
+ errno = 0;
+ val = strtol(s, NULL, 10);
+ if (errno != 0)
+ goto err;
+ if (val < 0)
+ goto err;
+
+ *rss = val * getpagesize();
+ return 0;
+
+err:
+ return -EINVAL;
+}
+
+
+int uv_uptime(double* uptime) {
+ static volatile int no_clock_boottime;
+ struct timespec now;
+ int r;
+
+ /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available
+ * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system
+ * is suspended.
+ */
+ if (no_clock_boottime) {
+ retry: r = clock_gettime(CLOCK_MONOTONIC, &now);
+ }
+ else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) {
+ no_clock_boottime = 1;
+ goto retry;
+ }
+
+ if (r)
+ return -errno;
+
+ *uptime = now.tv_sec;
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int numcpus;
+ uv_cpu_info_t* ci;
+ int err;
+
+ *cpu_infos = NULL;
+ *count = 0;
+
+ numcpus = sysconf(_SC_NPROCESSORS_ONLN);
+ assert(numcpus != (unsigned int) -1);
+ assert(numcpus != 0);
+
+ ci = calloc(numcpus, sizeof(*ci));
+ if (ci == NULL)
+ return -ENOMEM;
+
+ err = read_models(numcpus, ci);
+ if (err == 0)
+ err = read_times(numcpus, ci);
+
+ if (err) {
+ uv_free_cpu_info(ci, numcpus);
+ return err;
+ }
+
+ /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo.
+ * We don't check for errors here. Worst case, the field is left zero.
+ */
+ if (ci[0].speed == 0)
+ read_speeds(numcpus, ci);
+
+ *cpu_infos = ci;
+ *count = numcpus;
+
+ return 0;
+}
+
+
+static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) {
+ unsigned int num;
+
+ for (num = 0; num < numcpus; num++)
+ ci[num].speed = read_cpufreq(num) / 1000;
+}
+
+
+/* Also reads the CPU frequency on x86. The other architectures only have
+ * a BogoMIPS field, which may not be very accurate.
+ *
+ * Note: Simply returns on error, uv_cpu_info() takes care of the cleanup.
+ */
+static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
+ static const char model_marker[] = "model name\t: ";
+ static const char speed_marker[] = "cpu MHz\t\t: ";
+ const char* inferred_model;
+ unsigned int model_idx;
+ unsigned int speed_idx;
+ char buf[1024];
+ char* model;
+ FILE* fp;
+
+ /* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */
+ (void) &model_marker;
+ (void) &speed_marker;
+ (void) &speed_idx;
+ (void) &model;
+ (void) &buf;
+ (void) &fp;
+
+ model_idx = 0;
+ speed_idx = 0;
+
+#if defined(__arm__) || \
+ defined(__i386__) || \
+ defined(__mips__) || \
+ defined(__x86_64__)
+ fp = fopen("/proc/cpuinfo", "r");
+ if (fp == NULL)
+ return -errno;
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (model_idx < numcpus) {
+ if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
+ model = buf + sizeof(model_marker) - 1;
+ model = strndup(model, strlen(model) - 1); /* Strip newline. */
+ if (model == NULL) {
+ fclose(fp);
+ return -ENOMEM;
+ }
+ ci[model_idx++].model = model;
+ continue;
+ }
+ }
+#if defined(__arm__) || defined(__mips__)
+ if (model_idx < numcpus) {
+#if defined(__arm__)
+ /* Fallback for pre-3.8 kernels. */
+ static const char model_marker[] = "Processor\t: ";
+#else /* defined(__mips__) */
+ static const char model_marker[] = "cpu model\t\t: ";
+#endif
+ if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
+ model = buf + sizeof(model_marker) - 1;
+ model = strndup(model, strlen(model) - 1); /* Strip newline. */
+ if (model == NULL) {
+ fclose(fp);
+ return -ENOMEM;
+ }
+ ci[model_idx++].model = model;
+ continue;
+ }
+ }
+#else /* !__arm__ && !__mips__ */
+ if (speed_idx < numcpus) {
+ if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) {
+ ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1);
+ continue;
+ }
+ }
+#endif /* __arm__ || __mips__ */
+ }
+
+ fclose(fp);
+#endif /* __arm__ || __i386__ || __mips__ || __x86_64__ */
+
+ /* Now we want to make sure that all the models contain *something* because
+ * it's not safe to leave them as null. Copy the last entry unless there
+ * isn't one, in that case we simply put "unknown" into everything.
+ */
+ inferred_model = "unknown";
+ if (model_idx > 0)
+ inferred_model = ci[model_idx - 1].model;
+
+ while (model_idx < numcpus) {
+ model = strndup(inferred_model, strlen(inferred_model));
+ if (model == NULL)
+ return -ENOMEM;
+ ci[model_idx++].model = model;
+ }
+
+ return 0;
+}
+
+
+static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
+ unsigned long clock_ticks;
+ struct uv_cpu_times_s ts;
+ unsigned long user;
+ unsigned long nice;
+ unsigned long sys;
+ unsigned long idle;
+ unsigned long dummy;
+ unsigned long irq;
+ unsigned int num;
+ unsigned int len;
+ char buf[1024];
+ FILE* fp;
+
+ clock_ticks = sysconf(_SC_CLK_TCK);
+ assert(clock_ticks != (unsigned long) -1);
+ assert(clock_ticks != 0);
+
+ fp = fopen("/proc/stat", "r");
+ if (fp == NULL)
+ return -errno;
+
+ if (!fgets(buf, sizeof(buf), fp))
+ abort();
+
+ num = 0;
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (num >= numcpus)
+ break;
+
+ if (strncmp(buf, "cpu", 3))
+ break;
+
+ /* skip "cpu<num> " marker */
+ {
+ unsigned int n;
+ int r = sscanf(buf, "cpu%u ", &n);
+ assert(r == 1);
+ (void) r; /* silence build warning */
+ for (len = sizeof("cpu0"); n /= 10; len++);
+ }
+
+ /* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
+ * guest, guest_nice but we're only interested in the first four + irq.
+ *
+ * Don't use %*s to skip fields or %ll to read straight into the uint64_t
+ * fields, they're not allowed in C89 mode.
+ */
+ if (6 != sscanf(buf + len,
+ "%lu %lu %lu %lu %lu %lu",
+ &user,
+ &nice,
+ &sys,
+ &idle,
+ &dummy,
+ &irq))
+ abort();
+
+ ts.user = clock_ticks * user;
+ ts.nice = clock_ticks * nice;
+ ts.sys = clock_ticks * sys;
+ ts.idle = clock_ticks * idle;
+ ts.irq = clock_ticks * irq;
+ ci[num++].cpu_times = ts;
+ }
+ fclose(fp);
+ assert(num == numcpus);
+
+ return 0;
+}
+
+
+static unsigned long read_cpufreq(unsigned int cpunum) {
+ unsigned long val;
+ char buf[1024];
+ FILE* fp;
+
+ snprintf(buf,
+ sizeof(buf),
+ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq",
+ cpunum);
+
+ fp = fopen(buf, "r");
+ if (fp == NULL)
+ return 0;
+
+ if (fscanf(fp, "%lu", &val) != 1)
+ val = 0;
+
+ fclose(fp);
+
+ return val;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count) {
+#ifndef HAVE_IFADDRS_H
+ return -ENOSYS;
+#else
+ struct ifaddrs *addrs, *ent;
+ uv_interface_address_t* address;
+ int i;
+ struct sockaddr_ll *sll;
+
+ if (getifaddrs(&addrs))
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family == PF_PACKET)) {
+ continue;
+ }
+
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ /*
+ * On Linux getifaddrs returns information related to the raw underlying
+ * devices. We're not interested in this information yet.
+ */
+ if (ent->ifa_addr->sa_family == PF_PACKET)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != PF_PACKET)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sll = (struct sockaddr_ll*)ent->ifa_addr;
+ memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+#endif
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
+
+
+void uv__set_process_title(const char* title) {
+#if defined(PR_SET_NAME)
+ prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
+#endif
+}
diff --git a/third-party/libuv/src/unix/linux-inotify.c b/third-party/libuv/src/unix/linux-inotify.c
new file mode 100644
index 0000000000..7641f383c4
--- /dev/null
+++ b/third-party/libuv/src/unix/linux-inotify.c
@@ -0,0 +1,257 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "tree.h"
+#include "internal.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+struct watcher_list {
+ RB_ENTRY(watcher_list) entry;
+ QUEUE watchers;
+ char* path;
+ int wd;
+};
+
+struct watcher_root {
+ struct watcher_list* rbh_root;
+};
+#define CAST(p) ((struct watcher_root*)(p))
+
+
+static int compare_watchers(const struct watcher_list* a,
+ const struct watcher_list* b) {
+ if (a->wd < b->wd) return -1;
+ if (a->wd > b->wd) return 1;
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers)
+
+
+static void uv__inotify_read(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents);
+
+
+static int new_inotify_fd(void) {
+ int err;
+ int fd;
+
+ fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC);
+ if (fd != -1)
+ return fd;
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ fd = uv__inotify_init();
+ if (fd == -1)
+ return -errno;
+
+ err = uv__cloexec(fd, 1);
+ if (err == 0)
+ err = uv__nonblock(fd, 1);
+
+ if (err) {
+ uv__close(fd);
+ return err;
+ }
+
+ return fd;
+}
+
+
+static int init_inotify(uv_loop_t* loop) {
+ int err;
+
+ if (loop->inotify_fd != -1)
+ return 0;
+
+ err = new_inotify_fd();
+ if (err < 0)
+ return err;
+
+ loop->inotify_fd = err;
+ uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
+ uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
+ struct watcher_list w;
+ w.wd = wd;
+ return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w);
+}
+
+
+static void uv__inotify_read(uv_loop_t* loop,
+ uv__io_t* dummy,
+ unsigned int events) {
+ const struct uv__inotify_event* e;
+ struct watcher_list* w;
+ uv_fs_event_t* h;
+ QUEUE* q;
+ const char* path;
+ ssize_t size;
+ const char *p;
+ /* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
+ char buf[4096];
+
+ while (1) {
+ do
+ size = read(loop->inotify_fd, buf, sizeof(buf));
+ while (size == -1 && errno == EINTR);
+
+ if (size == -1) {
+ assert(errno == EAGAIN || errno == EWOULDBLOCK);
+ break;
+ }
+
+ assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */
+
+ /* Now we have one or more inotify_event structs. */
+ for (p = buf; p < buf + size; p += sizeof(*e) + e->len) {
+ e = (const struct uv__inotify_event*)p;
+
+ events = 0;
+ if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY))
+ events |= UV_CHANGE;
+ if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY))
+ events |= UV_RENAME;
+
+ w = find_watcher(loop, e->wd);
+ if (w == NULL)
+ continue; /* Stale event, no watchers left. */
+
+ /* inotify does not return the filename when monitoring a single file
+ * for modifications. Repurpose the filename for API compatibility.
+ * I'm not convinced this is a good thing, maybe it should go.
+ */
+ path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path);
+
+ QUEUE_FOREACH(q, &w->watchers) {
+ h = QUEUE_DATA(q, uv_fs_event_t, watchers);
+ h->cb(h, path, events, 0);
+ }
+ }
+ }
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+ return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* path,
+ unsigned int flags) {
+ struct watcher_list* w;
+ int events;
+ int err;
+ int wd;
+
+ if (uv__is_active(handle))
+ return -EINVAL;
+
+ err = init_inotify(handle->loop);
+ if (err)
+ return err;
+
+ events = UV__IN_ATTRIB
+ | UV__IN_CREATE
+ | UV__IN_MODIFY
+ | UV__IN_DELETE
+ | UV__IN_DELETE_SELF
+ | UV__IN_MOVE_SELF
+ | UV__IN_MOVED_FROM
+ | UV__IN_MOVED_TO;
+
+ wd = uv__inotify_add_watch(handle->loop->inotify_fd, path, events);
+ if (wd == -1)
+ return -errno;
+
+ w = find_watcher(handle->loop, wd);
+ if (w)
+ goto no_insert;
+
+ w = malloc(sizeof(*w) + strlen(path) + 1);
+ if (w == NULL)
+ return -ENOMEM;
+
+ w->wd = wd;
+ w->path = strcpy((char*)(w + 1), path);
+ QUEUE_INIT(&w->watchers);
+ RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w);
+
+no_insert:
+ uv__handle_start(handle);
+ QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers);
+ handle->filename = w->path;
+ handle->cb = cb;
+ handle->wd = wd;
+
+ return 0;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ struct watcher_list* w;
+
+ if (!uv__is_active(handle))
+ return -EINVAL;
+
+ w = find_watcher(handle->loop, handle->wd);
+ assert(w != NULL);
+
+ handle->wd = -1;
+ handle->filename = NULL;
+ uv__handle_stop(handle);
+ QUEUE_REMOVE(&handle->watchers);
+
+ if (QUEUE_EMPTY(&w->watchers)) {
+ /* No watchers left for this path. Clean up. */
+ RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
+ uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
+ free(w);
+ }
+
+ return 0;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ uv_fs_event_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/linux-syscalls.c b/third-party/libuv/src/unix/linux-syscalls.c
new file mode 100644
index 0000000000..06cc5943cf
--- /dev/null
+++ b/third-party/libuv/src/unix/linux-syscalls.c
@@ -0,0 +1,388 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "linux-syscalls.h"
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#if defined(__i386__)
+# ifndef __NR_socketcall
+# define __NR_socketcall 102
+# endif
+#endif
+
+#if defined(__arm__)
+# if defined(__thumb__) || defined(__ARM_EABI__)
+# define UV_SYSCALL_BASE 0
+# else
+# define UV_SYSCALL_BASE 0x900000
+# endif
+#endif /* __arm__ */
+
+#ifndef __NR_accept4
+# if defined(__x86_64__)
+# define __NR_accept4 288
+# elif defined(__i386__)
+ /* Nothing. Handled through socketcall(). */
+# elif defined(__arm__)
+# define __NR_accept4 (UV_SYSCALL_BASE + 366)
+# endif
+#endif /* __NR_accept4 */
+
+#ifndef __NR_eventfd
+# if defined(__x86_64__)
+# define __NR_eventfd 284
+# elif defined(__i386__)
+# define __NR_eventfd 323
+# elif defined(__arm__)
+# define __NR_eventfd (UV_SYSCALL_BASE + 351)
+# endif
+#endif /* __NR_eventfd */
+
+#ifndef __NR_eventfd2
+# if defined(__x86_64__)
+# define __NR_eventfd2 290
+# elif defined(__i386__)
+# define __NR_eventfd2 328
+# elif defined(__arm__)
+# define __NR_eventfd2 (UV_SYSCALL_BASE + 356)
+# endif
+#endif /* __NR_eventfd2 */
+
+#ifndef __NR_epoll_create
+# if defined(__x86_64__)
+# define __NR_epoll_create 213
+# elif defined(__i386__)
+# define __NR_epoll_create 254
+# elif defined(__arm__)
+# define __NR_epoll_create (UV_SYSCALL_BASE + 250)
+# endif
+#endif /* __NR_epoll_create */
+
+#ifndef __NR_epoll_create1
+# if defined(__x86_64__)
+# define __NR_epoll_create1 291
+# elif defined(__i386__)
+# define __NR_epoll_create1 329
+# elif defined(__arm__)
+# define __NR_epoll_create1 (UV_SYSCALL_BASE + 357)
+# endif
+#endif /* __NR_epoll_create1 */
+
+#ifndef __NR_epoll_ctl
+# if defined(__x86_64__)
+# define __NR_epoll_ctl 233 /* used to be 214 */
+# elif defined(__i386__)
+# define __NR_epoll_ctl 255
+# elif defined(__arm__)
+# define __NR_epoll_ctl (UV_SYSCALL_BASE + 251)
+# endif
+#endif /* __NR_epoll_ctl */
+
+#ifndef __NR_epoll_wait
+# if defined(__x86_64__)
+# define __NR_epoll_wait 232 /* used to be 215 */
+# elif defined(__i386__)
+# define __NR_epoll_wait 256
+# elif defined(__arm__)
+# define __NR_epoll_wait (UV_SYSCALL_BASE + 252)
+# endif
+#endif /* __NR_epoll_wait */
+
+#ifndef __NR_epoll_pwait
+# if defined(__x86_64__)
+# define __NR_epoll_pwait 281
+# elif defined(__i386__)
+# define __NR_epoll_pwait 319
+# elif defined(__arm__)
+# define __NR_epoll_pwait (UV_SYSCALL_BASE + 346)
+# endif
+#endif /* __NR_epoll_pwait */
+
+#ifndef __NR_inotify_init
+# if defined(__x86_64__)
+# define __NR_inotify_init 253
+# elif defined(__i386__)
+# define __NR_inotify_init 291
+# elif defined(__arm__)
+# define __NR_inotify_init (UV_SYSCALL_BASE + 316)
+# endif
+#endif /* __NR_inotify_init */
+
+#ifndef __NR_inotify_init1
+# if defined(__x86_64__)
+# define __NR_inotify_init1 294
+# elif defined(__i386__)
+# define __NR_inotify_init1 332
+# elif defined(__arm__)
+# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360)
+# endif
+#endif /* __NR_inotify_init1 */
+
+#ifndef __NR_inotify_add_watch
+# if defined(__x86_64__)
+# define __NR_inotify_add_watch 254
+# elif defined(__i386__)
+# define __NR_inotify_add_watch 292
+# elif defined(__arm__)
+# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317)
+# endif
+#endif /* __NR_inotify_add_watch */
+
+#ifndef __NR_inotify_rm_watch
+# if defined(__x86_64__)
+# define __NR_inotify_rm_watch 255
+# elif defined(__i386__)
+# define __NR_inotify_rm_watch 293
+# elif defined(__arm__)
+# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318)
+# endif
+#endif /* __NR_inotify_rm_watch */
+
+#ifndef __NR_pipe2
+# if defined(__x86_64__)
+# define __NR_pipe2 293
+# elif defined(__i386__)
+# define __NR_pipe2 331
+# elif defined(__arm__)
+# define __NR_pipe2 (UV_SYSCALL_BASE + 359)
+# endif
+#endif /* __NR_pipe2 */
+
+#ifndef __NR_recvmmsg
+# if defined(__x86_64__)
+# define __NR_recvmmsg 299
+# elif defined(__i386__)
+# define __NR_recvmmsg 337
+# elif defined(__arm__)
+# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
+# endif
+#endif /* __NR_recvmsg */
+
+#ifndef __NR_sendmmsg
+# if defined(__x86_64__)
+# define __NR_sendmmsg 307
+# elif defined(__i386__)
+# define __NR_sendmmsg 345
+# elif defined(__arm__)
+# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
+# endif
+#endif /* __NR_sendmmsg */
+
+#ifndef __NR_utimensat
+# if defined(__x86_64__)
+# define __NR_utimensat 280
+# elif defined(__i386__)
+# define __NR_utimensat 320
+# elif defined(__arm__)
+# define __NR_utimensat (UV_SYSCALL_BASE + 348)
+# endif
+#endif /* __NR_utimensat */
+
+
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
+#if defined(__i386__)
+ unsigned long args[4];
+ int r;
+
+ args[0] = (unsigned long) fd;
+ args[1] = (unsigned long) addr;
+ args[2] = (unsigned long) addrlen;
+ args[3] = (unsigned long) flags;
+
+ r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
+
+ /* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
+ * a bad flags argument. Try to distinguish between the two cases.
+ */
+ if (r == -1)
+ if (errno == EINVAL)
+ if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
+ errno = ENOSYS;
+
+ return r;
+#elif defined(__NR_accept4)
+ return syscall(__NR_accept4, fd, addr, addrlen, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__eventfd(unsigned int count) {
+#if defined(__NR_eventfd)
+ return syscall(__NR_eventfd, count);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__eventfd2(unsigned int count, int flags) {
+#if defined(__NR_eventfd2)
+ return syscall(__NR_eventfd2, count, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_create(int size) {
+#if defined(__NR_epoll_create)
+ return syscall(__NR_epoll_create, size);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_create1(int flags) {
+#if defined(__NR_epoll_create1)
+ return syscall(__NR_epoll_create1, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event* events) {
+#if defined(__NR_epoll_ctl)
+ return syscall(__NR_epoll_ctl, epfd, op, fd, events);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_wait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout) {
+#if defined(__NR_epoll_wait)
+ return syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__epoll_pwait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout,
+ const sigset_t* sigmask) {
+#if defined(__NR_epoll_pwait)
+ return syscall(__NR_epoll_pwait,
+ epfd,
+ events,
+ nevents,
+ timeout,
+ sigmask,
+ sizeof(*sigmask));
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init(void) {
+#if defined(__NR_inotify_init)
+ return syscall(__NR_inotify_init);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_init1(int flags) {
+#if defined(__NR_inotify_init1)
+ return syscall(__NR_inotify_init1, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_add_watch(int fd, const char* path, uint32_t mask) {
+#if defined(__NR_inotify_add_watch)
+ return syscall(__NR_inotify_add_watch, fd, path, mask);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__inotify_rm_watch(int fd, int32_t wd) {
+#if defined(__NR_inotify_rm_watch)
+ return syscall(__NR_inotify_rm_watch, fd, wd);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__pipe2(int pipefd[2], int flags) {
+#if defined(__NR_pipe2)
+ return syscall(__NR_pipe2, pipefd, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__sendmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags) {
+#if defined(__NR_sendmmsg)
+ return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__recvmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags,
+ struct timespec* timeout) {
+#if defined(__NR_recvmmsg)
+ return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
+
+
+int uv__utimesat(int dirfd,
+ const char* path,
+ const struct timespec times[2],
+ int flags)
+{
+#if defined(__NR_utimensat)
+ return syscall(__NR_utimensat, dirfd, path, times, flags);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
diff --git a/third-party/libuv/src/unix/linux-syscalls.h b/third-party/libuv/src/unix/linux-syscalls.h
new file mode 100644
index 0000000000..1ad9518548
--- /dev/null
+++ b/third-party/libuv/src/unix/linux-syscalls.h
@@ -0,0 +1,151 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_LINUX_SYSCALL_H_
+#define UV_LINUX_SYSCALL_H_
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+
+#include <stdint.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#if defined(__alpha__)
+# define UV__O_CLOEXEC 0x200000
+#elif defined(__hppa__)
+# define UV__O_CLOEXEC 0x200000
+#elif defined(__sparc__)
+# define UV__O_CLOEXEC 0x400000
+#else
+# define UV__O_CLOEXEC 0x80000
+#endif
+
+#if defined(__alpha__)
+# define UV__O_NONBLOCK 0x4
+#elif defined(__hppa__)
+# define UV__O_NONBLOCK 0x10004
+#elif defined(__mips__)
+# define UV__O_NONBLOCK 0x80
+#elif defined(__sparc__)
+# define UV__O_NONBLOCK 0x4000
+#else
+# define UV__O_NONBLOCK 0x800
+#endif
+
+#define UV__EFD_CLOEXEC UV__O_CLOEXEC
+#define UV__EFD_NONBLOCK UV__O_NONBLOCK
+
+#define UV__IN_CLOEXEC UV__O_CLOEXEC
+#define UV__IN_NONBLOCK UV__O_NONBLOCK
+
+#define UV__SOCK_CLOEXEC UV__O_CLOEXEC
+#define UV__SOCK_NONBLOCK UV__O_NONBLOCK
+
+/* epoll flags */
+#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC
+#define UV__EPOLL_CTL_ADD 1
+#define UV__EPOLL_CTL_DEL 2
+#define UV__EPOLL_CTL_MOD 3
+
+#define UV__EPOLLIN 1
+#define UV__EPOLLOUT 4
+#define UV__EPOLLERR 8
+#define UV__EPOLLHUP 16
+#define UV__EPOLLONESHOT 0x40000000
+#define UV__EPOLLET 0x80000000
+
+/* inotify flags */
+#define UV__IN_ACCESS 0x001
+#define UV__IN_MODIFY 0x002
+#define UV__IN_ATTRIB 0x004
+#define UV__IN_CLOSE_WRITE 0x008
+#define UV__IN_CLOSE_NOWRITE 0x010
+#define UV__IN_OPEN 0x020
+#define UV__IN_MOVED_FROM 0x040
+#define UV__IN_MOVED_TO 0x080
+#define UV__IN_CREATE 0x100
+#define UV__IN_DELETE 0x200
+#define UV__IN_DELETE_SELF 0x400
+#define UV__IN_MOVE_SELF 0x800
+
+#if defined(__x86_64__)
+struct uv__epoll_event {
+ uint32_t events;
+ uint64_t data;
+} __attribute__((packed));
+#else
+struct uv__epoll_event {
+ uint32_t events;
+ uint64_t data;
+};
+#endif
+
+struct uv__inotify_event {
+ int32_t wd;
+ uint32_t mask;
+ uint32_t cookie;
+ uint32_t len;
+ /* char name[0]; */
+};
+
+struct uv__mmsghdr {
+ struct msghdr msg_hdr;
+ unsigned int msg_len;
+};
+
+int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
+int uv__eventfd(unsigned int count);
+int uv__epoll_create(int size);
+int uv__epoll_create1(int flags);
+int uv__epoll_ctl(int epfd, int op, int fd, struct uv__epoll_event *ev);
+int uv__epoll_wait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout);
+int uv__epoll_pwait(int epfd,
+ struct uv__epoll_event* events,
+ int nevents,
+ int timeout,
+ const sigset_t* sigmask);
+int uv__eventfd2(unsigned int count, int flags);
+int uv__inotify_init(void);
+int uv__inotify_init1(int flags);
+int uv__inotify_add_watch(int fd, const char* path, uint32_t mask);
+int uv__inotify_rm_watch(int fd, int32_t wd);
+int uv__pipe2(int pipefd[2], int flags);
+int uv__recvmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags,
+ struct timespec* timeout);
+int uv__sendmmsg(int fd,
+ struct uv__mmsghdr* mmsg,
+ unsigned int vlen,
+ unsigned int flags);
+int uv__utimesat(int dirfd,
+ const char* path,
+ const struct timespec times[2],
+ int flags);
+
+#endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/third-party/libuv/src/unix/loop-watcher.c b/third-party/libuv/src/unix/loop-watcher.c
new file mode 100644
index 0000000000..dc03c206d2
--- /dev/null
+++ b/third-party/libuv/src/unix/loop-watcher.c
@@ -0,0 +1,63 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#define UV_LOOP_WATCHER_DEFINE(name, type) \
+ int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \
+ handle->name##_cb = NULL; \
+ return 0; \
+ } \
+ \
+ int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
+ if (uv__is_active(handle)) return 0; \
+ if (cb == NULL) return -EINVAL; \
+ QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue); \
+ handle->name##_cb = cb; \
+ uv__handle_start(handle); \
+ return 0; \
+ } \
+ \
+ int uv_##name##_stop(uv_##name##_t* handle) { \
+ if (!uv__is_active(handle)) return 0; \
+ QUEUE_REMOVE(&handle->queue); \
+ uv__handle_stop(handle); \
+ return 0; \
+ } \
+ \
+ void uv__run_##name(uv_loop_t* loop) { \
+ uv_##name##_t* h; \
+ QUEUE* q; \
+ QUEUE_FOREACH(q, &loop->name##_handles) { \
+ h = QUEUE_DATA(q, uv_##name##_t, queue); \
+ h->name##_cb(h, 0); \
+ } \
+ } \
+ \
+ void uv__##name##_close(uv_##name##_t* handle) { \
+ uv_##name##_stop(handle); \
+ }
+
+UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
+UV_LOOP_WATCHER_DEFINE(check, CHECK)
+UV_LOOP_WATCHER_DEFINE(idle, IDLE)
diff --git a/third-party/libuv/src/unix/loop.c b/third-party/libuv/src/unix/loop.c
new file mode 100644
index 0000000000..94a5c03819
--- /dev/null
+++ b/third-party/libuv/src/unix/loop.c
@@ -0,0 +1,163 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "tree.h"
+#include "internal.h"
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int uv__loop_init(uv_loop_t* loop, int default_loop);
+static void uv__loop_delete(uv_loop_t* loop);
+
+static uv_loop_t default_loop_struct;
+static uv_loop_t* default_loop_ptr;
+
+
+uv_loop_t* uv_default_loop(void) {
+ if (default_loop_ptr != NULL)
+ return default_loop_ptr;
+
+ if (uv__loop_init(&default_loop_struct, /* default_loop? */ 1))
+ return NULL;
+
+ default_loop_ptr = &default_loop_struct;
+ return default_loop_ptr;
+}
+
+
+uv_loop_t* uv_loop_new(void) {
+ uv_loop_t* loop;
+
+ loop = malloc(sizeof(*loop));
+ if (loop == NULL)
+ return NULL;
+
+ if (uv__loop_init(loop, /* default_loop? */ 0)) {
+ free(loop);
+ return NULL;
+ }
+
+ return loop;
+}
+
+
+void uv_loop_delete(uv_loop_t* loop) {
+ uv__loop_delete(loop);
+#ifndef NDEBUG
+ memset(loop, -1, sizeof(*loop));
+#endif
+ if (loop == default_loop_ptr)
+ default_loop_ptr = NULL;
+ else
+ free(loop);
+}
+
+
+static int uv__loop_init(uv_loop_t* loop, int default_loop) {
+ unsigned int i;
+ int err;
+
+ uv__signal_global_once_init();
+
+ memset(loop, 0, sizeof(*loop));
+ RB_INIT(&loop->timer_handles);
+ QUEUE_INIT(&loop->wq);
+ QUEUE_INIT(&loop->active_reqs);
+ QUEUE_INIT(&loop->idle_handles);
+ QUEUE_INIT(&loop->async_handles);
+ QUEUE_INIT(&loop->check_handles);
+ QUEUE_INIT(&loop->prepare_handles);
+ QUEUE_INIT(&loop->handle_queue);
+
+ loop->nfds = 0;
+ loop->watchers = NULL;
+ loop->nwatchers = 0;
+ QUEUE_INIT(&loop->pending_queue);
+ QUEUE_INIT(&loop->watcher_queue);
+
+ loop->closing_handles = NULL;
+ uv__update_time(loop);
+ uv__async_init(&loop->async_watcher);
+ loop->signal_pipefd[0] = -1;
+ loop->signal_pipefd[1] = -1;
+ loop->backend_fd = -1;
+ loop->emfile_fd = -1;
+
+ loop->timer_counter = 0;
+ loop->stop_flag = 0;
+
+ err = uv__platform_loop_init(loop, default_loop);
+ if (err)
+ return err;
+
+ uv_signal_init(loop, &loop->child_watcher);
+ uv__handle_unref(&loop->child_watcher);
+ loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
+
+ for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
+ QUEUE_INIT(loop->process_handles + i);
+
+ if (uv_mutex_init(&loop->wq_mutex))
+ abort();
+
+ if (uv_async_init(loop, &loop->wq_async, uv__work_done))
+ abort();
+
+ uv__handle_unref(&loop->wq_async);
+ loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+
+ return 0;
+}
+
+
+static void uv__loop_delete(uv_loop_t* loop) {
+ uv__signal_loop_cleanup(loop);
+ uv__platform_loop_delete(loop);
+ uv__async_stop(loop, &loop->async_watcher);
+
+ if (loop->emfile_fd != -1) {
+ uv__close(loop->emfile_fd);
+ loop->emfile_fd = -1;
+ }
+
+ if (loop->backend_fd != -1) {
+ uv__close(loop->backend_fd);
+ loop->backend_fd = -1;
+ }
+
+ uv_mutex_lock(&loop->wq_mutex);
+ assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
+ assert(!uv__has_active_reqs(loop));
+ uv_mutex_unlock(&loop->wq_mutex);
+ uv_mutex_destroy(&loop->wq_mutex);
+
+#if 0
+ assert(QUEUE_EMPTY(&loop->pending_queue));
+ assert(QUEUE_EMPTY(&loop->watcher_queue));
+ assert(loop->nfds == 0);
+#endif
+
+ free(loop->watchers);
+ loop->watchers = NULL;
+ loop->nwatchers = 0;
+}
diff --git a/third-party/libuv/src/unix/netbsd.c b/third-party/libuv/src/unix/netbsd.c
new file mode 100644
index 0000000000..7423a71078
--- /dev/null
+++ b/third-party/libuv/src/unix/netbsd.c
@@ -0,0 +1,367 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+
+#include <kvm.h>
+#include <paths.h>
+#include <ifaddrs.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <unistd.h>
+#include <time.h>
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+static char *process_title;
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct loadavg info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_LOADAVG};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
+
+ avg[0] = (double) info.ldavg[0] / info.fscale;
+ avg[1] = (double) info.ldavg[1] / info.fscale;
+ avg[2] = (double) info.ldavg[2] / info.fscale;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ int mib[4];
+ size_t cb;
+ pid_t mypid;
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+ mypid = getpid();
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = mypid;
+ mib[3] = KERN_PROC_ARGV;
+
+ cb = *size;
+ if (sysctl(mib, 4, buffer, &cb, NULL, 0))
+ return -errno;
+ *size = strlen(buffer);
+
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ struct uvmexp info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_UVMEXP};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+#if defined(HW_PHYSMEM64)
+ uint64_t info;
+ int which[] = {CTL_HW, HW_PHYSMEM64};
+#else
+ unsigned int info;
+ int which[] = {CTL_HW, HW_PHYSMEM};
+#endif
+ size_t size = sizeof(info);
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info;
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc ? strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ if (process_title) free(process_title);
+
+ process_title = strdup(title);
+ setproctitle("%s", title);
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (process_title) {
+ strncpy(buffer, process_title, size);
+ } else {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ kvm_t *kd = NULL;
+ struct kinfo_proc2 *kinfo = NULL;
+ pid_t pid;
+ int nprocs;
+ int max_size = sizeof(struct kinfo_proc2);
+ int page_size;
+
+ page_size = getpagesize();
+ pid = getpid();
+
+ kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
+
+ if (kd == NULL) goto error;
+
+ kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs);
+ if (kinfo == NULL) goto error;
+
+ *rss = kinfo->p_vm_rssize * page_size;
+
+ kvm_close(kd);
+
+ return 0;
+
+error:
+ if (kd) kvm_close(kd);
+ return -EPERM;
+}
+
+
+int uv_uptime(double* uptime) {
+ time_t now;
+ struct timeval info;
+ size_t size = sizeof(info);
+ static int which[] = {CTL_KERN, KERN_BOOTTIME};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ now = time(NULL);
+
+ *uptime = (double)(now - info.tv_sec);
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK);
+ unsigned int multiplier = ((uint64_t)1000L / ticks);
+ unsigned int cur = 0;
+ uv_cpu_info_t* cpu_info;
+ u_int64_t* cp_times;
+ char model[512];
+ u_int64_t cpuspeed;
+ int numcpus;
+ size_t size;
+ int i;
+
+ size = sizeof(model);
+ if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) &&
+ sysctlbyname("hw.model", &model, &size, NULL, 0)) {
+ return -errno;
+ }
+
+ size = sizeof(numcpus);
+ if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0))
+ return -errno;
+ *count = numcpus;
+
+ /* Only i386 and amd64 have machdep.tsc_freq */
+ size = sizeof(cpuspeed);
+ if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0))
+ cpuspeed = 0;
+
+ size = numcpus * CPUSTATES * sizeof(*cp_times);
+ cp_times = malloc(size);
+ if (cp_times == NULL)
+ return -ENOMEM;
+
+ if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0))
+ return -errno;
+
+ *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+ if (!(*cpu_infos)) {
+ free(cp_times);
+ free(*cpu_infos);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < numcpus; i++) {
+ cpu_info = &(*cpu_infos)[i];
+ cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
+ cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
+ cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
+ cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
+ cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
+ cpu_info->model = strdup(model);
+ cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
+ cur += CPUSTATES;
+ }
+ free(cp_times);
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+ struct ifaddrs *addrs, *ent;
+ uv_interface_address_t* address;
+ int i;
+ struct sockaddr_dl *sa_addr;
+
+ if (getifaddrs(&addrs))
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != PF_INET)) {
+ continue;
+ }
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ if (ent->ifa_addr->sa_family != PF_INET)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != AF_LINK)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/openbsd.c b/third-party/libuv/src/unix/openbsd.c
new file mode 100644
index 0000000000..f052d80c57
--- /dev/null
+++ b/third-party/libuv/src/unix/openbsd.c
@@ -0,0 +1,388 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/sched.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+
+static char *process_title;
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ return uv__kqueue_init(loop);
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
+}
+
+
+void uv_loadavg(double avg[3]) {
+ struct loadavg info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_LOADAVG};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+
+ avg[0] = (double) info.ldavg[0] / info.fscale;
+ avg[1] = (double) info.ldavg[1] / info.fscale;
+ avg[2] = (double) info.ldavg[2] / info.fscale;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ int mib[4];
+ char **argsbuf = NULL;
+ char **argsbuf_tmp;
+ size_t argsbuf_size = 100U;
+ size_t exepath_size;
+ pid_t mypid;
+ int err;
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+ mypid = getpid();
+ for (;;) {
+ err = -ENOMEM;
+ argsbuf_tmp = realloc(argsbuf, argsbuf_size);
+ if (argsbuf_tmp == NULL)
+ goto out;
+ argsbuf = argsbuf_tmp;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = mypid;
+ mib[3] = KERN_PROC_ARGV;
+ if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) {
+ break;
+ }
+ if (errno != ENOMEM) {
+ err = -errno;
+ goto out;
+ }
+ argsbuf_size *= 2U;
+ }
+ if (argsbuf[0] == NULL) {
+ err = -EINVAL; /* FIXME(bnoordhuis) More appropriate error. */
+ goto out;
+ }
+ exepath_size = strlen(argsbuf[0]);
+ if (exepath_size >= *size) {
+ err = -EINVAL;
+ goto out;
+ }
+ memcpy(buffer, argsbuf[0], exepath_size + 1U);
+ *size = exepath_size;
+ err = 0;
+
+out:
+ free(argsbuf);
+
+ return err;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ struct uvmexp info;
+ size_t size = sizeof(info);
+ int which[] = {CTL_VM, VM_UVMEXP};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ uint64_t info;
+ int which[] = {CTL_HW, HW_PHYSMEM64};
+ size_t size = sizeof(info);
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ return (uint64_t) info;
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ process_title = argc ? strdup(argv[0]) : NULL;
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ if (process_title) free(process_title);
+ process_title = strdup(title);
+ setproctitle(title);
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (process_title) {
+ strncpy(buffer, process_title, size);
+ } else {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ kvm_t *kd = NULL;
+ struct kinfo_proc *kinfo = NULL;
+ pid_t pid;
+ int nprocs, max_size = sizeof(struct kinfo_proc);
+ size_t page_size = getpagesize();
+
+ pid = getpid();
+
+ kd = kvm_open(NULL, _PATH_MEM, NULL, O_RDONLY, "kvm_open");
+ if (kd == NULL) goto error;
+
+ kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, max_size, &nprocs);
+ if (kinfo == NULL) goto error;
+
+ *rss = kinfo->p_vm_rssize * page_size;
+
+ kvm_close(kd);
+
+ return 0;
+
+error:
+ if (kd) kvm_close(kd);
+ return -EPERM;
+}
+
+
+int uv_uptime(double* uptime) {
+ time_t now;
+ struct timeval info;
+ size_t size = sizeof(info);
+ static int which[] = {CTL_KERN, KERN_BOOTTIME};
+
+ if (sysctl(which, 2, &info, &size, NULL, 0))
+ return -errno;
+
+ now = time(NULL);
+
+ *uptime = (double)(now - info.tv_sec);
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
+ multiplier = ((uint64_t)1000L / ticks), cpuspeed;
+ uint64_t info[CPUSTATES];
+ char model[512];
+ int numcpus = 1;
+ int which[] = {CTL_HW,HW_MODEL,0};
+ size_t size;
+ int i;
+ uv_cpu_info_t* cpu_info;
+
+ size = sizeof(model);
+ if (sysctl(which, 2, &model, &size, NULL, 0))
+ return -errno;
+
+ which[1] = HW_NCPU;
+ size = sizeof(numcpus);
+ if (sysctl(which, 2, &numcpus, &size, NULL, 0))
+ return -errno;
+
+ *cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
+ if (!(*cpu_infos))
+ return -ENOMEM;
+
+ *count = numcpus;
+
+ which[1] = HW_CPUSPEED;
+ size = sizeof(cpuspeed);
+ if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) {
+ SAVE_ERRNO(free(*cpu_infos));
+ return -errno;
+ }
+
+ size = sizeof(info);
+ which[0] = CTL_KERN;
+ which[1] = KERN_CPTIME2;
+ for (i = 0; i < numcpus; i++) {
+ which[2] = i;
+ size = sizeof(info);
+ if (sysctl(which, 3, &info, &size, NULL, 0)) {
+ SAVE_ERRNO(free(*cpu_infos));
+ return -errno;
+ }
+
+ cpu_info = &(*cpu_infos)[i];
+
+ cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier;
+ cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier;
+ cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier;
+ cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier;
+ cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier;
+
+ cpu_info->model = strdup(model);
+ cpu_info->speed = cpuspeed;
+ }
+
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses,
+ int* count) {
+ struct ifaddrs *addrs, *ent;
+ uv_interface_address_t* address;
+ int i;
+ struct sockaddr_dl *sa_addr;
+
+ if (getifaddrs(&addrs) != 0)
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != PF_INET)) {
+ continue;
+ }
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ if (ent->ifa_addr->sa_family != PF_INET)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != AF_LINK)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/pipe.c b/third-party/libuv/src/unix/pipe.c
new file mode 100644
index 0000000000..fd4afb6370
--- /dev/null
+++ b/third-party/libuv/src/unix/pipe.c
@@ -0,0 +1,216 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+
+int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
+ uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
+ handle->shutdown_req = NULL;
+ handle->connect_req = NULL;
+ handle->pipe_fname = NULL;
+ handle->ipc = ipc;
+ return 0;
+}
+
+
+int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
+ struct sockaddr_un saddr;
+ const char* pipe_fname;
+ int sockfd;
+ int bound;
+ int err;
+
+ pipe_fname = NULL;
+ sockfd = -1;
+ bound = 0;
+ err = -EINVAL;
+
+ /* Already bound? */
+ if (uv__stream_fd(handle) >= 0)
+ return -EINVAL;
+
+ /* Make a copy of the file name, it outlives this function's scope. */
+ pipe_fname = strdup(name);
+ if (pipe_fname == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* We've got a copy, don't touch the original any more. */
+ name = NULL;
+
+ err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
+ if (err < 0)
+ goto out;
+ sockfd = err;
+
+ memset(&saddr, 0, sizeof saddr);
+ strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1);
+ saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
+ saddr.sun_family = AF_UNIX;
+
+ if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
+ err = -errno;
+ /* Convert ENOENT to EACCES for compatibility with Windows. */
+ if (err == -ENOENT)
+ err = -EACCES;
+ goto out;
+ }
+ bound = 1;
+
+ /* Success. */
+ handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
+ handle->io_watcher.fd = sockfd;
+ return 0;
+
+out:
+ if (bound) {
+ /* unlink() before uv__close() to avoid races. */
+ assert(pipe_fname != NULL);
+ unlink(pipe_fname);
+ }
+ uv__close(sockfd);
+ free((void*)pipe_fname);
+ return err;
+}
+
+
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
+ if (uv__stream_fd(handle) == -1)
+ return -EINVAL;
+
+ if (listen(uv__stream_fd(handle), backlog))
+ return -errno;
+
+ handle->connection_cb = cb;
+ handle->io_watcher.cb = uv__server_io;
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
+ return 0;
+}
+
+
+void uv__pipe_close(uv_pipe_t* handle) {
+ if (handle->pipe_fname) {
+ /*
+ * Unlink the file system entity before closing the file descriptor.
+ * Doing it the other way around introduces a race where our process
+ * unlinks a socket with the same name that's just been created by
+ * another thread or process.
+ */
+ unlink(handle->pipe_fname);
+ free((void*)handle->pipe_fname);
+ handle->pipe_fname = NULL;
+ }
+
+ uv__stream_close((uv_stream_t*)handle);
+}
+
+
+int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
+#if defined(__APPLE__)
+ int err;
+
+ err = uv__stream_try_select((uv_stream_t*) handle, &fd);
+ if (err)
+ return err;
+#endif /* defined(__APPLE__) */
+
+ return uv__stream_open((uv_stream_t*)handle,
+ fd,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+}
+
+
+void uv_pipe_connect(uv_connect_t* req,
+ uv_pipe_t* handle,
+ const char* name,
+ uv_connect_cb cb) {
+ struct sockaddr_un saddr;
+ int new_sock;
+ int err;
+ int r;
+
+ new_sock = (uv__stream_fd(handle) == -1);
+ err = -EINVAL;
+
+ if (new_sock) {
+ err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
+ if (err < 0)
+ goto out;
+ handle->io_watcher.fd = err;
+ }
+
+ memset(&saddr, 0, sizeof saddr);
+ strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1);
+ saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
+ saddr.sun_family = AF_UNIX;
+
+ do {
+ r = connect(uv__stream_fd(handle),
+ (struct sockaddr*)&saddr, sizeof saddr);
+ }
+ while (r == -1 && errno == EINTR);
+
+ if (r == -1 && errno != EINPROGRESS) {
+ err = -errno;
+ goto out;
+ }
+
+ err = 0;
+ if (new_sock) {
+ err = uv__stream_open((uv_stream_t*)handle,
+ uv__stream_fd(handle),
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ }
+
+ if (err == 0)
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
+
+out:
+ handle->delayed_error = err;
+ handle->connect_req = req;
+
+ uv__req_init(handle->loop, req, UV_CONNECT);
+ req->handle = (uv_stream_t*)handle;
+ req->cb = cb;
+ QUEUE_INIT(&req->queue);
+
+ /* Force callback to run on next tick in case of error. */
+ if (err)
+ uv__io_feed(handle->loop, &handle->io_watcher);
+
+ /* Mimic the Windows pipe implementation, always
+ * return 0 and let the callback handle errors.
+ */
+}
+
+
+void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
+}
diff --git a/third-party/libuv/src/unix/poll.c b/third-party/libuv/src/unix/poll.c
new file mode 100644
index 0000000000..a34a8d1e14
--- /dev/null
+++ b/third-party/libuv/src/unix/poll.c
@@ -0,0 +1,107 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+
+static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ uv_poll_t* handle;
+ int pevents;
+
+ handle = container_of(w, uv_poll_t, io_watcher);
+
+ if (events & UV__POLLERR) {
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
+ uv__handle_stop(handle);
+ handle->poll_cb(handle, -EBADF, 0);
+ return;
+ }
+
+ pevents = 0;
+ if (events & UV__POLLIN)
+ pevents |= UV_READABLE;
+ if (events & UV__POLLOUT)
+ pevents |= UV_WRITABLE;
+
+ handle->poll_cb(handle, 0, pevents);
+}
+
+
+int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
+ uv__io_init(&handle->io_watcher, uv__poll_io, fd);
+ handle->poll_cb = NULL;
+ return 0;
+}
+
+
+int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
+ uv_os_sock_t socket) {
+ return uv_poll_init(loop, handle, socket);
+}
+
+
+static void uv__poll_stop(uv_poll_t* handle) {
+ uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
+ uv__handle_stop(handle);
+}
+
+
+int uv_poll_stop(uv_poll_t* handle) {
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+ uv__poll_stop(handle);
+ return 0;
+}
+
+
+int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
+ int events;
+
+ assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0);
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+
+ uv__poll_stop(handle);
+
+ if (pevents == 0)
+ return 0;
+
+ events = 0;
+ if (pevents & UV_READABLE)
+ events |= UV__POLLIN;
+ if (pevents & UV_WRITABLE)
+ events |= UV__POLLOUT;
+
+ uv__io_start(handle->loop, &handle->io_watcher, events);
+ uv__handle_start(handle);
+ handle->poll_cb = poll_cb;
+
+ return 0;
+}
+
+
+void uv__poll_close(uv_poll_t* handle) {
+ uv__poll_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/process.c b/third-party/libuv/src/unix/process.c
new file mode 100644
index 0000000000..6f96b754d8
--- /dev/null
+++ b/third-party/libuv/src/unix/process.c
@@ -0,0 +1,517 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <poll.h>
+
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
+# include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#else
+extern char **environ;
+#endif
+
+
+static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
+ assert(pid > 0);
+ return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
+}
+
+
+static void uv__chld(uv_signal_t* handle, int signum) {
+ uv_process_t* process;
+ uv_loop_t* loop;
+ int exit_status;
+ int term_signal;
+ unsigned int i;
+ int status;
+ pid_t pid;
+ QUEUE pending;
+ QUEUE* h;
+ QUEUE* q;
+
+ assert(signum == SIGCHLD);
+
+ QUEUE_INIT(&pending);
+ loop = handle->loop;
+
+ for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) {
+ h = loop->process_handles + i;
+ q = QUEUE_HEAD(h);
+
+ while (q != h) {
+ process = QUEUE_DATA(q, uv_process_t, queue);
+ q = QUEUE_NEXT(q);
+
+ do
+ pid = waitpid(process->pid, &status, WNOHANG);
+ while (pid == -1 && errno == EINTR);
+
+ if (pid == 0)
+ continue;
+
+ if (pid == -1) {
+ if (errno != ECHILD)
+ abort();
+ continue;
+ }
+
+ process->status = status;
+ QUEUE_REMOVE(&process->queue);
+ QUEUE_INSERT_TAIL(&pending, &process->queue);
+ }
+
+ while (!QUEUE_EMPTY(&pending)) {
+ q = QUEUE_HEAD(&pending);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ process = QUEUE_DATA(q, uv_process_t, queue);
+ uv__handle_stop(process);
+
+ if (process->exit_cb == NULL)
+ continue;
+
+ exit_status = 0;
+ if (WIFEXITED(process->status))
+ exit_status = WEXITSTATUS(process->status);
+
+ term_signal = 0;
+ if (WIFSIGNALED(process->status))
+ term_signal = WTERMSIG(process->status);
+
+ process->exit_cb(process, exit_status, term_signal);
+ }
+ }
+}
+
+
+int uv__make_socketpair(int fds[2], int flags) {
+#if defined(__linux__)
+ static int no_cloexec;
+
+ if (no_cloexec)
+ goto skip;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
+ return 0;
+
+ /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
+ * Anything else is a genuine error.
+ */
+ if (errno != EINVAL)
+ return -errno;
+
+ no_cloexec = 1;
+
+skip:
+#endif
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+ return -errno;
+
+ uv__cloexec(fds[0], 1);
+ uv__cloexec(fds[1], 1);
+
+ if (flags & UV__F_NONBLOCK) {
+ uv__nonblock(fds[0], 1);
+ uv__nonblock(fds[1], 1);
+ }
+
+ return 0;
+}
+
+
+int uv__make_pipe(int fds[2], int flags) {
+#if defined(__linux__)
+ static int no_pipe2;
+
+ if (no_pipe2)
+ goto skip;
+
+ if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
+ return 0;
+
+ if (errno != ENOSYS)
+ return -errno;
+
+ no_pipe2 = 1;
+
+skip:
+#endif
+
+ if (pipe(fds))
+ return -errno;
+
+ uv__cloexec(fds[0], 1);
+ uv__cloexec(fds[1], 1);
+
+ if (flags & UV__F_NONBLOCK) {
+ uv__nonblock(fds[0], 1);
+ uv__nonblock(fds[1], 1);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Used for initializing stdio streams like options.stdin_stream. Returns
+ * zero on success. See also the cleanup section in uv_spawn().
+ */
+static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
+ int mask;
+ int fd;
+
+ mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
+
+ switch (container->flags & mask) {
+ case UV_IGNORE:
+ return 0;
+
+ case UV_CREATE_PIPE:
+ assert(container->data.stream != NULL);
+ if (container->data.stream->type != UV_NAMED_PIPE)
+ return -EINVAL;
+ else
+ return uv__make_socketpair(fds, 0);
+
+ case UV_INHERIT_FD:
+ case UV_INHERIT_STREAM:
+ if (container->flags & UV_INHERIT_FD)
+ fd = container->data.fd;
+ else
+ fd = uv__stream_fd(container->data.stream);
+
+ if (fd == -1)
+ return -EINVAL;
+
+ fds[1] = fd;
+ return 0;
+
+ default:
+ assert(0 && "Unexpected flags");
+ return -EINVAL;
+ }
+}
+
+
+static int uv__process_open_stream(uv_stdio_container_t* container,
+ int pipefds[2],
+ int writable) {
+ int flags;
+
+ if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
+ return 0;
+
+ if (uv__close(pipefds[1]))
+ if (errno != EINTR && errno != EINPROGRESS)
+ abort();
+
+ pipefds[1] = -1;
+ uv__nonblock(pipefds[0], 1);
+
+ if (container->data.stream->type == UV_NAMED_PIPE &&
+ ((uv_pipe_t*)container->data.stream)->ipc)
+ flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
+ else if (writable)
+ flags = UV_STREAM_WRITABLE;
+ else
+ flags = UV_STREAM_READABLE;
+
+ return uv__stream_open(container->data.stream, pipefds[0], flags);
+}
+
+
+static void uv__process_close_stream(uv_stdio_container_t* container) {
+ if (!(container->flags & UV_CREATE_PIPE)) return;
+ uv__stream_close((uv_stream_t*)container->data.stream);
+}
+
+
+static void uv__write_int(int fd, int val) {
+ ssize_t n;
+
+ do
+ n = write(fd, &val, sizeof(val));
+ while (n == -1 && errno == EINTR);
+
+ if (n == -1 && errno == EPIPE)
+ return; /* parent process has quit */
+
+ assert(n == sizeof(val));
+}
+
+
+static void uv__process_child_init(const uv_process_options_t* options,
+ int stdio_count,
+ int (*pipes)[2],
+ int error_fd) {
+ int close_fd;
+ int use_fd;
+ int fd;
+
+ if (options->flags & UV_PROCESS_DETACHED)
+ setsid();
+
+ for (fd = 0; fd < stdio_count; fd++) {
+ close_fd = pipes[fd][0];
+ use_fd = pipes[fd][1];
+
+ if (use_fd < 0) {
+ if (fd >= 3)
+ continue;
+ else {
+ /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+ * set
+ */
+ use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
+ close_fd = use_fd;
+
+ if (use_fd == -1) {
+ uv__write_int(error_fd, -errno);
+ perror("failed to open stdio");
+ _exit(127);
+ }
+ }
+ }
+
+ if (fd == use_fd)
+ uv__cloexec(use_fd, 0);
+ else
+ dup2(use_fd, fd);
+
+ if (fd <= 2)
+ uv__nonblock(fd, 0);
+
+ if (close_fd != -1)
+ uv__close(close_fd);
+ }
+
+ for (fd = 0; fd < stdio_count; fd++) {
+ use_fd = pipes[fd][1];
+
+ if (use_fd >= 0 && fd != use_fd)
+ close(use_fd);
+ }
+
+ if (options->cwd != NULL && chdir(options->cwd)) {
+ uv__write_int(error_fd, -errno);
+ perror("chdir()");
+ _exit(127);
+ }
+
+ if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
+ uv__write_int(error_fd, -errno);
+ perror("setgid()");
+ _exit(127);
+ }
+
+ if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
+ uv__write_int(error_fd, -errno);
+ perror("setuid()");
+ _exit(127);
+ }
+
+ if (options->env != NULL) {
+ environ = options->env;
+ }
+
+ execvp(options->file, options->args);
+ uv__write_int(error_fd, -errno);
+ perror("execvp()");
+ _exit(127);
+}
+
+
+int uv_spawn(uv_loop_t* loop,
+ uv_process_t* process,
+ const uv_process_options_t* options) {
+ int signal_pipe[2] = { -1, -1 };
+ int (*pipes)[2];
+ int stdio_count;
+ QUEUE* q;
+ ssize_t r;
+ pid_t pid;
+ int err;
+ int exec_errorno;
+ int i;
+
+ assert(options->file != NULL);
+ assert(!(options->flags & ~(UV_PROCESS_DETACHED |
+ UV_PROCESS_SETGID |
+ UV_PROCESS_SETUID |
+ UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+
+ uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
+ QUEUE_INIT(&process->queue);
+
+ stdio_count = options->stdio_count;
+ if (stdio_count < 3)
+ stdio_count = 3;
+
+ err = -ENOMEM;
+ pipes = malloc(stdio_count * sizeof(*pipes));
+ if (pipes == NULL)
+ goto error;
+
+ for (i = 0; i < stdio_count; i++) {
+ pipes[i][0] = -1;
+ pipes[i][1] = -1;
+ }
+
+ for (i = 0; i < options->stdio_count; i++) {
+ err = uv__process_init_stdio(options->stdio + i, pipes[i]);
+ if (err)
+ goto error;
+ }
+
+ /* This pipe is used by the parent to wait until
+ * the child has called `execve()`. We need this
+ * to avoid the following race condition:
+ *
+ * if ((pid = fork()) > 0) {
+ * kill(pid, SIGTERM);
+ * }
+ * else if (pid == 0) {
+ * execve("/bin/cat", argp, envp);
+ * }
+ *
+ * The parent sends a signal immediately after forking.
+ * Since the child may not have called `execve()` yet,
+ * there is no telling what process receives the signal,
+ * our fork or /bin/cat.
+ *
+ * To avoid ambiguity, we create a pipe with both ends
+ * marked close-on-exec. Then, after the call to `fork()`,
+ * the parent polls the read end until it EOFs or errors with EPIPE.
+ */
+ err = uv__make_pipe(signal_pipe, 0);
+ if (err)
+ goto error;
+
+ uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
+
+ pid = fork();
+
+ if (pid == -1) {
+ err = -errno;
+ uv__close(signal_pipe[0]);
+ uv__close(signal_pipe[1]);
+ goto error;
+ }
+
+ if (pid == 0) {
+ uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
+ abort();
+ }
+
+ uv__close(signal_pipe[1]);
+
+ process->status = 0;
+ exec_errorno = 0;
+ do
+ r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno));
+ while (r == -1 && errno == EINTR);
+
+ if (r == 0)
+ ; /* okay, EOF */
+ else if (r == sizeof(exec_errorno))
+ ; /* okay, read errorno */
+ else if (r == -1 && errno == EPIPE)
+ ; /* okay, got EPIPE */
+ else
+ abort();
+
+ uv__close(signal_pipe[0]);
+
+ for (i = 0; i < options->stdio_count; i++) {
+ err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0);
+ if (err == 0)
+ continue;
+
+ while (i--)
+ uv__process_close_stream(options->stdio + i);
+
+ goto error;
+ }
+
+ /* Only activate this handle if exec() happened successfully */
+ if (exec_errorno == 0) {
+ q = uv__process_queue(loop, pid);
+ QUEUE_INSERT_TAIL(q, &process->queue);
+ uv__handle_start(process);
+ }
+
+ process->pid = pid;
+ process->exit_cb = options->exit_cb;
+
+ free(pipes);
+ return exec_errorno;
+
+error:
+ if (pipes != NULL) {
+ for (i = 0; i < stdio_count; i++) {
+ if (i < options->stdio_count)
+ if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
+ continue;
+ if (pipes[i][0] != -1)
+ close(pipes[i][0]);
+ if (pipes[i][1] != -1)
+ close(pipes[i][1]);
+ }
+ free(pipes);
+ }
+
+ return err;
+}
+
+
+int uv_process_kill(uv_process_t* process, int signum) {
+ return uv_kill(process->pid, signum);
+}
+
+
+int uv_kill(int pid, int signum) {
+ if (kill(pid, signum))
+ return -errno;
+ else
+ return 0;
+}
+
+
+void uv__process_close(uv_process_t* handle) {
+ /* TODO stop signal watcher when this is the last handle */
+ QUEUE_REMOVE(&handle->queue);
+ uv__handle_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/proctitle.c b/third-party/libuv/src/unix/proctitle.c
new file mode 100644
index 0000000000..16b0523731
--- /dev/null
+++ b/third-party/libuv/src/unix/proctitle.c
@@ -0,0 +1,102 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+extern void uv__set_process_title(const char* title);
+
+static void* args_mem;
+
+static struct {
+ char* str;
+ size_t len;
+} process_title;
+
+
+char** uv_setup_args(int argc, char** argv) {
+ char** new_argv;
+ size_t size;
+ char* s;
+ int i;
+
+ if (argc <= 0)
+ return argv;
+
+ /* Calculate how much memory we need for the argv strings. */
+ size = 0;
+ for (i = 0; i < argc; i++)
+ size += strlen(argv[i]) + 1;
+
+ process_title.str = argv[0];
+ process_title.len = argv[argc - 1] + strlen(argv[argc - 1]) - argv[0];
+ assert(process_title.len + 1 == size); /* argv memory should be adjacent. */
+
+ /* Add space for the argv pointers. */
+ size += (argc + 1) * sizeof(char*);
+
+ new_argv = malloc(size);
+ if (new_argv == NULL)
+ return argv;
+ args_mem = new_argv;
+
+ /* Copy over the strings and set up the pointer table. */
+ s = (char*) &new_argv[argc + 1];
+ for (i = 0; i < argc; i++) {
+ size = strlen(argv[i]) + 1;
+ memcpy(s, argv[i], size);
+ new_argv[i] = s;
+ s += size;
+ }
+ new_argv[i] = NULL;
+
+ return new_argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ if (process_title.len == 0)
+ return 0;
+
+ /* No need to terminate, byte after is always '\0'. */
+ strncpy(process_title.str, title, process_title.len);
+ uv__set_process_title(title);
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (process_title.len > 0)
+ strncpy(buffer, process_title.str, size);
+ else if (size > 0)
+ buffer[0] = '\0';
+
+ return 0;
+}
+
+
+UV_DESTRUCTOR(static void free_args_mem(void)) {
+ free(args_mem); /* Keep valgrind happy. */
+ args_mem = NULL;
+}
diff --git a/third-party/libuv/src/unix/pthread-fixes.c b/third-party/libuv/src/unix/pthread-fixes.c
new file mode 100644
index 0000000000..2e4c542bc2
--- /dev/null
+++ b/third-party/libuv/src/unix/pthread-fixes.c
@@ -0,0 +1,80 @@
+/* Copyright (c) 2013, Sony Mobile Communications AB
+ * Copyright (c) 2012, Google Inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * 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.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER 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.
+*/
+
+
+/*Android doesn't provide pthread_barrier_t for now.*/
+#ifndef PTHREAD_BARRIER_SERIAL_THREAD
+
+#include "pthread-fixes.h"
+
+int pthread_barrier_init(pthread_barrier_t* barrier,
+ const void* barrier_attr,
+ unsigned count) {
+ barrier->count = count;
+ pthread_mutex_init(&barrier->mutex, NULL);
+ pthread_cond_init(&barrier->cond, NULL);
+ return 0;
+}
+
+int pthread_barrier_wait(pthread_barrier_t* barrier) {
+ /* Lock the mutex*/
+ pthread_mutex_lock(&barrier->mutex);
+ /* Decrement the count. If this is the first thread to reach 0, wake up
+ waiters, unlock the mutex, then return PTHREAD_BARRIER_SERIAL_THREAD.*/
+ if (--barrier->count == 0) {
+ /* First thread to reach the barrier */
+ pthread_cond_broadcast(&barrier->cond);
+ pthread_mutex_unlock(&barrier->mutex);
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ /* Otherwise, wait for other threads until the count reaches 0, then
+ return 0 to indicate this is not the first thread.*/
+ do {
+ pthread_cond_wait(&barrier->cond, &barrier->mutex);
+ } while (barrier->count > 0);
+
+ pthread_mutex_unlock(&barrier->mutex);
+ return 0;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier) {
+ barrier->count = 0;
+ pthread_cond_destroy(&barrier->cond);
+ pthread_mutex_destroy(&barrier->mutex);
+ return 0;
+}
+
+#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */
+
+int pthread_yield(void) {
+ sched_yield();
+ return 0;
+}
diff --git a/third-party/libuv/src/unix/signal.c b/third-party/libuv/src/unix/signal.c
new file mode 100644
index 0000000000..0b7a405c15
--- /dev/null
+++ b/third-party/libuv/src/unix/signal.c
@@ -0,0 +1,465 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+typedef struct {
+ uv_signal_t* handle;
+ int signum;
+} uv__signal_msg_t;
+
+RB_HEAD(uv__signal_tree_s, uv_signal_s);
+
+
+static int uv__signal_unlock(void);
+static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
+static void uv__signal_stop(uv_signal_t* handle);
+
+
+static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT;
+static struct uv__signal_tree_s uv__signal_tree =
+ RB_INITIALIZER(uv__signal_tree);
+static int uv__signal_lock_pipefd[2];
+
+
+RB_GENERATE_STATIC(uv__signal_tree_s,
+ uv_signal_s, tree_entry,
+ uv__signal_compare)
+
+
+static void uv__signal_global_init(void) {
+ if (uv__make_pipe(uv__signal_lock_pipefd, 0))
+ abort();
+
+ if (uv__signal_unlock())
+ abort();
+}
+
+
+void uv__signal_global_once_init(void) {
+ pthread_once(&uv__signal_global_init_guard, uv__signal_global_init);
+}
+
+
+
+static int uv__signal_lock(void) {
+ int r;
+ char data;
+
+ do {
+ r = read(uv__signal_lock_pipefd[0], &data, sizeof data);
+ } while (r < 0 && errno == EINTR);
+
+ return (r < 0) ? -1 : 0;
+}
+
+
+static int uv__signal_unlock(void) {
+ int r;
+ char data = 42;
+
+ do {
+ r = write(uv__signal_lock_pipefd[1], &data, sizeof data);
+ } while (r < 0 && errno == EINTR);
+
+ return (r < 0) ? -1 : 0;
+}
+
+
+static void uv__signal_block_and_lock(sigset_t* saved_sigmask) {
+ sigset_t new_mask;
+
+ if (sigfillset(&new_mask))
+ abort();
+
+ if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask))
+ abort();
+
+ if (uv__signal_lock())
+ abort();
+}
+
+
+static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) {
+ if (uv__signal_unlock())
+ abort();
+
+ if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL))
+ abort();
+}
+
+
+static uv_signal_t* uv__signal_first_handle(int signum) {
+ /* This function must be called with the signal lock held. */
+ uv_signal_t lookup;
+ uv_signal_t* handle;
+
+ lookup.signum = signum;
+ lookup.loop = NULL;
+
+ handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
+
+ if (handle != NULL && handle->signum == signum)
+ return handle;
+
+ return NULL;
+}
+
+
+static void uv__signal_handler(int signum) {
+ uv__signal_msg_t msg;
+ uv_signal_t* handle;
+ int saved_errno;
+
+ saved_errno = errno;
+ memset(&msg, 0, sizeof msg);
+
+ if (uv__signal_lock()) {
+ errno = saved_errno;
+ return;
+ }
+
+ for (handle = uv__signal_first_handle(signum);
+ handle != NULL && handle->signum == signum;
+ handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
+ int r;
+
+ msg.signum = signum;
+ msg.handle = handle;
+
+ /* write() should be atomic for small data chunks, so the entire message
+ * should be written at once. In theory the pipe could become full, in
+ * which case the user is out of luck.
+ */
+ do {
+ r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
+ } while (r == -1 && errno == EINTR);
+
+ assert(r == sizeof msg ||
+ (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));
+
+ if (r != -1)
+ handle->caught_signals++;
+ }
+
+ uv__signal_unlock();
+ errno = saved_errno;
+}
+
+
+static int uv__signal_register_handler(int signum) {
+ /* When this function is called, the signal lock must be held. */
+ struct sigaction sa;
+
+ /* XXX use a separate signal stack? */
+ memset(&sa, 0, sizeof(sa));
+ if (sigfillset(&sa.sa_mask))
+ abort();
+ sa.sa_handler = uv__signal_handler;
+
+ /* XXX save old action so we can restore it later on? */
+ if (sigaction(signum, &sa, NULL))
+ return -errno;
+
+ return 0;
+}
+
+
+static void uv__signal_unregister_handler(int signum) {
+ /* When this function is called, the signal lock must be held. */
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+
+ /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a
+ * signal implies that it was successfully registered earlier, so EINVAL
+ * should never happen.
+ */
+ if (sigaction(signum, &sa, NULL))
+ abort();
+}
+
+
+static int uv__signal_loop_once_init(uv_loop_t* loop) {
+ int err;
+
+ /* Return if already initialized. */
+ if (loop->signal_pipefd[0] != -1)
+ return 0;
+
+ err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK);
+ if (err)
+ return err;
+
+ uv__io_init(&loop->signal_io_watcher,
+ uv__signal_event,
+ loop->signal_pipefd[0]);
+ uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+void uv__signal_loop_cleanup(uv_loop_t* loop) {
+ QUEUE* q;
+
+ /* Stop all the signal watchers that are still attached to this loop. This
+ * ensures that the (shared) signal tree doesn't contain any invalid entries
+ * entries, and that signal handlers are removed when appropriate.
+ */
+ QUEUE_FOREACH(q, &loop->handle_queue) {
+ uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue);
+
+ if (handle->type == UV_SIGNAL)
+ uv__signal_stop((uv_signal_t*) handle);
+ }
+
+ if (loop->signal_pipefd[0] != -1) {
+ uv__close(loop->signal_pipefd[0]);
+ loop->signal_pipefd[0] = -1;
+ }
+
+ if (loop->signal_pipefd[1] != -1) {
+ uv__close(loop->signal_pipefd[1]);
+ loop->signal_pipefd[1] = -1;
+ }
+}
+
+
+int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
+ int err;
+
+ err = uv__signal_loop_once_init(loop);
+ if (err)
+ return err;
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
+ handle->signum = 0;
+ handle->caught_signals = 0;
+ handle->dispatched_signals = 0;
+
+ return 0;
+}
+
+
+void uv__signal_close(uv_signal_t* handle) {
+
+ uv__signal_stop(handle);
+
+ /* If there are any caught signals "trapped" in the signal pipe, we can't
+ * call the close callback yet. Otherwise, add the handle to the finish_close
+ * queue.
+ */
+ if (handle->caught_signals == handle->dispatched_signals) {
+ uv__make_close_pending((uv_handle_t*) handle);
+ }
+}
+
+
+int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+ sigset_t saved_sigmask;
+ int err;
+
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+
+ /* If the user supplies signum == 0, then return an error already. If the
+ * signum is otherwise invalid then uv__signal_register will find out
+ * eventually.
+ */
+ if (signum == 0)
+ return -EINVAL;
+
+ /* Short circuit: if the signal watcher is already watching {signum} don't
+ * go through the process of deregistering and registering the handler.
+ * Additionally, this avoids pending signals getting lost in the small time
+ * time frame that handle->signum == 0.
+ */
+ if (signum == handle->signum) {
+ handle->signal_cb = signal_cb;
+ return 0;
+ }
+
+ /* If the signal handler was already active, stop it first. */
+ if (handle->signum != 0) {
+ uv__signal_stop(handle);
+ }
+
+ uv__signal_block_and_lock(&saved_sigmask);
+
+ /* If at this point there are no active signal watchers for this signum (in
+ * any of the loops), it's time to try and register a handler for it here.
+ */
+ if (uv__signal_first_handle(signum) == NULL) {
+ err = uv__signal_register_handler(signum);
+ if (err) {
+ /* Registering the signal handler failed. Must be an invalid signal. */
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+ return err;
+ }
+ }
+
+ handle->signum = signum;
+ RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
+
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+
+ handle->signal_cb = signal_cb;
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+static void uv__signal_event(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int events) {
+ uv__signal_msg_t* msg;
+ uv_signal_t* handle;
+ char buf[sizeof(uv__signal_msg_t) * 32];
+ size_t bytes, end, i;
+ int r;
+
+ bytes = 0;
+ end = 0;
+
+ do {
+ r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
+
+ if (r == -1 && errno == EINTR)
+ continue;
+
+ if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ /* If there are bytes in the buffer already (which really is extremely
+ * unlikely if possible at all) we can't exit the function here. We'll
+ * spin until more bytes are read instead.
+ */
+ if (bytes > 0)
+ continue;
+
+ /* Otherwise, there was nothing there. */
+ return;
+ }
+
+ /* Other errors really should never happen. */
+ if (r == -1)
+ abort();
+
+ bytes += r;
+
+ /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */
+ end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t);
+
+ for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) {
+ msg = (uv__signal_msg_t*) (buf + i);
+ handle = msg->handle;
+
+ if (msg->signum == handle->signum) {
+ assert(!(handle->flags & UV_CLOSING));
+ handle->signal_cb(handle, handle->signum);
+ }
+
+ handle->dispatched_signals++;
+
+ /* If uv_close was called while there were caught signals that were not
+ * yet dispatched, the uv__finish_close was deferred. Make close pending
+ * now if this has happened.
+ */
+ if ((handle->flags & UV_CLOSING) &&
+ (handle->caught_signals == handle->dispatched_signals)) {
+ uv__make_close_pending((uv_handle_t*) handle);
+ }
+ }
+
+ bytes -= end;
+
+ /* If there are any "partial" messages left, move them to the start of the
+ * the buffer, and spin. This should not happen.
+ */
+ if (bytes) {
+ memmove(buf, buf + end, bytes);
+ continue;
+ }
+ } while (end == sizeof buf);
+}
+
+
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+ /* Compare signums first so all watchers with the same signnum end up
+ * adjacent.
+ */
+ if (w1->signum < w2->signum) return -1;
+ if (w1->signum > w2->signum) return 1;
+
+ /* Sort by loop pointer, so we can easily look up the first item after
+ * { .signum = x, .loop = NULL }.
+ */
+ if (w1->loop < w2->loop) return -1;
+ if (w1->loop > w2->loop) return 1;
+
+ if (w1 < w2) return -1;
+ if (w1 > w2) return 1;
+
+ return 0;
+}
+
+
+int uv_signal_stop(uv_signal_t* handle) {
+ assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
+ uv__signal_stop(handle);
+ return 0;
+}
+
+
+static void uv__signal_stop(uv_signal_t* handle) {
+ uv_signal_t* removed_handle;
+ sigset_t saved_sigmask;
+
+ /* If the watcher wasn't started, this is a no-op. */
+ if (handle->signum == 0)
+ return;
+
+ uv__signal_block_and_lock(&saved_sigmask);
+
+ removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
+ assert(removed_handle == handle);
+ (void) removed_handle;
+
+ /* Check if there are other active signal watchers observing this signal. If
+ * not, unregister the signal handler.
+ */
+ if (uv__signal_first_handle(handle->signum) == NULL)
+ uv__signal_unregister_handler(handle->signum);
+
+ uv__signal_unlock_and_unblock(&saved_sigmask);
+
+ handle->signum = 0;
+ uv__handle_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/spinlock.h b/third-party/libuv/src/unix/spinlock.h
new file mode 100644
index 0000000000..a20c83cc60
--- /dev/null
+++ b/third-party/libuv/src/unix/spinlock.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef UV_SPINLOCK_H_
+#define UV_SPINLOCK_H_
+
+#include "internal.h" /* ACCESS_ONCE, UV_UNUSED */
+#include "atomic-ops.h"
+
+#define UV_SPINLOCK_INITIALIZER { 0 }
+
+typedef struct {
+ int lock;
+} uv_spinlock_t;
+
+UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock));
+UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock));
+UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock));
+UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock));
+
+UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)) {
+ ACCESS_ONCE(int, spinlock->lock) = 0;
+}
+
+UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)) {
+ while (!uv_spinlock_trylock(spinlock)) cpu_relax();
+}
+
+UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)) {
+ ACCESS_ONCE(int, spinlock->lock) = 0;
+}
+
+UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)) {
+ /* TODO(bnoordhuis) Maybe change to a ticket lock to guarantee fair queueing.
+ * Not really critical until we have locks that are (frequently) contended
+ * for by several threads.
+ */
+ return 0 == cmpxchgi(&spinlock->lock, 0, 1);
+}
+
+#endif /* UV_SPINLOCK_H_ */
diff --git a/third-party/libuv/src/unix/stream.c b/third-party/libuv/src/unix/stream.c
new file mode 100644
index 0000000000..9f5d40cf4b
--- /dev/null
+++ b/third-party/libuv/src/unix/stream.c
@@ -0,0 +1,1511 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <limits.h> /* IOV_MAX */
+
+#if defined(__APPLE__)
+# include <sys/event.h>
+# include <sys/time.h>
+# include <sys/select.h>
+
+/* Forward declaration */
+typedef struct uv__stream_select_s uv__stream_select_t;
+
+struct uv__stream_select_s {
+ uv_stream_t* stream;
+ uv_thread_t thread;
+ uv_sem_t close_sem;
+ uv_sem_t async_sem;
+ uv_async_t async;
+ int events;
+ int fake_fd;
+ int int_fd;
+ int fd;
+};
+#endif /* defined(__APPLE__) */
+
+static void uv__stream_connect(uv_stream_t*);
+static void uv__write(uv_stream_t* stream);
+static void uv__read(uv_stream_t* stream);
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
+static size_t uv__write_req_size(uv_write_t* req);
+
+
+/* Used by the accept() EMFILE party trick. */
+static int uv__open_cloexec(const char* path, int flags) {
+ int err;
+ int fd;
+
+#if defined(__linux__)
+ fd = open(path, flags | UV__O_CLOEXEC);
+ if (fd != -1)
+ return fd;
+
+ if (errno != EINVAL)
+ return -errno;
+
+ /* O_CLOEXEC not supported. */
+#endif
+
+ fd = open(path, flags);
+ if (fd == -1)
+ return -errno;
+
+ err = uv__cloexec(fd, 1);
+ if (err) {
+ uv__close(fd);
+ return err;
+ }
+
+ return fd;
+}
+
+
+static size_t uv_count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
+ unsigned int i;
+ size_t bytes;
+
+ bytes = 0;
+ for (i = 0; i < nbufs; i++)
+ bytes += bufs[i].len;
+
+ return bytes;
+}
+
+
+void uv__stream_init(uv_loop_t* loop,
+ uv_stream_t* stream,
+ uv_handle_type type) {
+ int err;
+
+ uv__handle_init(loop, (uv_handle_t*)stream, type);
+ stream->read_cb = NULL;
+ stream->read2_cb = NULL;
+ stream->alloc_cb = NULL;
+ stream->close_cb = NULL;
+ stream->connection_cb = NULL;
+ stream->connect_req = NULL;
+ stream->shutdown_req = NULL;
+ stream->accepted_fd = -1;
+ stream->delayed_error = 0;
+ QUEUE_INIT(&stream->write_queue);
+ QUEUE_INIT(&stream->write_completed_queue);
+ stream->write_queue_size = 0;
+
+ if (loop->emfile_fd == -1) {
+ err = uv__open_cloexec("/", O_RDONLY);
+ if (err >= 0)
+ loop->emfile_fd = err;
+ }
+
+#if defined(__APPLE__)
+ stream->select = NULL;
+#endif /* defined(__APPLE_) */
+
+ uv__io_init(&stream->io_watcher, uv__stream_io, -1);
+}
+
+
+static void uv__stream_osx_interrupt_select(uv_stream_t* stream) {
+#if defined(__APPLE__)
+ /* Notify select() thread about state change */
+ uv__stream_select_t* s;
+ int r;
+
+ s = stream->select;
+ if (s == NULL)
+ return;
+
+ /* Interrupt select() loop
+ * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will
+ * emit read event on other side
+ */
+ do
+ r = write(s->fake_fd, "x", 1);
+ while (r == -1 && errno == EINTR);
+
+ assert(r == 1);
+#else /* !defined(__APPLE__) */
+ /* No-op on any other platform */
+#endif /* !defined(__APPLE__) */
+}
+
+
+#if defined(__APPLE__)
+static void uv__stream_osx_select(void* arg) {
+ uv_stream_t* stream;
+ uv__stream_select_t* s;
+ char buf[1024];
+ fd_set sread;
+ fd_set swrite;
+ int events;
+ int fd;
+ int r;
+ int max_fd;
+
+ stream = arg;
+ s = stream->select;
+ fd = s->fd;
+
+ if (fd > s->int_fd)
+ max_fd = fd;
+ else
+ max_fd = s->int_fd;
+
+ while (1) {
+ /* Terminate on semaphore */
+ if (uv_sem_trywait(&s->close_sem) == 0)
+ break;
+
+ /* Watch fd using select(2) */
+ FD_ZERO(&sread);
+ FD_ZERO(&swrite);
+
+ if (uv__io_active(&stream->io_watcher, UV__POLLIN))
+ FD_SET(fd, &sread);
+ if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ FD_SET(fd, &swrite);
+ FD_SET(s->int_fd, &sread);
+
+ /* Wait indefinitely for fd events */
+ r = select(max_fd + 1, &sread, &swrite, NULL, NULL);
+ if (r == -1) {
+ if (errno == EINTR)
+ continue;
+
+ /* XXX: Possible?! */
+ abort();
+ }
+
+ /* Ignore timeouts */
+ if (r == 0)
+ continue;
+
+ /* Empty socketpair's buffer in case of interruption */
+ if (FD_ISSET(s->int_fd, &sread))
+ while (1) {
+ r = read(s->int_fd, buf, sizeof(buf));
+
+ if (r == sizeof(buf))
+ continue;
+
+ if (r != -1)
+ break;
+
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ break;
+
+ if (errno == EINTR)
+ continue;
+
+ abort();
+ }
+
+ /* Handle events */
+ events = 0;
+ if (FD_ISSET(fd, &sread))
+ events |= UV__POLLIN;
+ if (FD_ISSET(fd, &swrite))
+ events |= UV__POLLOUT;
+
+ assert(events != 0 || FD_ISSET(s->int_fd, &sread));
+ if (events != 0) {
+ ACCESS_ONCE(int, s->events) = events;
+
+ uv_async_send(&s->async);
+ uv_sem_wait(&s->async_sem);
+
+ /* Should be processed at this stage */
+ assert((s->events == 0) || (stream->flags & UV_CLOSING));
+ }
+ }
+}
+
+
+static void uv__stream_osx_select_cb(uv_async_t* handle, int status) {
+ uv__stream_select_t* s;
+ uv_stream_t* stream;
+ int events;
+
+ s = container_of(handle, uv__stream_select_t, async);
+ stream = s->stream;
+
+ /* Get and reset stream's events */
+ events = s->events;
+ ACCESS_ONCE(int, s->events) = 0;
+ uv_sem_post(&s->async_sem);
+
+ assert(events != 0);
+ assert(events == (events & (UV__POLLIN | UV__POLLOUT)));
+
+ /* Invoke callback on event-loop */
+ if ((events & UV__POLLIN) && uv__io_active(&stream->io_watcher, UV__POLLIN))
+ uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLIN);
+
+ if ((events & UV__POLLOUT) && uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__stream_io(stream->loop, &stream->io_watcher, UV__POLLOUT);
+}
+
+
+static void uv__stream_osx_cb_close(uv_handle_t* async) {
+ uv__stream_select_t* s;
+
+ s = container_of(async, uv__stream_select_t, async);
+ free(s);
+}
+
+
+int uv__stream_try_select(uv_stream_t* stream, int* fd) {
+ /*
+ * kqueue doesn't work with some files from /dev mount on osx.
+ * select(2) in separate thread for those fds
+ */
+
+ struct kevent filter[1];
+ struct kevent events[1];
+ struct timespec timeout;
+ uv__stream_select_t* s;
+ int fds[2];
+ int err;
+ int ret;
+ int kq;
+
+ kq = kqueue();
+ if (kq == -1) {
+ perror("(libuv) kqueue()");
+ return -errno;
+ }
+
+ EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
+
+ /* Use small timeout, because we only want to capture EINVALs */
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 1;
+
+ ret = kevent(kq, filter, 1, events, 1, &timeout);
+ uv__close(kq);
+
+ if (ret == -1)
+ return -errno;
+
+ if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL)
+ return 0;
+
+ /* At this point we definitely know that this fd won't work with kqueue */
+ s = malloc(sizeof(*s));
+ if (s == NULL)
+ return -ENOMEM;
+
+ s->events = 0;
+ s->fd = *fd;
+
+ err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
+ if (err) {
+ free(s);
+ return err;
+ }
+
+ s->async.flags |= UV__HANDLE_INTERNAL;
+ uv__handle_unref(&s->async);
+
+ if (uv_sem_init(&s->close_sem, 0))
+ goto fatal1;
+
+ if (uv_sem_init(&s->async_sem, 0))
+ goto fatal2;
+
+ /* Create fds for io watcher and to interrupt the select() loop. */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+ goto fatal3;
+
+ s->fake_fd = fds[0];
+ s->int_fd = fds[1];
+
+ if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
+ goto fatal4;
+
+ s->stream = stream;
+ stream->select = s;
+ *fd = s->fake_fd;
+
+ return 0;
+
+fatal4:
+ uv__close(s->fake_fd);
+ uv__close(s->int_fd);
+ s->fake_fd = -1;
+ s->int_fd = -1;
+fatal3:
+ uv_sem_destroy(&s->async_sem);
+fatal2:
+ uv_sem_destroy(&s->close_sem);
+fatal1:
+ uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
+ return -errno;
+}
+#endif /* defined(__APPLE__) */
+
+
+int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
+ assert(fd >= 0);
+ stream->flags |= flags;
+
+ if (stream->type == UV_TCP) {
+ if ((stream->flags & UV_TCP_NODELAY) && uv__tcp_nodelay(fd, 1))
+ return -errno;
+
+ /* TODO Use delay the user passed in. */
+ if ((stream->flags & UV_TCP_KEEPALIVE) && uv__tcp_keepalive(fd, 1, 60))
+ return -errno;
+ }
+
+ stream->io_watcher.fd = fd;
+
+ return 0;
+}
+
+
+void uv__stream_destroy(uv_stream_t* stream) {
+ uv_write_t* req;
+ QUEUE* q;
+
+ assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(stream->flags & UV_CLOSED);
+
+ if (stream->connect_req) {
+ uv__req_unregister(stream->loop, stream->connect_req);
+ stream->connect_req->cb(stream->connect_req, -ECANCELED);
+ stream->connect_req = NULL;
+ }
+
+ while (!QUEUE_EMPTY(&stream->write_queue)) {
+ q = QUEUE_HEAD(&stream->write_queue);
+ QUEUE_REMOVE(q);
+
+ req = QUEUE_DATA(q, uv_write_t, queue);
+ uv__req_unregister(stream->loop, req);
+
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+
+ if (req->cb != NULL)
+ req->cb(req, -ECANCELED);
+ }
+
+ while (!QUEUE_EMPTY(&stream->write_completed_queue)) {
+ q = QUEUE_HEAD(&stream->write_completed_queue);
+ QUEUE_REMOVE(q);
+
+ req = QUEUE_DATA(q, uv_write_t, queue);
+ uv__req_unregister(stream->loop, req);
+
+ if (req->bufs != NULL) {
+ stream->write_queue_size -= uv__write_req_size(req);
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+ }
+
+ if (req->cb)
+ req->cb(req, req->error);
+ }
+
+ if (stream->shutdown_req) {
+ /* The ECANCELED error code is a lie, the shutdown(2) syscall is a
+ * fait accompli at this point. Maybe we should revisit this in v0.11.
+ * A possible reason for leaving it unchanged is that it informs the
+ * callee that the handle has been destroyed.
+ */
+ uv__req_unregister(stream->loop, stream->shutdown_req);
+ stream->shutdown_req->cb(stream->shutdown_req, -ECANCELED);
+ stream->shutdown_req = NULL;
+ }
+}
+
+
+/* Implements a best effort approach to mitigating accept() EMFILE errors.
+ * We have a spare file descriptor stashed away that we close to get below
+ * the EMFILE limit. Next, we accept all pending connections and close them
+ * immediately to signal the clients that we're overloaded - and we are, but
+ * we still keep on trucking.
+ *
+ * There is one caveat: it's not reliable in a multi-threaded environment.
+ * The file descriptor limit is per process. Our party trick fails if another
+ * thread opens a file or creates a socket in the time window between us
+ * calling close() and accept().
+ */
+static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
+ int err;
+
+ if (loop->emfile_fd == -1)
+ return -EMFILE;
+
+ uv__close(loop->emfile_fd);
+ loop->emfile_fd = -1;
+
+ do {
+ err = uv__accept(accept_fd);
+ if (err >= 0)
+ uv__close(err);
+ } while (err >= 0 || err == -EINTR);
+
+ SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
+ return err;
+}
+
+
+#if defined(UV_HAVE_KQUEUE)
+# define UV_DEC_BACKLOG(w) w->rcount--;
+#else
+# define UV_DEC_BACKLOG(w) /* no-op */
+#endif /* defined(UV_HAVE_KQUEUE) */
+
+
+void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ uv_stream_t* stream;
+ int err;
+
+ stream = container_of(w, uv_stream_t, io_watcher);
+ assert(events == UV__POLLIN);
+ assert(stream->accepted_fd == -1);
+ assert(!(stream->flags & UV_CLOSING));
+
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+
+ /* connection_cb can close the server socket while we're
+ * in the loop so check it on each iteration.
+ */
+ while (uv__stream_fd(stream) != -1) {
+ assert(stream->accepted_fd == -1);
+
+#if defined(UV_HAVE_KQUEUE)
+ if (w->rcount <= 0)
+ return;
+#endif /* defined(UV_HAVE_KQUEUE) */
+
+ err = uv__accept(uv__stream_fd(stream));
+ if (err < 0) {
+ if (err == -EAGAIN || err == -EWOULDBLOCK)
+ return; /* Not an error. */
+
+ if (err == -ECONNABORTED)
+ continue; /* Ignore. Nothing we can do about that. */
+
+ if (err == -EMFILE || err == -ENFILE) {
+ err = uv__emfile_trick(loop, uv__stream_fd(stream));
+ if (err == -EAGAIN || err == -EWOULDBLOCK)
+ break;
+ }
+
+ stream->connection_cb(stream, err);
+ continue;
+ }
+
+ UV_DEC_BACKLOG(w)
+ stream->accepted_fd = err;
+ stream->connection_cb(stream, 0);
+
+ if (stream->accepted_fd != -1) {
+ /* The user hasn't yet accepted called uv_accept() */
+ uv__io_stop(loop, &stream->io_watcher, UV__POLLIN);
+ return;
+ }
+
+ if (stream->type == UV_TCP && (stream->flags & UV_TCP_SINGLE_ACCEPT)) {
+ /* Give other processes a chance to accept connections. */
+ struct timespec timeout = { 0, 1 };
+ nanosleep(&timeout, NULL);
+ }
+ }
+}
+
+
+#undef UV_DEC_BACKLOG
+
+
+int uv_accept(uv_stream_t* server, uv_stream_t* client) {
+ int err;
+
+ /* TODO document this */
+ assert(server->loop == client->loop);
+
+ if (server->accepted_fd == -1)
+ return -EAGAIN;
+
+ switch (client->type) {
+ case UV_NAMED_PIPE:
+ case UV_TCP:
+ err = uv__stream_open(client,
+ server->accepted_fd,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ if (err) {
+ /* TODO handle error */
+ uv__close(server->accepted_fd);
+ server->accepted_fd = -1;
+ return err;
+ }
+ break;
+
+ case UV_UDP:
+ err = uv_udp_open((uv_udp_t*) client, server->accepted_fd);
+ if (err) {
+ uv__close(server->accepted_fd);
+ server->accepted_fd = -1;
+ return err;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+
+ uv__io_start(server->loop, &server->io_watcher, UV__POLLIN);
+ server->accepted_fd = -1;
+ return 0;
+}
+
+
+int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
+ int err;
+
+ err = -EINVAL;
+ switch (stream->type) {
+ case UV_TCP:
+ err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
+ break;
+
+ case UV_NAMED_PIPE:
+ err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ if (err == 0)
+ uv__handle_start(stream);
+
+ return err;
+}
+
+
+static void uv__drain(uv_stream_t* stream) {
+ uv_shutdown_t* req;
+ int err;
+
+ assert(QUEUE_EMPTY(&stream->write_queue));
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__stream_osx_interrupt_select(stream);
+
+ /* Shutdown? */
+ if ((stream->flags & UV_STREAM_SHUTTING) &&
+ !(stream->flags & UV_CLOSING) &&
+ !(stream->flags & UV_STREAM_SHUT)) {
+ assert(stream->shutdown_req);
+
+ req = stream->shutdown_req;
+ stream->shutdown_req = NULL;
+ stream->flags &= ~UV_STREAM_SHUTTING;
+ uv__req_unregister(stream->loop, req);
+
+ err = 0;
+ if (shutdown(uv__stream_fd(stream), SHUT_WR))
+ err = -errno;
+
+ if (err == 0)
+ stream->flags |= UV_STREAM_SHUT;
+
+ if (req->cb != NULL)
+ req->cb(req, err);
+ }
+}
+
+
+static size_t uv__write_req_size(uv_write_t* req) {
+ size_t size;
+
+ assert(req->bufs != NULL);
+ size = uv_count_bufs(req->bufs + req->write_index,
+ req->nbufs - req->write_index);
+ assert(req->handle->write_queue_size >= size);
+
+ return size;
+}
+
+
+static void uv__write_req_finish(uv_write_t* req) {
+ uv_stream_t* stream = req->handle;
+
+ /* Pop the req off tcp->write_queue. */
+ QUEUE_REMOVE(&req->queue);
+
+ /* Only free when there was no error. On error, we touch up write_queue_size
+ * right before making the callback. The reason we don't do that right away
+ * is that a write_queue_size > 0 is our only way to signal to the user that
+ * they should stop writing - which they should if we got an error. Something
+ * to revisit in future revisions of the libuv API.
+ */
+ if (req->error == 0) {
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+ }
+
+ /* Add it to the write_completed_queue where it will have its
+ * callback called in the near future.
+ */
+ QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
+ uv__io_feed(stream->loop, &stream->io_watcher);
+}
+
+
+static int uv__handle_fd(uv_handle_t* handle) {
+ switch (handle->type) {
+ case UV_NAMED_PIPE:
+ case UV_TCP:
+ return ((uv_stream_t*) handle)->io_watcher.fd;
+
+ case UV_UDP:
+ return ((uv_udp_t*) handle)->io_watcher.fd;
+
+ default:
+ return -1;
+ }
+}
+
+static int uv__getiovmax() {
+#if defined(IOV_MAX)
+ return IOV_MAX;
+#elif defined(_SC_IOV_MAX)
+ static int iovmax = -1;
+ if (iovmax == -1)
+ iovmax = sysconf(_SC_IOV_MAX);
+ return iovmax;
+#else
+ return 1024;
+#endif
+}
+
+static void uv__write(uv_stream_t* stream) {
+ struct iovec* iov;
+ QUEUE* q;
+ uv_write_t* req;
+ int iovmax;
+ int iovcnt;
+ ssize_t n;
+
+start:
+
+ assert(uv__stream_fd(stream) >= 0);
+
+ if (QUEUE_EMPTY(&stream->write_queue))
+ return;
+
+ q = QUEUE_HEAD(&stream->write_queue);
+ req = QUEUE_DATA(q, uv_write_t, queue);
+ assert(req->handle == stream);
+
+ /*
+ * Cast to iovec. We had to have our own uv_buf_t instead of iovec
+ * because Windows's WSABUF is not an iovec.
+ */
+ assert(sizeof(uv_buf_t) == sizeof(struct iovec));
+ iov = (struct iovec*) &(req->bufs[req->write_index]);
+ iovcnt = req->nbufs - req->write_index;
+
+ iovmax = uv__getiovmax();
+
+ /* Limit iov count to avoid EINVALs from writev() */
+ if (iovcnt > iovmax)
+ iovcnt = iovmax;
+
+ /*
+ * Now do the actual writev. Note that we've been updating the pointers
+ * inside the iov each time we write. So there is no need to offset it.
+ */
+
+ if (req->send_handle) {
+ struct msghdr msg;
+ char scratch[64];
+ struct cmsghdr *cmsg;
+ int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
+
+ assert(fd_to_send >= 0);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = iovcnt;
+ msg.msg_flags = 0;
+
+ msg.msg_control = (void*) scratch;
+ msg.msg_controllen = CMSG_LEN(sizeof(fd_to_send));
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = msg.msg_controllen;
+
+ /* silence aliasing warning */
+ {
+ void* pv = CMSG_DATA(cmsg);
+ int* pi = pv;
+ *pi = fd_to_send;
+ }
+
+ do {
+ n = sendmsg(uv__stream_fd(stream), &msg, 0);
+ }
+ while (n == -1 && errno == EINTR);
+ } else {
+ do {
+ if (iovcnt == 1) {
+ n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len);
+ } else {
+ n = writev(uv__stream_fd(stream), iov, iovcnt);
+ }
+ }
+ while (n == -1 && errno == EINTR);
+ }
+
+ if (n < 0) {
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
+ /* Error */
+ req->error = -errno;
+ uv__write_req_finish(req);
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ if (!uv__io_active(&stream->io_watcher, UV__POLLIN))
+ uv__handle_stop(stream);
+ uv__stream_osx_interrupt_select(stream);
+ return;
+ } else if (stream->flags & UV_STREAM_BLOCKING) {
+ /* If this is a blocking stream, try again. */
+ goto start;
+ }
+ } else {
+ /* Successful write */
+
+ while (n >= 0) {
+ uv_buf_t* buf = &(req->bufs[req->write_index]);
+ size_t len = buf->len;
+
+ assert(req->write_index < req->nbufs);
+
+ if ((size_t)n < len) {
+ buf->base += n;
+ buf->len -= n;
+ stream->write_queue_size -= n;
+ n = 0;
+
+ /* There is more to write. */
+ if (stream->flags & UV_STREAM_BLOCKING) {
+ /*
+ * If we're blocking then we should not be enabling the write
+ * watcher - instead we need to try again.
+ */
+ goto start;
+ } else {
+ /* Break loop and ensure the watcher is pending. */
+ break;
+ }
+
+ } else {
+ /* Finished writing the buf at index req->write_index. */
+ req->write_index++;
+
+ assert((size_t)n >= len);
+ n -= len;
+
+ assert(stream->write_queue_size >= len);
+ stream->write_queue_size -= len;
+
+ if (req->write_index == req->nbufs) {
+ /* Then we're done! */
+ assert(n == 0);
+ uv__write_req_finish(req);
+ /* TODO: start trying to write the next request. */
+ return;
+ }
+ }
+ }
+ }
+
+ /* Either we've counted n down to zero or we've got EAGAIN. */
+ assert(n == 0 || n == -1);
+
+ /* Only non-blocking streams should use the write_watcher. */
+ assert(!(stream->flags & UV_STREAM_BLOCKING));
+
+ /* We're not done. */
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+ /* Notify select() thread about state change */
+ uv__stream_osx_interrupt_select(stream);
+}
+
+
+static void uv__write_callbacks(uv_stream_t* stream) {
+ uv_write_t* req;
+ QUEUE* q;
+
+ while (!QUEUE_EMPTY(&stream->write_completed_queue)) {
+ /* Pop a req off write_completed_queue. */
+ q = QUEUE_HEAD(&stream->write_completed_queue);
+ req = QUEUE_DATA(q, uv_write_t, queue);
+ QUEUE_REMOVE(q);
+ uv__req_unregister(stream->loop, req);
+
+ if (req->bufs != NULL) {
+ stream->write_queue_size -= uv__write_req_size(req);
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+ }
+
+ /* NOTE: call callback AFTER freeing the request data. */
+ if (req->cb)
+ req->cb(req, req->error);
+ }
+
+ assert(QUEUE_EMPTY(&stream->write_completed_queue));
+
+ /* Write queue drained. */
+ if (QUEUE_EMPTY(&stream->write_queue))
+ uv__drain(stream);
+}
+
+
+static uv_handle_type uv__handle_type(int fd) {
+ struct sockaddr_storage ss;
+ socklen_t len;
+ int type;
+
+ memset(&ss, 0, sizeof(ss));
+ len = sizeof(ss);
+
+ if (getsockname(fd, (struct sockaddr*)&ss, &len))
+ return UV_UNKNOWN_HANDLE;
+
+ len = sizeof type;
+
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len))
+ return UV_UNKNOWN_HANDLE;
+
+ if (type == SOCK_STREAM) {
+ switch (ss.ss_family) {
+ case AF_UNIX:
+ return UV_NAMED_PIPE;
+ case AF_INET:
+ case AF_INET6:
+ return UV_TCP;
+ }
+ }
+
+ if (type == SOCK_DGRAM &&
+ (ss.ss_family == AF_INET || ss.ss_family == AF_INET6))
+ return UV_UDP;
+
+ return UV_UNKNOWN_HANDLE;
+}
+
+
+static void uv__stream_read_cb(uv_stream_t* stream,
+ int status,
+ const uv_buf_t* buf,
+ uv_handle_type type) {
+ if (stream->read_cb != NULL)
+ stream->read_cb(stream, status, buf);
+ else
+ stream->read2_cb((uv_pipe_t*) stream, status, buf, type);
+}
+
+
+static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
+ stream->flags |= UV_STREAM_READ_EOF;
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
+ if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__handle_stop(stream);
+ uv__stream_osx_interrupt_select(stream);
+ uv__stream_read_cb(stream, UV_EOF, buf, UV_UNKNOWN_HANDLE);
+}
+
+
+static void uv__read(uv_stream_t* stream) {
+ uv_buf_t buf;
+ ssize_t nread;
+ struct msghdr msg;
+ struct cmsghdr* cmsg;
+ char cmsg_space[64];
+ int count;
+
+ stream->flags &= ~UV_STREAM_READ_PARTIAL;
+
+ /* Prevent loop starvation when the data comes in as fast as (or faster than)
+ * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
+ */
+ count = 32;
+
+ /* XXX: Maybe instead of having UV_STREAM_READING we just test if
+ * tcp->read_cb is NULL or not?
+ */
+ while ((stream->read_cb || stream->read2_cb)
+ && (stream->flags & UV_STREAM_READING)
+ && (count-- > 0)) {
+ assert(stream->alloc_cb != NULL);
+
+ stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf);
+ if (buf.len == 0) {
+ /* User indicates it can't or won't handle the read. */
+ uv__stream_read_cb(stream, UV_ENOBUFS, &buf, UV_UNKNOWN_HANDLE);
+ return;
+ }
+
+ assert(buf.base != NULL);
+ assert(uv__stream_fd(stream) >= 0);
+
+ if (stream->read_cb) {
+ do {
+ nread = read(uv__stream_fd(stream), buf.base, buf.len);
+ }
+ while (nread < 0 && errno == EINTR);
+ } else {
+ assert(stream->read2_cb);
+ /* read2_cb uses recvmsg */
+ msg.msg_flags = 0;
+ msg.msg_iov = (struct iovec*) &buf;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ /* Set up to receive a descriptor even if one isn't in the message */
+ msg.msg_controllen = 64;
+ msg.msg_control = (void*) cmsg_space;
+
+ do {
+ nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0);
+ }
+ while (nread < 0 && errno == EINTR);
+ }
+
+ if (nread < 0) {
+ /* Error */
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ /* Wait for the next one. */
+ if (stream->flags & UV_STREAM_READING) {
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+ uv__stream_osx_interrupt_select(stream);
+ }
+ uv__stream_read_cb(stream, 0, &buf, UV_UNKNOWN_HANDLE);
+ } else {
+ /* Error. User should call uv_close(). */
+ uv__stream_read_cb(stream, -errno, &buf, UV_UNKNOWN_HANDLE);
+ assert(!uv__io_active(&stream->io_watcher, UV__POLLIN) &&
+ "stream->read_cb(status=-1) did not call uv_close()");
+ }
+ return;
+ } else if (nread == 0) {
+ uv__stream_eof(stream, &buf);
+ return;
+ } else {
+ /* Successful read */
+ ssize_t buflen = buf.len;
+
+ if (stream->read_cb) {
+ stream->read_cb(stream, nread, &buf);
+ } else {
+ assert(stream->read2_cb);
+
+ /*
+ * XXX: Some implementations can send multiple file descriptors in a
+ * single message. We should be using CMSG_NXTHDR() to walk the
+ * chain to get at them all. This would require changing the API to
+ * hand these back up the caller, is a pain.
+ */
+
+ for (cmsg = CMSG_FIRSTHDR(&msg);
+ msg.msg_controllen > 0 && cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+
+ if (cmsg->cmsg_type == SCM_RIGHTS) {
+ if (stream->accepted_fd != -1) {
+ fprintf(stderr, "(libuv) ignoring extra FD received\n");
+ }
+
+ /* silence aliasing warning */
+ {
+ void* pv = CMSG_DATA(cmsg);
+ int* pi = pv;
+ stream->accepted_fd = *pi;
+ }
+
+ } else {
+ fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n",
+ cmsg->cmsg_type);
+ }
+ }
+
+
+ if (stream->accepted_fd >= 0) {
+ stream->read2_cb((uv_pipe_t*) stream,
+ nread,
+ &buf,
+ uv__handle_type(stream->accepted_fd));
+ } else {
+ stream->read2_cb((uv_pipe_t*) stream, nread, &buf, UV_UNKNOWN_HANDLE);
+ }
+ }
+
+ /* Return if we didn't fill the buffer, there is no more data to read. */
+ if (nread < buflen) {
+ stream->flags |= UV_STREAM_READ_PARTIAL;
+ return;
+ }
+ }
+ }
+}
+
+
+int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
+ assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) &&
+ "uv_shutdown (unix) only supports uv_handle_t right now");
+
+ if (!(stream->flags & UV_STREAM_WRITABLE) ||
+ stream->flags & UV_STREAM_SHUT ||
+ stream->flags & UV_CLOSED ||
+ stream->flags & UV_CLOSING) {
+ return -ENOTCONN;
+ }
+
+ assert(uv__stream_fd(stream) >= 0);
+
+ /* Initialize request */
+ uv__req_init(stream->loop, req, UV_SHUTDOWN);
+ req->handle = stream;
+ req->cb = cb;
+ stream->shutdown_req = req;
+ stream->flags |= UV_STREAM_SHUTTING;
+
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__stream_osx_interrupt_select(stream);
+
+ return 0;
+}
+
+
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+ uv_stream_t* stream;
+
+ stream = container_of(w, uv_stream_t, io_watcher);
+
+ assert(stream->type == UV_TCP ||
+ stream->type == UV_NAMED_PIPE ||
+ stream->type == UV_TTY);
+ assert(!(stream->flags & UV_CLOSING));
+
+ if (stream->connect_req) {
+ uv__stream_connect(stream);
+ return;
+ }
+
+ assert(uv__stream_fd(stream) >= 0);
+
+ /* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
+ if (events & (UV__POLLIN | UV__POLLERR))
+ uv__read(stream);
+
+ if (uv__stream_fd(stream) == -1)
+ return; /* read_cb closed stream. */
+
+ /* Short-circuit iff POLLHUP is set, the user is still interested in read
+ * events and uv__read() reported a partial read but not EOF. If the EOF
+ * flag is set, uv__read() called read_cb with err=UV_EOF and we don't
+ * have to do anything. If the partial read flag is not set, we can't
+ * report the EOF yet because there is still data to read.
+ */
+ if ((events & UV__POLLHUP) &&
+ (stream->flags & UV_STREAM_READING) &&
+ (stream->flags & UV_STREAM_READ_PARTIAL) &&
+ !(stream->flags & UV_STREAM_READ_EOF)) {
+ uv_buf_t buf = { NULL, 0 };
+ uv__stream_eof(stream, &buf);
+ }
+
+ if (uv__stream_fd(stream) == -1)
+ return; /* read_cb closed stream. */
+
+ if (events & (UV__POLLOUT | UV__POLLERR | UV__POLLHUP)) {
+ uv__write(stream);
+ uv__write_callbacks(stream);
+ }
+}
+
+
+/**
+ * We get called here from directly following a call to connect(2).
+ * In order to determine if we've errored out or succeeded must call
+ * getsockopt.
+ */
+static void uv__stream_connect(uv_stream_t* stream) {
+ int error;
+ uv_connect_t* req = stream->connect_req;
+ socklen_t errorsize = sizeof(int);
+
+ assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);
+ assert(req);
+
+ if (stream->delayed_error) {
+ /* To smooth over the differences between unixes errors that
+ * were reported synchronously on the first connect can be delayed
+ * until the next tick--which is now.
+ */
+ error = stream->delayed_error;
+ stream->delayed_error = 0;
+ } else {
+ /* Normal situation: we need to get the socket error from the kernel. */
+ assert(uv__stream_fd(stream) >= 0);
+ getsockopt(uv__stream_fd(stream),
+ SOL_SOCKET,
+ SO_ERROR,
+ &error,
+ &errorsize);
+ error = -error;
+ }
+
+ if (error == -EINPROGRESS)
+ return;
+
+ stream->connect_req = NULL;
+ uv__req_unregister(stream->loop, req);
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+ if (req->cb)
+ req->cb(req, error);
+}
+
+
+int uv_write2(uv_write_t* req,
+ uv_stream_t* stream,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
+ int empty_queue;
+
+ assert(nbufs > 0);
+ assert((stream->type == UV_TCP ||
+ stream->type == UV_NAMED_PIPE ||
+ stream->type == UV_TTY) &&
+ "uv_write (unix) does not yet support other types of streams");
+
+ if (uv__stream_fd(stream) < 0)
+ return -EBADF;
+
+ if (send_handle) {
+ if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
+ return -EINVAL;
+
+ /* XXX We abuse uv_write2() to send over UDP handles to child processes.
+ * Don't call uv__stream_fd() on those handles, it's a macro that on OS X
+ * evaluates to a function that operates on a uv_stream_t with a couple of
+ * OS X specific fields. On other Unices it does (handle)->io_watcher.fd,
+ * which works but only by accident.
+ */
+ if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
+ return -EBADF;
+ }
+
+ /* It's legal for write_queue_size > 0 even when the write_queue is empty;
+ * it means there are error-state requests in the write_completed_queue that
+ * will touch up write_queue_size later, see also uv__write_req_finish().
+ * We chould check that write_queue is empty instead but that implies making
+ * a write() syscall when we know that the handle is in error mode.
+ */
+ empty_queue = (stream->write_queue_size == 0);
+
+ /* Initialize the req */
+ uv__req_init(stream->loop, req, UV_WRITE);
+ req->cb = cb;
+ req->handle = stream;
+ req->error = 0;
+ req->send_handle = send_handle;
+ QUEUE_INIT(&req->queue);
+
+ req->bufs = req->bufsml;
+ if (nbufs > ARRAY_SIZE(req->bufsml))
+ req->bufs = malloc(nbufs * sizeof(bufs[0]));
+
+ if (req->bufs == NULL)
+ return -ENOMEM;
+
+ memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
+ req->nbufs = nbufs;
+ req->write_index = 0;
+ stream->write_queue_size += uv_count_bufs(bufs, nbufs);
+
+ /* Append the request to write_queue. */
+ QUEUE_INSERT_TAIL(&stream->write_queue, &req->queue);
+
+ /* If the queue was empty when this function began, we should attempt to
+ * do the write immediately. Otherwise start the write_watcher and wait
+ * for the fd to become writable.
+ */
+ if (stream->connect_req) {
+ /* Still connecting, do nothing. */
+ }
+ else if (empty_queue) {
+ uv__write(stream);
+ }
+ else {
+ /*
+ * blocking streams should never have anything in the queue.
+ * if this assert fires then somehow the blocking stream isn't being
+ * sufficiently flushed in uv__write.
+ */
+ assert(!(stream->flags & UV_STREAM_BLOCKING));
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__stream_osx_interrupt_select(stream);
+ }
+
+ return 0;
+}
+
+
+/* The buffers to be written must remain valid until the callback is called.
+ * This is not required for the uv_buf_t array.
+ */
+int uv_write(uv_write_t* req,
+ uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb) {
+ return uv_write2(req, handle, bufs, nbufs, NULL, cb);
+}
+
+
+void uv_try_write_cb(uv_write_t* req, int status) {
+ /* Should not be called */
+ abort();
+}
+
+
+int uv_try_write(uv_stream_t* stream,
+ const uv_buf_t bufs[],
+ unsigned int nbufs) {
+ int r;
+ int has_pollout;
+ size_t written;
+ size_t req_size;
+ uv_write_t req;
+
+ /* Connecting or already writing some data */
+ if (stream->connect_req != NULL || stream->write_queue_size != 0)
+ return 0;
+
+ has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT);
+
+ r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb);
+ if (r != 0)
+ return r;
+
+ /* Remove not written bytes from write queue size */
+ written = uv_count_bufs(bufs, nbufs);
+ if (req.bufs != NULL)
+ req_size = uv__write_req_size(&req);
+ else
+ req_size = 0;
+ written -= req_size;
+ stream->write_queue_size -= req_size;
+
+ /* Unqueue request, regardless of immediateness */
+ QUEUE_REMOVE(&req.queue);
+ uv__req_unregister(stream->loop, &req);
+ if (req.bufs != req.bufsml)
+ free(req.bufs);
+ req.bufs = NULL;
+
+ /* Do not poll for writable, if we wasn't before calling this */
+ if (!has_pollout) {
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ uv__stream_osx_interrupt_select(stream);
+ }
+
+ return (int) written;
+}
+
+
+static int uv__read_start_common(uv_stream_t* stream,
+ uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb,
+ uv_read2_cb read2_cb) {
+ assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
+ stream->type == UV_TTY);
+
+ if (stream->flags & UV_CLOSING)
+ return -EINVAL;
+
+ /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
+ * expresses the desired state of the user.
+ */
+ stream->flags |= UV_STREAM_READING;
+
+ /* TODO: try to do the read inline? */
+ /* TODO: keep track of tcp state. If we've gotten a EOF then we should
+ * not start the IO watcher.
+ */
+ assert(uv__stream_fd(stream) >= 0);
+ assert(alloc_cb);
+
+ stream->read_cb = read_cb;
+ stream->read2_cb = read2_cb;
+ stream->alloc_cb = alloc_cb;
+
+ uv__io_start(stream->loop, &stream->io_watcher, UV__POLLIN);
+ uv__handle_start(stream);
+ uv__stream_osx_interrupt_select(stream);
+
+ return 0;
+}
+
+
+int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
+ return uv__read_start_common(stream, alloc_cb, read_cb, NULL);
+}
+
+
+int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
+ uv_read2_cb read_cb) {
+ return uv__read_start_common(stream, alloc_cb, NULL, read_cb);
+}
+
+
+int uv_read_stop(uv_stream_t* stream) {
+ /* Sanity check. We're going to stop the handle unless it's primed for
+ * writing but that means there should be some kind of write action in
+ * progress.
+ */
+ assert(!uv__io_active(&stream->io_watcher, UV__POLLOUT) ||
+ !QUEUE_EMPTY(&stream->write_completed_queue) ||
+ !QUEUE_EMPTY(&stream->write_queue) ||
+ stream->shutdown_req != NULL ||
+ stream->connect_req != NULL);
+
+ stream->flags &= ~UV_STREAM_READING;
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLIN);
+ if (!uv__io_active(&stream->io_watcher, UV__POLLOUT))
+ uv__handle_stop(stream);
+ uv__stream_osx_interrupt_select(stream);
+
+ stream->read_cb = NULL;
+ stream->read2_cb = NULL;
+ stream->alloc_cb = NULL;
+ return 0;
+}
+
+
+int uv_is_readable(const uv_stream_t* stream) {
+ return !!(stream->flags & UV_STREAM_READABLE);
+}
+
+
+int uv_is_writable(const uv_stream_t* stream) {
+ return !!(stream->flags & UV_STREAM_WRITABLE);
+}
+
+
+#if defined(__APPLE__)
+int uv___stream_fd(uv_stream_t* handle) {
+ uv__stream_select_t* s;
+
+ assert(handle->type == UV_TCP ||
+ handle->type == UV_TTY ||
+ handle->type == UV_NAMED_PIPE);
+
+ s = handle->select;
+ if (s != NULL)
+ return s->fd;
+
+ return handle->io_watcher.fd;
+}
+#endif /* defined(__APPLE__) */
+
+
+void uv__stream_close(uv_stream_t* handle) {
+#if defined(__APPLE__)
+ /* Terminate select loop first */
+ if (handle->select != NULL) {
+ uv__stream_select_t* s;
+
+ s = handle->select;
+
+ uv_sem_post(&s->close_sem);
+ uv_sem_post(&s->async_sem);
+ uv__stream_osx_interrupt_select(handle);
+ uv_thread_join(&s->thread);
+ uv_sem_destroy(&s->close_sem);
+ uv_sem_destroy(&s->async_sem);
+ uv__close(s->fake_fd);
+ uv__close(s->int_fd);
+ uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
+
+ handle->select = NULL;
+ }
+#endif /* defined(__APPLE__) */
+
+ uv__io_close(handle->loop, &handle->io_watcher);
+ uv_read_stop(handle);
+ uv__handle_stop(handle);
+
+ if (handle->io_watcher.fd != -1) {
+ /* Don't close stdio file descriptors. Nothing good comes from it. */
+ if (handle->io_watcher.fd > STDERR_FILENO)
+ uv__close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
+ }
+
+ if (handle->accepted_fd != -1) {
+ uv__close(handle->accepted_fd);
+ handle->accepted_fd = -1;
+ }
+
+ assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
+}
+
+
+int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
+ assert(0 && "implement me");
+ abort();
+ return 0;
+}
diff --git a/third-party/libuv/src/unix/sunos.c b/third-party/libuv/src/unix/sunos.c
new file mode 100644
index 0000000000..f31a23fb3c
--- /dev/null
+++ b/third-party/libuv/src/unix/sunos.c
@@ -0,0 +1,734 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#ifndef SUNOS_NO_IFADDRS
+# include <ifaddrs.h>
+#endif
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include <sys/loadavg.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <kstat.h>
+#include <fcntl.h>
+
+#include <sys/port.h>
+#include <port.h>
+
+#define PORT_FIRED 0x69
+#define PORT_UNUSED 0x0
+#define PORT_LOADED 0x99
+#define PORT_DELETED -1
+
+#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
+#define PROCFS_FILE_OFFSET_BITS_HACK 1
+#undef _FILE_OFFSET_BITS
+#else
+#define PROCFS_FILE_OFFSET_BITS_HACK 0
+#endif
+
+#include <procfs.h>
+
+#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1)
+#define _FILE_OFFSET_BITS 64
+#endif
+
+
+int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
+ int err;
+ int fd;
+
+ loop->fs_fd = -1;
+ loop->backend_fd = -1;
+
+ fd = port_create();
+ if (fd == -1)
+ return -errno;
+
+ err = uv__cloexec(fd, 1);
+ if (err) {
+ uv__close(fd);
+ return err;
+ }
+ loop->backend_fd = fd;
+
+ return 0;
+}
+
+
+void uv__platform_loop_delete(uv_loop_t* loop) {
+ if (loop->fs_fd != -1) {
+ uv__close(loop->fs_fd);
+ loop->fs_fd = -1;
+ }
+
+ if (loop->backend_fd != -1) {
+ uv__close(loop->backend_fd);
+ loop->backend_fd = -1;
+ }
+}
+
+
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
+ struct port_event* events;
+ uintptr_t i;
+ uintptr_t nfds;
+
+ assert(loop->watchers != NULL);
+
+ events = (struct port_event*) loop->watchers[loop->nwatchers];
+ nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
+ if (events == NULL)
+ return;
+
+ /* Invalidate events with same file descriptor */
+ for (i = 0; i < nfds; i++)
+ if ((int) events[i].portev_object == fd)
+ events[i].portev_object = -1;
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ struct port_event events[1024];
+ struct port_event* pe;
+ struct timespec spec;
+ QUEUE* q;
+ uv__io_t* w;
+ uint64_t base;
+ uint64_t diff;
+ unsigned int nfds;
+ unsigned int i;
+ int saved_errno;
+ int nevents;
+ int count;
+ int fd;
+
+ if (loop->nfds == 0) {
+ assert(QUEUE_EMPTY(&loop->watcher_queue));
+ return;
+ }
+
+ while (!QUEUE_EMPTY(&loop->watcher_queue)) {
+ q = QUEUE_HEAD(&loop->watcher_queue);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+
+ if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0))
+ abort();
+
+ w->events = w->pevents;
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+
+ for (;;) {
+ if (timeout != -1) {
+ spec.tv_sec = timeout / 1000;
+ spec.tv_nsec = (timeout % 1000) * 1000000;
+ }
+
+ /* Work around a kernel bug where nfds is not updated. */
+ events[0].portev_source = 0;
+
+ nfds = 1;
+ saved_errno = 0;
+ if (port_getn(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ &nfds,
+ timeout == -1 ? NULL : &spec)) {
+ /* Work around another kernel bug: port_getn() may return events even
+ * on error.
+ */
+ if (errno == EINTR || errno == ETIME)
+ saved_errno = errno;
+ else
+ abort();
+ }
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (events[0].portev_source == 0) {
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+ goto update_timeout;
+ }
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+ return;
+ }
+
+ nevents = 0;
+
+ assert(loop->watchers != NULL);
+ loop->watchers[loop->nwatchers] = (void*) events;
+ loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+ for (i = 0; i < nfds; i++) {
+ pe = events + i;
+ fd = pe->portev_object;
+
+ /* Skip invalidated events, see uv__platform_invalidate_fd */
+ if (fd == -1)
+ continue;
+
+ assert(fd >= 0);
+ assert((unsigned) fd < loop->nwatchers);
+
+ w = loop->watchers[fd];
+
+ /* File descriptor that we've stopped watching, ignore. */
+ if (w == NULL)
+ continue;
+
+ w->cb(loop, w, pe->portev_events);
+ nevents++;
+
+ if (w != loop->watchers[fd])
+ continue; /* Disabled by callback. */
+
+ /* Events Ports operates in oneshot mode, rearm timer on next run. */
+ if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
+ QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
+ }
+ loop->watchers[loop->nwatchers] = NULL;
+ loop->watchers[loop->nwatchers + 1] = NULL;
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (saved_errno == ETIME) {
+ assert(timeout != -1);
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ diff = loop->time - base;
+ if (diff >= (uint64_t) timeout)
+ return;
+
+ timeout -= diff;
+ }
+}
+
+
+uint64_t uv__hrtime(uv_clocktype_t type) {
+ return gethrtime();
+}
+
+
+/*
+ * We could use a static buffer for the path manipulations that we need outside
+ * of the function, but this function could be called by multiple consumers and
+ * we don't want to potentially create a race condition in the use of snprintf.
+ */
+int uv_exepath(char* buffer, size_t* size) {
+ ssize_t res;
+ char buf[128];
+
+ if (buffer == NULL || size == NULL)
+ return -EINVAL;
+
+ snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
+ res = readlink(buf, buffer, *size - 1);
+ if (res == -1)
+ return -errno;
+
+ buffer[res] = '\0';
+ *size = res;
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
+}
+
+
+void uv_loadavg(double avg[3]) {
+ (void) getloadavg(avg, 3);
+}
+
+
+#if defined(PORT_SOURCE_FILE)
+
+static int uv__fs_event_rearm(uv_fs_event_t *handle) {
+ if (handle->fd == -1)
+ return -EBADF;
+
+ if (port_associate(handle->loop->fs_fd,
+ PORT_SOURCE_FILE,
+ (uintptr_t) &handle->fo,
+ FILE_ATTRIB | FILE_MODIFIED,
+ handle) == -1) {
+ return -errno;
+ }
+ handle->fd = PORT_LOADED;
+
+ return 0;
+}
+
+
+static void uv__fs_event_read(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
+ uv_fs_event_t *handle = NULL;
+ timespec_t timeout;
+ port_event_t pe;
+ int events;
+ int r;
+
+ (void) w;
+ (void) revents;
+
+ do {
+ uint_t n = 1;
+
+ /*
+ * Note that our use of port_getn() here (and not port_get()) is deliberate:
+ * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout
+ * causes port_get() to return success instead of ETIME when there aren't
+ * actually any events (!); by using port_getn() in lieu of port_get(),
+ * we can at least workaround the bug by checking for zero returned events
+ * and treating it as we would ETIME.
+ */
+ do {
+ memset(&timeout, 0, sizeof timeout);
+ r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout);
+ }
+ while (r == -1 && errno == EINTR);
+
+ if ((r == -1 && errno == ETIME) || n == 0)
+ break;
+
+ handle = (uv_fs_event_t*) pe.portev_user;
+ assert((r == 0) && "unexpected port_get() error");
+
+ events = 0;
+ if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED))
+ events |= UV_CHANGE;
+ if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED))
+ events |= UV_RENAME;
+ assert(events != 0);
+ handle->fd = PORT_FIRED;
+ handle->cb(handle, NULL, events, 0);
+ }
+ while (handle->fd != PORT_DELETED);
+
+ if (handle != NULL && handle->fd != PORT_DELETED)
+ uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+ return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags) {
+ int portfd;
+ int first_run;
+
+ if (uv__is_active(handle))
+ return -EINVAL;
+
+ first_run = 0;
+ if (handle->loop->fs_fd == -1) {
+ portfd = port_create();
+ if (portfd == -1)
+ return -errno;
+ handle->loop->fs_fd = portfd;
+ first_run = 1;
+ }
+
+ uv__handle_start(handle);
+ handle->filename = strdup(filename);
+ handle->fd = PORT_UNUSED;
+ handle->cb = cb;
+
+ memset(&handle->fo, 0, sizeof handle->fo);
+ handle->fo.fo_name = handle->filename;
+ uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */
+
+ if (first_run) {
+ uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
+ uv__io_start(handle->loop, &handle->loop->fs_event_watcher, UV__POLLIN);
+ }
+
+ return 0;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ if (!uv__is_active(handle))
+ return -EINVAL;
+
+ if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) {
+ port_dissociate(handle->loop->fs_fd,
+ PORT_SOURCE_FILE,
+ (uintptr_t) &handle->fo);
+ }
+
+ handle->fd = PORT_DELETED;
+ free(handle->filename);
+ handle->filename = NULL;
+ handle->fo.fo_name = NULL;
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ uv_fs_event_stop(handle);
+}
+
+#else /* !defined(PORT_SOURCE_FILE) */
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ return -ENOSYS;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags) {
+ return -ENOSYS;
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ return -ENOSYS;
+}
+
+
+void uv__fs_event_close(uv_fs_event_t* handle) {
+ UNREACHABLE();
+}
+
+#endif /* defined(PORT_SOURCE_FILE) */
+
+
+char** uv_setup_args(int argc, char** argv) {
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ if (size > 0) {
+ buffer[0] = '\0';
+ }
+ return 0;
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ psinfo_t psinfo;
+ int err;
+ int fd;
+
+ fd = open("/proc/self/psinfo", O_RDONLY);
+ if (fd == -1)
+ return -errno;
+
+ /* FIXME(bnoordhuis) Handle EINTR. */
+ err = -EINVAL;
+ if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
+ *rss = (size_t)psinfo.pr_rssize * 1024;
+ err = 0;
+ }
+ uv__close(fd);
+
+ return err;
+}
+
+
+int uv_uptime(double* uptime) {
+ kstat_ctl_t *kc;
+ kstat_t *ksp;
+ kstat_named_t *knp;
+
+ long hz = sysconf(_SC_CLK_TCK);
+
+ kc = kstat_open();
+ if (kc == NULL)
+ return -EPERM;
+
+ ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc");
+ if (kstat_read(kc, ksp, NULL) == -1) {
+ *uptime = -1;
+ } else {
+ knp = (kstat_named_t*) kstat_data_lookup(ksp, (char*) "clk_intr");
+ *uptime = knp->value.ul / hz;
+ }
+ kstat_close(kc);
+
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ int lookup_instance;
+ kstat_ctl_t *kc;
+ kstat_t *ksp;
+ kstat_named_t *knp;
+ uv_cpu_info_t* cpu_info;
+
+ kc = kstat_open();
+ if (kc == NULL)
+ return -EPERM;
+
+ /* Get count of cpus */
+ lookup_instance = 0;
+ while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
+ lookup_instance++;
+ }
+
+ *cpu_infos = malloc(lookup_instance * sizeof(**cpu_infos));
+ if (!(*cpu_infos)) {
+ kstat_close(kc);
+ return -ENOMEM;
+ }
+
+ *count = lookup_instance;
+
+ cpu_info = *cpu_infos;
+ lookup_instance = 0;
+ while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
+ if (kstat_read(kc, ksp, NULL) == -1) {
+ cpu_info->speed = 0;
+ cpu_info->model = NULL;
+ } else {
+ knp = kstat_data_lookup(ksp, (char*) "clock_MHz");
+ assert(knp->data_type == KSTAT_DATA_INT32 ||
+ knp->data_type == KSTAT_DATA_INT64);
+ cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32
+ : knp->value.i64;
+
+ knp = kstat_data_lookup(ksp, (char*) "brand");
+ assert(knp->data_type == KSTAT_DATA_STRING);
+ cpu_info->model = strdup(KSTAT_NAMED_STR_PTR(knp));
+ }
+
+ lookup_instance++;
+ cpu_info++;
+ }
+
+ cpu_info = *cpu_infos;
+ lookup_instance = 0;
+ for (;;) {
+ ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys");
+
+ if (ksp == NULL)
+ break;
+
+ if (kstat_read(kc, ksp, NULL) == -1) {
+ cpu_info->cpu_times.user = 0;
+ cpu_info->cpu_times.nice = 0;
+ cpu_info->cpu_times.sys = 0;
+ cpu_info->cpu_times.idle = 0;
+ cpu_info->cpu_times.irq = 0;
+ } else {
+ knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user");
+ assert(knp->data_type == KSTAT_DATA_UINT64);
+ cpu_info->cpu_times.user = knp->value.ui64;
+
+ knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel");
+ assert(knp->data_type == KSTAT_DATA_UINT64);
+ cpu_info->cpu_times.sys = knp->value.ui64;
+
+ knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle");
+ assert(knp->data_type == KSTAT_DATA_UINT64);
+ cpu_info->cpu_times.idle = knp->value.ui64;
+
+ knp = kstat_data_lookup(ksp, (char*) "intr");
+ assert(knp->data_type == KSTAT_DATA_UINT64);
+ cpu_info->cpu_times.irq = knp->value.ui64;
+ cpu_info->cpu_times.nice = 0;
+ }
+
+ lookup_instance++;
+ cpu_info++;
+ }
+
+ kstat_close(kc);
+
+ return 0;
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+#ifdef SUNOS_NO_IFADDRS
+ return -ENOSYS;
+#else
+ uv_interface_address_t* address;
+ struct sockaddr_dl* sa_addr;
+ struct ifaddrs* addrs;
+ struct ifaddrs* ent;
+ int i;
+
+ if (getifaddrs(&addrs))
+ return -errno;
+
+ *count = 0;
+
+ /* Count the number of interfaces */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family == PF_PACKET)) {
+ continue;
+ }
+
+ (*count)++;
+ }
+
+ *addresses = malloc(*count * sizeof(**addresses));
+ if (!(*addresses))
+ return -ENOMEM;
+
+ address = *addresses;
+
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+ continue;
+
+ if (ent->ifa_addr == NULL)
+ continue;
+
+ address->name = strdup(ent->ifa_name);
+
+ if (ent->ifa_addr->sa_family == AF_INET6) {
+ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+ } else {
+ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+ }
+
+ if (ent->ifa_netmask->sa_family == AF_INET6) {
+ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+ } else {
+ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+ }
+
+ address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) ||
+ (ent->ifa_flags & IFF_LOOPBACK));
+
+ address++;
+ }
+
+ /* Fill in physical addresses for each interface */
+ for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
+ (ent->ifa_addr == NULL) ||
+ (ent->ifa_addr->sa_family != AF_LINK)) {
+ continue;
+ }
+
+ address = *addresses;
+
+ for (i = 0; i < (*count); i++) {
+ if (strcmp(address->name, ent->ifa_name) == 0) {
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return 0;
+#endif /* SUNOS_NO_IFADDRS */
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(addresses[i].name);
+ }
+
+ free(addresses);
+}
diff --git a/third-party/libuv/src/unix/tcp.c b/third-party/libuv/src/unix/tcp.c
new file mode 100644
index 0000000000..2c36dc3ffc
--- /dev/null
+++ b/third-party/libuv/src/unix/tcp.c
@@ -0,0 +1,312 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+
+
+int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
+ uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
+ return 0;
+}
+
+
+static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) {
+ int sockfd;
+ int err;
+
+ if (uv__stream_fd(handle) != -1)
+ return 0;
+
+ err = uv__socket(domain, SOCK_STREAM, 0);
+ if (err < 0)
+ return err;
+ sockfd = err;
+
+ err = uv__stream_open((uv_stream_t*) handle, sockfd, flags);
+ if (err) {
+ uv__close(sockfd);
+ return err;
+ }
+
+ return 0;
+}
+
+
+int uv__tcp_bind(uv_tcp_t* tcp,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ int err;
+ int on;
+
+ err = maybe_new_socket(tcp,
+ addr->sa_family,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ if (err)
+ return err;
+
+ on = 1;
+ if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
+ return -errno;
+
+#ifdef IPV6_V6ONLY
+ if (addr->sa_family == AF_INET6) {
+ on = (flags & UV_TCP_IPV6ONLY) != 0;
+ if (setsockopt(tcp->io_watcher.fd,
+ IPPROTO_IPV6,
+ IPV6_V6ONLY,
+ &on,
+ sizeof on) == -1) {
+ return -errno;
+ }
+ }
+#endif
+
+ errno = 0;
+ if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
+ return -errno;
+
+ tcp->delayed_error = -errno;
+ return 0;
+}
+
+
+int uv__tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_connect_cb cb) {
+ int err;
+ int r;
+
+ assert(handle->type == UV_TCP);
+
+ if (handle->connect_req != NULL)
+ return -EALREADY; /* FIXME(bnoordhuis) -EINVAL or maybe -EBUSY. */
+
+ err = maybe_new_socket(handle,
+ addr->sa_family,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+ if (err)
+ return err;
+
+ handle->delayed_error = 0;
+
+ do
+ r = connect(uv__stream_fd(handle), addr, addrlen);
+ while (r == -1 && errno == EINTR);
+
+ if (r == -1) {
+ if (errno == EINPROGRESS)
+ ; /* not an error */
+ else if (errno == ECONNREFUSED)
+ /* If we get a ECONNREFUSED wait until the next tick to report the
+ * error. Solaris wants to report immediately--other unixes want to
+ * wait.
+ */
+ handle->delayed_error = -errno;
+ else
+ return -errno;
+ }
+
+ uv__req_init(handle->loop, req, UV_CONNECT);
+ req->cb = cb;
+ req->handle = (uv_stream_t*) handle;
+ QUEUE_INIT(&req->queue);
+ handle->connect_req = req;
+
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+
+ if (handle->delayed_error)
+ uv__io_feed(handle->loop, &handle->io_watcher);
+
+ return 0;
+}
+
+
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
+ return uv__stream_open((uv_stream_t*)handle,
+ sock,
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE);
+}
+
+
+int uv_tcp_getsockname(uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen) {
+ socklen_t socklen;
+
+ if (handle->delayed_error)
+ return handle->delayed_error;
+
+ if (uv__stream_fd(handle) < 0)
+ return -EINVAL; /* FIXME(bnoordhuis) -EBADF */
+
+ /* sizeof(socklen_t) != sizeof(int) on some systems. */
+ socklen = (socklen_t) *namelen;
+
+ if (getsockname(uv__stream_fd(handle), name, &socklen))
+ return -errno;
+
+ *namelen = (int) socklen;
+ return 0;
+}
+
+
+int uv_tcp_getpeername(uv_tcp_t* handle,
+ struct sockaddr* name,
+ int* namelen) {
+ socklen_t socklen;
+
+ if (handle->delayed_error)
+ return handle->delayed_error;
+
+ if (uv__stream_fd(handle) < 0)
+ return -EINVAL; /* FIXME(bnoordhuis) -EBADF */
+
+ /* sizeof(socklen_t) != sizeof(int) on some systems. */
+ socklen = (socklen_t) *namelen;
+
+ if (getpeername(uv__stream_fd(handle), name, &socklen))
+ return -errno;
+
+ *namelen = (int) socklen;
+ return 0;
+}
+
+
+int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
+ static int single_accept = -1;
+ int err;
+
+ if (tcp->delayed_error)
+ return tcp->delayed_error;
+
+ if (single_accept == -1) {
+ const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
+ single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */
+ }
+
+ if (single_accept)
+ tcp->flags |= UV_TCP_SINGLE_ACCEPT;
+
+ err = maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE);
+ if (err)
+ return err;
+
+ if (listen(tcp->io_watcher.fd, backlog))
+ return -errno;
+
+ tcp->connection_cb = cb;
+
+ /* Start listening for connections. */
+ tcp->io_watcher.cb = uv__server_io;
+ uv__io_start(tcp->loop, &tcp->io_watcher, UV__POLLIN);
+
+ return 0;
+}
+
+
+int uv__tcp_nodelay(int fd, int on) {
+ return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+}
+
+
+int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
+ return -errno;
+
+#ifdef TCP_KEEPIDLE
+ if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
+ return -errno;
+#endif
+
+ /* Solaris/SmartOS, if you don't support keep-alive,
+ * then don't advertise it in your system headers...
+ */
+ /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
+#if defined(TCP_KEEPALIVE) && !defined(__sun)
+ if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
+ return -errno;
+#endif
+
+ return 0;
+}
+
+
+int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
+ int err;
+
+ if (uv__stream_fd(handle) != -1) {
+ err = uv__tcp_nodelay(uv__stream_fd(handle), on);
+ if (err)
+ return err;
+ }
+
+ if (on)
+ handle->flags |= UV_TCP_NODELAY;
+ else
+ handle->flags &= ~UV_TCP_NODELAY;
+
+ return 0;
+}
+
+
+int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
+ int err;
+
+ if (uv__stream_fd(handle) != -1) {
+ err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
+ if (err)
+ return err;
+ }
+
+ if (on)
+ handle->flags |= UV_TCP_KEEPALIVE;
+ else
+ handle->flags &= ~UV_TCP_KEEPALIVE;
+
+ /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
+ * uv_tcp_t with an int that's almost never used...
+ */
+
+ return 0;
+}
+
+
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+ if (enable)
+ handle->flags &= ~UV_TCP_SINGLE_ACCEPT;
+ else
+ handle->flags |= UV_TCP_SINGLE_ACCEPT;
+ return 0;
+}
+
+
+void uv__tcp_close(uv_tcp_t* handle) {
+ uv__stream_close((uv_stream_t*)handle);
+}
diff --git a/third-party/libuv/src/unix/thread.c b/third-party/libuv/src/unix/thread.c
new file mode 100644
index 0000000000..f2ce082842
--- /dev/null
+++ b/third-party/libuv/src/unix/thread.c
@@ -0,0 +1,464 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <pthread.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <sys/time.h>
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+int uv_thread_join(uv_thread_t *tid) {
+ return -pthread_join(*tid, NULL);
+}
+
+
+int uv_mutex_init(uv_mutex_t* mutex) {
+#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
+ return -pthread_mutex_init(mutex, NULL);
+#else
+ pthread_mutexattr_t attr;
+ int err;
+
+ if (pthread_mutexattr_init(&attr))
+ abort();
+
+ if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK))
+ abort();
+
+ err = pthread_mutex_init(mutex, &attr);
+
+ if (pthread_mutexattr_destroy(&attr))
+ abort();
+
+ return -err;
+#endif
+}
+
+
+void uv_mutex_destroy(uv_mutex_t* mutex) {
+ if (pthread_mutex_destroy(mutex))
+ abort();
+}
+
+
+void uv_mutex_lock(uv_mutex_t* mutex) {
+ if (pthread_mutex_lock(mutex))
+ abort();
+}
+
+
+int uv_mutex_trylock(uv_mutex_t* mutex) {
+ int err;
+
+ /* FIXME(bnoordhuis) EAGAIN means recursive lock limit reached. Arguably
+ * a bug, should probably abort rather than return -EAGAIN.
+ */
+ err = pthread_mutex_trylock(mutex);
+ if (err && err != EBUSY && err != EAGAIN)
+ abort();
+
+ return -err;
+}
+
+
+void uv_mutex_unlock(uv_mutex_t* mutex) {
+ if (pthread_mutex_unlock(mutex))
+ abort();
+}
+
+
+int uv_rwlock_init(uv_rwlock_t* rwlock) {
+ return -pthread_rwlock_init(rwlock, NULL);
+}
+
+
+void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
+ if (pthread_rwlock_destroy(rwlock))
+ abort();
+}
+
+
+void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
+ if (pthread_rwlock_rdlock(rwlock))
+ abort();
+}
+
+
+int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
+ int err;
+
+ err = pthread_rwlock_tryrdlock(rwlock);
+ if (err && err != EBUSY && err != EAGAIN)
+ abort();
+
+ return -err;
+}
+
+
+void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
+ if (pthread_rwlock_unlock(rwlock))
+ abort();
+}
+
+
+void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
+ if (pthread_rwlock_wrlock(rwlock))
+ abort();
+}
+
+
+int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
+ int err;
+
+ err = pthread_rwlock_trywrlock(rwlock);
+ if (err && err != EBUSY && err != EAGAIN)
+ abort();
+
+ return -err;
+}
+
+
+void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
+ if (pthread_rwlock_unlock(rwlock))
+ abort();
+}
+
+
+void uv_once(uv_once_t* guard, void (*callback)(void)) {
+ if (pthread_once(guard, callback))
+ abort();
+}
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+ kern_return_t err;
+
+ err = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value);
+ if (err == KERN_SUCCESS)
+ return 0;
+ if (err == KERN_INVALID_ARGUMENT)
+ return -EINVAL;
+ if (err == KERN_RESOURCE_SHORTAGE)
+ return -ENOMEM;
+
+ abort();
+ return -EINVAL; /* Satisfy the compiler. */
+}
+
+
+void uv_sem_destroy(uv_sem_t* sem) {
+ if (semaphore_destroy(mach_task_self(), *sem))
+ abort();
+}
+
+
+void uv_sem_post(uv_sem_t* sem) {
+ if (semaphore_signal(*sem))
+ abort();
+}
+
+
+void uv_sem_wait(uv_sem_t* sem) {
+ int r;
+
+ do
+ r = semaphore_wait(*sem);
+ while (r == KERN_ABORTED);
+
+ if (r != KERN_SUCCESS)
+ abort();
+}
+
+
+int uv_sem_trywait(uv_sem_t* sem) {
+ mach_timespec_t interval;
+ kern_return_t err;
+
+ interval.tv_sec = 0;
+ interval.tv_nsec = 0;
+
+ err = semaphore_timedwait(*sem, interval);
+ if (err == KERN_SUCCESS)
+ return 0;
+ if (err == KERN_OPERATION_TIMED_OUT)
+ return -EAGAIN;
+
+ abort();
+ return -EINVAL; /* Satisfy the compiler. */
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+ if (sem_init(sem, 0, value))
+ return -errno;
+ return 0;
+}
+
+
+void uv_sem_destroy(uv_sem_t* sem) {
+ if (sem_destroy(sem))
+ abort();
+}
+
+
+void uv_sem_post(uv_sem_t* sem) {
+ if (sem_post(sem))
+ abort();
+}
+
+
+void uv_sem_wait(uv_sem_t* sem) {
+ int r;
+
+ do
+ r = sem_wait(sem);
+ while (r == -1 && errno == EINTR);
+
+ if (r)
+ abort();
+}
+
+
+int uv_sem_trywait(uv_sem_t* sem) {
+ int r;
+
+ do
+ r = sem_trywait(sem);
+ while (r == -1 && errno == EINTR);
+
+ if (r) {
+ if (errno == EAGAIN)
+ return -EAGAIN;
+ abort();
+ }
+
+ return 0;
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+int uv_cond_init(uv_cond_t* cond) {
+ return -pthread_cond_init(cond, NULL);
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+int uv_cond_init(uv_cond_t* cond) {
+ pthread_condattr_t attr;
+ int err;
+
+ err = pthread_condattr_init(&attr);
+ if (err)
+ return -err;
+
+#if !defined(__ANDROID__)
+ err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ if (err)
+ goto error2;
+#endif
+
+ err = pthread_cond_init(cond, &attr);
+ if (err)
+ goto error2;
+
+ err = pthread_condattr_destroy(&attr);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ pthread_cond_destroy(cond);
+error2:
+ pthread_condattr_destroy(&attr);
+ return -err;
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+void uv_cond_destroy(uv_cond_t* cond) {
+ if (pthread_cond_destroy(cond))
+ abort();
+}
+
+void uv_cond_signal(uv_cond_t* cond) {
+ if (pthread_cond_signal(cond))
+ abort();
+}
+
+void uv_cond_broadcast(uv_cond_t* cond) {
+ if (pthread_cond_broadcast(cond))
+ abort();
+}
+
+void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (pthread_cond_wait(cond, mutex))
+ abort();
+}
+
+
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
+ int r;
+ struct timespec ts;
+
+#if defined(__APPLE__) && defined(__MACH__)
+ ts.tv_sec = timeout / NANOSEC;
+ ts.tv_nsec = timeout % NANOSEC;
+ r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
+#else
+ timeout += uv__hrtime(UV_CLOCK_PRECISE);
+ ts.tv_sec = timeout / NANOSEC;
+ ts.tv_nsec = timeout % NANOSEC;
+#if defined(__ANDROID__)
+ /*
+ * The bionic pthread implementation doesn't support CLOCK_MONOTONIC,
+ * but has this alternative function instead.
+ */
+ r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts);
+#else
+ r = pthread_cond_timedwait(cond, mutex, &ts);
+#endif /* __ANDROID__ */
+#endif
+
+
+ if (r == 0)
+ return 0;
+
+ if (r == ETIMEDOUT)
+ return -ETIMEDOUT;
+
+ abort();
+ return -EINVAL; /* Satisfy the compiler. */
+}
+
+
+#if defined(__APPLE__) && defined(__MACH__)
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ int err;
+
+ barrier->n = count;
+ barrier->count = 0;
+
+ err = uv_mutex_init(&barrier->mutex);
+ if (err)
+ return -err;
+
+ err = uv_sem_init(&barrier->turnstile1, 0);
+ if (err)
+ goto error2;
+
+ err = uv_sem_init(&barrier->turnstile2, 1);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ uv_sem_destroy(&barrier->turnstile1);
+error2:
+ uv_mutex_destroy(&barrier->mutex);
+ return -err;
+
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ uv_sem_destroy(&barrier->turnstile2);
+ uv_sem_destroy(&barrier->turnstile1);
+ uv_mutex_destroy(&barrier->mutex);
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ uv_mutex_lock(&barrier->mutex);
+ if (++barrier->count == barrier->n) {
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile1);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile1);
+
+ uv_mutex_lock(&barrier->mutex);
+ if (--barrier->count == 0) {
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile2);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile2);
+}
+
+#else /* !(defined(__APPLE__) && defined(__MACH__)) */
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ return -pthread_barrier_init(barrier, NULL, count);
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ if (pthread_barrier_destroy(barrier))
+ abort();
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ int r = pthread_barrier_wait(barrier);
+ if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
+ abort();
+}
+
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
+int uv_key_create(uv_key_t* key) {
+ return -pthread_key_create(key, NULL);
+}
+
+
+void uv_key_delete(uv_key_t* key) {
+ if (pthread_key_delete(*key))
+ abort();
+}
+
+
+void* uv_key_get(uv_key_t* key) {
+ return pthread_getspecific(*key);
+}
+
+
+void uv_key_set(uv_key_t* key, void* value) {
+ if (pthread_setspecific(*key, value))
+ abort();
+}
diff --git a/third-party/libuv/src/unix/threadpool.c b/third-party/libuv/src/unix/threadpool.c
new file mode 100644
index 0000000000..7923250a09
--- /dev/null
+++ b/third-party/libuv/src/unix/threadpool.c
@@ -0,0 +1,280 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "internal.h"
+#include <stdlib.h>
+
+#define MAX_THREADPOOL_SIZE 128
+
+static uv_once_t once = UV_ONCE_INIT;
+static uv_cond_t cond;
+static uv_mutex_t mutex;
+static unsigned int nthreads;
+static uv_thread_t* threads;
+static uv_thread_t default_threads[4];
+static QUEUE exit_message;
+static QUEUE wq;
+static volatile int initialized;
+
+
+static void uv__cancelled(struct uv__work* w) {
+ abort();
+}
+
+
+/* To avoid deadlock with uv_cancel() it's crucial that the worker
+ * never holds the global mutex and the loop-local mutex at the same time.
+ */
+static void worker(void* arg) {
+ struct uv__work* w;
+ QUEUE* q;
+
+ (void) arg;
+
+ for (;;) {
+ uv_mutex_lock(&mutex);
+
+ while (QUEUE_EMPTY(&wq))
+ uv_cond_wait(&cond, &mutex);
+
+ q = QUEUE_HEAD(&wq);
+
+ if (q == &exit_message)
+ uv_cond_signal(&cond);
+ else {
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q); /* Signal uv_cancel() that the work req is
+ executing. */
+ }
+
+ uv_mutex_unlock(&mutex);
+
+ if (q == &exit_message)
+ break;
+
+ w = QUEUE_DATA(q, struct uv__work, wq);
+ w->work(w);
+
+ uv_mutex_lock(&w->loop->wq_mutex);
+ w->work = NULL; /* Signal uv_cancel() that the work req is done
+ executing. */
+ QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq);
+ uv_async_send(&w->loop->wq_async);
+ uv_mutex_unlock(&w->loop->wq_mutex);
+ }
+}
+
+
+static void post(QUEUE* q) {
+ uv_mutex_lock(&mutex);
+ QUEUE_INSERT_TAIL(&wq, q);
+ uv_cond_signal(&cond);
+ uv_mutex_unlock(&mutex);
+}
+
+
+static void init_once(void) {
+ unsigned int i;
+ const char* val;
+
+ nthreads = ARRAY_SIZE(default_threads);
+ val = getenv("UV_THREADPOOL_SIZE");
+ if (val != NULL)
+ nthreads = atoi(val);
+ if (nthreads == 0)
+ nthreads = 1;
+ if (nthreads > MAX_THREADPOOL_SIZE)
+ nthreads = MAX_THREADPOOL_SIZE;
+
+ threads = default_threads;
+ if (nthreads > ARRAY_SIZE(default_threads)) {
+ threads = malloc(nthreads * sizeof(threads[0]));
+ if (threads == NULL) {
+ nthreads = ARRAY_SIZE(default_threads);
+ threads = default_threads;
+ }
+ }
+
+ if (uv_cond_init(&cond))
+ abort();
+
+ if (uv_mutex_init(&mutex))
+ abort();
+
+ QUEUE_INIT(&wq);
+
+ for (i = 0; i < nthreads; i++)
+ if (uv_thread_create(threads + i, worker, NULL))
+ abort();
+
+ initialized = 1;
+}
+
+
+UV_DESTRUCTOR(static void cleanup(void)) {
+ unsigned int i;
+
+ if (initialized == 0)
+ return;
+
+ post(&exit_message);
+
+ for (i = 0; i < nthreads; i++)
+ if (uv_thread_join(threads + i))
+ abort();
+
+ if (threads != default_threads)
+ free(threads);
+
+ uv_mutex_destroy(&mutex);
+ uv_cond_destroy(&cond);
+
+ threads = NULL;
+ nthreads = 0;
+ initialized = 0;
+}
+
+
+void uv__work_submit(uv_loop_t* loop,
+ struct uv__work* w,
+ void (*work)(struct uv__work* w),
+ void (*done)(struct uv__work* w, int status)) {
+ uv_once(&once, init_once);
+ w->loop = loop;
+ w->work = work;
+ w->done = done;
+ post(&w->wq);
+}
+
+
+static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
+ int cancelled;
+
+ uv_mutex_lock(&mutex);
+ uv_mutex_lock(&w->loop->wq_mutex);
+
+ cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL;
+ if (cancelled)
+ QUEUE_REMOVE(&w->wq);
+
+ uv_mutex_unlock(&w->loop->wq_mutex);
+ uv_mutex_unlock(&mutex);
+
+ if (!cancelled)
+ return -EBUSY;
+
+ w->work = uv__cancelled;
+ uv_mutex_lock(&loop->wq_mutex);
+ QUEUE_INSERT_TAIL(&loop->wq, &w->wq);
+ uv_async_send(&loop->wq_async);
+ uv_mutex_unlock(&loop->wq_mutex);
+
+ return 0;
+}
+
+
+void uv__work_done(uv_async_t* handle, int status) {
+ struct uv__work* w;
+ uv_loop_t* loop;
+ QUEUE* q;
+ QUEUE wq;
+ int err;
+
+ loop = container_of(handle, uv_loop_t, wq_async);
+ QUEUE_INIT(&wq);
+
+ uv_mutex_lock(&loop->wq_mutex);
+ if (!QUEUE_EMPTY(&loop->wq)) {
+ q = QUEUE_HEAD(&loop->wq);
+ QUEUE_SPLIT(&loop->wq, q, &wq);
+ }
+ uv_mutex_unlock(&loop->wq_mutex);
+
+ while (!QUEUE_EMPTY(&wq)) {
+ q = QUEUE_HEAD(&wq);
+ QUEUE_REMOVE(q);
+
+ w = container_of(q, struct uv__work, wq);
+ err = (w->work == uv__cancelled) ? -ECANCELED : 0;
+ w->done(w, err);
+ }
+}
+
+
+static void uv__queue_work(struct uv__work* w) {
+ uv_work_t* req = container_of(w, uv_work_t, work_req);
+
+ req->work_cb(req);
+}
+
+
+static void uv__queue_done(struct uv__work* w, int err) {
+ uv_work_t* req;
+
+ req = container_of(w, uv_work_t, work_req);
+ uv__req_unregister(req->loop, req);
+
+ if (req->after_work_cb == NULL)
+ return;
+
+ req->after_work_cb(req, err);
+}
+
+
+int uv_queue_work(uv_loop_t* loop,
+ uv_work_t* req,
+ uv_work_cb work_cb,
+ uv_after_work_cb after_work_cb) {
+ if (work_cb == NULL)
+ return -EINVAL;
+
+ uv__req_init(loop, req, UV_WORK);
+ req->loop = loop;
+ req->work_cb = work_cb;
+ req->after_work_cb = after_work_cb;
+ uv__work_submit(loop, &req->work_req, uv__queue_work, uv__queue_done);
+ return 0;
+}
+
+
+int uv_cancel(uv_req_t* req) {
+ struct uv__work* wreq;
+ uv_loop_t* loop;
+
+ switch (req->type) {
+ case UV_FS:
+ loop = ((uv_fs_t*) req)->loop;
+ wreq = &((uv_fs_t*) req)->work_req;
+ break;
+ case UV_GETADDRINFO:
+ loop = ((uv_getaddrinfo_t*) req)->loop;
+ wreq = &((uv_getaddrinfo_t*) req)->work_req;
+ break;
+ case UV_WORK:
+ loop = ((uv_work_t*) req)->loop;
+ wreq = &((uv_work_t*) req)->work_req;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return uv__work_cancel(loop, req, wreq);
+}
diff --git a/third-party/libuv/src/unix/timer.c b/third-party/libuv/src/unix/timer.c
new file mode 100644
index 0000000000..240efad503
--- /dev/null
+++ b/third-party/libuv/src/unix/timer.c
@@ -0,0 +1,153 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+#include <assert.h>
+#include <limits.h>
+
+
+static int uv__timer_cmp(const uv_timer_t* a, const uv_timer_t* b) {
+ if (a->timeout < b->timeout)
+ return -1;
+ if (a->timeout > b->timeout)
+ return 1;
+ /*
+ * compare start_id when both has the same timeout. start_id is
+ * allocated with loop->timer_counter in uv_timer_start().
+ */
+ if (a->start_id < b->start_id)
+ return -1;
+ if (a->start_id > b->start_id)
+ return 1;
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(uv__timers, uv_timer_s, tree_entry, uv__timer_cmp)
+
+
+int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
+ handle->timer_cb = NULL;
+ handle->repeat = 0;
+
+ return 0;
+}
+
+
+int uv_timer_start(uv_timer_t* handle,
+ uv_timer_cb cb,
+ uint64_t timeout,
+ uint64_t repeat) {
+ uint64_t clamped_timeout;
+
+ if (uv__is_active(handle))
+ uv_timer_stop(handle);
+
+ clamped_timeout = handle->loop->time + timeout;
+ if (clamped_timeout < timeout)
+ clamped_timeout = (uint64_t) -1;
+
+ handle->timer_cb = cb;
+ handle->timeout = clamped_timeout;
+ handle->repeat = repeat;
+ /* start_id is the second index to be compared in uv__timer_cmp() */
+ handle->start_id = handle->loop->timer_counter++;
+
+ RB_INSERT(uv__timers, &handle->loop->timer_handles, handle);
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+int uv_timer_stop(uv_timer_t* handle) {
+ if (!uv__is_active(handle))
+ return 0;
+
+ RB_REMOVE(uv__timers, &handle->loop->timer_handles, handle);
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+int uv_timer_again(uv_timer_t* handle) {
+ if (handle->timer_cb == NULL)
+ return -EINVAL;
+
+ if (handle->repeat) {
+ uv_timer_stop(handle);
+ uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
+ }
+
+ return 0;
+}
+
+
+void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
+ handle->repeat = repeat;
+}
+
+
+uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
+ return handle->repeat;
+}
+
+
+int uv__next_timeout(const uv_loop_t* loop) {
+ const uv_timer_t* handle;
+ uint64_t diff;
+
+ /* RB_MIN expects a non-const tree root. That's okay, it doesn't modify it. */
+ handle = RB_MIN(uv__timers, (struct uv__timers*) &loop->timer_handles);
+
+ if (handle == NULL)
+ return -1; /* block indefinitely */
+
+ if (handle->timeout <= loop->time)
+ return 0;
+
+ diff = handle->timeout - loop->time;
+ if (diff > INT_MAX)
+ diff = INT_MAX;
+
+ return diff;
+}
+
+
+void uv__run_timers(uv_loop_t* loop) {
+ uv_timer_t* handle;
+
+ while ((handle = RB_MIN(uv__timers, &loop->timer_handles))) {
+ if (handle->timeout > loop->time)
+ break;
+
+ uv_timer_stop(handle);
+ uv_timer_again(handle);
+ handle->timer_cb(handle, 0);
+ }
+}
+
+
+void uv__timer_close(uv_timer_t* handle) {
+ uv_timer_stop(handle);
+}
diff --git a/third-party/libuv/src/unix/tty.c b/third-party/libuv/src/unix/tty.c
new file mode 100644
index 0000000000..ca9459dd0d
--- /dev/null
+++ b/third-party/libuv/src/unix/tty.c
@@ -0,0 +1,184 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+#include "spinlock.h"
+
+#include <assert.h>
+#include <unistd.h>
+#include <termios.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+static int orig_termios_fd = -1;
+static struct termios orig_termios;
+static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
+
+
+int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
+ uv__stream_init(loop, (uv_stream_t*)tty, UV_TTY);
+
+#if defined(__APPLE__)
+ {
+ int err = uv__stream_try_select((uv_stream_t*) tty, &fd);
+ if (err)
+ return err;
+ }
+#endif /* defined(__APPLE__) */
+
+ if (readable) {
+ uv__nonblock(fd, 1);
+ uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_READABLE);
+ } else {
+ /* Note: writable tty we set to blocking mode. */
+ uv__stream_open((uv_stream_t*)tty, fd, UV_STREAM_WRITABLE);
+ tty->flags |= UV_STREAM_BLOCKING;
+ }
+
+ tty->mode = 0;
+ return 0;
+}
+
+
+int uv_tty_set_mode(uv_tty_t* tty, int mode) {
+ struct termios raw;
+ int fd;
+
+ fd = uv__stream_fd(tty);
+
+ if (mode && tty->mode == 0) { /* on */
+ if (tcgetattr(fd, &tty->orig_termios))
+ return -errno;
+
+ /* This is used for uv_tty_reset_mode() */
+ uv_spinlock_lock(&termios_spinlock);
+ if (orig_termios_fd == -1) {
+ orig_termios = tty->orig_termios;
+ orig_termios_fd = fd;
+ }
+ uv_spinlock_unlock(&termios_spinlock);
+
+ raw = tty->orig_termios;
+ raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+ raw.c_oflag |= (ONLCR);
+ raw.c_cflag |= (CS8);
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+ raw.c_cc[VMIN] = 1;
+ raw.c_cc[VTIME] = 0;
+
+ /* Put terminal in raw mode after draining */
+ if (tcsetattr(fd, TCSADRAIN, &raw))
+ return -errno;
+
+ tty->mode = 1;
+ } else if (mode == 0 && tty->mode) { /* off */
+ /* Put terminal in original mode after flushing */
+ if (tcsetattr(fd, TCSAFLUSH, &tty->orig_termios))
+ return -errno;
+ tty->mode = 0;
+ }
+
+ return 0;
+}
+
+
+int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
+ struct winsize ws;
+
+ if (ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws))
+ return -errno;
+
+ *width = ws.ws_col;
+ *height = ws.ws_row;
+
+ return 0;
+}
+
+
+uv_handle_type uv_guess_handle(uv_file file) {
+ struct sockaddr sa;
+ struct stat s;
+ socklen_t len;
+ int type;
+
+ if (file < 0)
+ return UV_UNKNOWN_HANDLE;
+
+ if (isatty(file))
+ return UV_TTY;
+
+ if (fstat(file, &s))
+ return UV_UNKNOWN_HANDLE;
+
+ if (S_ISREG(s.st_mode))
+ return UV_FILE;
+
+ if (S_ISCHR(s.st_mode))
+ return UV_FILE; /* XXX UV_NAMED_PIPE? */
+
+ if (S_ISFIFO(s.st_mode))
+ return UV_NAMED_PIPE;
+
+ if (!S_ISSOCK(s.st_mode))
+ return UV_UNKNOWN_HANDLE;
+
+ len = sizeof(type);
+ if (getsockopt(file, SOL_SOCKET, SO_TYPE, &type, &len))
+ return UV_UNKNOWN_HANDLE;
+
+ len = sizeof(sa);
+ if (getsockname(file, &sa, &len))
+ return UV_UNKNOWN_HANDLE;
+
+ if (type == SOCK_DGRAM)
+ if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6)
+ return UV_UDP;
+
+ if (type == SOCK_STREAM) {
+ if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6)
+ return UV_TCP;
+ if (sa.sa_family == AF_UNIX)
+ return UV_NAMED_PIPE;
+ }
+
+ return UV_UNKNOWN_HANDLE;
+}
+
+
+/* This function is async signal-safe, meaning that it's safe to call from
+ * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s
+ * critical section when the signal was raised.
+ */
+int uv_tty_reset_mode(void) {
+ int err;
+
+ if (!uv_spinlock_trylock(&termios_spinlock))
+ return -EBUSY; /* In uv_tty_set_mode(). */
+
+ err = 0;
+ if (orig_termios_fd != -1)
+ if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios))
+ err = -errno;
+
+ uv_spinlock_unlock(&termios_spinlock);
+ return err;
+}
diff --git a/third-party/libuv/src/unix/udp.c b/third-party/libuv/src/unix/udp.c
new file mode 100644
index 0000000000..a2b3dc3298
--- /dev/null
+++ b/third-party/libuv/src/unix/udp.c
@@ -0,0 +1,595 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+#include <assert.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+static void uv__udp_run_completed(uv_udp_t* handle);
+static void uv__udp_run_pending(uv_udp_t* handle);
+static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
+static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
+static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
+static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain);
+
+
+void uv__udp_close(uv_udp_t* handle) {
+ uv__io_close(handle->loop, &handle->io_watcher);
+ uv__handle_stop(handle);
+
+ if (handle->io_watcher.fd != -1) {
+ uv__close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
+ }
+}
+
+
+void uv__udp_finish_close(uv_udp_t* handle) {
+ uv_udp_send_t* req;
+ QUEUE* q;
+
+ assert(!uv__io_active(&handle->io_watcher, UV__POLLIN | UV__POLLOUT));
+ assert(handle->io_watcher.fd == -1);
+
+ uv__udp_run_completed(handle);
+
+ while (!QUEUE_EMPTY(&handle->write_queue)) {
+ q = QUEUE_HEAD(&handle->write_queue);
+ QUEUE_REMOVE(q);
+
+ req = QUEUE_DATA(q, uv_udp_send_t, queue);
+ uv__req_unregister(handle->loop, req);
+
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+
+ if (req->send_cb != NULL)
+ req->send_cb(req, -ECANCELED);
+ }
+
+ /* Now tear down the handle. */
+ handle->recv_cb = NULL;
+ handle->alloc_cb = NULL;
+ /* but _do not_ touch close_cb */
+}
+
+
+static void uv__udp_run_pending(uv_udp_t* handle) {
+ uv_udp_send_t* req;
+ QUEUE* q;
+ struct msghdr h;
+ ssize_t size;
+
+ while (!QUEUE_EMPTY(&handle->write_queue)) {
+ q = QUEUE_HEAD(&handle->write_queue);
+ assert(q != NULL);
+
+ req = QUEUE_DATA(q, uv_udp_send_t, queue);
+ assert(req != NULL);
+
+ memset(&h, 0, sizeof h);
+ h.msg_name = &req->addr;
+ h.msg_namelen = (req->addr.sin6_family == AF_INET6 ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
+ h.msg_iov = (struct iovec*) req->bufs;
+ h.msg_iovlen = req->nbufs;
+
+ do {
+ size = sendmsg(handle->io_watcher.fd, &h, 0);
+ }
+ while (size == -1 && errno == EINTR);
+
+ /* TODO try to write once or twice more in the
+ * hope that the socket becomes readable again?
+ */
+ if (size == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
+ break;
+
+ req->status = (size == -1 ? -errno : size);
+
+ /* Sending a datagram is an atomic operation: either all data
+ * is written or nothing is (and EMSGSIZE is raised). That is
+ * why we don't handle partial writes. Just pop the request
+ * off the write queue and onto the completed queue, done.
+ */
+ QUEUE_REMOVE(&req->queue);
+ QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
+ }
+}
+
+
+static void uv__udp_run_completed(uv_udp_t* handle) {
+ uv_udp_send_t* req;
+ QUEUE* q;
+
+ while (!QUEUE_EMPTY(&handle->write_completed_queue)) {
+ q = QUEUE_HEAD(&handle->write_completed_queue);
+ QUEUE_REMOVE(q);
+
+ req = QUEUE_DATA(q, uv_udp_send_t, queue);
+ uv__req_unregister(handle->loop, req);
+
+ if (req->bufs != req->bufsml)
+ free(req->bufs);
+ req->bufs = NULL;
+
+ if (req->send_cb == NULL)
+ continue;
+
+ /* req->status >= 0 == bytes written
+ * req->status < 0 == errno
+ */
+ if (req->status >= 0)
+ req->send_cb(req, 0);
+ else
+ req->send_cb(req, req->status);
+ }
+}
+
+
+static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
+ if (revents & UV__POLLIN)
+ uv__udp_recvmsg(loop, w, revents);
+
+ if (revents & UV__POLLOUT)
+ uv__udp_sendmsg(loop, w, revents);
+}
+
+
+static void uv__udp_recvmsg(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
+ struct sockaddr_storage peer;
+ struct msghdr h;
+ uv_udp_t* handle;
+ ssize_t nread;
+ uv_buf_t buf;
+ int flags;
+ int count;
+
+ handle = container_of(w, uv_udp_t, io_watcher);
+ assert(handle->type == UV_UDP);
+ assert(revents & UV__POLLIN);
+
+ assert(handle->recv_cb != NULL);
+ assert(handle->alloc_cb != NULL);
+
+ /* Prevent loop starvation when the data comes in as fast as (or faster than)
+ * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
+ */
+ count = 32;
+
+ memset(&h, 0, sizeof(h));
+ h.msg_name = &peer;
+
+ do {
+ handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf);
+ if (buf.len == 0) {
+ handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
+ return;
+ }
+ assert(buf.base != NULL);
+
+ h.msg_namelen = sizeof(peer);
+ h.msg_iov = (void*) &buf;
+ h.msg_iovlen = 1;
+
+ do {
+ nread = recvmsg(handle->io_watcher.fd, &h, 0);
+ }
+ while (nread == -1 && errno == EINTR);
+
+ if (nread == -1) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ handle->recv_cb(handle, 0, &buf, NULL, 0);
+ else
+ handle->recv_cb(handle, -errno, &buf, NULL, 0);
+ }
+ else {
+ flags = 0;
+
+ if (h.msg_flags & MSG_TRUNC)
+ flags |= UV_UDP_PARTIAL;
+
+ handle->recv_cb(handle,
+ nread,
+ &buf,
+ (const struct sockaddr*) &peer,
+ flags);
+ }
+ }
+ /* recv_cb callback may decide to pause or close the handle */
+ while (nread != -1
+ && count-- > 0
+ && handle->io_watcher.fd != -1
+ && handle->recv_cb != NULL);
+}
+
+
+static void uv__udp_sendmsg(uv_loop_t* loop,
+ uv__io_t* w,
+ unsigned int revents) {
+ uv_udp_t* handle;
+
+ handle = container_of(w, uv_udp_t, io_watcher);
+ assert(handle->type == UV_UDP);
+ assert(revents & UV__POLLOUT);
+
+ assert(!QUEUE_EMPTY(&handle->write_queue)
+ || !QUEUE_EMPTY(&handle->write_completed_queue));
+
+ /* Write out pending data first. */
+ uv__udp_run_pending(handle);
+
+ /* Drain 'request completed' queue. */
+ uv__udp_run_completed(handle);
+
+ if (!QUEUE_EMPTY(&handle->write_completed_queue)) {
+ /* Schedule completion callbacks. */
+ uv__io_feed(handle->loop, &handle->io_watcher);
+ }
+ else if (QUEUE_EMPTY(&handle->write_queue)) {
+ /* Pending queue and completion queue empty, stop watcher. */
+ uv__io_stop(loop, &handle->io_watcher, UV__POLLOUT);
+
+ if (!uv__io_active(&handle->io_watcher, UV__POLLIN))
+ uv__handle_stop(handle);
+ }
+}
+
+
+/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
+ * refinements for programs that use multicast.
+ *
+ * Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that
+ * are different from the BSDs: it _shares_ the port rather than steal it
+ * from the current listener. While useful, it's not something we can emulate
+ * on other platforms so we don't enable it.
+ */
+static int uv__set_reuse(int fd) {
+ int yes;
+
+#if defined(SO_REUSEPORT) && !defined(__linux__)
+ yes = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
+ return -errno;
+#else
+ yes = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
+ return -errno;
+#endif
+
+ return 0;
+}
+
+
+int uv__udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ int err;
+ int yes;
+ int fd;
+
+ err = -EINVAL;
+ fd = -1;
+
+ /* Check for bad flags. */
+ if (flags & ~UV_UDP_IPV6ONLY)
+ return -EINVAL;
+
+ /* Cannot set IPv6-only mode on non-IPv6 socket. */
+ if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6)
+ return -EINVAL;
+
+ fd = handle->io_watcher.fd;
+ if (fd == -1) {
+ fd = uv__socket(addr->sa_family, SOCK_DGRAM, 0);
+ if (fd == -1)
+ return -errno;
+ handle->io_watcher.fd = fd;
+ }
+
+ err = uv__set_reuse(fd);
+ if (err)
+ goto out;
+
+ if (flags & UV_UDP_IPV6ONLY) {
+#ifdef IPV6_V6ONLY
+ yes = 1;
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
+ err = -errno;
+ goto out;
+ }
+#else
+ err = -ENOTSUP;
+ goto out;
+#endif
+ }
+
+ if (bind(fd, addr, addrlen)) {
+ err = -errno;
+ goto out;
+ }
+
+ return 0;
+
+out:
+ uv__close(handle->io_watcher.fd);
+ handle->io_watcher.fd = -1;
+ return err;
+}
+
+
+static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
+ unsigned char taddr[sizeof(struct sockaddr_in6)];
+ socklen_t addrlen;
+
+ assert(domain == AF_INET || domain == AF_INET6);
+
+ if (handle->io_watcher.fd != -1)
+ return 0;
+
+ switch (domain) {
+ case AF_INET:
+ {
+ struct sockaddr_in* addr = (void*)&taddr;
+ memset(addr, 0, sizeof *addr);
+ addr->sin_family = AF_INET;
+ addr->sin_addr.s_addr = INADDR_ANY;
+ addrlen = sizeof *addr;
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6* addr = (void*)&taddr;
+ memset(addr, 0, sizeof *addr);
+ addr->sin6_family = AF_INET6;
+ addr->sin6_addr = in6addr_any;
+ addrlen = sizeof *addr;
+ break;
+ }
+ default:
+ assert(0 && "unsupported address family");
+ abort();
+ }
+
+ return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, 0);
+}
+
+
+int uv__udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_udp_send_cb send_cb) {
+ int err;
+
+ assert(nbufs > 0);
+
+ err = uv__udp_maybe_deferred_bind(handle, addr->sa_family);
+ if (err)
+ return err;
+
+ uv__req_init(handle->loop, req, UV_UDP_SEND);
+
+ assert(addrlen <= sizeof(req->addr));
+ memcpy(&req->addr, addr, addrlen);
+ req->send_cb = send_cb;
+ req->handle = handle;
+ req->nbufs = nbufs;
+
+ req->bufs = req->bufsml;
+ if (nbufs > ARRAY_SIZE(req->bufsml))
+ req->bufs = malloc(nbufs * sizeof(bufs[0]));
+
+ if (req->bufs == NULL)
+ return -ENOMEM;
+
+ memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
+ QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue);
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLOUT);
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
+ handle->alloc_cb = NULL;
+ handle->recv_cb = NULL;
+ uv__io_init(&handle->io_watcher, uv__udp_io, -1);
+ QUEUE_INIT(&handle->write_queue);
+ QUEUE_INIT(&handle->write_completed_queue);
+ return 0;
+}
+
+
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+ int err;
+
+ /* Check for already active socket. */
+ if (handle->io_watcher.fd != -1)
+ return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
+
+ err = uv__set_reuse(sock);
+ if (err)
+ return err;
+
+ handle->io_watcher.fd = sock;
+ return 0;
+}
+
+
+int uv_udp_set_membership(uv_udp_t* handle,
+ const char* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
+ struct ip_mreq mreq;
+ int optname;
+
+ memset(&mreq, 0, sizeof mreq);
+
+ if (interface_addr) {
+ mreq.imr_interface.s_addr = inet_addr(interface_addr);
+ } else {
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ }
+
+ mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
+
+ switch (membership) {
+ case UV_JOIN_GROUP:
+ optname = IP_ADD_MEMBERSHIP;
+ break;
+ case UV_LEAVE_GROUP:
+ optname = IP_DROP_MEMBERSHIP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (setsockopt(handle->io_watcher.fd,
+ IPPROTO_IP,
+ optname,
+ &mreq,
+ sizeof(mreq))) {
+ return -errno;
+ }
+
+ return 0;
+}
+
+
+static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
+#if defined(__sun)
+ char arg = val;
+#else
+ int arg = val;
+#endif
+
+ if (val < 0 || val > 255)
+ return -EINVAL;
+
+ if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, option, &arg, sizeof(arg)))
+ return -errno;
+
+ return 0;
+}
+
+
+int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
+ if (setsockopt(handle->io_watcher.fd,
+ SOL_SOCKET,
+ SO_BROADCAST,
+ &on,
+ sizeof(on))) {
+ return -errno;
+ }
+
+ return 0;
+}
+
+
+int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
+ if (ttl < 1 || ttl > 255)
+ return -EINVAL;
+
+ if (setsockopt(handle->io_watcher.fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)))
+ return -errno;
+
+ return 0;
+}
+
+
+int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
+ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, ttl);
+}
+
+
+int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
+ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on);
+}
+
+
+int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
+ socklen_t socklen;
+
+ if (handle->io_watcher.fd == -1)
+ return -EINVAL; /* FIXME(bnoordhuis) -EBADF */
+
+ /* sizeof(socklen_t) != sizeof(int) on some systems. */
+ socklen = (socklen_t) *namelen;
+
+ if (getsockname(handle->io_watcher.fd, name, &socklen))
+ return -errno;
+
+ *namelen = (int) socklen;
+ return 0;
+}
+
+
+int uv__udp_recv_start(uv_udp_t* handle,
+ uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
+ int err;
+
+ if (alloc_cb == NULL || recv_cb == NULL)
+ return -EINVAL;
+
+ if (uv__io_active(&handle->io_watcher, UV__POLLIN))
+ return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
+
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET);
+ if (err)
+ return err;
+
+ handle->alloc_cb = alloc_cb;
+ handle->recv_cb = recv_cb;
+
+ uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+int uv__udp_recv_stop(uv_udp_t* handle) {
+ uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN);
+
+ if (!uv__io_active(&handle->io_watcher, UV__POLLOUT))
+ uv__handle_stop(handle);
+
+ handle->alloc_cb = NULL;
+ handle->recv_cb = NULL;
+
+ return 0;
+}
diff --git a/third-party/libuv/src/unix/uv-dtrace.d b/third-party/libuv/src/unix/uv-dtrace.d
new file mode 100644
index 0000000000..7848450c94
--- /dev/null
+++ b/third-party/libuv/src/unix/uv-dtrace.d
@@ -0,0 +1,25 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+provider uv {
+ probe tick__start(void* loop, int mode);
+ probe tick__stop(void* loop, int mode);
+};
diff --git a/third-party/libuv/src/uv-common.c b/third-party/libuv/src/uv-common.c
new file mode 100644
index 0000000000..e5fc507756
--- /dev/null
+++ b/third-party/libuv/src/uv-common.c
@@ -0,0 +1,446 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
+ * include any headers.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include "uv.h"
+#include "uv-common.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stddef.h> /* NULL */
+#include <stdlib.h> /* malloc */
+#include <string.h> /* memset */
+
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS) && !defined(_WIN32)
+# include <net/if.h> /* if_nametoindex */
+#endif
+
+/* EAI_* constants. */
+#if !defined(_WIN32)
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netdb.h>
+#endif
+
+#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
+
+size_t uv_handle_size(uv_handle_type type) {
+ switch (type) {
+ UV_HANDLE_TYPE_MAP(XX)
+ default:
+ return -1;
+ }
+}
+
+size_t uv_req_size(uv_req_type type) {
+ switch(type) {
+ UV_REQ_TYPE_MAP(XX)
+ default:
+ return -1;
+ }
+}
+
+#undef XX
+
+
+uv_buf_t uv_buf_init(char* base, unsigned int len) {
+ uv_buf_t buf;
+ buf.base = base;
+ buf.len = len;
+ return buf;
+}
+
+
+#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
+const char* uv_err_name(int err) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_ERR_NAME_GEN)
+ default:
+ assert(0);
+ return NULL;
+ }
+}
+#undef UV_ERR_NAME_GEN
+
+
+#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
+const char* uv_strerror(int err) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_STRERROR_GEN)
+ default:
+ return "Unknown system error";
+ }
+}
+#undef UV_STRERROR_GEN
+
+
+int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
+ memset(addr, 0, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(port);
+ return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
+}
+
+
+int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
+ char address_part[40];
+ size_t address_part_size;
+ const char* zone_index;
+#endif
+
+ memset(addr, 0, sizeof(*addr));
+ addr->sin6_family = AF_INET6;
+ addr->sin6_port = htons(port);
+
+#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
+ zone_index = strchr(ip, '%');
+ if (zone_index != NULL) {
+ address_part_size = zone_index - ip;
+ if (address_part_size >= sizeof(address_part))
+ address_part_size = sizeof(address_part) - 1;
+
+ memcpy(address_part, ip, address_part_size);
+ address_part[address_part_size] = '\0';
+ ip = address_part;
+
+ zone_index++; /* skip '%' */
+ /* NOTE: unknown interface (id=0) is silently ignored */
+#ifdef _WIN32
+ addr->sin6_scope_id = atoi(zone_index);
+#else
+ addr->sin6_scope_id = if_nametoindex(zone_index);
+#endif
+ }
+#endif
+
+ return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
+}
+
+
+int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
+ return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
+}
+
+
+int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
+ return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
+}
+
+
+int uv_tcp_bind(uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_TCP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__tcp_bind(handle, addr, addrlen, flags);
+}
+
+
+int uv_udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int flags) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__udp_bind(handle, addr, addrlen, flags);
+}
+
+
+int uv_tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ uv_connect_cb cb) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_TCP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__tcp_connect(req, handle, addr, addrlen, cb);
+}
+
+
+int uv_udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ uv_udp_send_cb send_cb) {
+ unsigned int addrlen;
+
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+
+ if (addr->sa_family == AF_INET)
+ addrlen = sizeof(struct sockaddr_in);
+ else if (addr->sa_family == AF_INET6)
+ addrlen = sizeof(struct sockaddr_in6);
+ else
+ return UV_EINVAL;
+
+ return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
+}
+
+
+int uv_udp_recv_start(uv_udp_t* handle,
+ uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
+ if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL)
+ return UV_EINVAL;
+ else
+ return uv__udp_recv_start(handle, alloc_cb, recv_cb);
+}
+
+
+int uv_udp_recv_stop(uv_udp_t* handle) {
+ if (handle->type != UV_UDP)
+ return UV_EINVAL;
+ else
+ return uv__udp_recv_stop(handle);
+}
+
+
+struct thread_ctx {
+ void (*entry)(void* arg);
+ void* arg;
+};
+
+
+#ifdef _WIN32
+static UINT __stdcall uv__thread_start(void* arg)
+#else
+static void* uv__thread_start(void *arg)
+#endif
+{
+ struct thread_ctx *ctx_p;
+ struct thread_ctx ctx;
+
+ ctx_p = arg;
+ ctx = *ctx_p;
+ free(ctx_p);
+ ctx.entry(ctx.arg);
+
+ return 0;
+}
+
+
+int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
+ struct thread_ctx* ctx;
+ int err;
+
+ ctx = malloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return UV_ENOMEM;
+
+ ctx->entry = entry;
+ ctx->arg = arg;
+
+#ifdef _WIN32
+ *tid = (HANDLE) _beginthreadex(NULL, 0, uv__thread_start, ctx, 0, NULL);
+ err = *tid ? 0 : errno;
+#else
+ err = pthread_create(tid, NULL, uv__thread_start, ctx);
+#endif
+
+ if (err)
+ free(ctx);
+
+ return err ? -1 : 0;
+}
+
+
+unsigned long uv_thread_self(void) {
+#ifdef _WIN32
+ return (unsigned long) GetCurrentThreadId();
+#else
+ return (unsigned long) pthread_self();
+#endif
+}
+
+
+void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
+ QUEUE* q;
+ uv_handle_t* h;
+
+ QUEUE_FOREACH(q, &loop->handle_queue) {
+ h = QUEUE_DATA(q, uv_handle_t, handle_queue);
+ if (h->flags & UV__HANDLE_INTERNAL) continue;
+ walk_cb(h, arg);
+ }
+}
+
+
+#ifndef NDEBUG
+static void uv__print_handles(uv_loop_t* loop, int only_active) {
+ const char* type;
+ QUEUE* q;
+ uv_handle_t* h;
+
+ if (loop == NULL)
+ loop = uv_default_loop();
+
+ QUEUE_FOREACH(q, &loop->handle_queue) {
+ h = QUEUE_DATA(q, uv_handle_t, handle_queue);
+
+ if (only_active && !uv__is_active(h))
+ continue;
+
+ switch (h->type) {
+#define X(uc, lc) case UV_##uc: type = #lc; break;
+ UV_HANDLE_TYPE_MAP(X)
+#undef X
+ default: type = "<unknown>";
+ }
+
+ fprintf(stderr,
+ "[%c%c%c] %-8s %p\n",
+ "R-"[!(h->flags & UV__HANDLE_REF)],
+ "A-"[!(h->flags & UV__HANDLE_ACTIVE)],
+ "I-"[!(h->flags & UV__HANDLE_INTERNAL)],
+ type,
+ (void*)h);
+ }
+}
+
+
+void uv_print_all_handles(uv_loop_t* loop) {
+ uv__print_handles(loop, 0);
+}
+
+
+void uv_print_active_handles(uv_loop_t* loop) {
+ uv__print_handles(loop, 1);
+}
+#endif
+
+
+void uv_ref(uv_handle_t* handle) {
+ uv__handle_ref(handle);
+}
+
+
+void uv_unref(uv_handle_t* handle) {
+ uv__handle_unref(handle);
+}
+
+
+int uv_has_ref(const uv_handle_t* handle) {
+ return uv__has_ref(handle);
+}
+
+
+void uv_stop(uv_loop_t* loop) {
+ loop->stop_flag = 1;
+}
+
+
+uint64_t uv_now(uv_loop_t* loop) {
+ return loop->time;
+}
+
+
+int uv__getaddrinfo_translate_error(int sys_err) {
+ switch (sys_err) {
+ case 0: return 0;
+#if defined(EAI_ADDRFAMILY)
+ case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
+#endif
+#if defined(EAI_AGAIN)
+ case EAI_AGAIN: return UV_EAI_AGAIN;
+#endif
+#if defined(EAI_BADFLAGS)
+ case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
+#endif
+#if defined(EAI_BADHINTS)
+ case EAI_BADHINTS: return UV_EAI_BADHINTS;
+#endif
+#if defined(EAI_CANCELED)
+ case EAI_CANCELED: return UV_EAI_CANCELED;
+#endif
+#if defined(EAI_FAIL)
+ case EAI_FAIL: return UV_EAI_FAIL;
+#endif
+#if defined(EAI_FAMILY)
+ case EAI_FAMILY: return UV_EAI_FAMILY;
+#endif
+#if defined(EAI_MEMORY)
+ case EAI_MEMORY: return UV_EAI_MEMORY;
+#endif
+#if defined(EAI_NODATA)
+ case EAI_NODATA: return UV_EAI_NODATA;
+#endif
+#if defined(EAI_NONAME)
+# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
+ case EAI_NONAME: return UV_EAI_NONAME;
+# endif
+#endif
+#if defined(EAI_OVERFLOW)
+ case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
+#endif
+#if defined(EAI_PROTOCOL)
+ case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
+#endif
+#if defined(EAI_SERVICE)
+ case EAI_SERVICE: return UV_EAI_SERVICE;
+#endif
+#if defined(EAI_SOCKTYPE)
+ case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
+#endif
+#if defined(EAI_SYSTEM)
+ case EAI_SYSTEM: return UV_EAI_SYSTEM;
+#endif
+ }
+ assert(!"unknown EAI_* error code");
+ abort();
+ return 0; /* Pacify compiler. */
+}
diff --git a/third-party/libuv/src/uv-common.h b/third-party/libuv/src/uv-common.h
new file mode 100644
index 0000000000..3bcdcef3d4
--- /dev/null
+++ b/third-party/libuv/src/uv-common.h
@@ -0,0 +1,187 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * This file is private to libuv. It provides common functionality to both
+ * Windows and Unix backends.
+ */
+
+#ifndef UV_COMMON_H_
+#define UV_COMMON_H_
+
+#include <assert.h>
+#include <stddef.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#include "uv.h"
+#include "tree.h"
+#include "queue.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#define container_of(ptr, type, member) \
+ ((type *) ((char *) (ptr) - offsetof(type, member)))
+
+#ifndef _WIN32
+enum {
+ UV__HANDLE_INTERNAL = 0x8000,
+ UV__HANDLE_ACTIVE = 0x4000,
+ UV__HANDLE_REF = 0x2000,
+ UV__HANDLE_CLOSING = 0 /* no-op on unix */
+};
+#else
+# define UV__HANDLE_INTERNAL 0x80
+# define UV__HANDLE_ACTIVE 0x40
+# define UV__HANDLE_REF 0x20
+# define UV__HANDLE_CLOSING 0x01
+#endif
+
+int uv__tcp_bind(uv_tcp_t* tcp,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags);
+
+int uv__tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_connect_cb cb);
+
+int uv__udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags);
+
+int uv__udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_udp_send_cb send_cb);
+
+int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb,
+ uv_udp_recv_cb recv_cb);
+
+int uv__udp_recv_stop(uv_udp_t* handle);
+
+void uv__fs_poll_close(uv_fs_poll_t* handle);
+
+int uv__getaddrinfo_translate_error(int sys_err); /* EAI_* error. */
+
+#define uv__has_active_reqs(loop) \
+ (QUEUE_EMPTY(&(loop)->active_reqs) == 0)
+
+#define uv__req_register(loop, req) \
+ do { \
+ QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); \
+ } \
+ while (0)
+
+#define uv__req_unregister(loop, req) \
+ do { \
+ assert(uv__has_active_reqs(loop)); \
+ QUEUE_REMOVE(&(req)->active_queue); \
+ } \
+ while (0)
+
+#define uv__has_active_handles(loop) \
+ ((loop)->active_handles > 0)
+
+#define uv__active_handle_add(h) \
+ do { \
+ (h)->loop->active_handles++; \
+ } \
+ while (0)
+
+#define uv__active_handle_rm(h) \
+ do { \
+ (h)->loop->active_handles--; \
+ } \
+ while (0)
+
+#define uv__is_active(h) \
+ (((h)->flags & UV__HANDLE_ACTIVE) != 0)
+
+#define uv__is_closing(h) \
+ (((h)->flags & (UV_CLOSING | UV_CLOSED)) != 0)
+
+#define uv__handle_start(h) \
+ do { \
+ assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \
+ if (((h)->flags & UV__HANDLE_ACTIVE) != 0) break; \
+ (h)->flags |= UV__HANDLE_ACTIVE; \
+ if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_add(h); \
+ } \
+ while (0)
+
+#define uv__handle_stop(h) \
+ do { \
+ assert(((h)->flags & UV__HANDLE_CLOSING) == 0); \
+ if (((h)->flags & UV__HANDLE_ACTIVE) == 0) break; \
+ (h)->flags &= ~UV__HANDLE_ACTIVE; \
+ if (((h)->flags & UV__HANDLE_REF) != 0) uv__active_handle_rm(h); \
+ } \
+ while (0)
+
+#define uv__handle_ref(h) \
+ do { \
+ if (((h)->flags & UV__HANDLE_REF) != 0) break; \
+ (h)->flags |= UV__HANDLE_REF; \
+ if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \
+ if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \
+ } \
+ while (0)
+
+#define uv__handle_unref(h) \
+ do { \
+ if (((h)->flags & UV__HANDLE_REF) == 0) break; \
+ (h)->flags &= ~UV__HANDLE_REF; \
+ if (((h)->flags & UV__HANDLE_CLOSING) != 0) break; \
+ if (((h)->flags & UV__HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \
+ } \
+ while (0)
+
+#define uv__has_ref(h) \
+ (((h)->flags & UV__HANDLE_REF) != 0)
+
+#if defined(_WIN32)
+# define uv__handle_platform_init(h)
+#else
+# define uv__handle_platform_init(h) ((h)->next_closing = NULL)
+#endif
+
+#define uv__handle_init(loop_, h, type_) \
+ do { \
+ (h)->loop = (loop_); \
+ (h)->type = (type_); \
+ (h)->flags = UV__HANDLE_REF; /* Ref the loop when active. */ \
+ QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); \
+ uv__handle_platform_init(h); \
+ } \
+ while (0)
+
+#endif /* UV_COMMON_H_ */
diff --git a/third-party/libuv/src/version.c b/third-party/libuv/src/version.c
new file mode 100644
index 0000000000..0636348dae
--- /dev/null
+++ b/third-party/libuv/src/version.c
@@ -0,0 +1,63 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+
+ /*
+ * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
+ * stable. When the minor version is odd, the API can change between patch
+ * releases. Make sure you update the -soname directives in config-unix.mk
+ * and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
+ * not UV_VERSION_PATCH.)
+ */
+
+#define UV_VERSION_MAJOR 0
+#define UV_VERSION_MINOR 11
+#define UV_VERSION_PATCH 19
+#define UV_VERSION_IS_RELEASE 1
+
+
+#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
+ (UV_VERSION_MINOR << 8) | \
+ (UV_VERSION_PATCH))
+
+#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v)
+#define UV_STRINGIFY_HELPER(v) #v
+
+#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \
+ UV_STRINGIFY(UV_VERSION_MINOR) "." \
+ UV_STRINGIFY(UV_VERSION_PATCH)
+
+#if UV_VERSION_IS_RELEASE
+# define UV_VERSION_STRING UV_VERSION_STRING_BASE
+#else
+# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
+#endif
+
+
+unsigned int uv_version(void) {
+ return UV_VERSION;
+}
+
+
+const char* uv_version_string(void) {
+ return UV_VERSION_STRING;
+}
diff --git a/third-party/libuv/src/win/async.c b/third-party/libuv/src/win/async.c
new file mode 100644
index 0000000000..e192ead90d
--- /dev/null
+++ b/third-party/libuv/src/win/async.c
@@ -0,0 +1,99 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "atomicops-inl.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
+ if (handle->flags & UV__HANDLE_CLOSING &&
+ !handle->async_sent) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ uv__handle_close(handle);
+ }
+}
+
+
+int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
+ uv_req_t* req;
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC);
+ handle->async_sent = 0;
+ handle->async_cb = async_cb;
+
+ req = &handle->async_req;
+ uv_req_init(loop, req);
+ req->type = UV_WAKEUP;
+ req->data = handle;
+
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+void uv_async_close(uv_loop_t* loop, uv_async_t* handle) {
+ if (!((uv_async_t*)handle)->async_sent) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+
+ uv__handle_closing(handle);
+}
+
+
+int uv_async_send(uv_async_t* handle) {
+ uv_loop_t* loop = handle->loop;
+
+ if (handle->type != UV_ASYNC) {
+ /* Can't set errno because that's not thread-safe. */
+ return -1;
+ }
+
+ /* The user should make sure never to call uv_async_send to a closing */
+ /* or closed handle. */
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
+
+ if (!uv__atomic_exchange_set(&handle->async_sent)) {
+ POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
+ }
+
+ return 0;
+}
+
+
+void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
+ uv_req_t* req) {
+ assert(handle->type == UV_ASYNC);
+ assert(req->type == UV_WAKEUP);
+
+ handle->async_sent = 0;
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ } else if (handle->async_cb != NULL) {
+ handle->async_cb(handle, 0);
+ }
+}
diff --git a/third-party/libuv/src/win/atomicops-inl.h b/third-party/libuv/src/win/atomicops-inl.h
new file mode 100644
index 0000000000..61e006026c
--- /dev/null
+++ b/third-party/libuv/src/win/atomicops-inl.h
@@ -0,0 +1,56 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_ATOMICOPS_INL_H_
+#define UV_WIN_ATOMICOPS_INL_H_
+
+#include "uv.h"
+
+
+/* Atomic set operation on char */
+#ifdef _MSC_VER /* MSVC */
+
+/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
+/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
+/* exist, and interlocked operations on larger targets might require the */
+/* target to be aligned. */
+#pragma intrinsic(_InterlockedOr8)
+
+static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
+ return _InterlockedOr8(target, 1);
+}
+
+#else /* GCC */
+
+/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
+static inline char uv__atomic_exchange_set(char volatile* target) {
+ const char one = 1;
+ char old_value;
+ __asm__ __volatile__ ("lock xchgb %0, %1\n\t"
+ : "=r"(old_value), "=m"(*target)
+ : "0"(one), "m"(*target)
+ : "memory");
+ return old_value;
+}
+
+#endif
+
+#endif /* UV_WIN_ATOMICOPS_INL_H_ */
diff --git a/third-party/libuv/src/win/core.c b/third-party/libuv/src/win/core.c
new file mode 100644
index 0000000000..e1a77655ac
--- /dev/null
+++ b/third-party/libuv/src/win/core.c
@@ -0,0 +1,362 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <crtdbg.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+/* The only event loop we support right now */
+static uv_loop_t uv_default_loop_;
+
+/* uv_once intialization guards */
+static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
+static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
+
+
+#ifdef _DEBUG
+/* Our crt debug report handler allows us to temporarily disable asserts */
+/* just for the current thread. */
+
+__declspec( thread ) int uv__crt_assert_enabled = TRUE;
+
+static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
+ if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
+ return FALSE;
+
+ if (ret_val) {
+ /* Set ret_val to 0 to continue with normal execution. */
+ /* Set ret_val to 1 to trigger a breakpoint. */
+
+ if(IsDebuggerPresent())
+ *ret_val = 1;
+ else
+ *ret_val = 0;
+ }
+
+ /* Don't call _CrtDbgReport. */
+ return TRUE;
+}
+#endif
+
+
+static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
+ const wchar_t* function, const wchar_t * file, unsigned int line,
+ uintptr_t reserved) {
+ /* No-op. */
+}
+
+
+static void uv_init(void) {
+ /* Tell Windows that we will handle critical errors. */
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+
+ /* Tell the CRT to not exit the application when an invalid parameter is */
+ /* passed. The main issue is that invalid FDs will trigger this behavior. */
+#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
+ _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
+#endif
+
+ /* We also need to setup our debug report handler because some CRT */
+ /* functions (eg _get_osfhandle) raise an assert when called with invalid */
+ /* FDs even though they return the proper error code in the release build. */
+#ifdef _DEBUG
+ _CrtSetReportHook(uv__crt_dbg_report_handler);
+#endif
+
+ /* Fetch winapi function pointers. This must be done first because other */
+ /* intialization code might need these function pointers to be loaded. */
+ uv_winapi_init();
+
+ /* Initialize winsock */
+ uv_winsock_init();
+
+ /* Initialize FS */
+ uv_fs_init();
+
+ /* Initialize signal stuff */
+ uv_signals_init();
+
+ /* Initialize console */
+ uv_console_init();
+
+ /* Initialize utilities */
+ uv__util_init();
+}
+
+
+static void uv_loop_init(uv_loop_t* loop) {
+ /* Create an I/O completion port */
+ loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
+ if (loop->iocp == NULL) {
+ uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
+ }
+
+ /* To prevent uninitialized memory access, loop->time must be intialized */
+ /* to zero before calling uv_update_time for the first time. */
+ loop->time = 0;
+ loop->last_tick_count = 0;
+ uv_update_time(loop);
+
+ QUEUE_INIT(&loop->handle_queue);
+ QUEUE_INIT(&loop->active_reqs);
+ loop->active_handles = 0;
+
+ loop->pending_reqs_tail = NULL;
+
+ loop->endgame_handles = NULL;
+
+ RB_INIT(&loop->timers);
+
+ loop->check_handles = NULL;
+ loop->prepare_handles = NULL;
+ loop->idle_handles = NULL;
+
+ loop->next_prepare_handle = NULL;
+ loop->next_check_handle = NULL;
+ loop->next_idle_handle = NULL;
+
+ memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
+
+ loop->active_tcp_streams = 0;
+ loop->active_udp_streams = 0;
+
+ loop->timer_counter = 0;
+ loop->stop_flag = 0;
+}
+
+
+static void uv_default_loop_init(void) {
+ /* Initialize libuv itself first */
+ uv__once_init();
+
+ /* Initialize the main loop */
+ uv_loop_init(&uv_default_loop_);
+}
+
+
+void uv__once_init(void) {
+ uv_once(&uv_init_guard_, uv_init);
+}
+
+
+uv_loop_t* uv_default_loop(void) {
+ uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
+ return &uv_default_loop_;
+}
+
+
+uv_loop_t* uv_loop_new(void) {
+ uv_loop_t* loop;
+
+ /* Initialize libuv itself first */
+ uv__once_init();
+
+ loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
+
+ if (!loop) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ uv_loop_init(loop);
+ return loop;
+}
+
+
+void uv_loop_delete(uv_loop_t* loop) {
+ if (loop != &uv_default_loop_) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
+ SOCKET sock = loop->poll_peer_sockets[i];
+ if (sock != 0 && sock != INVALID_SOCKET) {
+ closesocket(sock);
+ }
+ }
+
+ free(loop);
+ }
+}
+
+
+int uv_backend_fd(const uv_loop_t* loop) {
+ return -1;
+}
+
+
+int uv_backend_timeout(const uv_loop_t* loop) {
+ return 0;
+}
+
+
+static void uv_poll(uv_loop_t* loop, int block) {
+ DWORD bytes, timeout;
+ ULONG_PTR key;
+ OVERLAPPED* overlapped;
+ uv_req_t* req;
+
+ if (block) {
+ timeout = uv_get_poll_timeout(loop);
+ } else {
+ timeout = 0;
+ }
+
+ GetQueuedCompletionStatus(loop->iocp,
+ &bytes,
+ &key,
+ &overlapped,
+ timeout);
+
+ if (overlapped) {
+ /* Package was dequeued */
+ req = uv_overlapped_to_req(overlapped);
+ uv_insert_pending_req(loop, req);
+ } else if (GetLastError() != WAIT_TIMEOUT) {
+ /* Serious error */
+ uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
+ } else {
+ /* We're sure that at least `timeout` milliseconds have expired, but */
+ /* this may not be reflected yet in the GetTickCount() return value. */
+ /* Therefore we ensure it's taken into account here. */
+ uv__time_forward(loop, timeout);
+ }
+}
+
+
+static void uv_poll_ex(uv_loop_t* loop, int block) {
+ BOOL success;
+ DWORD timeout;
+ uv_req_t* req;
+ OVERLAPPED_ENTRY overlappeds[128];
+ ULONG count;
+ ULONG i;
+
+ if (block) {
+ timeout = uv_get_poll_timeout(loop);
+ } else {
+ timeout = 0;
+ }
+
+ success = pGetQueuedCompletionStatusEx(loop->iocp,
+ overlappeds,
+ ARRAY_SIZE(overlappeds),
+ &count,
+ timeout,
+ FALSE);
+
+ if (success) {
+ for (i = 0; i < count; i++) {
+ /* Package was dequeued */
+ req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
+ uv_insert_pending_req(loop, req);
+ }
+ } else if (GetLastError() != WAIT_TIMEOUT) {
+ /* Serious error */
+ uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
+ } else if (timeout > 0) {
+ /* We're sure that at least `timeout` milliseconds have expired, but */
+ /* this may not be reflected yet in the GetTickCount() return value. */
+ /* Therefore we ensure it's taken into account here. */
+ uv__time_forward(loop, timeout);
+ }
+}
+
+
+static int uv__loop_alive(const uv_loop_t* loop) {
+ return loop->active_handles > 0 ||
+ !QUEUE_EMPTY(&loop->active_reqs) ||
+ loop->endgame_handles != NULL;
+}
+
+
+int uv_loop_alive(const uv_loop_t* loop) {
+ return uv__loop_alive(loop);
+}
+
+
+int uv_run(uv_loop_t *loop, uv_run_mode mode) {
+ int r;
+ void (*poll)(uv_loop_t* loop, int block);
+
+ if (pGetQueuedCompletionStatusEx)
+ poll = &uv_poll_ex;
+ else
+ poll = &uv_poll;
+
+ r = uv__loop_alive(loop);
+ if (!r)
+ uv_update_time(loop);
+
+ while (r != 0 && loop->stop_flag == 0) {
+ uv_update_time(loop);
+ uv_process_timers(loop);
+
+ uv_process_reqs(loop);
+ uv_idle_invoke(loop);
+ uv_prepare_invoke(loop);
+
+ (*poll)(loop, loop->idle_handles == NULL &&
+ loop->pending_reqs_tail == NULL &&
+ loop->endgame_handles == NULL &&
+ !loop->stop_flag &&
+ (loop->active_handles > 0 ||
+ !QUEUE_EMPTY(&loop->active_reqs)) &&
+ !(mode & UV_RUN_NOWAIT));
+
+ uv_check_invoke(loop);
+ uv_process_endgames(loop);
+
+ if (mode == UV_RUN_ONCE) {
+ /* UV_RUN_ONCE implies forward progess: at least one callback must have
+ * been invoked when it returns. uv__io_poll() can return without doing
+ * I/O (meaning: no callbacks) when its timeout expires - which means we
+ * have pending timers that satisfy the forward progress constraint.
+ *
+ * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
+ * the check.
+ */
+ uv_update_time(loop);
+ uv_process_timers(loop);
+ }
+
+ r = uv__loop_alive(loop);
+ if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
+ break;
+ }
+
+ /* The if statement lets the compiler compile it to a conditional store.
+ * Avoids dirtying a cache line.
+ */
+ if (loop->stop_flag != 0)
+ loop->stop_flag = 0;
+
+ return r;
+}
diff --git a/third-party/libuv/src/win/dl.c b/third-party/libuv/src/win/dl.c
new file mode 100644
index 0000000000..d5b8f7c7d3
--- /dev/null
+++ b/third-party/libuv/src/win/dl.c
@@ -0,0 +1,86 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+static int uv__dlerror(uv_lib_t* lib, int errorno);
+
+
+int uv_dlopen(const char* filename, uv_lib_t* lib) {
+ WCHAR filename_w[32768];
+
+ lib->handle = NULL;
+ lib->errmsg = NULL;
+
+ if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) {
+ return uv__dlerror(lib, GetLastError());
+ }
+
+ lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (lib->handle == NULL) {
+ return uv__dlerror(lib, GetLastError());
+ }
+
+ return 0;
+}
+
+
+void uv_dlclose(uv_lib_t* lib) {
+ if (lib->errmsg) {
+ LocalFree((void*)lib->errmsg);
+ lib->errmsg = NULL;
+ }
+
+ if (lib->handle) {
+ /* Ignore errors. No good way to signal them without leaking memory. */
+ FreeLibrary(lib->handle);
+ lib->handle = NULL;
+ }
+}
+
+
+int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
+ *ptr = (void*) GetProcAddress(lib->handle, name);
+ return uv__dlerror(lib, *ptr ? 0 : GetLastError());
+}
+
+
+const char* uv_dlerror(uv_lib_t* lib) {
+ return lib->errmsg ? lib->errmsg : "no error";
+}
+
+
+static int uv__dlerror(uv_lib_t* lib, int errorno) {
+ if (lib->errmsg) {
+ LocalFree((void*)lib->errmsg);
+ lib->errmsg = NULL;
+ }
+
+ if (errorno) {
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ (LPSTR)&lib->errmsg, 0, NULL);
+ }
+
+ return errorno ? -1 : 0;
+}
diff --git a/third-party/libuv/src/win/error.c b/third-party/libuv/src/win/error.c
new file mode 100644
index 0000000000..3162bc787f
--- /dev/null
+++ b/third-party/libuv/src/win/error.c
@@ -0,0 +1,169 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/*
+ * Display an error message and abort the event loop.
+ */
+void uv_fatal_error(const int errorno, const char* syscall) {
+ char* buf = NULL;
+ const char* errmsg;
+
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL);
+
+ if (buf) {
+ errmsg = buf;
+ } else {
+ errmsg = "Unknown error";
+ }
+
+ /* FormatMessage messages include a newline character already, */
+ /* so don't add another. */
+ if (syscall) {
+ fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
+ } else {
+ fprintf(stderr, "(%d) %s", errorno, errmsg);
+ }
+
+ if (buf) {
+ LocalFree(buf);
+ }
+
+ *((char*)NULL) = 0xff; /* Force debug break */
+ abort();
+}
+
+
+int uv_translate_sys_error(int sys_errno) {
+ if (sys_errno <= 0) {
+ return sys_errno; /* If < 0 then it's already a libuv error. */
+ }
+
+ switch (sys_errno) {
+ case ERROR_NOACCESS: return UV_EACCES;
+ case WSAEACCES: return UV_EACCES;
+ case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
+ case WSAEADDRINUSE: return UV_EADDRINUSE;
+ case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
+ case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
+ case WSAEWOULDBLOCK: return UV_EAGAIN;
+ case WSAEALREADY: return UV_EALREADY;
+ case ERROR_INVALID_FLAGS: return UV_EBADF;
+ case ERROR_INVALID_HANDLE: return UV_EBADF;
+ case ERROR_LOCK_VIOLATION: return UV_EBUSY;
+ case ERROR_PIPE_BUSY: return UV_EBUSY;
+ case ERROR_SHARING_VIOLATION: return UV_EBUSY;
+ case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
+ case WSAEINTR: return UV_ECANCELED;
+ case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
+ case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
+ case WSAECONNABORTED: return UV_ECONNABORTED;
+ case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
+ case WSAECONNREFUSED: return UV_ECONNREFUSED;
+ case ERROR_NETNAME_DELETED: return UV_ECONNRESET;
+ case WSAECONNRESET: return UV_ECONNRESET;
+ case ERROR_ALREADY_EXISTS: return UV_EEXIST;
+ case ERROR_FILE_EXISTS: return UV_EEXIST;
+ case ERROR_BUFFER_OVERFLOW: return UV_EFAULT;
+ case WSAEFAULT: return UV_EFAULT;
+ case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
+ case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
+ case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
+ case ERROR_INVALID_DATA: return UV_EINVAL;
+ case ERROR_INVALID_PARAMETER: return UV_EINVAL;
+ case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
+ case WSAEINVAL: return UV_EINVAL;
+ case WSAEPFNOSUPPORT: return UV_EINVAL;
+ case WSAESOCKTNOSUPPORT: return UV_EINVAL;
+ case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
+ case ERROR_BUS_RESET: return UV_EIO;
+ case ERROR_CRC: return UV_EIO;
+ case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
+ case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
+ case ERROR_DISK_CORRUPT: return UV_EIO;
+ case ERROR_EOM_OVERFLOW: return UV_EIO;
+ case ERROR_FILEMARK_DETECTED: return UV_EIO;
+ case ERROR_GEN_FAILURE: return UV_EIO;
+ case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
+ case ERROR_IO_DEVICE: return UV_EIO;
+ case ERROR_NO_DATA_DETECTED: return UV_EIO;
+ case ERROR_NO_SIGNAL_SENT: return UV_EIO;
+ case ERROR_OPEN_FAILED: return UV_EIO;
+ case ERROR_SETMARK_DETECTED: return UV_EIO;
+ case ERROR_SIGNAL_REFUSED: return UV_EIO;
+ case WSAEISCONN: return UV_EISCONN;
+ case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
+ case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
+ case WSAEMFILE: return UV_EMFILE;
+ case WSAEMSGSIZE: return UV_EMSGSIZE;
+ case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG;
+ case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
+ case WSAENETUNREACH: return UV_ENETUNREACH;
+ case WSAENOBUFS: return UV_ENOBUFS;
+ case ERROR_DIRECTORY: return UV_ENOENT;
+ case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
+ case ERROR_INVALID_NAME: return UV_ENOENT;
+ case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
+ case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
+ case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
+ case WSAHOST_NOT_FOUND: return UV_ENOENT;
+ case WSANO_DATA: return UV_ENOENT;
+ case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
+ case ERROR_OUTOFMEMORY: return UV_ENOMEM;
+ case ERROR_CANNOT_MAKE: return UV_ENOSPC;
+ case ERROR_DISK_FULL: return UV_ENOSPC;
+ case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
+ case ERROR_END_OF_MEDIA: return UV_ENOSPC;
+ case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
+ case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
+ case WSAENOTCONN: return UV_ENOTCONN;
+ case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
+ case WSAENOTSOCK: return UV_ENOTSOCK;
+ case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
+ case ERROR_BROKEN_PIPE: return UV_EOF;
+ case ERROR_ACCESS_DENIED: return UV_EPERM;
+ case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
+ case ERROR_BAD_PIPE: return UV_EPIPE;
+ case ERROR_NO_DATA: return UV_EPIPE;
+ case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
+ case WSAESHUTDOWN: return UV_EPIPE;
+ case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
+ case ERROR_WRITE_PROTECT: return UV_EROFS;
+ case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
+ case WSAETIMEDOUT: return UV_ETIMEDOUT;
+ case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
+ case ERROR_INVALID_FUNCTION: return UV_EISDIR;
+ case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG;
+ default: return UV_UNKNOWN;
+ }
+}
diff --git a/third-party/libuv/src/win/fs-event.c b/third-party/libuv/src/win/fs-event.c
new file mode 100644
index 0000000000..6132b79c82
--- /dev/null
+++ b/third-party/libuv/src/win/fs-event.c
@@ -0,0 +1,527 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <malloc.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+const unsigned int uv_directory_watcher_buffer_size = 4096;
+
+
+static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
+ uv_fs_event_t* handle) {
+ assert(handle->dir_handle != INVALID_HANDLE_VALUE);
+ assert(!handle->req_pending);
+
+ memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
+ if (!ReadDirectoryChangesW(handle->dir_handle,
+ handle->buffer,
+ uv_directory_watcher_buffer_size,
+ FALSE,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE |
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
+ FILE_NOTIFY_CHANGE_CREATION |
+ FILE_NOTIFY_CHANGE_SECURITY,
+ NULL,
+ &handle->req.overlapped,
+ NULL)) {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(&handle->req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)&handle->req);
+ }
+
+ handle->req_pending = 1;
+}
+
+
+static int uv_split_path(const WCHAR* filename, WCHAR** dir,
+ WCHAR** file) {
+ int len = wcslen(filename);
+ int i = len;
+ while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
+
+ if (i == 0) {
+ if (dir) {
+ *dir = (WCHAR*)malloc((MAX_PATH + 1) * sizeof(WCHAR));
+ if (!*dir) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
+ free(*dir);
+ *dir = NULL;
+ return -1;
+ }
+ }
+
+ *file = wcsdup(filename);
+ } else {
+ if (dir) {
+ *dir = (WCHAR*)malloc((i + 1) * sizeof(WCHAR));
+ if (!*dir) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+ wcsncpy(*dir, filename, i);
+ (*dir)[i] = L'\0';
+ }
+
+ *file = (WCHAR*)malloc((len - i) * sizeof(WCHAR));
+ if (!*file) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+ wcsncpy(*file, filename + i + 1, len - i - 1);
+ (*file)[len - i - 1] = L'\0';
+ }
+
+ return 0;
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT);
+ handle->dir_handle = INVALID_HANDLE_VALUE;
+ handle->buffer = NULL;
+ handle->req_pending = 0;
+ handle->filew = NULL;
+ handle->short_filew = NULL;
+ handle->dirw = NULL;
+
+ uv_req_init(loop, (uv_req_t*)&handle->req);
+ handle->req.type = UV_FS_EVENT_REQ;
+ handle->req.data = handle;
+
+ return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+ uv_fs_event_cb cb,
+ const char* filename,
+ unsigned int flags) {
+ int name_size, is_path_dir;
+ DWORD attr, last_error;
+ WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
+ WCHAR short_path[MAX_PATH];
+
+ if (uv__is_active(handle))
+ return UV_EINVAL;
+
+ handle->cb = cb;
+ handle->filename = strdup(filename);
+ if (!handle->filename) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ uv__handle_start(handle);
+
+ /* Convert name to UTF16. */
+ name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR);
+ filenamew = (WCHAR*)malloc(name_size);
+ if (!filenamew) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ if (!uv_utf8_to_utf16(filename, filenamew,
+ name_size / sizeof(WCHAR))) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /* Determine whether filename is a file or a directory. */
+ attr = GetFileAttributesW(filenamew);
+ if (attr == INVALID_FILE_ATTRIBUTES) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
+
+ if (is_path_dir) {
+ /* filename is a directory, so that's the directory that we will watch. */
+ handle->dirw = filenamew;
+ dir_to_watch = filenamew;
+ } else {
+ /*
+ * filename is a file. So we split filename into dir & file parts, and
+ * watch the dir directory.
+ */
+
+ /* Convert to short path. */
+ if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ if (uv_split_path(filenamew, &dir, &handle->filew) != 0) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ dir_to_watch = dir;
+ free(filenamew);
+ filenamew = NULL;
+ }
+
+ handle->dir_handle = CreateFileW(dir_to_watch,
+ FILE_LIST_DIRECTORY,
+ FILE_SHARE_READ | FILE_SHARE_DELETE |
+ FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (dir) {
+ free(dir);
+ dir = NULL;
+ }
+
+ if (handle->dir_handle == INVALID_HANDLE_VALUE) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ if (CreateIoCompletionPort(handle->dir_handle,
+ handle->loop->iocp,
+ (ULONG_PTR)handle,
+ 0) == NULL) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ if (!handle->buffer) {
+ handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size,
+ sizeof(DWORD));
+ }
+ if (!handle->buffer) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped));
+
+ if (!ReadDirectoryChangesW(handle->dir_handle,
+ handle->buffer,
+ uv_directory_watcher_buffer_size,
+ FALSE,
+ FILE_NOTIFY_CHANGE_FILE_NAME |
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_SIZE |
+ FILE_NOTIFY_CHANGE_LAST_WRITE |
+ FILE_NOTIFY_CHANGE_LAST_ACCESS |
+ FILE_NOTIFY_CHANGE_CREATION |
+ FILE_NOTIFY_CHANGE_SECURITY,
+ NULL,
+ &handle->req.overlapped,
+ NULL)) {
+ last_error = GetLastError();
+ goto error;
+ }
+
+ handle->req_pending = 1;
+ return 0;
+
+error:
+ if (handle->filename) {
+ free(handle->filename);
+ handle->filename = NULL;
+ }
+
+ if (handle->filew) {
+ free(handle->filew);
+ handle->filew = NULL;
+ }
+
+ if (handle->short_filew) {
+ free(handle->short_filew);
+ handle->short_filew = NULL;
+ }
+
+ free(filenamew);
+
+ if (handle->dir_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle->dir_handle);
+ handle->dir_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (handle->buffer) {
+ _aligned_free(handle->buffer);
+ handle->buffer = NULL;
+ }
+
+ return uv_translate_sys_error(last_error);
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+ if (!uv__is_active(handle))
+ return UV_EINVAL;
+
+ if (handle->dir_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle->dir_handle);
+ handle->dir_handle = INVALID_HANDLE_VALUE;
+ }
+
+ uv__handle_stop(handle);
+
+ if (handle->filew) {
+ free(handle->filew);
+ handle->filew = NULL;
+ }
+
+ if (handle->short_filew) {
+ free(handle->short_filew);
+ handle->short_filew = NULL;
+ }
+
+ if (handle->filename) {
+ free(handle->filename);
+ handle->filename = NULL;
+ }
+
+ if (handle->dirw) {
+ free(handle->dirw);
+ handle->dirw = NULL;
+ }
+
+ return 0;
+}
+
+
+void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
+ uv_fs_event_t* handle) {
+ FILE_NOTIFY_INFORMATION* file_info;
+ int err, sizew, size, result;
+ char* filename = NULL;
+ WCHAR* filenamew, *long_filenamew = NULL;
+ DWORD offset = 0;
+
+ assert(req->type == UV_FS_EVENT_REQ);
+ assert(handle->req_pending);
+ handle->req_pending = 0;
+
+ /* Don't report any callbacks if:
+ * - We're closing, just push the handle onto the endgame queue
+ * - We are not active, just ignore the callback
+ */
+ if (!uv__is_active(handle)) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+ return;
+ }
+
+ file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
+
+ if (REQ_SUCCESS(req)) {
+ if (req->overlapped.InternalHigh > 0) {
+ do {
+ file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
+ assert(!filename);
+ assert(!long_filenamew);
+
+ /*
+ * Fire the event only if we were asked to watch a directory,
+ * or if the filename filter matches.
+ */
+ if (handle->dirw ||
+ _wcsnicmp(handle->filew, file_info->FileName,
+ file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
+ _wcsnicmp(handle->short_filew, file_info->FileName,
+ file_info->FileNameLength / sizeof(WCHAR)) == 0) {
+
+ if (handle->dirw) {
+ /*
+ * We attempt to convert the file name to its long form for
+ * events that still point to valid files on disk.
+ * For removed and renamed events, we do not provide the file name.
+ */
+ if (file_info->Action != FILE_ACTION_REMOVED &&
+ file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
+ /* Construct a full path to the file. */
+ size = wcslen(handle->dirw) +
+ file_info->FileNameLength / sizeof(WCHAR) + 2;
+
+ filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
+ if (!filenamew) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
+ file_info->FileNameLength / sizeof(WCHAR),
+ file_info->FileName);
+
+ filenamew[size - 1] = L'\0';
+
+ /* Convert to long name. */
+ size = GetLongPathNameW(filenamew, NULL, 0);
+
+ if (size) {
+ long_filenamew = (WCHAR*)malloc(size * sizeof(WCHAR));
+ if (!long_filenamew) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ size = GetLongPathNameW(filenamew, long_filenamew, size);
+ if (size) {
+ long_filenamew[size] = '\0';
+ } else {
+ free(long_filenamew);
+ long_filenamew = NULL;
+ }
+ }
+
+ free(filenamew);
+
+ if (long_filenamew) {
+ /* Get the file name out of the long path. */
+ result = uv_split_path(long_filenamew, NULL, &filenamew);
+ free(long_filenamew);
+
+ if (result == 0) {
+ long_filenamew = filenamew;
+ sizew = -1;
+ } else {
+ long_filenamew = NULL;
+ }
+ }
+
+ /*
+ * If we couldn't get the long name - just use the name
+ * provided by ReadDirectoryChangesW.
+ */
+ if (!long_filenamew) {
+ filenamew = file_info->FileName;
+ sizew = file_info->FileNameLength / sizeof(WCHAR);
+ }
+ } else {
+ /* Removed or renamed callbacks don't provide filename. */
+ filenamew = NULL;
+ }
+ } else {
+ /* We already have the long name of the file, so just use it. */
+ filenamew = handle->filew;
+ sizew = -1;
+ }
+
+ if (filenamew) {
+ /* Convert the filename to utf8. */
+ size = uv_utf16_to_utf8(filenamew,
+ sizew,
+ NULL,
+ 0);
+ if (size) {
+ filename = (char*)malloc(size + 1);
+ if (!filename) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ size = uv_utf16_to_utf8(filenamew,
+ sizew,
+ filename,
+ size);
+ if (size) {
+ filename[size] = '\0';
+ } else {
+ free(filename);
+ filename = NULL;
+ }
+ }
+ }
+
+ switch (file_info->Action) {
+ case FILE_ACTION_ADDED:
+ case FILE_ACTION_REMOVED:
+ case FILE_ACTION_RENAMED_OLD_NAME:
+ case FILE_ACTION_RENAMED_NEW_NAME:
+ handle->cb(handle, filename, UV_RENAME, 0);
+ break;
+
+ case FILE_ACTION_MODIFIED:
+ handle->cb(handle, filename, UV_CHANGE, 0);
+ break;
+ }
+
+ free(filename);
+ filename = NULL;
+ free(long_filenamew);
+ long_filenamew = NULL;
+ }
+
+ offset = file_info->NextEntryOffset;
+ } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
+ } else {
+ handle->cb(handle, NULL, UV_CHANGE, 0);
+ }
+ } else {
+ err = GET_REQ_ERROR(req);
+ handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
+ }
+
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
+ uv_fs_event_queue_readdirchanges(loop, handle);
+ } else {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+}
+
+
+void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
+ uv_fs_event_stop(handle);
+
+ uv__handle_closing(handle);
+
+ if (!handle->req_pending) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+
+}
+
+
+void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
+ if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ if (handle->buffer) {
+ _aligned_free(handle->buffer);
+ handle->buffer = NULL;
+ }
+
+ uv__handle_close(handle);
+ }
+}
diff --git a/third-party/libuv/src/win/fs.c b/third-party/libuv/src/win/fs.c
new file mode 100644
index 0000000000..c4182758c7
--- /dev/null
+++ b/third-party/libuv/src/win/fs.c
@@ -0,0 +1,2043 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <direct.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/utime.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+#include "handle-inl.h"
+
+
+#define UV_FS_FREE_PATHS 0x0002
+#define UV_FS_FREE_PTR 0x0008
+#define UV_FS_CLEANEDUP 0x0010
+
+
+#define QUEUE_FS_TP_JOB(loop, req) \
+ do { \
+ if (!QueueUserWorkItem(&uv_fs_thread_proc, \
+ req, \
+ WT_EXECUTEDEFAULT)) { \
+ return uv_translate_sys_error(GetLastError()); \
+ } \
+ uv__req_register(loop, req); \
+ } while (0)
+
+#define SET_REQ_RESULT(req, result_value) \
+ do { \
+ req->result = (result_value); \
+ if (req->result == -1) { \
+ req->sys_errno_ = _doserrno; \
+ req->result = uv_translate_sys_error(req->sys_errno_); \
+ } \
+ } while (0)
+
+#define SET_REQ_WIN32_ERROR(req, sys_errno) \
+ do { \
+ req->sys_errno_ = (sys_errno); \
+ req->result = uv_translate_sys_error(req->sys_errno_); \
+ } while (0)
+
+#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \
+ do { \
+ req->result = (uv_errno); \
+ req->sys_errno_ = (sys_errno); \
+ } while (0)
+
+#define VERIFY_FD(fd, req) \
+ if (fd == -1) { \
+ req->result = UV_EBADF; \
+ req->sys_errno_ = ERROR_INVALID_HANDLE; \
+ return; \
+ }
+
+#define FILETIME_TO_UINT(filetime) \
+ (*((uint64_t*) &(filetime)) - 116444736000000000ULL)
+
+#define FILETIME_TO_TIME_T(filetime) \
+ (FILETIME_TO_UINT(filetime) / 10000000ULL)
+
+#define FILETIME_TO_TIME_NS(filetime, secs) \
+ ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100)
+
+#define FILETIME_TO_TIMESPEC(ts, filetime) \
+ do { \
+ (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \
+ (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \
+ } while(0)
+
+#define TIME_T_TO_FILETIME(time, filetime_ptr) \
+ do { \
+ *(uint64_t*) (filetime_ptr) = ((int64_t) (time) * 10000000LL) + \
+ 116444736000000000ULL; \
+ } while(0)
+
+#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/')
+#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \
+ ((c) >= L'A' && (c) <= L'Z'))
+
+const WCHAR JUNCTION_PREFIX[] = L"\\??\\";
+const WCHAR JUNCTION_PREFIX_LEN = 4;
+
+const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\";
+const WCHAR LONG_PATH_PREFIX_LEN = 4;
+
+
+void uv_fs_init() {
+ _fmode = _O_BINARY;
+}
+
+
+INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
+ const char* path, const char* new_path, const int copy_path) {
+ char* buf;
+ char* pos;
+ ssize_t buf_sz = 0, path_len, pathw_len, new_pathw_len;
+
+ /* new_path can only be set if path is also set. */
+ assert(new_path == NULL || path != NULL);
+
+ if (path != NULL) {
+ pathw_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ path,
+ -1,
+ NULL,
+ 0);
+ if (pathw_len == 0) {
+ return GetLastError();
+ }
+
+ buf_sz += pathw_len * sizeof(WCHAR);
+ }
+
+ if (path != NULL && copy_path) {
+ path_len = 1 + strlen(path);
+ buf_sz += path_len;
+ }
+
+ if (new_path != NULL) {
+ new_pathw_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ new_path,
+ -1,
+ NULL,
+ 0);
+ if (new_pathw_len == 0) {
+ return GetLastError();
+ }
+
+ buf_sz += new_pathw_len * sizeof(WCHAR);
+ }
+
+
+ if (buf_sz == 0) {
+ req->pathw = NULL;
+ req->new_pathw = NULL;
+ req->path = NULL;
+ return 0;
+ }
+
+ buf = (char*) malloc(buf_sz);
+ if (buf == NULL) {
+ return ERROR_OUTOFMEMORY;
+ }
+
+ pos = buf;
+
+ if (path != NULL) {
+ DWORD r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ path,
+ -1,
+ (WCHAR*) pos,
+ pathw_len);
+ assert(r == pathw_len);
+ req->pathw = (WCHAR*) pos;
+ pos += r * sizeof(WCHAR);
+ } else {
+ req->pathw = NULL;
+ }
+
+ if (new_path != NULL) {
+ DWORD r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ new_path,
+ -1,
+ (WCHAR*) pos,
+ new_pathw_len);
+ assert(r == new_pathw_len);
+ req->new_pathw = (WCHAR*) pos;
+ pos += r * sizeof(WCHAR);
+ } else {
+ req->new_pathw = NULL;
+ }
+
+ if (!copy_path) {
+ req->path = path;
+ } else if (path) {
+ memcpy(pos, path, path_len);
+ assert(path_len == buf_sz - (pos - buf));
+ req->path = pos;
+ } else {
+ req->path = NULL;
+ }
+
+ req->flags |= UV_FS_FREE_PATHS;
+
+ return 0;
+}
+
+
+
+INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
+ uv_fs_type fs_type, const uv_fs_cb cb) {
+ uv_req_init(loop, (uv_req_t*) req);
+
+ req->type = UV_FS;
+ req->loop = loop;
+ req->flags = 0;
+ req->fs_type = fs_type;
+ req->result = 0;
+ req->ptr = NULL;
+ req->path = NULL;
+
+ if (cb != NULL) {
+ req->cb = cb;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+ }
+}
+
+
+INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
+ uint64_t* target_len_ptr) {
+ char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
+ WCHAR *w_target;
+ DWORD w_target_len;
+ char* target;
+ int target_len;
+ DWORD bytes;
+
+ if (!DeviceIoControl(handle,
+ FSCTL_GET_REPARSE_POINT,
+ NULL,
+ 0,
+ buffer,
+ sizeof buffer,
+ &bytes,
+ NULL)) {
+ return -1;
+ }
+
+ if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+ /* Real symlink */
+ w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer +
+ (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset /
+ sizeof(WCHAR));
+ w_target_len =
+ reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
+ sizeof(WCHAR);
+
+ /* Real symlinks can contain pretty much everything, but the only thing */
+ /* we really care about is undoing the implicit conversion to an NT */
+ /* namespaced path that CreateSymbolicLink will perform on absolute */
+ /* paths. If the path is win32-namespaced then the user must have */
+ /* explicitly made it so, and we better just return the unmodified */
+ /* reparse data. */
+ if (w_target_len >= 4 &&
+ w_target[0] == L'\\' &&
+ w_target[1] == L'?' &&
+ w_target[2] == L'?' &&
+ w_target[3] == L'\\') {
+ /* Starts with \??\ */
+ if (w_target_len >= 6 &&
+ ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
+ (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
+ w_target[5] == L':' &&
+ (w_target_len == 6 || w_target[6] == L'\\')) {
+ /* \??\«drive»:\ */
+ w_target += 4;
+ w_target_len -= 4;
+
+ } else if (w_target_len >= 8 &&
+ (w_target[4] == L'U' || w_target[4] == L'u') &&
+ (w_target[5] == L'N' || w_target[5] == L'n') &&
+ (w_target[6] == L'C' || w_target[6] == L'c') &&
+ w_target[7] == L'\\') {
+ /* \??\UNC\«server»\«share»\ - make sure the final path looks like */
+ /* \\«server»\«share»\ */
+ w_target += 6;
+ w_target[0] = L'\\';
+ w_target_len -= 6;
+ }
+ }
+
+ } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+ /* Junction. */
+ w_target = reparse_data->MountPointReparseBuffer.PathBuffer +
+ (reparse_data->MountPointReparseBuffer.SubstituteNameOffset /
+ sizeof(WCHAR));
+ w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
+ sizeof(WCHAR);
+
+ /* Only treat junctions that look like \??\«drive»:\ as symlink. */
+ /* Junctions can also be used as mount points, like \??\Volume{«guid»}, */
+ /* but that's confusing for programs since they wouldn't be able to */
+ /* actually understand such a path when returned by uv_readlink(). */
+ /* UNC paths are never valid for junctions so we don't care about them. */
+ if (!(w_target_len >= 6 &&
+ w_target[0] == L'\\' &&
+ w_target[1] == L'?' &&
+ w_target[2] == L'?' &&
+ w_target[3] == L'\\' &&
+ ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
+ (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
+ w_target[5] == L':' &&
+ (w_target_len == 6 || w_target[6] == L'\\'))) {
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+
+ /* Remove leading \??\ */
+ w_target += 4;
+ w_target_len -= 4;
+
+ } else {
+ /* Reparse tag does not indicate a symlink. */
+ SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+ return -1;
+ }
+
+ /* If needed, compute the length of the target. */
+ if (target_ptr != NULL || target_len_ptr != NULL) {
+ /* Compute the length of the target. */
+ target_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ w_target,
+ w_target_len,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (target_len == 0) {
+ return -1;
+ }
+ }
+
+ /* If requested, allocate memory and convert to UTF8. */
+ if (target_ptr != NULL) {
+ int r;
+ target = (char*) malloc(target_len + 1);
+ if (target == NULL) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return -1;
+ }
+
+ r = WideCharToMultiByte(CP_UTF8,
+ 0,
+ w_target,
+ w_target_len,
+ target,
+ target_len,
+ NULL,
+ NULL);
+ assert(r == target_len);
+ target[target_len] = '\0';
+
+ *target_ptr = target;
+ }
+
+ if (target_len_ptr != NULL) {
+ *target_len_ptr = target_len;
+ }
+
+ return 0;
+}
+
+
+void fs__open(uv_fs_t* req) {
+ DWORD access;
+ DWORD share;
+ DWORD disposition;
+ DWORD attributes = 0;
+ HANDLE file;
+ int fd, current_umask;
+ int flags = req->file_flags;
+
+ /* Obtain the active umask. umask() never fails and returns the previous */
+ /* umask. */
+ current_umask = umask(0);
+ umask(current_umask);
+
+ /* convert flags and mode to CreateFile parameters */
+ switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
+ case _O_RDONLY:
+ access = FILE_GENERIC_READ;
+ attributes |= FILE_FLAG_BACKUP_SEMANTICS;
+ break;
+ case _O_WRONLY:
+ access = FILE_GENERIC_WRITE;
+ break;
+ case _O_RDWR:
+ access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
+ break;
+ default:
+ goto einval;
+ }
+
+ if (flags & _O_APPEND) {
+ access &= ~FILE_WRITE_DATA;
+ access |= FILE_APPEND_DATA;
+ attributes &= ~FILE_FLAG_BACKUP_SEMANTICS;
+ }
+
+ /*
+ * Here is where we deviate significantly from what CRT's _open()
+ * does. We indiscriminately use all the sharing modes, to match
+ * UNIX semantics. In particular, this ensures that the file can
+ * be deleted even whilst it's open, fixing issue #1449.
+ */
+ share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+
+ switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+ case 0:
+ case _O_EXCL:
+ disposition = OPEN_EXISTING;
+ break;
+ case _O_CREAT:
+ disposition = OPEN_ALWAYS;
+ break;
+ case _O_CREAT | _O_EXCL:
+ case _O_CREAT | _O_TRUNC | _O_EXCL:
+ disposition = CREATE_NEW;
+ break;
+ case _O_TRUNC:
+ case _O_TRUNC | _O_EXCL:
+ disposition = TRUNCATE_EXISTING;
+ break;
+ case _O_CREAT | _O_TRUNC:
+ disposition = CREATE_ALWAYS;
+ break;
+ default:
+ goto einval;
+ }
+
+ attributes |= FILE_ATTRIBUTE_NORMAL;
+ if (flags & _O_CREAT) {
+ if (!((req->mode & ~current_umask) & _S_IWRITE)) {
+ attributes |= FILE_ATTRIBUTE_READONLY;
+ }
+ }
+
+ if (flags & _O_TEMPORARY ) {
+ attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
+ access |= DELETE;
+ }
+
+ if (flags & _O_SHORT_LIVED) {
+ attributes |= FILE_ATTRIBUTE_TEMPORARY;
+ }
+
+ switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) {
+ case 0:
+ break;
+ case _O_SEQUENTIAL:
+ attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+ break;
+ case _O_RANDOM:
+ attributes |= FILE_FLAG_RANDOM_ACCESS;
+ break;
+ default:
+ goto einval;
+ }
+
+ /* Setting this flag makes it possible to open a directory. */
+ attributes |= FILE_FLAG_BACKUP_SEMANTICS;
+
+ file = CreateFileW(req->pathw,
+ access,
+ share,
+ NULL,
+ disposition,
+ attributes,
+ NULL);
+ if (file == INVALID_HANDLE_VALUE) {
+ DWORD error = GetLastError();
+ if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) &&
+ !(flags & _O_EXCL)) {
+ /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */
+ /* specified, it means the path referred to a directory. */
+ SET_REQ_UV_ERROR(req, UV_EISDIR, error);
+ } else {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ }
+ return;
+ }
+
+ fd = _open_osfhandle((intptr_t) file, flags);
+ if (fd < 0) {
+ /* The only known failure mode for _open_osfhandle() is EMFILE, in which
+ * case GetLastError() will return zero. However we'll try to handle other
+ * errors as well, should they ever occur.
+ */
+ if (errno == EMFILE)
+ SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
+ else if (GetLastError() != ERROR_SUCCESS)
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ else
+ SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+ return;
+ }
+
+ SET_REQ_RESULT(req, fd);
+ return;
+
+ einval:
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
+}
+
+void fs__close(uv_fs_t* req) {
+ int fd = req->fd;
+ int result;
+
+ VERIFY_FD(fd, req);
+
+ result = _close(fd);
+ SET_REQ_RESULT(req, result);
+}
+
+
+void fs__read(uv_fs_t* req) {
+ int fd = req->fd;
+ size_t length = req->length;
+ int64_t offset = req->offset;
+ HANDLE handle;
+ OVERLAPPED overlapped, *overlapped_ptr;
+ LARGE_INTEGER offset_;
+ DWORD bytes;
+ DWORD error;
+
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+ return;
+ }
+
+ if (length > INT_MAX) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
+ return;
+ }
+
+ if (offset != -1) {
+ memset(&overlapped, 0, sizeof overlapped);
+
+ offset_.QuadPart = offset;
+ overlapped.Offset = offset_.LowPart;
+ overlapped.OffsetHigh = offset_.HighPart;
+
+ overlapped_ptr = &overlapped;
+ } else {
+ overlapped_ptr = NULL;
+ }
+
+ if (ReadFile(handle, req->buf, req->length, &bytes, overlapped_ptr)) {
+ SET_REQ_RESULT(req, bytes);
+ } else {
+ error = GetLastError();
+ if (error == ERROR_HANDLE_EOF) {
+ SET_REQ_RESULT(req, bytes);
+ } else {
+ SET_REQ_WIN32_ERROR(req, error);
+ }
+ }
+}
+
+
+void fs__write(uv_fs_t* req) {
+ int fd = req->fd;
+ size_t length = req->length;
+ int64_t offset = req->offset;
+ HANDLE handle;
+ OVERLAPPED overlapped, *overlapped_ptr;
+ LARGE_INTEGER offset_;
+ DWORD bytes;
+
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+ return;
+ }
+
+ if (length > INT_MAX) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
+ return;
+ }
+
+ if (offset != -1) {
+ memset(&overlapped, 0, sizeof overlapped);
+
+ offset_.QuadPart = offset;
+ overlapped.Offset = offset_.LowPart;
+ overlapped.OffsetHigh = offset_.HighPart;
+
+ overlapped_ptr = &overlapped;
+ } else {
+ overlapped_ptr = NULL;
+ }
+
+ if (WriteFile(handle, req->buf, length, &bytes, overlapped_ptr)) {
+ SET_REQ_RESULT(req, bytes);
+ } else {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ }
+}
+
+
+void fs__rmdir(uv_fs_t* req) {
+ int result = _wrmdir(req->pathw);
+ SET_REQ_RESULT(req, result);
+}
+
+
+void fs__unlink(uv_fs_t* req) {
+ const WCHAR* pathw = req->pathw;
+ HANDLE handle;
+ BY_HANDLE_FILE_INFORMATION info;
+ FILE_DISPOSITION_INFORMATION disposition;
+ IO_STATUS_BLOCK iosb;
+ NTSTATUS status;
+
+ handle = CreateFileW(pathw,
+ FILE_READ_ATTRIBUTES | DELETE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ if (!GetFileInformationByHandle(handle, &info)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ CloseHandle(handle);
+ return;
+ }
+
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ /* Do not allow deletion of directories, unless it is a symlink. When */
+ /* the path refers to a non-symlink directory, report EPERM as mandated */
+ /* by POSIX.1. */
+
+ /* Check if it is a reparse point. If it's not, it's a normal directory. */
+ if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
+ CloseHandle(handle);
+ return;
+ }
+
+ /* Read the reparse point and check if it is a valid symlink. */
+ /* If not, don't unlink. */
+ if (fs__readlink_handle(handle, NULL, NULL) < 0) {
+ DWORD error = GetLastError();
+ if (error == ERROR_SYMLINK_NOT_SUPPORTED)
+ error = ERROR_ACCESS_DENIED;
+ SET_REQ_WIN32_ERROR(req, error);
+ CloseHandle(handle);
+ return;
+ }
+ }
+
+ /* Try to set the delete flag. */
+ disposition.DeleteFile = TRUE;
+ status = pNtSetInformationFile(handle,
+ &iosb,
+ &disposition,
+ sizeof disposition,
+ FileDispositionInformation);
+ if (NT_SUCCESS(status)) {
+ SET_REQ_SUCCESS(req);
+ } else {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+ }
+
+ CloseHandle(handle);
+}
+
+
+void fs__mkdir(uv_fs_t* req) {
+ /* TODO: use req->mode. */
+ int result = _wmkdir(req->pathw);
+ SET_REQ_RESULT(req, result);
+}
+
+
+void fs__readdir(uv_fs_t* req) {
+ WCHAR* pathw = req->pathw;
+ size_t len = wcslen(pathw);
+ int result, size;
+ WCHAR* buf = NULL, *ptr, *name;
+ HANDLE dir;
+ WIN32_FIND_DATAW ent = { 0 };
+ size_t buf_char_len = 4096;
+ WCHAR* path2;
+ const WCHAR* fmt;
+
+ if (len == 0) {
+ fmt = L"./*";
+ } else if (pathw[len - 1] == L'/' || pathw[len - 1] == L'\\') {
+ fmt = L"%s*";
+ } else {
+ fmt = L"%s\\*";
+ }
+
+ /* Figure out whether path is a file or a directory. */
+ if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) {
+ req->result = UV_ENOTDIR;
+ req->sys_errno_ = ERROR_SUCCESS;
+ return;
+ }
+
+ path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
+ if (!path2) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ _snwprintf(path2, len + 3, fmt, pathw);
+ dir = FindFirstFileW(path2, &ent);
+ free(path2);
+
+ if(dir == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ result = 0;
+
+ do {
+ name = ent.cFileName;
+
+ if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) {
+ len = wcslen(name);
+
+ if (!buf) {
+ buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR));
+ if (!buf) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ ptr = buf;
+ }
+
+ while ((ptr - buf) + len + 1 > buf_char_len) {
+ buf_char_len *= 2;
+ path2 = buf;
+ buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR));
+ if (!buf) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
+ }
+
+ ptr = buf + (ptr - path2);
+ }
+
+ wcscpy(ptr, name);
+ ptr += len + 1;
+ result++;
+ }
+ } while(FindNextFileW(dir, &ent));
+
+ FindClose(dir);
+
+ if (buf) {
+ /* Convert result to UTF8. */
+ size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
+ if (!size) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ req->ptr = (char*)malloc(size + 1);
+ if (!req->ptr) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size);
+ if (!size) {
+ free(buf);
+ free(req->ptr);
+ req->ptr = NULL;
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+ free(buf);
+
+ ((char*)req->ptr)[size] = '\0';
+ req->flags |= UV_FS_FREE_PTR;
+ } else {
+ req->ptr = NULL;
+ }
+
+ SET_REQ_RESULT(req, result);
+}
+
+
+INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
+ FILE_ALL_INFORMATION file_info;
+ FILE_FS_VOLUME_INFORMATION volume_info;
+ NTSTATUS nt_status;
+ IO_STATUS_BLOCK io_status;
+
+ nt_status = pNtQueryInformationFile(handle,
+ &io_status,
+ &file_info,
+ sizeof file_info,
+ FileAllInformation);
+
+ /* Buffer overflow (a warning status code) is expected here. */
+ if (NT_ERROR(nt_status)) {
+ SetLastError(pRtlNtStatusToDosError(nt_status));
+ return -1;
+ }
+
+ nt_status = pNtQueryVolumeInformationFile(handle,
+ &io_status,
+ &volume_info,
+ sizeof volume_info,
+ FileFsVolumeInformation);
+
+ /* Buffer overflow (a warning status code) is expected here. */
+ if (NT_ERROR(nt_status)) {
+ SetLastError(pRtlNtStatusToDosError(nt_status));
+ return -1;
+ }
+
+ /* Todo: st_mode should probably always be 0666 for everyone. We might also
+ * want to report 0777 if the file is a .exe or a directory.
+ *
+ * Currently it's based on whether the 'readonly' attribute is set, which
+ * makes little sense because the semantics are so different: the 'read-only'
+ * flag is just a way for a user to protect against accidental deleteion, and
+ * serves no security purpose. Windows uses ACLs for that.
+ *
+ * Also people now use uv_fs_chmod() to take away the writable bit for good
+ * reasons. Windows however just makes the file read-only, which makes it
+ * impossible to delete the file afterwards, since read-only files can't be
+ * deleted.
+ *
+ * IOW it's all just a clusterfuck and we should think of something that
+ * makes slighty more sense.
+ *
+ * And uv_fs_chmod should probably just fail on windows or be a total no-op.
+ * There's nothing sensible it can do anyway.
+ */
+ statbuf->st_mode = 0;
+
+ if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ statbuf->st_mode |= S_IFLNK;
+ if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0)
+ return -1;
+
+ } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ statbuf->st_mode |= _S_IFDIR;
+ statbuf->st_size = 0;
+
+ } else {
+ statbuf->st_mode |= _S_IFREG;
+ statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
+ }
+
+ if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)
+ statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6);
+ else
+ statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
+ ((_S_IREAD | _S_IWRITE) >> 6);
+
+ FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime);
+ FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime);
+ FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime);
+ FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime);
+
+ statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart;
+
+ /* st_blocks contains the on-disk allocation size in 512-byte units. */
+ statbuf->st_blocks =
+ file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL;
+
+ statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks;
+
+ statbuf->st_dev = volume_info.VolumeSerialNumber;
+
+ /* The st_blksize is supposed to be the 'optimal' number of bytes for reading
+ * and writing to the disk. That is, for any definition of 'optimal' - it's
+ * supposed to at least avoid read-update-write behavior when writing to the
+ * disk.
+ *
+ * However nobody knows this and even fewer people actually use this value,
+ * and in order to fill it out we'd have to make another syscall to query the
+ * volume for FILE_FS_SECTOR_SIZE_INFORMATION.
+ *
+ * Therefore we'll just report a sensible value that's quite commonly okay
+ * on modern hardware.
+ */
+ statbuf->st_blksize = 2048;
+
+ /* Todo: set st_flags to something meaningful. Also provide a wrapper for
+ * chattr(2).
+ */
+ statbuf->st_flags = 0;
+
+ /* Windows has nothing sensible to say about these values, so they'll just
+ * remain empty.
+ */
+ statbuf->st_gid = 0;
+ statbuf->st_uid = 0;
+ statbuf->st_rdev = 0;
+ statbuf->st_gen = 0;
+
+ return 0;
+}
+
+
+INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
+ size_t len = wcslen(pathw);
+
+ /* TODO: ignore namespaced paths. */
+ if (len > 1 && pathw[len - 2] != L':' &&
+ (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) {
+ pathw[len - 1] = '\0';
+ }
+}
+
+
+INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+ HANDLE handle;
+ DWORD flags;
+
+ flags = FILE_FLAG_BACKUP_SEMANTICS;
+ if (do_lstat) {
+ flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+ }
+
+ handle = CreateFileW(req->pathw,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ flags,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ if (fs__stat_handle(handle, &req->statbuf) != 0) {
+ DWORD error = GetLastError();
+ if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) {
+ /* We opened a reparse point but it was not a symlink. Try again. */
+ fs__stat_impl(req, 0);
+
+ } else {
+ /* Stat failed. */
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ }
+
+ CloseHandle(handle);
+ return;
+ }
+
+ req->ptr = &req->statbuf;
+ req->result = 0;
+ CloseHandle(handle);
+}
+
+
+static void fs__stat(uv_fs_t* req) {
+ fs__stat_prepare_path(req->pathw);
+ fs__stat_impl(req, 0);
+}
+
+
+static void fs__lstat(uv_fs_t* req) {
+ fs__stat_prepare_path(req->pathw);
+ fs__stat_impl(req, 1);
+}
+
+
+static void fs__fstat(uv_fs_t* req) {
+ int fd = req->fd;
+ HANDLE handle;
+
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+ return;
+ }
+
+ if (fs__stat_handle(handle, &req->statbuf) != 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ req->ptr = &req->statbuf;
+ req->result = 0;
+}
+
+
+static void fs__rename(uv_fs_t* req) {
+ if (!MoveFileExW(req->pathw, req->new_pathw, MOVEFILE_REPLACE_EXISTING)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ SET_REQ_RESULT(req, 0);
+}
+
+
+INLINE static void fs__sync_impl(uv_fs_t* req) {
+ int fd = req->fd;
+ int result;
+
+ VERIFY_FD(fd, req);
+
+ result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1;
+ if (result == -1) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ } else {
+ SET_REQ_RESULT(req, result);
+ }
+}
+
+
+static void fs__fsync(uv_fs_t* req) {
+ fs__sync_impl(req);
+}
+
+
+static void fs__fdatasync(uv_fs_t* req) {
+ fs__sync_impl(req);
+}
+
+
+static void fs__ftruncate(uv_fs_t* req) {
+ int fd = req->fd;
+ HANDLE handle;
+ NTSTATUS status;
+ IO_STATUS_BLOCK io_status;
+ FILE_END_OF_FILE_INFORMATION eof_info;
+
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+
+ eof_info.EndOfFile.QuadPart = req->offset;
+
+ status = pNtSetInformationFile(handle,
+ &io_status,
+ &eof_info,
+ sizeof eof_info,
+ FileEndOfFileInformation);
+
+ if (NT_SUCCESS(status)) {
+ SET_REQ_RESULT(req, 0);
+ } else {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+ }
+}
+
+
+static void fs__sendfile(uv_fs_t* req) {
+ int fd_in = req->fd, fd_out = req->fd_out;
+ size_t length = req->length;
+ int64_t offset = req->offset;
+ const size_t max_buf_size = 65536;
+ size_t buf_size = length < max_buf_size ? length : max_buf_size;
+ int n, result = 0;
+ int64_t result_offset = 0;
+ char* buf = (char*) malloc(buf_size);
+ if (!buf) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ if (offset != -1) {
+ result_offset = _lseeki64(fd_in, offset, SEEK_SET);
+ }
+
+ if (result_offset == -1) {
+ result = -1;
+ } else {
+ while (length > 0) {
+ n = _read(fd_in, buf, length < buf_size ? length : buf_size);
+ if (n == 0) {
+ break;
+ } else if (n == -1) {
+ result = -1;
+ break;
+ }
+
+ length -= n;
+
+ n = _write(fd_out, buf, n);
+ if (n == -1) {
+ result = -1;
+ break;
+ }
+
+ result += n;
+ }
+ }
+
+ free(buf);
+
+ SET_REQ_RESULT(req, result);
+}
+
+
+static void fs__chmod(uv_fs_t* req) {
+ int result = _wchmod(req->pathw, req->mode);
+ SET_REQ_RESULT(req, result);
+}
+
+
+static void fs__fchmod(uv_fs_t* req) {
+ int fd = req->fd;
+ HANDLE handle;
+ NTSTATUS nt_status;
+ IO_STATUS_BLOCK io_status;
+ FILE_BASIC_INFORMATION file_info;
+
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+
+ nt_status = pNtQueryInformationFile(handle,
+ &io_status,
+ &file_info,
+ sizeof file_info,
+ FileBasicInformation);
+
+ if (!NT_SUCCESS(nt_status)) {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+ return;
+ }
+
+ if (req->mode & _S_IWRITE) {
+ file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
+ } else {
+ file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ }
+
+ nt_status = pNtSetInformationFile(handle,
+ &io_status,
+ &file_info,
+ sizeof file_info,
+ FileBasicInformation);
+
+ if (!NT_SUCCESS(nt_status)) {
+ SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+ return;
+ }
+
+ SET_REQ_SUCCESS(req);
+}
+
+
+INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
+ FILETIME filetime_a, filetime_m;
+
+ TIME_T_TO_FILETIME((time_t) atime, &filetime_a);
+ TIME_T_TO_FILETIME((time_t) mtime, &filetime_m);
+
+ if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void fs__utime(uv_fs_t* req) {
+ HANDLE handle;
+
+ handle = CreateFileW(req->pathw,
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ CloseHandle(handle);
+ return;
+ }
+
+ CloseHandle(handle);
+
+ req->result = 0;
+}
+
+
+static void fs__futime(uv_fs_t* req) {
+ int fd = req->fd;
+ HANDLE handle;
+ VERIFY_FD(fd, req);
+
+ handle = uv__get_osfhandle(fd);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+ return;
+ }
+
+ if (fs__utime_handle(handle, req->atime, req->mtime) != 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ req->result = 0;
+}
+
+
+static void fs__link(uv_fs_t* req) {
+ DWORD r = CreateHardLinkW(req->new_pathw, req->pathw, NULL);
+ if (r == 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ } else {
+ req->result = 0;
+ }
+}
+
+
+static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
+ const WCHAR* new_path) {
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ REPARSE_DATA_BUFFER *buffer = NULL;
+ int created = 0;
+ int target_len;
+ int is_absolute, is_long_path;
+ int needed_buf_size, used_buf_size, used_data_size, path_buf_len;
+ int start, len, i;
+ int add_slash;
+ DWORD bytes;
+ WCHAR* path_buf;
+
+ target_len = wcslen(path);
+ is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0;
+
+ if (is_long_path) {
+ is_absolute = 1;
+ } else {
+ is_absolute = target_len >= 3 && IS_LETTER(path[0]) &&
+ path[1] == L':' && IS_SLASH(path[2]);
+ }
+
+ if (!is_absolute) {
+ /* Not supporting relative paths */
+ SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED);
+ return;
+ }
+
+ // Do a pessimistic calculation of the required buffer size
+ needed_buf_size =
+ FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
+ JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
+ 2 * (target_len + 2) * sizeof(WCHAR);
+
+ // Allocate the buffer
+ buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size);
+ if (!buffer) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ // Grab a pointer to the part of the buffer where filenames go
+ path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
+ path_buf_len = 0;
+
+ // Copy the substitute (internal) target path
+ start = path_buf_len;
+
+ wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX,
+ JUNCTION_PREFIX_LEN);
+ path_buf_len += JUNCTION_PREFIX_LEN;
+
+ add_slash = 0;
+ for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
+ if (IS_SLASH(path[i])) {
+ add_slash = 1;
+ continue;
+ }
+
+ if (add_slash) {
+ path_buf[path_buf_len++] = L'\\';
+ add_slash = 0;
+ }
+
+ path_buf[path_buf_len++] = path[i];
+ }
+ path_buf[path_buf_len++] = L'\\';
+ len = path_buf_len - start;
+
+ // Set the info about the substitute name
+ buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR);
+ buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
+
+ // Insert null terminator
+ path_buf[path_buf_len++] = L'\0';
+
+ // Copy the print name of the target path
+ start = path_buf_len;
+ add_slash = 0;
+ for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
+ if (IS_SLASH(path[i])) {
+ add_slash = 1;
+ continue;
+ }
+
+ if (add_slash) {
+ path_buf[path_buf_len++] = L'\\';
+ add_slash = 0;
+ }
+
+ path_buf[path_buf_len++] = path[i];
+ }
+ len = path_buf_len - start;
+ if (len == 2) {
+ path_buf[path_buf_len++] = L'\\';
+ len++;
+ }
+
+ // Set the info about the print name
+ buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
+ buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
+
+ // Insert another null terminator
+ path_buf[path_buf_len++] = L'\0';
+
+ // Calculate how much buffer space was actually used
+ used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
+ path_buf_len * sizeof(WCHAR);
+ used_data_size = used_buf_size -
+ FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer);
+
+ // Put general info in the data buffer
+ buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+ buffer->ReparseDataLength = used_data_size;
+ buffer->Reserved = 0;
+
+ // Create a new directory
+ if (!CreateDirectoryW(new_path, NULL)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ goto error;
+ }
+ created = 1;
+
+ // Open the directory
+ handle = CreateFileW(new_path,
+ GENERIC_ALL,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS |
+ FILE_FLAG_OPEN_REPARSE_POINT,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ goto error;
+ }
+
+ // Create the actual reparse point
+ if (!DeviceIoControl(handle,
+ FSCTL_SET_REPARSE_POINT,
+ buffer,
+ used_buf_size,
+ NULL,
+ 0,
+ &bytes,
+ NULL)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ goto error;
+ }
+
+ // Clean up
+ CloseHandle(handle);
+ free(buffer);
+
+ SET_REQ_RESULT(req, 0);
+ return;
+
+error:
+ free(buffer);
+
+ if (handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle);
+ }
+
+ if (created) {
+ RemoveDirectoryW(new_path);
+ }
+}
+
+
+static void fs__symlink(uv_fs_t* req) {
+ WCHAR* pathw = req->pathw;
+ WCHAR* new_pathw = req->new_pathw;
+ int flags = req->file_flags;
+ int result;
+
+
+ if (flags & UV_FS_SYMLINK_JUNCTION) {
+ fs__create_junction(req, pathw, new_pathw);
+ } else if (pCreateSymbolicLinkW) {
+ result = pCreateSymbolicLinkW(new_pathw,
+ pathw,
+ flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
+ if (result == -1) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ } else {
+ SET_REQ_RESULT(req, result);
+ }
+ } else {
+ SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+ }
+}
+
+
+static void fs__readlink(uv_fs_t* req) {
+ HANDLE handle;
+
+ handle = CreateFileW(req->pathw,
+ 0,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+
+ if (handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ CloseHandle(handle);
+ return;
+ }
+
+ req->flags |= UV_FS_FREE_PTR;
+ SET_REQ_RESULT(req, 0);
+
+ CloseHandle(handle);
+}
+
+
+
+static void fs__chown(uv_fs_t* req) {
+ req->result = 0;
+}
+
+
+static void fs__fchown(uv_fs_t* req) {
+ req->result = 0;
+}
+
+
+static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
+ uv_fs_t* req = (uv_fs_t*) parameter;
+ uv_loop_t* loop = req->loop;
+
+ assert(req != NULL);
+ assert(req->type == UV_FS);
+
+#define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break;
+ switch (req->fs_type) {
+ XX(OPEN, open)
+ XX(CLOSE, close)
+ XX(READ, read)
+ XX(WRITE, write)
+ XX(SENDFILE, sendfile)
+ XX(STAT, stat)
+ XX(LSTAT, lstat)
+ XX(FSTAT, fstat)
+ XX(FTRUNCATE, ftruncate)
+ XX(UTIME, utime)
+ XX(FUTIME, futime)
+ XX(CHMOD, chmod)
+ XX(FCHMOD, fchmod)
+ XX(FSYNC, fsync)
+ XX(FDATASYNC, fdatasync)
+ XX(UNLINK, unlink)
+ XX(RMDIR, rmdir)
+ XX(MKDIR, mkdir)
+ XX(RENAME, rename)
+ XX(READDIR, readdir)
+ XX(LINK, link)
+ XX(SYMLINK, symlink)
+ XX(READLINK, readlink)
+ XX(CHOWN, chown)
+ XX(FCHOWN, fchown);
+ default:
+ assert(!"bad uv_fs_type");
+ }
+
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+}
+
+
+int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
+ int mode, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->file_flags = flags;
+ req->mode = mode;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__open(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
+ req->fd = fd;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__close(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
+ size_t length, int64_t offset, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_READ, cb);
+
+ req->fd = fd;
+ req->buf = buf;
+ req->length = length;
+ req->offset = offset;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__read(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file fd, const void* buf,
+ size_t length, int64_t offset, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
+
+ req->fd = fd;
+ req->buf = (void*) buf;
+ req->length = length;
+ req->offset = offset;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__write(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__unlink(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
+ uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->mode = mode;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__mkdir(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__rmdir(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
+ uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->file_flags = flags;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__readdir(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_LINK, cb);
+
+ err = fs__capture_path(loop, req, path, new_path, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__link(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, int flags, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb);
+
+ err = fs__capture_path(loop, req, path, new_path, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->file_flags = flags;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__symlink(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__readlink(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
+ uv_gid_t gid, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_CHOWN, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__chown(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
+ uv_gid_t gid, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb);
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__fchown(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_STAT, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__stat(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__lstat(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
+ req->fd = fd;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__fstat(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
+ const char* new_path, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
+
+ err = fs__capture_path(loop, req, path, new_path, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__rename(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
+ req->fd = fd;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__fsync(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
+ req->fd = fd;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__fdatasync(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd,
+ int64_t offset, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
+
+ req->fd = fd;
+ req->offset = offset;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__ftruncate(req);
+ return req->result;
+ }
+}
+
+
+
+int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
+ uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
+
+ req->fd = fd_in;
+ req->fd_out = fd_out;
+ req->offset = in_offset;
+ req->length = length;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__sendfile(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
+ uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_CHMOD, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->mode = mode;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__chmod(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode,
+ uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb);
+
+ req->fd = fd;
+ req->mode = mode;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__fchmod(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
+ double mtime, uv_fs_cb cb) {
+ int err;
+
+ uv_fs_req_init(loop, req, UV_FS_UTIME, cb);
+
+ err = fs__capture_path(loop, req, path, NULL, cb != NULL);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ req->atime = atime;
+ req->mtime = mtime;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__utime(req);
+ return req->result;
+ }
+}
+
+
+int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
+ double mtime, uv_fs_cb cb) {
+ uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
+
+ req->fd = fd;
+ req->atime = atime;
+ req->mtime = mtime;
+
+ if (cb) {
+ QUEUE_FS_TP_JOB(loop, req);
+ return 0;
+ } else {
+ fs__futime(req);
+ return req->result;
+ }
+}
+
+
+void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
+ assert(req->cb);
+ uv__req_unregister(loop, req);
+ req->cb(req);
+}
+
+
+void uv_fs_req_cleanup(uv_fs_t* req) {
+ if (req->flags & UV_FS_CLEANEDUP)
+ return;
+
+ if (req->flags & UV_FS_FREE_PATHS)
+ free(req->pathw);
+
+ if (req->flags & UV_FS_FREE_PTR)
+ free(req->ptr);
+
+ req->path = NULL;
+ req->pathw = NULL;
+ req->new_pathw = NULL;
+ req->ptr = NULL;
+
+ req->flags |= UV_FS_CLEANEDUP;
+}
+
diff --git a/third-party/libuv/src/win/getaddrinfo.c b/third-party/libuv/src/win/getaddrinfo.c
new file mode 100644
index 0000000000..fb4ab0a602
--- /dev/null
+++ b/third-party/libuv/src/win/getaddrinfo.c
@@ -0,0 +1,344 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <malloc.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+
+/*
+ * MinGW is missing this
+ */
+#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR)
+ typedef struct addrinfoW {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ size_t ai_addrlen;
+ WCHAR* ai_canonname;
+ struct sockaddr* ai_addr;
+ struct addrinfoW* ai_next;
+ } ADDRINFOW, *PADDRINFOW;
+
+ DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node,
+ const WCHAR* service,
+ const ADDRINFOW* hints,
+ PADDRINFOW* result);
+
+ DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo);
+#endif
+
+
+/* adjust size value to be multiple of 4. Use to keep pointer aligned */
+/* Do we need different versions of this for different architectures? */
+#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2)
+
+
+/* getaddrinfo worker thread implementation */
+static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
+ uv_getaddrinfo_t* req = (uv_getaddrinfo_t*) parameter;
+ uv_loop_t* loop = req->loop;
+ int ret;
+
+ assert(req != NULL);
+
+ /* call OS function on this thread */
+ ret = GetAddrInfoW(req->node,
+ req->service,
+ req->hints,
+ &req->res);
+ req->retcode = ret;
+
+ /* post getaddrinfo completed */
+ POST_COMPLETION_FOR_REQ(loop, req);
+
+ return 0;
+}
+
+
+/*
+ * Called from uv_run when complete. Call user specified callback
+ * then free returned addrinfo
+ * Returned addrinfo strings are converted from UTF-16 to UTF-8.
+ *
+ * To minimize allocation we calculate total size required,
+ * and copy all structs and referenced strings into the one block.
+ * Each size calculation is adjusted to avoid unaligned pointers.
+ */
+void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req) {
+ int addrinfo_len = 0;
+ int name_len = 0;
+ size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
+ struct addrinfoW* addrinfow_ptr;
+ struct addrinfo* addrinfo_ptr;
+ char* alloc_ptr = NULL;
+ char* cur_ptr = NULL;
+ int err = 0;
+
+ /* release input parameter memory */
+ if (req->alloc != NULL) {
+ free(req->alloc);
+ req->alloc = NULL;
+ }
+
+ if (req->retcode == 0) {
+ /* convert addrinfoW to addrinfo */
+ /* first calculate required length */
+ addrinfow_ptr = req->res;
+ while (addrinfow_ptr != NULL) {
+ addrinfo_len += addrinfo_struct_len +
+ ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
+ if (addrinfow_ptr->ai_canonname != NULL) {
+ name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
+ if (name_len == 0) {
+ /* FIXME(bnoordhuis) Retain GetLastError(). */
+ err = UV_EAI_SYSTEM;
+ goto complete;
+ }
+ addrinfo_len += ALIGNED_SIZE(name_len);
+ }
+ addrinfow_ptr = addrinfow_ptr->ai_next;
+ }
+
+ /* allocate memory for addrinfo results */
+ alloc_ptr = (char*)malloc(addrinfo_len);
+
+ /* do conversions */
+ if (alloc_ptr != NULL) {
+ cur_ptr = alloc_ptr;
+ addrinfow_ptr = req->res;
+
+ while (addrinfow_ptr != NULL) {
+ /* copy addrinfo struct data */
+ assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len);
+ addrinfo_ptr = (struct addrinfo*)cur_ptr;
+ addrinfo_ptr->ai_family = addrinfow_ptr->ai_family;
+ addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype;
+ addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol;
+ addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags;
+ addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen;
+ addrinfo_ptr->ai_canonname = NULL;
+ addrinfo_ptr->ai_addr = NULL;
+ addrinfo_ptr->ai_next = NULL;
+
+ cur_ptr += addrinfo_struct_len;
+
+ /* copy sockaddr */
+ if (addrinfo_ptr->ai_addrlen > 0) {
+ assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
+ alloc_ptr + addrinfo_len);
+ memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
+ addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
+ cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
+ }
+
+ /* convert canonical name to UTF-8 */
+ if (addrinfow_ptr->ai_canonname != NULL) {
+ name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
+ -1,
+ NULL,
+ 0);
+ assert(name_len > 0);
+ assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
+ name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
+ -1,
+ cur_ptr,
+ name_len);
+ assert(name_len > 0);
+ addrinfo_ptr->ai_canonname = cur_ptr;
+ cur_ptr += ALIGNED_SIZE(name_len);
+ }
+ assert(cur_ptr <= alloc_ptr + addrinfo_len);
+
+ /* set next ptr */
+ addrinfow_ptr = addrinfow_ptr->ai_next;
+ if (addrinfow_ptr != NULL) {
+ addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr;
+ }
+ }
+ } else {
+ err = UV_EAI_MEMORY;
+ }
+ } else {
+ /* GetAddrInfo failed */
+ err = uv__getaddrinfo_translate_error(req->retcode);
+ }
+
+ /* return memory to system */
+ if (req->res != NULL) {
+ FreeAddrInfoW(req->res);
+ req->res = NULL;
+ }
+
+complete:
+ uv__req_unregister(loop, req);
+
+ /* finally do callback with converted result */
+ req->getaddrinfo_cb(req, err, (struct addrinfo*)alloc_ptr);
+}
+
+
+void uv_freeaddrinfo(struct addrinfo* ai) {
+ char* alloc_ptr = (char*)ai;
+
+ /* release copied result memory */
+ if (alloc_ptr != NULL) {
+ free(alloc_ptr);
+ }
+}
+
+
+/*
+ * Entry point for getaddrinfo
+ * we convert the UTF-8 strings to UNICODE
+ * and save the UNICODE string pointers in the req
+ * We also copy hints so that caller does not need to keep memory until the
+ * callback.
+ * return 0 if a callback will be made
+ * return error code if validation fails
+ *
+ * To minimize allocation we calculate total size required,
+ * and copy all structs and referenced strings into the one block.
+ * Each size calculation is adjusted to avoid unaligned pointers.
+ */
+int uv_getaddrinfo(uv_loop_t* loop,
+ uv_getaddrinfo_t* req,
+ uv_getaddrinfo_cb getaddrinfo_cb,
+ const char* node,
+ const char* service,
+ const struct addrinfo* hints) {
+ int nodesize = 0;
+ int servicesize = 0;
+ int hintssize = 0;
+ char* alloc_ptr = NULL;
+ int err;
+
+ if (req == NULL || getaddrinfo_cb == NULL ||
+ (node == NULL && service == NULL)) {
+ err = WSAEINVAL;
+ goto error;
+ }
+
+ uv_req_init(loop, (uv_req_t*)req);
+
+ req->getaddrinfo_cb = getaddrinfo_cb;
+ req->res = NULL;
+ req->type = UV_GETADDRINFO;
+ req->loop = loop;
+
+ /* calculate required memory size for all input values */
+ if (node != NULL) {
+ nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
+ if (nodesize == 0) {
+ err = GetLastError();
+ goto error;
+ }
+ }
+
+ if (service != NULL) {
+ servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
+ sizeof(WCHAR));
+ if (servicesize == 0) {
+ err = GetLastError();
+ goto error;
+ }
+ }
+ if (hints != NULL) {
+ hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
+ }
+
+ /* allocate memory for inputs, and partition it as needed */
+ alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
+ if (!alloc_ptr) {
+ err = WSAENOBUFS;
+ goto error;
+ }
+
+ /* save alloc_ptr now so we can free if error */
+ req->alloc = (void*)alloc_ptr;
+
+ /* convert node string to UTF16 into allocated memory and save pointer in */
+ /* the reques. */
+ if (node != NULL) {
+ req->node = (WCHAR*)alloc_ptr;
+ if (uv_utf8_to_utf16(node,
+ (WCHAR*) alloc_ptr,
+ nodesize / sizeof(WCHAR)) == 0) {
+ err = GetLastError();
+ goto error;
+ }
+ alloc_ptr += nodesize;
+ } else {
+ req->node = NULL;
+ }
+
+ /* convert service string to UTF16 into allocated memory and save pointer */
+ /* in the req. */
+ if (service != NULL) {
+ req->service = (WCHAR*)alloc_ptr;
+ if (uv_utf8_to_utf16(service,
+ (WCHAR*) alloc_ptr,
+ servicesize / sizeof(WCHAR)) == 0) {
+ err = GetLastError();
+ goto error;
+ }
+ alloc_ptr += servicesize;
+ } else {
+ req->service = NULL;
+ }
+
+ /* copy hints to allocated memory and save pointer in req */
+ if (hints != NULL) {
+ req->hints = (struct addrinfoW*)alloc_ptr;
+ req->hints->ai_family = hints->ai_family;
+ req->hints->ai_socktype = hints->ai_socktype;
+ req->hints->ai_protocol = hints->ai_protocol;
+ req->hints->ai_flags = hints->ai_flags;
+ req->hints->ai_addrlen = 0;
+ req->hints->ai_canonname = NULL;
+ req->hints->ai_addr = NULL;
+ req->hints->ai_next = NULL;
+ } else {
+ req->hints = NULL;
+ }
+
+ /* Ask thread to run. Treat this as a long operation */
+ if (QueueUserWorkItem(&getaddrinfo_thread_proc,
+ req,
+ WT_EXECUTELONGFUNCTION) == 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ uv__req_register(loop, req);
+
+ return 0;
+
+error:
+ if (req != NULL && req->alloc != NULL) {
+ free(req->alloc);
+ }
+ return uv_translate_sys_error(err);
+}
diff --git a/third-party/libuv/src/win/handle-inl.h b/third-party/libuv/src/win/handle-inl.h
new file mode 100644
index 0000000000..5776eb7f76
--- /dev/null
+++ b/third-party/libuv/src/win/handle-inl.h
@@ -0,0 +1,179 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_HANDLE_INL_H_
+#define UV_WIN_HANDLE_INL_H_
+
+#include <assert.h>
+#include <io.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define DECREASE_ACTIVE_COUNT(loop, handle) \
+ do { \
+ if (--(handle)->activecnt == 0 && \
+ !((handle)->flags & UV__HANDLE_CLOSING)) { \
+ uv__handle_stop((handle)); \
+ } \
+ assert((handle)->activecnt >= 0); \
+ } while (0)
+
+
+#define INCREASE_ACTIVE_COUNT(loop, handle) \
+ do { \
+ if ((handle)->activecnt++ == 0) { \
+ uv__handle_start((handle)); \
+ } \
+ assert((handle)->activecnt > 0); \
+ } while (0)
+
+
+#define DECREASE_PENDING_REQ_COUNT(handle) \
+ do { \
+ assert(handle->reqs_pending > 0); \
+ handle->reqs_pending--; \
+ \
+ if (handle->flags & UV__HANDLE_CLOSING && \
+ handle->reqs_pending == 0) { \
+ uv_want_endgame(loop, (uv_handle_t*)handle); \
+ } \
+ } while (0)
+
+
+#define uv__handle_closing(handle) \
+ do { \
+ assert(!((handle)->flags & UV__HANDLE_CLOSING)); \
+ \
+ if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \
+ ((handle)->flags & UV__HANDLE_REF))) \
+ uv__active_handle_add((uv_handle_t*) (handle)); \
+ \
+ (handle)->flags |= UV__HANDLE_CLOSING; \
+ (handle)->flags &= ~UV__HANDLE_ACTIVE; \
+ } while (0)
+
+
+#define uv__handle_close(handle) \
+ do { \
+ QUEUE_REMOVE(&(handle)->handle_queue); \
+ uv__active_handle_rm((uv_handle_t*) (handle)); \
+ \
+ (handle)->flags |= UV_HANDLE_CLOSED; \
+ \
+ if ((handle)->close_cb) \
+ (handle)->close_cb((uv_handle_t*) (handle)); \
+ } while (0)
+
+
+INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
+ if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
+ handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
+
+ handle->endgame_next = loop->endgame_handles;
+ loop->endgame_handles = handle;
+ }
+}
+
+
+INLINE static void uv_process_endgames(uv_loop_t* loop) {
+ uv_handle_t* handle;
+
+ while (loop->endgame_handles) {
+ handle = loop->endgame_handles;
+ loop->endgame_handles = handle->endgame_next;
+
+ handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
+
+ switch (handle->type) {
+ case UV_TCP:
+ uv_tcp_endgame(loop, (uv_tcp_t*) handle);
+ break;
+
+ case UV_NAMED_PIPE:
+ uv_pipe_endgame(loop, (uv_pipe_t*) handle);
+ break;
+
+ case UV_TTY:
+ uv_tty_endgame(loop, (uv_tty_t*) handle);
+ break;
+
+ case UV_UDP:
+ uv_udp_endgame(loop, (uv_udp_t*) handle);
+ break;
+
+ case UV_POLL:
+ uv_poll_endgame(loop, (uv_poll_t*) handle);
+ break;
+
+ case UV_TIMER:
+ uv_timer_endgame(loop, (uv_timer_t*) handle);
+ break;
+
+ case UV_PREPARE:
+ case UV_CHECK:
+ case UV_IDLE:
+ uv_loop_watcher_endgame(loop, handle);
+ break;
+
+ case UV_ASYNC:
+ uv_async_endgame(loop, (uv_async_t*) handle);
+ break;
+
+ case UV_SIGNAL:
+ uv_signal_endgame(loop, (uv_signal_t*) handle);
+ break;
+
+ case UV_PROCESS:
+ uv_process_endgame(loop, (uv_process_t*) handle);
+ break;
+
+ case UV_FS_EVENT:
+ uv_fs_event_endgame(loop, (uv_fs_event_t*) handle);
+ break;
+
+ case UV_FS_POLL:
+ uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+INLINE static HANDLE uv__get_osfhandle(int fd)
+{
+ /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
+ /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
+ /* for invalid FDs in release builds (or if you let the assert continue). */
+ /* So this wrapper function disables asserts when calling _get_osfhandle. */
+
+ HANDLE handle;
+ UV_BEGIN_DISABLE_CRT_ASSERT();
+ handle = (HANDLE) _get_osfhandle(fd);
+ UV_END_DISABLE_CRT_ASSERT();
+ return handle;
+}
+
+#endif /* UV_WIN_HANDLE_INL_H_ */
diff --git a/third-party/libuv/src/win/handle.c b/third-party/libuv/src/win/handle.c
new file mode 100644
index 0000000000..72b49d9790
--- /dev/null
+++ b/third-party/libuv/src/win/handle.c
@@ -0,0 +1,154 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+uv_handle_type uv_guess_handle(uv_file file) {
+ HANDLE handle;
+ DWORD mode;
+
+ if (file < 0) {
+ return UV_UNKNOWN_HANDLE;
+ }
+
+ handle = uv__get_osfhandle(file);
+
+ switch (GetFileType(handle)) {
+ case FILE_TYPE_CHAR:
+ if (GetConsoleMode(handle, &mode)) {
+ return UV_TTY;
+ } else {
+ return UV_FILE;
+ }
+
+ case FILE_TYPE_PIPE:
+ return UV_NAMED_PIPE;
+
+ case FILE_TYPE_DISK:
+ return UV_FILE;
+
+ default:
+ return UV_UNKNOWN_HANDLE;
+ }
+}
+
+
+int uv_is_active(const uv_handle_t* handle) {
+ return (handle->flags & UV__HANDLE_ACTIVE) &&
+ !(handle->flags & UV__HANDLE_CLOSING);
+}
+
+
+void uv_close(uv_handle_t* handle, uv_close_cb cb) {
+ uv_loop_t* loop = handle->loop;
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ assert(0);
+ return;
+ }
+
+ handle->close_cb = cb;
+
+ /* Handle-specific close actions */
+ switch (handle->type) {
+ case UV_TCP:
+ uv_tcp_close(loop, (uv_tcp_t*)handle);
+ return;
+
+ case UV_NAMED_PIPE:
+ uv_pipe_close(loop, (uv_pipe_t*) handle);
+ return;
+
+ case UV_TTY:
+ uv_tty_close((uv_tty_t*) handle);
+ return;
+
+ case UV_UDP:
+ uv_udp_close(loop, (uv_udp_t*) handle);
+ return;
+
+ case UV_POLL:
+ uv_poll_close(loop, (uv_poll_t*) handle);
+ return;
+
+ case UV_TIMER:
+ uv_timer_stop((uv_timer_t*)handle);
+ uv__handle_closing(handle);
+ uv_want_endgame(loop, handle);
+ return;
+
+ case UV_PREPARE:
+ uv_prepare_stop((uv_prepare_t*)handle);
+ uv__handle_closing(handle);
+ uv_want_endgame(loop, handle);
+ return;
+
+ case UV_CHECK:
+ uv_check_stop((uv_check_t*)handle);
+ uv__handle_closing(handle);
+ uv_want_endgame(loop, handle);
+ return;
+
+ case UV_IDLE:
+ uv_idle_stop((uv_idle_t*)handle);
+ uv__handle_closing(handle);
+ uv_want_endgame(loop, handle);
+ return;
+
+ case UV_ASYNC:
+ uv_async_close(loop, (uv_async_t*) handle);
+ return;
+
+ case UV_SIGNAL:
+ uv_signal_close(loop, (uv_signal_t*) handle);
+ return;
+
+ case UV_PROCESS:
+ uv_process_close(loop, (uv_process_t*) handle);
+ return;
+
+ case UV_FS_EVENT:
+ uv_fs_event_close(loop, (uv_fs_event_t*) handle);
+ return;
+
+ case UV_FS_POLL:
+ uv__fs_poll_close((uv_fs_poll_t*) handle);
+ uv__handle_closing(handle);
+ uv_want_endgame(loop, handle);
+ return;
+
+ default:
+ /* Not supported */
+ abort();
+ }
+}
+
+
+int uv_is_closing(const uv_handle_t* handle) {
+ return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED));
+}
diff --git a/third-party/libuv/src/win/internal.h b/third-party/libuv/src/win/internal.h
new file mode 100644
index 0000000000..cf6c85846c
--- /dev/null
+++ b/third-party/libuv/src/win/internal.h
@@ -0,0 +1,379 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_INTERNAL_H_
+#define UV_WIN_INTERNAL_H_
+
+#include "uv.h"
+#include "../uv-common.h"
+
+#include "tree.h"
+#include "winapi.h"
+#include "winsock.h"
+
+#ifdef _MSC_VER
+# define INLINE __inline
+#else
+# define INLINE inline
+#endif
+
+
+#ifdef _DEBUG
+extern __declspec( thread ) int uv__crt_assert_enabled;
+
+#define UV_BEGIN_DISABLE_CRT_ASSERT() \
+ { \
+ int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \
+ uv__crt_assert_enabled = FALSE;
+
+
+#define UV_END_DISABLE_CRT_ASSERT() \
+ uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \
+ }
+
+#else
+#define UV_BEGIN_DISABLE_CRT_ASSERT()
+#define UV_END_DISABLE_CRT_ASSERT()
+#endif
+
+/*
+ * Handles
+ * (also see handle-inl.h)
+ */
+
+/* Used by all handles. */
+#define UV_HANDLE_CLOSED 0x00000002
+#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
+#define UV_HANDLE_ACTIVE 0x00000010
+
+/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
+/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
+/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */
+/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */
+
+/* Used by streams and UDP handles. */
+#define UV_HANDLE_READING 0x00000100
+#define UV_HANDLE_BOUND 0x00000200
+#define UV_HANDLE_BIND_ERROR 0x00000400
+#define UV_HANDLE_LISTENING 0x00000800
+#define UV_HANDLE_CONNECTION 0x00001000
+#define UV_HANDLE_CONNECTED 0x00002000
+#define UV_HANDLE_READABLE 0x00008000
+#define UV_HANDLE_WRITABLE 0x00010000
+#define UV_HANDLE_READ_PENDING 0x00020000
+#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000
+#define UV_HANDLE_ZERO_READ 0x00080000
+#define UV_HANDLE_EMULATE_IOCP 0x00100000
+#define UV_HANDLE_BLOCKING_WRITES 0x00200000
+
+/* Only used by uv_tcp_t handles. */
+#define UV_HANDLE_IPV6 0x01000000
+#define UV_HANDLE_TCP_NODELAY 0x02000000
+#define UV_HANDLE_TCP_KEEPALIVE 0x04000000
+#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000
+#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000
+#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000
+#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000
+
+/* Only used by uv_pipe_t handles. */
+#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
+#define UV_HANDLE_PIPESERVER 0x02000000
+
+/* Only used by uv_tty_t handles. */
+#define UV_HANDLE_TTY_READABLE 0x01000000
+#define UV_HANDLE_TTY_RAW 0x02000000
+#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000
+#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000
+
+/* Only used by uv_poll_t handles. */
+#define UV_HANDLE_POLL_SLOW 0x02000000
+
+
+/*
+ * Requests: see req-inl.h
+ */
+
+
+/*
+ * Streams: see stream-inl.h
+ */
+
+
+/*
+ * TCP
+ */
+int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
+int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
+int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb);
+int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
+ const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+
+void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
+void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_write_t* req);
+void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_req_t* req);
+void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_connect_t* req);
+
+void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
+void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
+
+int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
+ int tcp_connection);
+
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+ LPWSAPROTOCOL_INFOW protocol_info);
+
+
+/*
+ * UDP
+ */
+void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
+void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
+ uv_udp_send_t* req);
+
+void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle);
+void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
+
+
+/*
+ * Pipes
+ */
+int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+ char* name, size_t nameSize);
+
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
+int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
+int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb);
+int uv_pipe_read2_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+ uv_read2_cb read_cb);
+int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
+ const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
+ const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
+ uv_write_cb cb);
+
+void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_req_t* req);
+void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_write_t* req);
+void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_req_t* raw_req);
+void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_connect_t* req);
+void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_shutdown_t* req);
+
+void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle);
+void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle);
+void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
+
+
+/*
+ * TTY
+ */
+void uv_console_init();
+
+int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb);
+int uv_tty_read_stop(uv_tty_t* handle);
+int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
+ const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+void uv_tty_close(uv_tty_t* handle);
+
+void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* req);
+void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_write_t* req);
+/* TODO: remove me */
+void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* raw_req);
+/* TODO: remove me */
+void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_connect_t* req);
+
+void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle);
+
+
+/*
+ * Poll watchers
+ */
+void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+ uv_req_t* req);
+
+int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle);
+void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
+
+
+/*
+ * Timers
+ */
+void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
+
+DWORD uv_get_poll_timeout(uv_loop_t* loop);
+void uv__time_forward(uv_loop_t* loop, uint64_t msecs);
+void uv_process_timers(uv_loop_t* loop);
+
+
+/*
+ * Loop watchers
+ */
+void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
+
+void uv_prepare_invoke(uv_loop_t* loop);
+void uv_check_invoke(uv_loop_t* loop);
+void uv_idle_invoke(uv_loop_t* loop);
+
+void uv__once_init();
+
+
+/*
+ * Async watcher
+ */
+void uv_async_close(uv_loop_t* loop, uv_async_t* handle);
+void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
+
+void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
+ uv_req_t* req);
+
+
+/*
+ * Signal watcher
+ */
+void uv_signals_init();
+int uv__signal_dispatch(int signum);
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle);
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+ uv_req_t* req);
+
+
+/*
+ * Spawn
+ */
+void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
+void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
+void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
+
+
+/*
+ * Error
+ */
+int uv_translate_sys_error(int sys_errno);
+
+
+/*
+ * Getaddrinfo
+ */
+void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req);
+
+
+/*
+ * FS
+ */
+void uv_fs_init();
+void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req);
+
+
+/*
+ * Threadpool
+ */
+void uv_process_work_req(uv_loop_t* loop, uv_work_t* req);
+
+
+/*
+ * FS Event
+ */
+void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
+ uv_fs_event_t* handle);
+void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle);
+void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
+
+
+/*
+ * Stat poller.
+ */
+void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
+
+
+/*
+ * Utilities.
+ */
+void uv__util_init();
+
+int uv_parent_pid();
+void uv_fatal_error(const int errorno, const char* syscall);
+
+
+/*
+ * Process stdio handles.
+ */
+int uv__stdio_create(uv_loop_t* loop,
+ const uv_process_options_t* options,
+ BYTE** buffer_ptr);
+void uv__stdio_destroy(BYTE* buffer);
+void uv__stdio_noinherit(BYTE* buffer);
+int uv__stdio_verify(BYTE* buffer, WORD size);
+WORD uv__stdio_size(BYTE* buffer);
+HANDLE uv__stdio_handle(BYTE* buffer, int fd);
+
+
+/*
+ * Winapi and ntapi utility functions
+ */
+void uv_winapi_init();
+
+
+/*
+ * Winsock utility functions
+ */
+void uv_winsock_init();
+
+int uv_ntstatus_to_winsock_error(NTSTATUS status);
+
+BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target);
+BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target);
+
+int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
+ int* addr_len, WSAOVERLAPPED *overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
+ OVERLAPPED* overlapped);
+
+/* Whether there are any non-IFS LSPs stacked on TCP */
+extern int uv_tcp_non_ifs_lsp_ipv4;
+extern int uv_tcp_non_ifs_lsp_ipv6;
+
+/* Ip address used to bind to any port at any interface */
+extern struct sockaddr_in uv_addr_ip4_any_;
+extern struct sockaddr_in6 uv_addr_ip6_any_;
+
+#endif /* UV_WIN_INTERNAL_H_ */
diff --git a/third-party/libuv/src/win/loop-watcher.c b/third-party/libuv/src/win/loop-watcher.c
new file mode 100644
index 0000000000..6dbc861edd
--- /dev/null
+++ b/third-party/libuv/src/win/loop-watcher.c
@@ -0,0 +1,124 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ handle->flags |= UV_HANDLE_CLOSED;
+ uv__handle_close(handle);
+ }
+}
+
+
+#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
+ int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \
+ \
+ return 0; \
+ } \
+ \
+ \
+ int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
+ uv_loop_t* loop = handle->loop; \
+ uv_##name##_t* old_head; \
+ \
+ assert(handle->type == UV_##NAME); \
+ \
+ if (handle->flags & UV_HANDLE_ACTIVE) \
+ return 0; \
+ \
+ if (cb == NULL) \
+ return UV_EINVAL; \
+ \
+ old_head = loop->name##_handles; \
+ \
+ handle->name##_next = old_head; \
+ handle->name##_prev = NULL; \
+ \
+ if (old_head) { \
+ old_head->name##_prev = handle; \
+ } \
+ \
+ loop->name##_handles = handle; \
+ \
+ handle->name##_cb = cb; \
+ handle->flags |= UV_HANDLE_ACTIVE; \
+ uv__handle_start(handle); \
+ \
+ return 0; \
+ } \
+ \
+ \
+ int uv_##name##_stop(uv_##name##_t* handle) { \
+ uv_loop_t* loop = handle->loop; \
+ \
+ assert(handle->type == UV_##NAME); \
+ \
+ if (!(handle->flags & UV_HANDLE_ACTIVE)) \
+ return 0; \
+ \
+ /* Update loop head if needed */ \
+ if (loop->name##_handles == handle) { \
+ loop->name##_handles = handle->name##_next; \
+ } \
+ \
+ /* Update the iterator-next pointer of needed */ \
+ if (loop->next_##name##_handle == handle) { \
+ loop->next_##name##_handle = handle->name##_next; \
+ } \
+ \
+ if (handle->name##_prev) { \
+ handle->name##_prev->name##_next = handle->name##_next; \
+ } \
+ if (handle->name##_next) { \
+ handle->name##_next->name##_prev = handle->name##_prev; \
+ } \
+ \
+ handle->flags &= ~UV_HANDLE_ACTIVE; \
+ uv__handle_stop(handle); \
+ \
+ return 0; \
+ } \
+ \
+ \
+ void uv_##name##_invoke(uv_loop_t* loop) { \
+ uv_##name##_t* handle; \
+ \
+ (loop)->next_##name##_handle = (loop)->name##_handles; \
+ \
+ while ((loop)->next_##name##_handle != NULL) { \
+ handle = (loop)->next_##name##_handle; \
+ (loop)->next_##name##_handle = handle->name##_next; \
+ \
+ handle->name##_cb(handle, 0); \
+ } \
+ }
+
+UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
+UV_LOOP_WATCHER_DEFINE(check, CHECK)
+UV_LOOP_WATCHER_DEFINE(idle, IDLE)
diff --git a/third-party/libuv/src/win/pipe.c b/third-party/libuv/src/win/pipe.c
new file mode 100644
index 0000000000..f3d3110d31
--- /dev/null
+++ b/third-party/libuv/src/win/pipe.c
@@ -0,0 +1,1747 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+/* A zero-size buffer for use by uv_pipe_read */
+static char uv_zero_[] = "";
+
+/* Null uv_buf_t */
+static const uv_buf_t uv_null_buf_ = { 0, NULL };
+
+/* The timeout that the pipe will wait for the remote end to write data */
+/* when the local ends wants to shut it down. */
+static const int64_t eof_timeout = 50; /* ms */
+
+static const int default_pending_pipe_instances = 4;
+
+/* IPC protocol flags. */
+#define UV_IPC_RAW_DATA 0x0001
+#define UV_IPC_TCP_SERVER 0x0002
+#define UV_IPC_TCP_CONNECTION 0x0004
+
+/* IPC frame header. */
+typedef struct {
+ int flags;
+ uint64_t raw_data_length;
+} uv_ipc_frame_header_t;
+
+/* IPC frame, which contains an imported TCP socket stream. */
+typedef struct {
+ uv_ipc_frame_header_t header;
+ WSAPROTOCOL_INFOW socket_info;
+} uv_ipc_frame_uv_stream;
+
+static void eof_timer_init(uv_pipe_t* pipe);
+static void eof_timer_start(uv_pipe_t* pipe);
+static void eof_timer_stop(uv_pipe_t* pipe);
+static void eof_timer_cb(uv_timer_t* timer, int status);
+static void eof_timer_destroy(uv_pipe_t* pipe);
+static void eof_timer_close_cb(uv_handle_t* handle);
+
+
+static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
+ _snprintf(name, size, "\\\\.\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
+}
+
+
+int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
+ uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
+
+ handle->reqs_pending = 0;
+ handle->handle = INVALID_HANDLE_VALUE;
+ handle->name = NULL;
+ handle->ipc_pid = 0;
+ handle->remaining_ipc_rawdata_bytes = 0;
+ handle->pending_ipc_info.socket_info = NULL;
+ handle->pending_ipc_info.tcp_connection = 0;
+ handle->ipc = ipc;
+ handle->non_overlapped_writes_tail = NULL;
+
+ uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
+
+ return 0;
+}
+
+
+static void uv_pipe_connection_init(uv_pipe_t* handle) {
+ uv_connection_init((uv_stream_t*) handle);
+ handle->read_req.data = handle;
+ handle->eof_timer = NULL;
+}
+
+
+static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
+ HANDLE pipeHandle;
+
+ /*
+ * Assume that we have a duplex pipe first, so attempt to
+ * connect with GENERIC_READ | GENERIC_WRITE.
+ */
+ pipeHandle = CreateFileW(name,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ return pipeHandle;
+ }
+
+ /*
+ * If the pipe is not duplex CreateFileW fails with
+ * ERROR_ACCESS_DENIED. In that case try to connect
+ * as a read-only or write-only.
+ */
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ pipeHandle = CreateFileW(name,
+ GENERIC_READ | FILE_WRITE_ATTRIBUTES,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ *duplex_flags = UV_HANDLE_READABLE;
+ return pipeHandle;
+ }
+ }
+
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ pipeHandle = CreateFileW(name,
+ GENERIC_WRITE | FILE_READ_ATTRIBUTES,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ *duplex_flags = UV_HANDLE_WRITABLE;
+ return pipeHandle;
+ }
+ }
+
+ return INVALID_HANDLE_VALUE;
+}
+
+
+int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+ char* name, size_t nameSize) {
+ HANDLE pipeHandle;
+ int err;
+ char* ptr = (char*)handle;
+
+ for (;;) {
+ uv_unique_pipe_name(ptr, name, nameSize);
+
+ pipeHandle = CreateNamedPipeA(name,
+ access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
+ NULL);
+
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ /* No name collisions. We're done. */
+ break;
+ }
+
+ err = GetLastError();
+ if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) {
+ goto error;
+ }
+
+ /* Pipe name collision. Increment the pointer and try again. */
+ ptr++;
+ }
+
+ if (CreateIoCompletionPort(pipeHandle,
+ loop->iocp,
+ (ULONG_PTR)handle,
+ 0) == NULL) {
+ err = GetLastError();
+ goto error;
+ }
+
+ uv_pipe_connection_init(handle);
+ handle->handle = pipeHandle;
+
+ return 0;
+
+ error:
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(pipeHandle);
+ }
+
+ return err;
+}
+
+
+static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
+ HANDLE pipeHandle, DWORD duplex_flags) {
+ NTSTATUS nt_status;
+ IO_STATUS_BLOCK io_status;
+ FILE_MODE_INFORMATION mode_info;
+ DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
+
+ if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
+ /* If this returns ERROR_INVALID_PARAMETER we probably opened something */
+ /* that is not a pipe. */
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ SetLastError(WSAENOTSOCK);
+ }
+ return -1;
+ }
+
+ /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */
+ nt_status = pNtQueryInformationFile(pipeHandle,
+ &io_status,
+ &mode_info,
+ sizeof(mode_info),
+ FileModeInformation);
+ if (nt_status != STATUS_SUCCESS) {
+ return -1;
+ }
+
+ if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT ||
+ mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) {
+ /* Non-overlapped pipe. */
+ handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE;
+ } else {
+ /* Overlapped pipe. Try to associate with IOCP. */
+ if (CreateIoCompletionPort(pipeHandle,
+ loop->iocp,
+ (ULONG_PTR)handle,
+ 0) == NULL) {
+ handle->flags |= UV_HANDLE_EMULATE_IOCP;
+ }
+ }
+
+ handle->handle = pipeHandle;
+ handle->flags |= duplex_flags;
+
+ return 0;
+}
+
+
+static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
+ uv_loop_t* loop;
+ uv_pipe_t* handle;
+ uv_shutdown_t* req;
+
+ req = (uv_shutdown_t*) parameter;
+ assert(req);
+ handle = (uv_pipe_t*) req->handle;
+ assert(handle);
+ loop = handle->loop;
+ assert(loop);
+
+ FlushFileBuffers(handle->handle);
+
+ /* Post completed */
+ POST_COMPLETION_FOR_REQ(loop, req);
+
+ return 0;
+}
+
+
+void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
+ int err;
+ DWORD result;
+ uv_shutdown_t* req;
+ NTSTATUS nt_status;
+ IO_STATUS_BLOCK io_status;
+ FILE_PIPE_LOCAL_INFORMATION pipe_info;
+
+ if ((handle->flags & UV_HANDLE_CONNECTION) &&
+ handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+ req = handle->shutdown_req;
+
+ /* Clear the shutdown_req field so we don't go here again. */
+ handle->shutdown_req = NULL;
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ /* Already closing. Cancel the shutdown. */
+ if (req->cb) {
+ req->cb(req, UV_ECANCELED);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+
+ /* Try to avoid flushing the pipe buffer in the thread pool. */
+ nt_status = pNtQueryInformationFile(handle->handle,
+ &io_status,
+ &pipe_info,
+ sizeof pipe_info,
+ FilePipeLocalInformation);
+
+ if (nt_status != STATUS_SUCCESS) {
+ /* Failure */
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
+ if (req->cb) {
+ err = pRtlNtStatusToDosError(nt_status);
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+
+ if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
+ /* Short-circuit, no need to call FlushFileBuffers. */
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ return;
+ }
+
+ /* Run FlushFileBuffers in the thread pool. */
+ result = QueueUserWorkItem(pipe_shutdown_thread_proc,
+ req,
+ WT_EXECUTELONGFUNCTION);
+ if (result) {
+ return;
+
+ } else {
+ /* Failure. */
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
+ if (req->cb) {
+ err = GetLastError();
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+ }
+
+ if (handle->flags & UV__HANDLE_CLOSING &&
+ handle->reqs_pending == 0) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ if (handle->flags & UV_HANDLE_CONNECTION) {
+ if (handle->pending_ipc_info.socket_info) {
+ free(handle->pending_ipc_info.socket_info);
+ handle->pending_ipc_info.socket_info = NULL;
+ }
+
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(handle->read_req.wait_handle);
+ handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+ }
+ if (handle->read_req.event_handle) {
+ CloseHandle(handle->read_req.event_handle);
+ handle->read_req.event_handle = NULL;
+ }
+ }
+ }
+
+ if (handle->flags & UV_HANDLE_PIPESERVER) {
+ assert(handle->accept_reqs);
+ free(handle->accept_reqs);
+ handle->accept_reqs = NULL;
+ }
+
+ uv__handle_close(handle);
+ }
+}
+
+
+void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
+ handle->pending_instances = count;
+ handle->flags |= UV_HANDLE_PIPESERVER;
+}
+
+
+/* Creates a pipe server. */
+int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
+ uv_loop_t* loop = handle->loop;
+ int i, err, nameSize;
+ uv_pipe_accept_t* req;
+
+ if (handle->flags & UV_HANDLE_BOUND) {
+ return UV_EINVAL;
+ }
+
+ if (!name) {
+ return UV_EINVAL;
+ }
+
+ if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
+ handle->pending_instances = default_pending_pipe_instances;
+ }
+
+ handle->accept_reqs = (uv_pipe_accept_t*)
+ malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
+ if (!handle->accept_reqs) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ for (i = 0; i < handle->pending_instances; i++) {
+ req = &handle->accept_reqs[i];
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_ACCEPT;
+ req->data = handle;
+ req->pipeHandle = INVALID_HANDLE_VALUE;
+ req->next_pending = NULL;
+ }
+
+ /* Convert name to UTF16. */
+ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ handle->name = (WCHAR*)malloc(nameSize);
+ if (!handle->name) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /*
+ * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
+ * If this fails then there's already a pipe server for the given pipe name.
+ */
+ handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
+ FILE_FLAG_FIRST_PIPE_INSTANCE,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
+
+ if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
+ err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED) {
+ err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */
+ } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) {
+ err = WSAEACCES; /* Translates to UV_EACCES. */
+ }
+ goto error;
+ }
+
+ if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) {
+ err = GetLastError();
+ goto error;
+ }
+
+ handle->pending_accepts = NULL;
+ handle->flags |= UV_HANDLE_PIPESERVER;
+ handle->flags |= UV_HANDLE_BOUND;
+
+ return 0;
+
+error:
+ if (handle->name) {
+ free(handle->name);
+ handle->name = NULL;
+ }
+
+ if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle->accept_reqs[0].pipeHandle);
+ handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
+ uv_loop_t* loop;
+ uv_pipe_t* handle;
+ uv_connect_t* req;
+ HANDLE pipeHandle = INVALID_HANDLE_VALUE;
+ DWORD duplex_flags;
+
+ req = (uv_connect_t*) parameter;
+ assert(req);
+ handle = (uv_pipe_t*) req->handle;
+ assert(handle);
+ loop = handle->loop;
+ assert(loop);
+
+ /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
+ /* We wait for the pipe to become available with WaitNamedPipe. */
+ while (WaitNamedPipeW(handle->name, 30000)) {
+ /* The pipe is now available, try to connect. */
+ pipeHandle = open_named_pipe(handle->name, &duplex_flags);
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ break;
+ }
+
+ SwitchToThread();
+ }
+
+ if (pipeHandle != INVALID_HANDLE_VALUE &&
+ !uv_set_pipe_handle(loop, handle, pipeHandle, duplex_flags)) {
+ SET_REQ_SUCCESS(req);
+ } else {
+ SET_REQ_ERROR(req, GetLastError());
+ }
+
+ /* Post completed */
+ POST_COMPLETION_FOR_REQ(loop, req);
+
+ return 0;
+}
+
+
+void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+ const char* name, uv_connect_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ int err, nameSize;
+ HANDLE pipeHandle = INVALID_HANDLE_VALUE;
+ DWORD duplex_flags;
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_CONNECT;
+ req->handle = (uv_stream_t*) handle;
+ req->cb = cb;
+
+ /* Convert name to UTF16. */
+ nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ handle->name = (WCHAR*)malloc(nameSize);
+ if (!handle->name) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
+ err = GetLastError();
+ goto error;
+ }
+
+ pipeHandle = open_named_pipe(handle->name, &duplex_flags);
+ if (pipeHandle == INVALID_HANDLE_VALUE) {
+ if (GetLastError() == ERROR_PIPE_BUSY) {
+ /* Wait for the server to make a pipe instance available. */
+ if (!QueueUserWorkItem(&pipe_connect_thread_proc,
+ req,
+ WT_EXECUTELONGFUNCTION)) {
+ err = GetLastError();
+ goto error;
+ }
+
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ handle->reqs_pending++;
+
+ return;
+ }
+
+ err = GetLastError();
+ goto error;
+ }
+
+ assert(pipeHandle != INVALID_HANDLE_VALUE);
+
+ if (uv_set_pipe_handle(loop,
+ (uv_pipe_t*) req->handle,
+ pipeHandle,
+ duplex_flags)) {
+ err = GetLastError();
+ goto error;
+ }
+
+ SET_REQ_SUCCESS(req);
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ return;
+
+error:
+ if (handle->name) {
+ free(handle->name);
+ handle->name = NULL;
+ }
+
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(pipeHandle);
+ }
+
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, err);
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ return;
+}
+
+
+/* Cleans up uv_pipe_t (server or connection) and all resources associated */
+/* with it. */
+void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
+ int i;
+ HANDLE pipeHandle;
+
+ if (handle->name) {
+ free(handle->name);
+ handle->name = NULL;
+ }
+
+ if (handle->flags & UV_HANDLE_PIPESERVER) {
+ for (i = 0; i < handle->pending_instances; i++) {
+ pipeHandle = handle->accept_reqs[i].pipeHandle;
+ if (pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(pipeHandle);
+ handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
+ }
+ }
+ }
+
+ if (handle->flags & UV_HANDLE_CONNECTION) {
+ handle->flags &= ~UV_HANDLE_WRITABLE;
+ eof_timer_destroy(handle);
+ }
+
+ if ((handle->flags & UV_HANDLE_CONNECTION)
+ && handle->handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle->handle);
+ handle->handle = INVALID_HANDLE_VALUE;
+ }
+}
+
+
+void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
+ if (handle->flags & UV_HANDLE_READING) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ }
+
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ handle->flags &= ~UV_HANDLE_LISTENING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ }
+
+ uv_pipe_cleanup(loop, handle);
+
+ if (handle->reqs_pending == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(handle);
+}
+
+
+static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_pipe_accept_t* req, BOOL firstInstance) {
+ assert(handle->flags & UV_HANDLE_LISTENING);
+
+ if (!firstInstance) {
+ assert(req->pipeHandle == INVALID_HANDLE_VALUE);
+
+ req->pipeHandle = CreateNamedPipeW(handle->name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
+
+ if (req->pipeHandle == INVALID_HANDLE_VALUE) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ handle->reqs_pending++;
+ return;
+ }
+
+ if (uv_set_pipe_handle(loop, handle, req->pipeHandle, 0)) {
+ CloseHandle(req->pipeHandle);
+ req->pipeHandle = INVALID_HANDLE_VALUE;
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ handle->reqs_pending++;
+ return;
+ }
+ }
+
+ assert(req->pipeHandle != INVALID_HANDLE_VALUE);
+
+ /* Prepare the overlapped structure. */
+ memset(&(req->overlapped), 0, sizeof(req->overlapped));
+
+ if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) &&
+ GetLastError() != ERROR_IO_PENDING) {
+ if (GetLastError() == ERROR_PIPE_CONNECTED) {
+ SET_REQ_SUCCESS(req);
+ } else {
+ CloseHandle(req->pipeHandle);
+ req->pipeHandle = INVALID_HANDLE_VALUE;
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, GetLastError());
+ }
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ handle->reqs_pending++;
+ return;
+ }
+
+ handle->reqs_pending++;
+}
+
+
+int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
+ uv_loop_t* loop = server->loop;
+ uv_pipe_t* pipe_client;
+ uv_pipe_accept_t* req;
+
+ if (server->ipc) {
+ if (!server->pending_ipc_info.socket_info) {
+ /* No valid pending sockets. */
+ return WSAEWOULDBLOCK;
+ }
+
+ return uv_tcp_import((uv_tcp_t*)client, server->pending_ipc_info.socket_info,
+ server->pending_ipc_info.tcp_connection);
+ } else {
+ pipe_client = (uv_pipe_t*)client;
+
+ /* Find a connection instance that has been connected, but not yet */
+ /* accepted. */
+ req = server->pending_accepts;
+
+ if (!req) {
+ /* No valid connections found, so we error out. */
+ return WSAEWOULDBLOCK;
+ }
+
+ /* Initialize the client handle and copy the pipeHandle to the client */
+ uv_pipe_connection_init(pipe_client);
+ pipe_client->handle = req->pipeHandle;
+ pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+
+ /* Prepare the req to pick up a new connection */
+ server->pending_accepts = req->next_pending;
+ req->next_pending = NULL;
+ req->pipeHandle = INVALID_HANDLE_VALUE;
+
+ if (!(server->flags & UV__HANDLE_CLOSING)) {
+ uv_pipe_queue_accept(loop, server, req, FALSE);
+ }
+ }
+
+ return 0;
+}
+
+
+/* Starts listening for connections for the given pipe. */
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ int i;
+
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ handle->connection_cb = cb;
+ }
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return WSAEINVAL;
+ }
+
+ if (handle->flags & UV_HANDLE_READING) {
+ return WSAEISCONN;
+ }
+
+ if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
+ return ERROR_NOT_SUPPORTED;
+ }
+
+ handle->flags |= UV_HANDLE_LISTENING;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+ handle->connection_cb = cb;
+
+ /* First pipe handle should have already been created in uv_pipe_bind */
+ assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
+
+ for (i = 0; i < handle->pending_instances; i++) {
+ uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
+ }
+
+ return 0;
+}
+
+
+static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
+ int result;
+ DWORD bytes;
+ uv_read_t* req = (uv_read_t*) parameter;
+ uv_pipe_t* handle = (uv_pipe_t*) req->data;
+ uv_loop_t* loop = handle->loop;
+
+ assert(req != NULL);
+ assert(req->type == UV_READ);
+ assert(handle->type == UV_NAMED_PIPE);
+
+ result = ReadFile(handle->handle,
+ &uv_zero_,
+ 0,
+ &bytes,
+ NULL);
+
+ if (!result) {
+ SET_REQ_ERROR(req, GetLastError());
+ }
+
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+}
+
+
+static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) {
+ int result;
+ DWORD bytes;
+ uv_write_t* req = (uv_write_t*) parameter;
+ uv_pipe_t* handle = (uv_pipe_t*) req->handle;
+ uv_loop_t* loop = handle->loop;
+
+ assert(req != NULL);
+ assert(req->type == UV_WRITE);
+ assert(handle->type == UV_NAMED_PIPE);
+ assert(req->write_buffer.base);
+
+ result = WriteFile(handle->handle,
+ req->write_buffer.base,
+ req->write_buffer.len,
+ &bytes,
+ NULL);
+
+ if (!result) {
+ SET_REQ_ERROR(req, GetLastError());
+ }
+
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+}
+
+
+static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) {
+ uv_read_t* req;
+ uv_tcp_t* handle;
+
+ req = (uv_read_t*) context;
+ assert(req != NULL);
+ handle = (uv_tcp_t*)req->data;
+ assert(handle != NULL);
+ assert(!timed_out);
+
+ if (!PostQueuedCompletionStatus(handle->loop->iocp,
+ req->overlapped.InternalHigh,
+ 0,
+ &req->overlapped)) {
+ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+ }
+}
+
+
+static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) {
+ uv_write_t* req;
+ uv_tcp_t* handle;
+
+ req = (uv_write_t*) context;
+ assert(req != NULL);
+ handle = (uv_tcp_t*)req->handle;
+ assert(handle != NULL);
+ assert(!timed_out);
+
+ if (!PostQueuedCompletionStatus(handle->loop->iocp,
+ req->overlapped.InternalHigh,
+ 0,
+ &req->overlapped)) {
+ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+ }
+}
+
+
+static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
+ uv_read_t* req;
+ int result;
+
+ assert(handle->flags & UV_HANDLE_READING);
+ assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+ assert(handle->handle != INVALID_HANDLE_VALUE);
+
+ req = &handle->read_req;
+
+ if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
+ req,
+ WT_EXECUTELONGFUNCTION)) {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, GetLastError());
+ goto error;
+ }
+ } else {
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
+ }
+
+ /* Do 0-read */
+ result = ReadFile(handle->handle,
+ &uv_zero_,
+ 0,
+ NULL,
+ &req->overlapped);
+
+ if (!result && GetLastError() != ERROR_IO_PENDING) {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, GetLastError());
+ goto error;
+ }
+
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ if (!req->event_handle) {
+ req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+ if (!req->event_handle) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+ }
+ if (req->wait_handle == INVALID_HANDLE_VALUE) {
+ if (!RegisterWaitForSingleObject(&req->wait_handle,
+ req->overlapped.hEvent, post_completion_read_wait, (void*) req,
+ INFINITE, WT_EXECUTEINWAITTHREAD)) {
+ SET_REQ_ERROR(req, GetLastError());
+ goto error;
+ }
+ }
+ }
+ }
+
+ /* Start the eof timer if there is one */
+ eof_timer_start(handle);
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+ return;
+
+error:
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+}
+
+
+static int uv_pipe_read_start_impl(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb, uv_read2_cb read2_cb) {
+ uv_loop_t* loop = handle->loop;
+
+ handle->flags |= UV_HANDLE_READING;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb = read_cb;
+ handle->read2_cb = read2_cb;
+ handle->alloc_cb = alloc_cb;
+
+ /* If reading was stopped and then started again, there could still be a */
+ /* read request pending. */
+ if (!(handle->flags & UV_HANDLE_READ_PENDING))
+ uv_pipe_queue_read(loop, handle);
+
+ return 0;
+}
+
+
+int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
+ return uv_pipe_read_start_impl(handle, alloc_cb, read_cb, NULL);
+}
+
+
+int uv_pipe_read2_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+ uv_read2_cb read_cb) {
+ return uv_pipe_read_start_impl(handle, alloc_cb, NULL, read_cb);
+}
+
+
+static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
+ uv_write_t* req) {
+ req->next_req = NULL;
+ if (handle->non_overlapped_writes_tail) {
+ req->next_req =
+ handle->non_overlapped_writes_tail->next_req;
+ handle->non_overlapped_writes_tail->next_req = (uv_req_t*)req;
+ handle->non_overlapped_writes_tail = req;
+ } else {
+ req->next_req = (uv_req_t*)req;
+ handle->non_overlapped_writes_tail = req;
+ }
+}
+
+
+static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) {
+ uv_write_t* req;
+
+ if (handle->non_overlapped_writes_tail) {
+ req = (uv_write_t*)handle->non_overlapped_writes_tail->next_req;
+
+ if (req == handle->non_overlapped_writes_tail) {
+ handle->non_overlapped_writes_tail = NULL;
+ } else {
+ handle->non_overlapped_writes_tail->next_req =
+ req->next_req;
+ }
+
+ return req;
+ } else {
+ /* queue empty */
+ return NULL;
+ }
+}
+
+
+static void uv_queue_non_overlapped_write(uv_pipe_t* handle) {
+ uv_write_t* req = uv_remove_non_overlapped_write_req(handle);
+ if (req) {
+ if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc,
+ req,
+ WT_EXECUTELONGFUNCTION)) {
+ uv_fatal_error(GetLastError(), "QueueUserWorkItem");
+ }
+ }
+}
+
+
+static int uv_pipe_write_impl(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
+ int err;
+ int result;
+ uv_tcp_t* tcp_send_handle;
+ uv_write_t* ipc_header_req;
+ uv_ipc_frame_uv_stream ipc_frame;
+
+ if (nbufs != 1 && (nbufs != 0 || !send_handle)) {
+ return ERROR_NOT_SUPPORTED;
+ }
+
+ /* Only TCP handles are supported for sharing. */
+ if (send_handle && ((send_handle->type != UV_TCP) ||
+ (!(send_handle->flags & UV_HANDLE_BOUND) &&
+ !(send_handle->flags & UV_HANDLE_CONNECTION)))) {
+ return ERROR_NOT_SUPPORTED;
+ }
+
+ assert(handle->handle != INVALID_HANDLE_VALUE);
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_WRITE;
+ req->handle = (uv_stream_t*) handle;
+ req->cb = cb;
+ req->ipc_header = 0;
+ req->event_handle = NULL;
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ if (handle->ipc) {
+ assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
+ ipc_frame.header.flags = 0;
+
+ /* Use the IPC framing protocol. */
+ if (send_handle) {
+ tcp_send_handle = (uv_tcp_t*)send_handle;
+
+ err = uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid,
+ &ipc_frame.socket_info);
+ if (err) {
+ return err;
+ }
+ ipc_frame.header.flags |= UV_IPC_TCP_SERVER;
+
+ if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) {
+ ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION;
+ }
+ }
+
+ if (nbufs == 1) {
+ ipc_frame.header.flags |= UV_IPC_RAW_DATA;
+ ipc_frame.header.raw_data_length = bufs[0].len;
+ }
+
+ /*
+ * Use the provided req if we're only doing a single write.
+ * If we're doing multiple writes, use ipc_header_write_req to do
+ * the first write, and then use the provided req for the second write.
+ */
+ if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
+ ipc_header_req = req;
+ } else {
+ /*
+ * Try to use the preallocated write req if it's available.
+ * Otherwise allocate a new one.
+ */
+ if (handle->ipc_header_write_req.type != UV_WRITE) {
+ ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req;
+ } else {
+ ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
+ if (!ipc_header_req) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+ }
+
+ uv_req_init(loop, (uv_req_t*) ipc_header_req);
+ ipc_header_req->type = UV_WRITE;
+ ipc_header_req->handle = (uv_stream_t*) handle;
+ ipc_header_req->cb = NULL;
+ ipc_header_req->ipc_header = 1;
+ }
+
+ /* Write the header or the whole frame. */
+ memset(&ipc_header_req->overlapped, 0, sizeof(ipc_header_req->overlapped));
+
+ /* Using overlapped IO, but wait for completion before returning.
+ This write is blocking because ipc_frame is on stack. */
+ ipc_header_req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+ if (!ipc_header_req->overlapped.hEvent) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+
+ result = WriteFile(handle->handle,
+ &ipc_frame,
+ ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
+ sizeof(ipc_frame) : sizeof(ipc_frame.header),
+ NULL,
+ &ipc_header_req->overlapped);
+ if (!result && GetLastError() != ERROR_IO_PENDING) {
+ err = GetLastError();
+ CloseHandle(ipc_header_req->overlapped.hEvent);
+ return err;
+ }
+
+ if (!result) {
+ /* Request not completed immediately. Wait for it.*/
+ if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) !=
+ WAIT_OBJECT_0) {
+ err = GetLastError();
+ CloseHandle(ipc_header_req->overlapped.hEvent);
+ return err;
+ }
+ }
+ ipc_header_req->queued_bytes = 0;
+ CloseHandle(ipc_header_req->overlapped.hEvent);
+ ipc_header_req->overlapped.hEvent = NULL;
+
+ REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+
+ /* If we don't have any raw data to write - we're done. */
+ if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
+ return 0;
+ }
+ }
+
+ if ((handle->flags &
+ (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) ==
+ (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) {
+ DWORD bytes;
+ result = WriteFile(handle->handle,
+ bufs[0].base,
+ bufs[0].len,
+ &bytes,
+ NULL);
+
+ if (!result) {
+ return err;
+ } else {
+ /* Request completed immediately. */
+ req->queued_bytes = 0;
+ }
+
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+ } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ req->write_buffer = bufs[0];
+ uv_insert_non_overlapped_write_req(handle, req);
+ if (handle->write_reqs_pending == 0) {
+ uv_queue_non_overlapped_write(handle);
+ }
+
+ /* Request queued by the kernel. */
+ req->queued_bytes = uv_count_bufs(bufs, nbufs);
+ handle->write_queue_size += req->queued_bytes;
+ } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
+ /* Using overlapped IO, but wait for completion before returning */
+ req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+ if (!req->overlapped.hEvent) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+
+ result = WriteFile(handle->handle,
+ bufs[0].base,
+ bufs[0].len,
+ NULL,
+ &req->overlapped);
+
+ if (!result && GetLastError() != ERROR_IO_PENDING) {
+ err = GetLastError();
+ CloseHandle(req->overlapped.hEvent);
+ return err;
+ }
+
+ if (result) {
+ /* Request completed immediately. */
+ req->queued_bytes = 0;
+ } else {
+ /* Request queued by the kernel. */
+ if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) !=
+ WAIT_OBJECT_0) {
+ err = GetLastError();
+ CloseHandle(ipc_header_req->overlapped.hEvent);
+ return uv_translate_sys_error(err);
+ }
+ }
+ CloseHandle(req->overlapped.hEvent);
+
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+ } else {
+ result = WriteFile(handle->handle,
+ bufs[0].base,
+ bufs[0].len,
+ NULL,
+ &req->overlapped);
+
+ if (!result && GetLastError() != ERROR_IO_PENDING) {
+ return GetLastError();
+ }
+
+ if (result) {
+ /* Request completed immediately. */
+ req->queued_bytes = 0;
+ } else {
+ /* Request queued by the kernel. */
+ req->queued_bytes = uv_count_bufs(bufs, nbufs);
+ handle->write_queue_size += req->queued_bytes;
+ }
+
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+ if (!req->event_handle) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+ if (!RegisterWaitForSingleObject(&req->wait_handle,
+ req->overlapped.hEvent, post_completion_write_wait, (void*) req,
+ INFINITE, WT_EXECUTEINWAITTHREAD)) {
+ return GetLastError();
+ }
+ }
+ }
+
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+
+ return 0;
+}
+
+
+int uv_pipe_write(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb) {
+ return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb);
+}
+
+
+int uv_pipe_write2(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_pipe_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
+ if (!handle->ipc) {
+ return WSAEINVAL;
+ }
+
+ return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb);
+}
+
+
+static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_buf_t buf) {
+ /* If there is an eof timer running, we don't need it any more, */
+ /* so discard it. */
+ eof_timer_destroy(handle);
+
+ handle->flags &= ~UV_HANDLE_READABLE;
+ uv_read_stop((uv_stream_t*) handle);
+
+ if (handle->read2_cb) {
+ handle->read2_cb(handle, UV_EOF, &uv_null_buf_, UV_UNKNOWN_HANDLE);
+ } else {
+ handle->read_cb((uv_stream_t*) handle, UV_EOF, &uv_null_buf_);
+ }
+}
+
+
+static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
+ uv_buf_t buf) {
+ /* If there is an eof timer running, we don't need it any more, */
+ /* so discard it. */
+ eof_timer_destroy(handle);
+
+ uv_read_stop((uv_stream_t*) handle);
+
+ if (handle->read2_cb) {
+ handle->read2_cb(handle,
+ uv_translate_sys_error(error),
+ &buf,
+ UV_UNKNOWN_HANDLE);
+ } else {
+ handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf);
+ }
+}
+
+
+static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
+ int error, uv_buf_t buf) {
+ if (error == ERROR_BROKEN_PIPE) {
+ uv_pipe_read_eof(loop, handle, buf);
+ } else {
+ uv_pipe_read_error(loop, handle, error, buf);
+ }
+}
+
+
+void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_req_t* req) {
+ DWORD bytes, avail;
+ uv_buf_t buf;
+ uv_ipc_frame_uv_stream ipc_frame;
+
+ assert(handle->type == UV_NAMED_PIPE);
+
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
+ eof_timer_stop(handle);
+
+ if (!REQ_SUCCESS(req)) {
+ /* An error occurred doing the 0-read. */
+ if (handle->flags & UV_HANDLE_READING) {
+ uv_pipe_read_error_or_eof(loop,
+ handle,
+ GET_REQ_ERROR(req),
+ uv_null_buf_);
+ }
+ } else {
+ /* Do non-blocking reads until the buffer is empty */
+ while (handle->flags & UV_HANDLE_READING) {
+ if (!PeekNamedPipe(handle->handle,
+ NULL,
+ 0,
+ NULL,
+ &avail,
+ NULL)) {
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
+ break;
+ }
+
+ if (avail == 0) {
+ /* There is nothing to read after all. */
+ break;
+ }
+
+ if (handle->ipc) {
+ /* Use the IPC framing protocol to read the incoming data. */
+ if (handle->remaining_ipc_rawdata_bytes == 0) {
+ /* We're reading a new frame. First, read the header. */
+ assert(avail >= sizeof(ipc_frame.header));
+
+ if (!ReadFile(handle->handle,
+ &ipc_frame.header,
+ sizeof(ipc_frame.header),
+ &bytes,
+ NULL)) {
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
+ uv_null_buf_);
+ break;
+ }
+
+ assert(bytes == sizeof(ipc_frame.header));
+ assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA |
+ UV_IPC_TCP_CONNECTION));
+
+ if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) {
+ assert(avail - sizeof(ipc_frame.header) >=
+ sizeof(ipc_frame.socket_info));
+
+ /* Read the TCP socket info. */
+ if (!ReadFile(handle->handle,
+ &ipc_frame.socket_info,
+ sizeof(ipc_frame) - sizeof(ipc_frame.header),
+ &bytes,
+ NULL)) {
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
+ uv_null_buf_);
+ break;
+ }
+
+ assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header));
+
+ /* Store the pending socket info. */
+ assert(!handle->pending_ipc_info.socket_info);
+ handle->pending_ipc_info.socket_info =
+ (WSAPROTOCOL_INFOW*)malloc(sizeof(*(handle->pending_ipc_info.socket_info)));
+ if (!handle->pending_ipc_info.socket_info) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ *(handle->pending_ipc_info.socket_info) = ipc_frame.socket_info;
+ handle->pending_ipc_info.tcp_connection =
+ ipc_frame.header.flags & UV_IPC_TCP_CONNECTION;
+ }
+
+ if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
+ handle->remaining_ipc_rawdata_bytes =
+ ipc_frame.header.raw_data_length;
+ continue;
+ }
+ } else {
+ avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes);
+ }
+ }
+
+ handle->alloc_cb((uv_handle_t*) handle, avail, &buf);
+ if (buf.len == 0) {
+ if (handle->read2_cb) {
+ handle->read2_cb(handle, UV_ENOBUFS, &buf, UV_UNKNOWN_HANDLE);
+ } else if (handle->read_cb) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+ }
+ break;
+ }
+ assert(buf.base != NULL);
+
+ if (ReadFile(handle->handle,
+ buf.base,
+ buf.len,
+ &bytes,
+ NULL)) {
+ /* Successful read */
+ if (handle->ipc) {
+ assert(handle->remaining_ipc_rawdata_bytes >= bytes);
+ handle->remaining_ipc_rawdata_bytes =
+ handle->remaining_ipc_rawdata_bytes - bytes;
+ if (handle->read2_cb) {
+ handle->read2_cb(handle, bytes, &buf,
+ handle->pending_ipc_info.socket_info ? UV_TCP : UV_UNKNOWN_HANDLE);
+ } else if (handle->read_cb) {
+ handle->read_cb((uv_stream_t*)handle, bytes, &buf);
+ }
+
+ if (handle->pending_ipc_info.socket_info) {
+ free(handle->pending_ipc_info.socket_info);
+ handle->pending_ipc_info.socket_info = NULL;
+ }
+ } else {
+ handle->read_cb((uv_stream_t*)handle, bytes, &buf);
+ }
+
+ /* Read again only if bytes == buf.len */
+ if (bytes <= buf.len) {
+ break;
+ }
+ } else {
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
+ break;
+ }
+ }
+
+ /* Post another 0-read if still reading and not closing. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_pipe_queue_read(loop, handle);
+ }
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_write_t* req) {
+ int err;
+
+ assert(handle->type == UV_NAMED_PIPE);
+
+ assert(handle->write_queue_size >= req->queued_bytes);
+ handle->write_queue_size -= req->queued_bytes;
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ if (req->wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(req->wait_handle);
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ }
+ if (req->event_handle) {
+ CloseHandle(req->event_handle);
+ req->event_handle = NULL;
+ }
+ }
+
+ if (req->ipc_header) {
+ if (req == &handle->ipc_header_write_req) {
+ req->type = UV_UNKNOWN_REQ;
+ } else {
+ free(req);
+ }
+ } else {
+ if (req->cb) {
+ err = GET_REQ_ERROR(req);
+ req->cb(req, uv_translate_sys_error(err));
+ }
+ }
+
+ handle->write_reqs_pending--;
+
+ if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
+ handle->non_overlapped_writes_tail) {
+ assert(handle->write_reqs_pending > 0);
+ uv_queue_non_overlapped_write(handle);
+ }
+
+ if (handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_req_t* raw_req) {
+ uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req;
+
+ assert(handle->type == UV_NAMED_PIPE);
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */
+ assert(req->pipeHandle == INVALID_HANDLE_VALUE);
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+
+ if (REQ_SUCCESS(req)) {
+ assert(req->pipeHandle != INVALID_HANDLE_VALUE);
+ req->next_pending = handle->pending_accepts;
+ handle->pending_accepts = req;
+
+ if (handle->connection_cb) {
+ handle->connection_cb((uv_stream_t*)handle, 0);
+ }
+ } else {
+ if (req->pipeHandle != INVALID_HANDLE_VALUE) {
+ CloseHandle(req->pipeHandle);
+ req->pipeHandle = INVALID_HANDLE_VALUE;
+ }
+ if (!(handle->flags & UV__HANDLE_CLOSING)) {
+ uv_pipe_queue_accept(loop, handle, req, FALSE);
+ }
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_connect_t* req) {
+ int err;
+
+ assert(handle->type == UV_NAMED_PIPE);
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (req->cb) {
+ err = 0;
+ if (REQ_SUCCESS(req)) {
+ uv_pipe_connection_init(handle);
+ } else {
+ err = GET_REQ_ERROR(req);
+ }
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
+ uv_shutdown_t* req) {
+ assert(handle->type == UV_NAMED_PIPE);
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (handle->flags & UV_HANDLE_READABLE) {
+ /* Initialize and optionally start the eof timer. Only do this if the */
+ /* pipe is readable and we haven't seen EOF come in ourselves. */
+ eof_timer_init(handle);
+
+ /* If reading start the timer right now. */
+ /* Otherwise uv_pipe_queue_read will start it. */
+ if (handle->flags & UV_HANDLE_READ_PENDING) {
+ eof_timer_start(handle);
+ }
+
+ } else {
+ /* This pipe is not readable. We can just close it to let the other end */
+ /* know that we're done writing. */
+ CloseHandle(handle->handle);
+ handle->handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (req->cb) {
+ req->cb(req, 0);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+static void eof_timer_init(uv_pipe_t* pipe) {
+ int r;
+
+ assert(pipe->eof_timer == NULL);
+ assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+ pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer);
+
+ r = uv_timer_init(pipe->loop, pipe->eof_timer);
+ assert(r == 0); /* timers can't fail */
+ pipe->eof_timer->data = pipe;
+ uv_unref((uv_handle_t*) pipe->eof_timer);
+}
+
+
+static void eof_timer_start(uv_pipe_t* pipe) {
+ assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+ if (pipe->eof_timer != NULL) {
+ uv_timer_start(pipe->eof_timer, eof_timer_cb, eof_timeout, 0);
+ }
+}
+
+
+static void eof_timer_stop(uv_pipe_t* pipe) {
+ assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+ if (pipe->eof_timer != NULL) {
+ uv_timer_stop(pipe->eof_timer);
+ }
+}
+
+
+static void eof_timer_cb(uv_timer_t* timer, int status) {
+ uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
+ uv_loop_t* loop = timer->loop;
+
+ assert(status == 0); /* timers can't fail */
+ assert(pipe->type == UV_NAMED_PIPE);
+
+ /* This should always be true, since we start the timer only */
+ /* in uv_pipe_queue_read after successfully calling ReadFile, */
+ /* or in uv_process_pipe_shutdown_req if a read is pending, */
+ /* and we always immediately stop the timer in */
+ /* uv_process_pipe_read_req. */
+ assert(pipe->flags & UV_HANDLE_READ_PENDING);
+
+ /* If there are many packets coming off the iocp then the timer callback */
+ /* may be called before the read request is coming off the queue. */
+ /* Therefore we check here if the read request has completed but will */
+ /* be processed later. */
+ if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
+ HasOverlappedIoCompleted(&pipe->read_req.overlapped)) {
+ return;
+ }
+
+ /* Force both ends off the pipe. */
+ CloseHandle(pipe->handle);
+ pipe->handle = INVALID_HANDLE_VALUE;
+
+ /* Stop reading, so the pending read that is going to fail will */
+ /* not be reported to the user. */
+ uv_read_stop((uv_stream_t*) pipe);
+
+ /* Report the eof and update flags. This will get reported even if the */
+ /* user stopped reading in the meantime. TODO: is that okay? */
+ uv_pipe_read_eof(loop, pipe, uv_null_buf_);
+}
+
+
+static void eof_timer_destroy(uv_pipe_t* pipe) {
+ assert(pipe->flags && UV_HANDLE_CONNECTION);
+
+ if (pipe->eof_timer) {
+ uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
+ pipe->eof_timer = NULL;
+ }
+}
+
+
+static void eof_timer_close_cb(uv_handle_t* handle) {
+ assert(handle->type == UV_TIMER);
+ free(handle);
+}
+
+
+int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
+ HANDLE os_handle = uv__get_osfhandle(file);
+
+ if (os_handle == INVALID_HANDLE_VALUE ||
+ uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
+ return UV_EINVAL;
+ }
+
+ uv_pipe_connection_init(pipe);
+ pipe->handle = os_handle;
+ pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+
+ if (pipe->ipc) {
+ assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
+ pipe->ipc_pid = uv_parent_pid();
+ assert(pipe->ipc_pid != -1);
+ }
+ return 0;
+}
diff --git a/third-party/libuv/src/win/poll.c b/third-party/libuv/src/win/poll.c
new file mode 100644
index 0000000000..75351afd75
--- /dev/null
+++ b/third-party/libuv/src/win/poll.c
@@ -0,0 +1,617 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = {
+ {0xe70f1aa0, 0xab8b, 0x11cf,
+ {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}},
+ {0xf9eab0c0, 0x26d4, 0x11d0,
+ {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}},
+ {0x9fc48064, 0x7298, 0x43e4,
+ {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}}
+};
+
+typedef struct uv_single_fd_set_s {
+ unsigned int fd_count;
+ SOCKET fd_array[1];
+} uv_single_fd_set_t;
+
+
+static OVERLAPPED overlapped_dummy_;
+static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT;
+
+
+static void uv__init_overlapped_dummy(void) {
+ HANDLE event;
+
+ event = CreateEvent(NULL, TRUE, TRUE, NULL);
+ if (event == NULL)
+ uv_fatal_error(GetLastError(), "CreateEvent");
+
+ memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_);
+ overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1);
+}
+
+
+static OVERLAPPED* uv__get_overlapped_dummy() {
+ uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy);
+ return &overlapped_dummy_;
+}
+
+
+static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+ uv_req_t* req;
+ AFD_POLL_INFO* afd_poll_info;
+ DWORD result;
+
+ /* Find a yet unsubmitted req to submit. */
+ if (handle->submitted_events_1 == 0) {
+ req = &handle->poll_req_1;
+ afd_poll_info = &handle->afd_poll_info_1;
+ handle->submitted_events_1 = handle->events;
+ handle->mask_events_1 = 0;
+ handle->mask_events_2 = handle->events;
+ } else if (handle->submitted_events_2 == 0) {
+ req = &handle->poll_req_2;
+ afd_poll_info = &handle->afd_poll_info_2;
+ handle->submitted_events_2 = handle->events;
+ handle->mask_events_1 = handle->events;
+ handle->mask_events_2 = 0;
+ } else {
+ assert(0);
+ }
+
+ /* Setting Exclusive to TRUE makes the other poll request return if there */
+ /* is any. */
+ afd_poll_info->Exclusive = TRUE;
+ afd_poll_info->NumberOfHandles = 1;
+ afd_poll_info->Timeout.QuadPart = INT64_MAX;
+ afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket;
+ afd_poll_info->Handles[0].Status = 0;
+ afd_poll_info->Handles[0].Events = 0;
+
+ if (handle->events & UV_READABLE) {
+ afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE |
+ AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT;
+ }
+ if (handle->events & UV_WRITABLE) {
+ afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
+ }
+
+ memset(&req->overlapped, 0, sizeof req->overlapped);
+
+ result = uv_msafd_poll((SOCKET) handle->peer_socket,
+ afd_poll_info,
+ &req->overlapped);
+ if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
+ /* Queue this req, reporting an error. */
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, req);
+ }
+}
+
+
+static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+ AFD_POLL_INFO afd_poll_info;
+ DWORD result;
+
+ afd_poll_info.Exclusive = TRUE;
+ afd_poll_info.NumberOfHandles = 1;
+ afd_poll_info.Timeout.QuadPart = INT64_MAX;
+ afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
+ afd_poll_info.Handles[0].Status = 0;
+ afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
+
+ result = uv_msafd_poll(handle->socket,
+ &afd_poll_info,
+ uv__get_overlapped_dummy());
+
+ if (result == SOCKET_ERROR) {
+ DWORD error = WSAGetLastError();
+ if (error != WSA_IO_PENDING) {
+ return WSAGetLastError();
+ }
+ }
+
+ return 0;
+}
+
+
+static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+ uv_req_t* req) {
+ unsigned char mask_events;
+ AFD_POLL_INFO* afd_poll_info;
+
+ if (req == &handle->poll_req_1) {
+ afd_poll_info = &handle->afd_poll_info_1;
+ handle->submitted_events_1 = 0;
+ mask_events = handle->mask_events_1;
+ } else if (req == &handle->poll_req_2) {
+ afd_poll_info = &handle->afd_poll_info_2;
+ handle->submitted_events_2 = 0;
+ mask_events = handle->mask_events_2;
+ } else {
+ assert(0);
+ }
+
+ /* Report an error unless the select was just interrupted. */
+ if (!REQ_SUCCESS(req)) {
+ DWORD error = GET_REQ_SOCK_ERROR(req);
+ if (error != WSAEINTR && handle->events != 0) {
+ handle->events = 0; /* Stop the watcher */
+ handle->poll_cb(handle, uv_translate_sys_error(error), 0);
+ }
+
+ } else if (afd_poll_info->NumberOfHandles >= 1) {
+ unsigned char events = 0;
+
+ if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE |
+ AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) {
+ events |= UV_READABLE;
+ }
+ if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND |
+ AFD_POLL_CONNECT_FAIL)) != 0) {
+ events |= UV_WRITABLE;
+ }
+
+ events &= handle->events & ~mask_events;
+
+ if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) {
+ /* Stop polling. */
+ handle->events = 0;
+ uv__handle_stop(handle);
+ }
+
+ if (events != 0) {
+ handle->poll_cb(handle, 0, events);
+ }
+ }
+
+ if ((handle->events & ~(handle->submitted_events_1 |
+ handle->submitted_events_2)) != 0) {
+ uv__fast_poll_submit_poll_req(loop, handle);
+ } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+ handle->submitted_events_1 == 0 &&
+ handle->submitted_events_2 == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
+ assert(handle->type == UV_POLL);
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
+ assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
+
+ handle->events = events;
+
+ if (handle->events != 0) {
+ uv__handle_start(handle);
+ } else {
+ uv__handle_stop(handle);
+ }
+
+ if ((handle->events & ~(handle->submitted_events_1 |
+ handle->submitted_events_2)) != 0) {
+ uv__fast_poll_submit_poll_req(handle->loop, handle);
+ }
+
+ return 0;
+}
+
+
+static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+ handle->events = 0;
+ uv__handle_closing(handle);
+
+ if (handle->submitted_events_1 == 0 &&
+ handle->submitted_events_2 == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ return 0;
+ } else {
+ /* Cancel outstanding poll requests by executing another, unique poll */
+ /* request that forces the outstanding ones to return. */
+ return uv__fast_poll_cancel_poll_req(loop, handle);
+ }
+}
+
+
+static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
+ WSAPROTOCOL_INFOW* protocol_info) {
+ SOCKET sock = 0;
+
+ sock = WSASocketW(protocol_info->iAddressFamily,
+ protocol_info->iSocketType,
+ protocol_info->iProtocol,
+ protocol_info,
+ 0,
+ WSA_FLAG_OVERLAPPED);
+ if (sock == INVALID_SOCKET) {
+ return INVALID_SOCKET;
+ }
+
+ if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
+ goto error;
+ };
+
+ if (CreateIoCompletionPort((HANDLE) sock,
+ iocp,
+ (ULONG_PTR) sock,
+ 0) == NULL) {
+ goto error;
+ }
+
+ return sock;
+
+ error:
+ closesocket(sock);
+ return INVALID_SOCKET;
+}
+
+
+static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop,
+ WSAPROTOCOL_INFOW* protocol_info) {
+ int index, i;
+ SOCKET peer_socket;
+
+ index = -1;
+ for (i = 0; i < ARRAY_SIZE(uv_msafd_provider_ids); i++) {
+ if (memcmp((void*) &protocol_info->ProviderId,
+ (void*) &uv_msafd_provider_ids[i],
+ sizeof protocol_info->ProviderId) == 0) {
+ index = i;
+ }
+ }
+
+ /* Check if the protocol uses an msafd socket. */
+ if (index < 0) {
+ return INVALID_SOCKET;
+ }
+
+ /* If we didn't (try) to create a peer socket yet, try to make one. Don't */
+ /* try again if the peer socket creation failed earlier for the same */
+ /* protocol. */
+ peer_socket = loop->poll_peer_sockets[index];
+ if (peer_socket == 0) {
+ peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info);
+ loop->poll_peer_sockets[index] = peer_socket;
+ }
+
+ return peer_socket;
+}
+
+
+static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
+ uv_req_t* req = (uv_req_t*) arg;
+ uv_poll_t* handle = (uv_poll_t*) req->data;
+ unsigned char reported_events;
+ int r;
+ uv_single_fd_set_t rfds, wfds, efds;
+ struct timeval timeout;
+
+ assert(handle->type == UV_POLL);
+ assert(req->type == UV_POLL_REQ);
+
+ if (handle->events & UV_READABLE) {
+ rfds.fd_count = 1;
+ rfds.fd_array[0] = handle->socket;
+ } else {
+ rfds.fd_count = 0;
+ }
+
+ if (handle->events & UV_WRITABLE) {
+ wfds.fd_count = 1;
+ wfds.fd_array[0] = handle->socket;
+ efds.fd_count = 1;
+ efds.fd_array[0] = handle->socket;
+ } else {
+ wfds.fd_count = 0;
+ efds.fd_count = 0;
+ }
+
+ /* Make the select() time out after 3 minutes. If select() hangs because */
+ /* the user closed the socket, we will at least not hang indefinitely. */
+ timeout.tv_sec = 3 * 60;
+ timeout.tv_usec = 0;
+
+ r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout);
+ if (r == SOCKET_ERROR) {
+ /* Queue this req, reporting an error. */
+ SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError());
+ POST_COMPLETION_FOR_REQ(handle->loop, req);
+ return 0;
+ }
+
+ reported_events = 0;
+
+ if (r > 0) {
+ if (rfds.fd_count > 0) {
+ assert(rfds.fd_count == 1);
+ assert(rfds.fd_array[0] == handle->socket);
+ reported_events |= UV_READABLE;
+ }
+
+ if (wfds.fd_count > 0) {
+ assert(wfds.fd_count == 1);
+ assert(wfds.fd_array[0] == handle->socket);
+ reported_events |= UV_WRITABLE;
+ } else if (efds.fd_count > 0) {
+ assert(efds.fd_count == 1);
+ assert(efds.fd_array[0] == handle->socket);
+ reported_events |= UV_WRITABLE;
+ }
+ }
+
+ SET_REQ_SUCCESS(req);
+ req->overlapped.InternalHigh = (DWORD) reported_events;
+ POST_COMPLETION_FOR_REQ(handle->loop, req);
+
+ return 0;
+}
+
+
+static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+ uv_req_t* req;
+
+ /* Find a yet unsubmitted req to submit. */
+ if (handle->submitted_events_1 == 0) {
+ req = &handle->poll_req_1;
+ handle->submitted_events_1 = handle->events;
+ handle->mask_events_1 = 0;
+ handle->mask_events_2 = handle->events;
+ } else if (handle->submitted_events_2 == 0) {
+ req = &handle->poll_req_2;
+ handle->submitted_events_2 = handle->events;
+ handle->mask_events_1 = handle->events;
+ handle->mask_events_2 = 0;
+ } else {
+ assert(0);
+ }
+
+ if (!QueueUserWorkItem(uv__slow_poll_thread_proc,
+ (void*) req,
+ WT_EXECUTELONGFUNCTION)) {
+ /* Make this req pending, reporting an error. */
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, req);
+ }
+}
+
+
+
+static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+ uv_req_t* req) {
+ unsigned char mask_events;
+ int err;
+
+ if (req == &handle->poll_req_1) {
+ handle->submitted_events_1 = 0;
+ mask_events = handle->mask_events_1;
+ } else if (req == &handle->poll_req_2) {
+ handle->submitted_events_2 = 0;
+ mask_events = handle->mask_events_2;
+ } else {
+ assert(0);
+ }
+
+ if (!REQ_SUCCESS(req)) {
+ /* Error. */
+ if (handle->events != 0) {
+ err = GET_REQ_ERROR(req);
+ handle->events = 0; /* Stop the watcher */
+ handle->poll_cb(handle, uv_translate_sys_error(err), 0);
+ }
+ } else {
+ /* Got some events. */
+ int events = req->overlapped.InternalHigh & handle->events & ~mask_events;
+ if (events != 0) {
+ handle->poll_cb(handle, 0, events);
+ }
+ }
+
+ if ((handle->events & ~(handle->submitted_events_1 |
+ handle->submitted_events_2)) != 0) {
+ uv__slow_poll_submit_poll_req(loop, handle);
+ } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+ handle->submitted_events_1 == 0 &&
+ handle->submitted_events_2 == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
+ assert(handle->type == UV_POLL);
+ assert(!(handle->flags & UV__HANDLE_CLOSING));
+ assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
+
+ handle->events = events;
+
+ if (handle->events != 0) {
+ uv__handle_start(handle);
+ } else {
+ uv__handle_stop(handle);
+ }
+
+ if ((handle->events &
+ ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
+ uv__slow_poll_submit_poll_req(handle->loop, handle);
+ }
+
+ return 0;
+}
+
+
+static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+ handle->events = 0;
+ uv__handle_closing(handle);
+
+ if (handle->submitted_events_1 == 0 &&
+ handle->submitted_events_2 == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+
+ return 0;
+}
+
+
+int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
+ return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
+}
+
+
+int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
+ uv_os_sock_t socket) {
+ WSAPROTOCOL_INFOW protocol_info;
+ int len;
+ SOCKET peer_socket, base_socket;
+ DWORD bytes;
+
+ /* Try to obtain a base handle for the socket. This increases this chances */
+ /* that we find an AFD handle and are able to use the fast poll mechanism. */
+ /* This will always fail on windows XP/2k3, since they don't support the */
+ /* SIO_BASE_HANDLE ioctl. */
+#ifndef NDEBUG
+ base_socket = INVALID_SOCKET;
+#endif
+
+ if (WSAIoctl(socket,
+ SIO_BASE_HANDLE,
+ NULL,
+ 0,
+ &base_socket,
+ sizeof base_socket,
+ &bytes,
+ NULL,
+ NULL) == 0) {
+ assert(base_socket != 0 && base_socket != INVALID_SOCKET);
+ socket = base_socket;
+ }
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
+ handle->socket = socket;
+ handle->events = 0;
+
+ /* Obtain protocol information about the socket. */
+ len = sizeof protocol_info;
+ if (getsockopt(socket,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &len) != 0) {
+ return WSAGetLastError();
+ }
+
+ /* Get the peer socket that is needed to enable fast poll. If the returned */
+ /* value is NULL, the protocol is not implemented by MSAFD and we'll have */
+ /* to use slow mode. */
+ peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info);
+
+ if (peer_socket != INVALID_SOCKET) {
+ /* Initialize fast poll specific fields. */
+ handle->peer_socket = peer_socket;
+ } else {
+ /* Initialize slow poll specific fields. */
+ handle->flags |= UV_HANDLE_POLL_SLOW;
+ }
+
+ /* Intialize 2 poll reqs. */
+ handle->submitted_events_1 = 0;
+ uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1));
+ handle->poll_req_1.type = UV_POLL_REQ;
+ handle->poll_req_1.data = handle;
+
+ handle->submitted_events_2 = 0;
+ uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2));
+ handle->poll_req_2.type = UV_POLL_REQ;
+ handle->poll_req_2.data = handle;
+
+ return 0;
+}
+
+
+int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+ err = uv__fast_poll_set(handle->loop, handle, events);
+ } else {
+ err = uv__slow_poll_set(handle->loop, handle, events);
+ }
+
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ handle->poll_cb = cb;
+
+ return 0;
+}
+
+
+int uv_poll_stop(uv_poll_t* handle) {
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+ err = uv__fast_poll_set(handle->loop, handle, 0);
+ } else {
+ err = uv__slow_poll_set(handle->loop, handle, 0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) {
+ if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+ uv__fast_poll_process_poll_req(loop, handle, req);
+ } else {
+ uv__slow_poll_process_poll_req(loop, handle, req);
+ }
+}
+
+
+int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+ if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+ return uv__fast_poll_close(loop, handle);
+ } else {
+ return uv__slow_poll_close(loop, handle);
+ }
+}
+
+
+void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ assert(handle->submitted_events_1 == 0);
+ assert(handle->submitted_events_2 == 0);
+
+ uv__handle_close(handle);
+}
diff --git a/third-party/libuv/src/win/process-stdio.c b/third-party/libuv/src/win/process-stdio.c
new file mode 100644
index 0000000000..5757764bfd
--- /dev/null
+++ b/third-party/libuv/src/win/process-stdio.c
@@ -0,0 +1,510 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+/*
+ * The `child_stdio_buffer` buffer has the following layout:
+ * int number_of_fds
+ * unsigned char crt_flags[number_of_fds]
+ * HANDLE os_handle[number_of_fds]
+ */
+#define CHILD_STDIO_SIZE(count) \
+ (sizeof(int) + \
+ sizeof(unsigned char) * (count) + \
+ sizeof(uintptr_t) * (count))
+
+#define CHILD_STDIO_COUNT(buffer) \
+ *((unsigned int*) (buffer))
+
+#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \
+ *((unsigned char*) (buffer) + sizeof(int) + fd)
+
+#define CHILD_STDIO_HANDLE(buffer, fd) \
+ *((HANDLE*) ((unsigned char*) (buffer) + \
+ sizeof(int) + \
+ sizeof(unsigned char) * \
+ CHILD_STDIO_COUNT((buffer)) + \
+ sizeof(HANDLE) * (fd)))
+
+
+/* CRT file descriptor mode flags */
+#define FOPEN 0x01
+#define FEOFLAG 0x02
+#define FCRLF 0x04
+#define FPIPE 0x08
+#define FNOINHERIT 0x10
+#define FAPPEND 0x20
+#define FDEV 0x40
+#define FTEXT 0x80
+
+
+/*
+ * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited
+ * the parent process. Don't check for errors - the stdio handles may not be
+ * valid, or may be closed already. There is no guarantee that this function
+ * does a perfect job.
+ */
+void uv_disable_stdio_inheritance(void) {
+ HANDLE handle;
+ STARTUPINFOW si;
+
+ /* Make the windows stdio handles non-inheritable. */
+ handle = GetStdHandle(STD_INPUT_HANDLE);
+ if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+ SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+ handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+ SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+ handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+ SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+ /* Make inherited CRT FDs non-inheritable. */
+ GetStartupInfoW(&si);
+ if (uv__stdio_verify(si.lpReserved2, si.cbReserved2))
+ uv__stdio_noinherit(si.lpReserved2);
+}
+
+
+static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
+ uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
+ char pipe_name[64];
+ SECURITY_ATTRIBUTES sa;
+ DWORD server_access = 0;
+ DWORD client_access = 0;
+ HANDLE child_pipe = INVALID_HANDLE_VALUE;
+ int err;
+
+ if (flags & UV_READABLE_PIPE) {
+ /* The server needs inbound access too, otherwise CreateNamedPipe() */
+ /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */
+ /* probe the state of the write buffer when we're trying to shutdown */
+ /* the pipe. */
+ server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
+ client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
+ }
+ if (flags & UV_WRITABLE_PIPE) {
+ server_access |= PIPE_ACCESS_INBOUND;
+ client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
+ }
+
+ /* Create server pipe handle. */
+ err = uv_stdio_pipe_server(loop,
+ server_pipe,
+ server_access,
+ pipe_name,
+ sizeof(pipe_name));
+ if (err)
+ goto error;
+
+ /* Create child pipe handle. */
+ sa.nLength = sizeof sa;
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ child_pipe = CreateFileA(pipe_name,
+ client_access,
+ 0,
+ &sa,
+ OPEN_EXISTING,
+ server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
+ NULL);
+ if (child_pipe == INVALID_HANDLE_VALUE) {
+ err = GetLastError();
+ goto error;
+ }
+
+#ifndef NDEBUG
+ /* Validate that the pipe was opened in the right mode. */
+ {
+ DWORD mode;
+ BOOL r = GetNamedPipeHandleState(child_pipe,
+ &mode,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0);
+ assert(r == TRUE);
+ assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
+ }
+#endif
+
+ /* Do a blocking ConnectNamedPipe. This should not block because we have */
+ /* both ends of the pipe created. */
+ if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
+ if (GetLastError() != ERROR_PIPE_CONNECTED) {
+ err = GetLastError();
+ goto error;
+ }
+ }
+
+ /* The server end is now readable and/or writable. */
+ if (flags & UV_READABLE_PIPE)
+ server_pipe->flags |= UV_HANDLE_WRITABLE;
+ if (flags & UV_WRITABLE_PIPE)
+ server_pipe->flags |= UV_HANDLE_READABLE;
+
+ *child_pipe_ptr = child_pipe;
+ return 0;
+
+ error:
+ if (server_pipe->handle != INVALID_HANDLE_VALUE) {
+ uv_pipe_cleanup(loop, server_pipe);
+ }
+
+ if (child_pipe != INVALID_HANDLE_VALUE) {
+ CloseHandle(child_pipe);
+ }
+
+ return err;
+}
+
+
+static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
+ HANDLE current_process;
+
+
+ /* _get_osfhandle will sometimes return -2 in case of an error. This seems */
+ /* to happen when fd <= 2 and the process' corresponding stdio handle is */
+ /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */
+ /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */
+ /* use the duplicate. Therefore we filter out known-invalid handles here. */
+ if (handle == INVALID_HANDLE_VALUE ||
+ handle == NULL ||
+ handle == (HANDLE) -2) {
+ *dup = INVALID_HANDLE_VALUE;
+ return ERROR_INVALID_HANDLE;
+ }
+
+ current_process = GetCurrentProcess();
+
+ if (!DuplicateHandle(current_process,
+ handle,
+ current_process,
+ dup,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS)) {
+ *dup = INVALID_HANDLE_VALUE;
+ return GetLastError();
+ }
+
+ return 0;
+}
+
+
+static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
+ HANDLE handle;
+
+ if (fd == -1) {
+ *dup = INVALID_HANDLE_VALUE;
+ return ERROR_INVALID_HANDLE;
+ }
+
+ handle = uv__get_osfhandle(fd);
+ return uv__duplicate_handle(loop, handle, dup);
+}
+
+
+int uv__create_nul_handle(HANDLE* handle_ptr,
+ DWORD access) {
+ HANDLE handle;
+ SECURITY_ATTRIBUTES sa;
+
+ sa.nLength = sizeof sa;
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ handle = CreateFileW(L"NUL",
+ access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sa,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return GetLastError();
+ }
+
+ *handle_ptr = handle;
+ return 0;
+}
+
+
+int uv__stdio_create(uv_loop_t* loop,
+ const uv_process_options_t* options,
+ BYTE** buffer_ptr) {
+ BYTE* buffer;
+ int count, i;
+ int err;
+
+ count = options->stdio_count;
+
+ if (count < 0 || count > 255) {
+ /* Only support FDs 0-255 */
+ return ERROR_NOT_SUPPORTED;
+ } else if (count < 3) {
+ /* There should always be at least 3 stdio handles. */
+ count = 3;
+ }
+
+ /* Allocate the child stdio buffer */
+ buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count));
+ if (buffer == NULL) {
+ return ERROR_OUTOFMEMORY;
+ }
+
+ /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
+ /* clean up on failure. */
+ CHILD_STDIO_COUNT(buffer) = count;
+ for (i = 0; i < count; i++) {
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
+ CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
+ }
+
+ for (i = 0; i < count; i++) {
+ uv_stdio_container_t fdopt;
+ if (i < options->stdio_count) {
+ fdopt = options->stdio[i];
+ } else {
+ fdopt.flags = UV_IGNORE;
+ }
+
+ switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
+ UV_INHERIT_STREAM)) {
+ case UV_IGNORE:
+ /* Starting a process with no stdin/stout/stderr can confuse it. */
+ /* So no matter what the user specified, we make sure the first */
+ /* three FDs are always open in their typical modes, e.g. stdin */
+ /* be readable and stdout/err should be writable. For FDs > 2, don't */
+ /* do anything - all handles in the stdio buffer are initialized with */
+ /* INVALID_HANDLE_VALUE, which should be okay. */
+ if (i <= 2) {
+ DWORD access = (i == 0) ? FILE_GENERIC_READ :
+ FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
+
+ err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i),
+ access);
+ if (err)
+ goto error;
+
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+ }
+ break;
+
+ case UV_CREATE_PIPE: {
+ /* Create a pair of two connected pipe ends; one end is turned into */
+ /* an uv_pipe_t for use by the parent. The other one is given to */
+ /* the child. */
+ uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
+ HANDLE child_pipe;
+
+ /* Create a new, connected pipe pair. stdio[i].stream should point */
+ /* to an uninitialized, but not connected pipe handle. */
+ assert(fdopt.data.stream->type == UV_NAMED_PIPE);
+ assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
+ assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
+
+ err = uv__create_stdio_pipe_pair(loop,
+ parent_pipe,
+ &child_pipe,
+ fdopt.flags);
+ if (err)
+ goto error;
+
+ CHILD_STDIO_HANDLE(buffer, i) = child_pipe;
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
+ break;
+ }
+
+ case UV_INHERIT_FD: {
+ /* Inherit a raw FD. */
+ HANDLE child_handle;
+
+ /* Make an inheritable duplicate of the handle. */
+ err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle);
+ if (err) {
+ /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */
+ /* error. */
+ if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) {
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
+ CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
+ break;
+ }
+ goto error;
+ }
+
+ /* Figure out what the type is. */
+ switch (GetFileType(child_handle)) {
+ case FILE_TYPE_DISK:
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN;
+ break;
+
+ case FILE_TYPE_PIPE:
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
+
+ case FILE_TYPE_CHAR:
+ case FILE_TYPE_REMOTE:
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+ break;
+
+ case FILE_TYPE_UNKNOWN:
+ if (GetLastError() != 0) {
+ err = GetLastError();
+ CloseHandle(child_handle);
+ goto error;
+ }
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+ break;
+
+ default:
+ assert(0);
+ }
+
+ CHILD_STDIO_HANDLE(buffer, i) = child_handle;
+ break;
+ }
+
+ case UV_INHERIT_STREAM: {
+ /* Use an existing stream as the stdio handle for the child. */
+ HANDLE stream_handle, child_handle;
+ unsigned char crt_flags;
+ uv_stream_t* stream = fdopt.data.stream;
+
+ /* Leech the handle out of the stream. */
+ if (stream->type == UV_TTY) {
+ stream_handle = ((uv_tty_t*) stream)->handle;
+ crt_flags = FOPEN | FDEV;
+ } else if (stream->type == UV_NAMED_PIPE &&
+ stream->flags & UV_HANDLE_CONNECTED) {
+ stream_handle = ((uv_pipe_t*) stream)->handle;
+ crt_flags = FOPEN | FPIPE;
+ } else {
+ stream_handle = INVALID_HANDLE_VALUE;
+ crt_flags = 0;
+ }
+
+ if (stream_handle == NULL ||
+ stream_handle == INVALID_HANDLE_VALUE) {
+ /* The handle is already closed, or not yet created, or the */
+ /* stream type is not supported. */
+ err = ERROR_NOT_SUPPORTED;
+ goto error;
+ }
+
+ /* Make an inheritable copy of the handle. */
+ if (uv__duplicate_handle(loop,
+ stream_handle,
+ &child_handle) < 0) {
+ goto error;
+ }
+
+ CHILD_STDIO_HANDLE(buffer, i) = child_handle;
+ CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags;
+ break;
+ }
+
+ default:
+ assert(0);
+ }
+ }
+
+ *buffer_ptr = buffer;
+ return 0;
+
+ error:
+ uv__stdio_destroy(buffer);
+ return err;
+}
+
+
+void uv__stdio_destroy(BYTE* buffer) {
+ int i, count;
+
+ count = CHILD_STDIO_COUNT(buffer);
+ for (i = 0; i < count; i++) {
+ HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
+ if (handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle);
+ }
+ }
+
+ free(buffer);
+}
+
+
+void uv__stdio_noinherit(BYTE* buffer) {
+ int i, count;
+
+ count = CHILD_STDIO_COUNT(buffer);
+ for (i = 0; i < count; i++) {
+ HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
+ if (handle != INVALID_HANDLE_VALUE) {
+ SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+ }
+ }
+}
+
+
+int uv__stdio_verify(BYTE* buffer, WORD size) {
+ unsigned int count;
+
+ /* Check the buffer pointer. */
+ if (buffer == NULL)
+ return 0;
+
+ /* Verify that the buffer is at least big enough to hold the count. */
+ if (size < CHILD_STDIO_SIZE(0))
+ return 0;
+
+ /* Verify if the count is within range. */
+ count = CHILD_STDIO_COUNT(buffer);
+ if (count > 256)
+ return 0;
+
+ /* Verify that the buffer size is big enough to hold info for N FDs. */
+ if (size < CHILD_STDIO_SIZE(count))
+ return 0;
+
+ return 1;
+}
+
+
+WORD uv__stdio_size(BYTE* buffer) {
+ return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer)));
+}
+
+
+HANDLE uv__stdio_handle(BYTE* buffer, int fd) {
+ return CHILD_STDIO_HANDLE(buffer, fd);
+}
diff --git a/third-party/libuv/src/win/process.c b/third-party/libuv/src/win/process.c
new file mode 100644
index 0000000000..813e522f75
--- /dev/null
+++ b/third-party/libuv/src/win/process.c
@@ -0,0 +1,1120 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <limits.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+#define SIGKILL 9
+
+
+typedef struct env_var {
+ const char* narrow;
+ const WCHAR* wide;
+ size_t len; /* including null or '=' */
+ DWORD value_len;
+ int supplied;
+} env_var_t;
+
+#define E_V(str) { str "=", L##str, sizeof(str), 0, 0 }
+
+
+static HANDLE uv_global_job_handle_;
+static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT;
+
+
+static void uv__init_global_job_handle(void) {
+ /* Create a job object and set it up to kill all contained processes when
+ * it's closed. Since this handle is made non-inheritable and we're not
+ * giving it to anyone, we're the only process holding a reference to it.
+ * That means that if this process exits it is closed and all the processes
+ * it contains are killed. All processes created with uv_spawn that are not
+ * spawned with the UV_PROCESS_DETACHED flag are assigned to this job.
+ *
+ * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the
+ * processes that we explicitly add are affected, and *their* subprocesses
+ * are not. This ensures that our child processes are not limited in their
+ * ability to use job control on Windows versions that don't deal with
+ * nested jobs (prior to Windows 8 / Server 2012). It also lets our child
+ * processes created detached processes without explicitly breaking away
+ * from job control (which uv_spawn doesn't, either).
+ */
+ SECURITY_ATTRIBUTES attr;
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
+
+ memset(&attr, 0, sizeof attr);
+ attr.bInheritHandle = FALSE;
+
+ memset(&info, 0, sizeof info);
+ info.BasicLimitInformation.LimitFlags =
+ JOB_OBJECT_LIMIT_BREAKAWAY_OK |
+ JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK |
+ JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION |
+ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+
+ uv_global_job_handle_ = CreateJobObjectW(&attr, NULL);
+ if (uv_global_job_handle_ == NULL)
+ uv_fatal_error(GetLastError(), "CreateJobObjectW");
+
+ if (!SetInformationJobObject(uv_global_job_handle_,
+ JobObjectExtendedLimitInformation,
+ &info,
+ sizeof info))
+ uv_fatal_error(GetLastError(), "SetInformationJobObject");
+}
+
+
+static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
+ int ws_len, r;
+ WCHAR* ws;
+
+ ws_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ s,
+ -1,
+ NULL,
+ 0);
+ if (ws_len <= 0) {
+ return GetLastError();
+ }
+
+ ws = (WCHAR*) malloc(ws_len * sizeof(WCHAR));
+ if (ws == NULL) {
+ return ERROR_OUTOFMEMORY;
+ }
+
+ r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ s,
+ -1,
+ ws,
+ ws_len);
+ assert(r == ws_len);
+
+ *ws_ptr = ws;
+ return 0;
+}
+
+
+static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS);
+ handle->exit_cb = NULL;
+ handle->pid = 0;
+ handle->exit_signal = 0;
+ handle->wait_handle = INVALID_HANDLE_VALUE;
+ handle->process_handle = INVALID_HANDLE_VALUE;
+ handle->child_stdio_buffer = NULL;
+ handle->exit_cb_pending = 0;
+
+ uv_req_init(loop, (uv_req_t*)&handle->exit_req);
+ handle->exit_req.type = UV_PROCESS_EXIT;
+ handle->exit_req.data = handle;
+}
+
+
+/*
+ * Path search functions
+ */
+
+/*
+ * Helper function for search_path
+ */
+static WCHAR* search_path_join_test(const WCHAR* dir,
+ size_t dir_len,
+ const WCHAR* name,
+ size_t name_len,
+ const WCHAR* ext,
+ size_t ext_len,
+ const WCHAR* cwd,
+ size_t cwd_len) {
+ WCHAR *result, *result_pos;
+ DWORD attrs;
+
+ if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
+ /* It's a full path without drive letter, use cwd's drive letter only */
+ cwd_len = 2;
+ } else if (dir_len >= 2 && dir[1] == L':' &&
+ (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) {
+ /* It's a relative path with drive letter (ext.g. D:../some/file)
+ * Replace drive letter in dir by full cwd if it points to the same drive,
+ * otherwise use the dir only.
+ */
+ if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) {
+ cwd_len = 0;
+ } else {
+ dir += 2;
+ dir_len -= 2;
+ }
+ } else if (dir_len > 2 && dir[1] == L':') {
+ /* It's an absolute path with drive letter
+ * Don't use the cwd at all
+ */
+ cwd_len = 0;
+ }
+
+ /* Allocate buffer for output */
+ result = result_pos = (WCHAR*)malloc(sizeof(WCHAR) *
+ (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
+
+ /* Copy cwd */
+ wcsncpy(result_pos, cwd, cwd_len);
+ result_pos += cwd_len;
+
+ /* Add a path separator if cwd didn't end with one */
+ if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) {
+ result_pos[0] = L'\\';
+ result_pos++;
+ }
+
+ /* Copy dir */
+ wcsncpy(result_pos, dir, dir_len);
+ result_pos += dir_len;
+
+ /* Add a separator if the dir didn't end with one */
+ if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) {
+ result_pos[0] = L'\\';
+ result_pos++;
+ }
+
+ /* Copy filename */
+ wcsncpy(result_pos, name, name_len);
+ result_pos += name_len;
+
+ if (ext_len) {
+ /* Add a dot if the filename didn't end with one */
+ if (name_len && result_pos[-1] != '.') {
+ result_pos[0] = L'.';
+ result_pos++;
+ }
+
+ /* Copy extension */
+ wcsncpy(result_pos, ext, ext_len);
+ result_pos += ext_len;
+ }
+
+ /* Null terminator */
+ result_pos[0] = L'\0';
+
+ attrs = GetFileAttributesW(result);
+
+ if (attrs != INVALID_FILE_ATTRIBUTES &&
+ !(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
+ return result;
+ }
+
+ free(result);
+ return NULL;
+}
+
+
+/*
+ * Helper function for search_path
+ */
+static WCHAR* path_search_walk_ext(const WCHAR *dir,
+ size_t dir_len,
+ const WCHAR *name,
+ size_t name_len,
+ WCHAR *cwd,
+ size_t cwd_len,
+ int name_has_ext) {
+ WCHAR* result;
+
+ /* If the name itself has a nonempty extension, try this extension first */
+ if (name_has_ext) {
+ result = search_path_join_test(dir, dir_len,
+ name, name_len,
+ L"", 0,
+ cwd, cwd_len);
+ if (result != NULL) {
+ return result;
+ }
+ }
+
+ /* Try .com extension */
+ result = search_path_join_test(dir, dir_len,
+ name, name_len,
+ L"com", 3,
+ cwd, cwd_len);
+ if (result != NULL) {
+ return result;
+ }
+
+ /* Try .exe extension */
+ result = search_path_join_test(dir, dir_len,
+ name, name_len,
+ L"exe", 3,
+ cwd, cwd_len);
+ if (result != NULL) {
+ return result;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * search_path searches the system path for an executable filename -
+ * the windows API doesn't provide this as a standalone function nor as an
+ * option to CreateProcess.
+ *
+ * It tries to return an absolute filename.
+ *
+ * Furthermore, it tries to follow the semantics that cmd.exe, with this
+ * exception that PATHEXT environment variable isn't used. Since CreateProcess
+ * can start only .com and .exe files, only those extensions are tried. This
+ * behavior equals that of msvcrt's spawn functions.
+ *
+ * - Do not search the path if the filename already contains a path (either
+ * relative or absolute).
+ *
+ * - If there's really only a filename, check the current directory for file,
+ * then search all path directories.
+ *
+ * - If filename specified has *any* extension, search for the file with the
+ * specified extension first.
+ *
+ * - If the literal filename is not found in a directory, try *appending*
+ * (not replacing) .com first and then .exe.
+ *
+ * - The path variable may contain relative paths; relative paths are relative
+ * to the cwd.
+ *
+ * - Directories in path may or may not end with a trailing backslash.
+ *
+ * - CMD does not trim leading/trailing whitespace from path/pathex entries
+ * nor from the environment variables as a whole.
+ *
+ * - When cmd.exe cannot read a directory, it will just skip it and go on
+ * searching. However, unlike posix-y systems, it will happily try to run a
+ * file that is not readable/executable; if the spawn fails it will not
+ * continue searching.
+ *
+ * TODO: correctly interpret UNC paths
+ */
+static WCHAR* search_path(const WCHAR *file,
+ WCHAR *cwd,
+ const WCHAR *path) {
+ int file_has_dir;
+ WCHAR* result = NULL;
+ WCHAR *file_name_start;
+ WCHAR *dot;
+ const WCHAR *dir_start, *dir_end, *dir_path;
+ size_t dir_len;
+ int name_has_ext;
+
+ size_t file_len = wcslen(file);
+ size_t cwd_len = wcslen(cwd);
+
+ /* If the caller supplies an empty filename,
+ * we're not gonna return c:\windows\.exe -- GFY!
+ */
+ if (file_len == 0
+ || (file_len == 1 && file[0] == L'.')) {
+ return NULL;
+ }
+
+ /* Find the start of the filename so we can split the directory from the */
+ /* name. */
+ for (file_name_start = (WCHAR*)file + file_len;
+ file_name_start > file
+ && file_name_start[-1] != L'\\'
+ && file_name_start[-1] != L'/'
+ && file_name_start[-1] != L':';
+ file_name_start--);
+
+ file_has_dir = file_name_start != file;
+
+ /* Check if the filename includes an extension */
+ dot = wcschr(file_name_start, L'.');
+ name_has_ext = (dot != NULL && dot[1] != L'\0');
+
+ if (file_has_dir) {
+ /* The file has a path inside, don't use path */
+ result = path_search_walk_ext(
+ file, file_name_start - file,
+ file_name_start, file_len - (file_name_start - file),
+ cwd, cwd_len,
+ name_has_ext);
+
+ } else {
+ dir_end = path;
+
+ /* The file is really only a name; look in cwd first, then scan path */
+ result = path_search_walk_ext(L"", 0,
+ file, file_len,
+ cwd, cwd_len,
+ name_has_ext);
+
+ while (result == NULL) {
+ if (*dir_end == L'\0') {
+ break;
+ }
+
+ /* Skip the separator that dir_end now points to */
+ if (dir_end != path) {
+ dir_end++;
+ }
+
+ /* Next slice starts just after where the previous one ended */
+ dir_start = dir_end;
+
+ /* Slice until the next ; or \0 is found */
+ dir_end = wcschr(dir_start, L';');
+ if (dir_end == NULL) {
+ dir_end = wcschr(dir_start, L'\0');
+ }
+
+ /* If the slice is zero-length, don't bother */
+ if (dir_end - dir_start == 0) {
+ continue;
+ }
+
+ dir_path = dir_start;
+ dir_len = dir_end - dir_start;
+
+ /* Adjust if the path is quoted. */
+ if (dir_path[0] == '"' || dir_path[0] == '\'') {
+ ++dir_path;
+ --dir_len;
+ }
+
+ if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') {
+ --dir_len;
+ }
+
+ result = path_search_walk_ext(dir_path, dir_len,
+ file, file_len,
+ cwd, cwd_len,
+ name_has_ext);
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ * Quotes command line arguments
+ * Returns a pointer to the end (next char to be written) of the buffer
+ */
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) {
+ size_t len = wcslen(source);
+ size_t i;
+ int quote_hit;
+ WCHAR* start;
+
+ /*
+ * Check if the string must be quoted;
+ * if unnecessary, don't do it, it may only confuse older programs.
+ */
+ if (len == 0) {
+ return target;
+ }
+
+ if (NULL == wcspbrk(source, L" \t\"")) {
+ /* No quotation needed */
+ wcsncpy(target, source, len);
+ target += len;
+ return target;
+ }
+
+ if (NULL == wcspbrk(source, L"\"\\")) {
+ /*
+ * No embedded double quotes or backlashes, so I can just wrap
+ * quote marks around the whole thing.
+ */
+ *(target++) = L'"';
+ wcsncpy(target, source, len);
+ target += len;
+ *(target++) = L'"';
+ return target;
+ }
+
+ /*
+ * Expected input/output:
+ * input : hello"world
+ * output: "hello\"world"
+ * input : hello""world
+ * output: "hello\"\"world"
+ * input : hello\world
+ * output: hello\world
+ * input : hello\\world
+ * output: hello\\world
+ * input : hello\"world
+ * output: "hello\\\"world"
+ * input : hello\\"world
+ * output: "hello\\\\\"world"
+ * input : hello world\
+ * output: "hello world\"
+ */
+
+ *(target++) = L'"';
+ start = target;
+ quote_hit = 1;
+
+ for (i = len; i > 0; --i) {
+ *(target++) = source[i - 1];
+
+ if (quote_hit && source[i - 1] == L'\\') {
+ *(target++) = L'\\';
+ } else if(source[i - 1] == L'"') {
+ quote_hit = 1;
+ *(target++) = L'\\';
+ } else {
+ quote_hit = 0;
+ }
+ }
+ target[0] = L'\0';
+ wcsrev(start);
+ *(target++) = L'"';
+ return target;
+}
+
+
+int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
+ char** arg;
+ WCHAR* dst = NULL;
+ WCHAR* temp_buffer = NULL;
+ size_t dst_len = 0;
+ size_t temp_buffer_len = 0;
+ WCHAR* pos;
+ int arg_count = 0;
+ int err = 0;
+
+ /* Count the required size. */
+ for (arg = args; *arg; arg++) {
+ DWORD arg_len;
+
+ arg_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *arg,
+ -1,
+ NULL,
+ 0);
+ if (arg_len == 0) {
+ return GetLastError();
+ }
+
+ dst_len += arg_len;
+
+ if (arg_len > temp_buffer_len)
+ temp_buffer_len = arg_len;
+
+ arg_count++;
+ }
+
+ /* Adjust for potential quotes. Also assume the worst-case scenario */
+ /* that every character needs escaping, so we need twice as much space. */
+ dst_len = dst_len * 2 + arg_count * 2;
+
+ /* Allocate buffer for the final command line. */
+ dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR));
+ if (dst == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto error;
+ }
+
+ /* Allocate temporary working buffer. */
+ temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR));
+ if (temp_buffer == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto error;
+ }
+
+ pos = dst;
+ for (arg = args; *arg; arg++) {
+ DWORD arg_len;
+
+ /* Convert argument to wide char. */
+ arg_len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *arg,
+ -1,
+ temp_buffer,
+ (int) (dst + dst_len - pos));
+ if (arg_len == 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ if (verbatim_arguments) {
+ /* Copy verbatim. */
+ wcscpy(pos, temp_buffer);
+ pos += arg_len - 1;
+ } else {
+ /* Quote/escape, if needed. */
+ pos = quote_cmd_arg(temp_buffer, pos);
+ }
+
+ *pos++ = *(arg + 1) ? L' ' : L'\0';
+ }
+
+ free(temp_buffer);
+
+ *dst_ptr = dst;
+ return 0;
+
+error:
+ free(dst);
+ free(temp_buffer);
+ return err;
+}
+
+
+/*
+ * If we learn that people are passing in huge environment blocks
+ * then we should probably qsort() the array and then bsearch()
+ * to see if it contains this variable. But there are ownership
+ * issues associated with that solution; this is the caller's
+ * char**, and modifying it is rude.
+ */
+static void check_required_vars_contains_var(env_var_t* required, int count,
+ const char* var) {
+ int i;
+ for (i = 0; i < count; ++i) {
+ if (_strnicmp(required[i].narrow, var, required[i].len) == 0) {
+ required[i].supplied = 1;
+ return;
+ }
+ }
+}
+
+
+/*
+ * The way windows takes environment variables is different than what C does;
+ * Windows wants a contiguous block of null-terminated strings, terminated
+ * with an additional null.
+ *
+ * Windows has a few "essential" environment variables. winsock will fail
+ * to initialize if SYSTEMROOT is not defined; some APIs make reference to
+ * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that
+ * these get defined if the input environment block does not contain any
+ * values for them.
+ */
+int make_program_env(char* env_block[], WCHAR** dst_ptr) {
+ WCHAR* dst;
+ WCHAR* ptr;
+ char** env;
+ size_t env_len = 1; /* room for closing null */
+ int len;
+ int i;
+ DWORD var_size;
+
+ env_var_t required_vars[] = {
+ E_V("SYSTEMROOT"),
+ E_V("SYSTEMDRIVE"),
+ E_V("TEMP"),
+ };
+
+ for (env = env_block; *env; env++) {
+ int len;
+ check_required_vars_contains_var(required_vars,
+ ARRAY_SIZE(required_vars),
+ *env);
+
+ len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *env,
+ -1,
+ NULL,
+ 0);
+ if (len <= 0) {
+ return GetLastError();
+ }
+
+ env_len += len;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
+ if (!required_vars[i].supplied) {
+ env_len += required_vars[i].len;
+ var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0);
+ if (var_size == 0) {
+ return GetLastError();
+ }
+ required_vars[i].value_len = var_size;
+ env_len += var_size;
+ }
+ }
+
+ dst = malloc(env_len * sizeof(WCHAR));
+ if (!dst) {
+ return ERROR_OUTOFMEMORY;
+ }
+
+ ptr = dst;
+
+ for (env = env_block; *env; env++, ptr += len) {
+ len = MultiByteToWideChar(CP_UTF8,
+ 0,
+ *env,
+ -1,
+ ptr,
+ (int) (env_len - (ptr - dst)));
+ if (len <= 0) {
+ free(dst);
+ return GetLastError();
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(required_vars); ++i) {
+ if (!required_vars[i].supplied) {
+ wcscpy(ptr, required_vars[i].wide);
+ ptr += required_vars[i].len - 1;
+ *ptr++ = L'=';
+ var_size = GetEnvironmentVariableW(required_vars[i].wide,
+ ptr,
+ required_vars[i].value_len);
+ if (var_size == 0) {
+ uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
+ }
+ ptr += required_vars[i].value_len;
+ }
+ }
+
+ /* Terminate with an extra NULL. */
+ *ptr = L'\0';
+
+ *dst_ptr = dst;
+ return 0;
+}
+
+
+/*
+ * Called on Windows thread-pool thread to indicate that
+ * a child process has exited.
+ */
+static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
+ uv_process_t* process = (uv_process_t*) data;
+ uv_loop_t* loop = process->loop;
+
+ assert(didTimeout == FALSE);
+ assert(process);
+ assert(!process->exit_cb_pending);
+
+ process->exit_cb_pending = 1;
+
+ /* Post completed */
+ POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
+}
+
+
+/* Called on main thread after a child process has exited. */
+void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
+ int64_t exit_code;
+ DWORD status;
+
+ assert(handle->exit_cb_pending);
+ handle->exit_cb_pending = 0;
+
+ /* If we're closing, don't call the exit callback. Just schedule a close */
+ /* callback now. */
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ return;
+ }
+
+ /* Unregister from process notification. */
+ if (handle->wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(handle->wait_handle);
+ handle->wait_handle = INVALID_HANDLE_VALUE;
+ }
+
+ /* Set the handle to inactive: no callbacks will be made after the exit */
+ /* callback.*/
+ uv__handle_stop(handle);
+
+ if (GetExitCodeProcess(handle->process_handle, &status)) {
+ exit_code = status;
+ } else {
+ /* Unable to to obtain the exit code. This should never happen. */
+ exit_code = uv_translate_sys_error(GetLastError());
+ }
+
+ /* Fire the exit callback. */
+ if (handle->exit_cb) {
+ handle->exit_cb(handle, exit_code, handle->exit_signal);
+ }
+}
+
+
+void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
+ uv__handle_closing(handle);
+
+ if (handle->wait_handle != INVALID_HANDLE_VALUE) {
+ /* This blocks until either the wait was cancelled, or the callback has */
+ /* completed. */
+ BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
+ if (!r) {
+ /* This should never happen, and if it happens, we can't recover... */
+ uv_fatal_error(GetLastError(), "UnregisterWaitEx");
+ }
+
+ handle->wait_handle = INVALID_HANDLE_VALUE;
+ }
+
+ if (!handle->exit_cb_pending) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+}
+
+
+void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
+ assert(!handle->exit_cb_pending);
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ /* Clean-up the process handle. */
+ CloseHandle(handle->process_handle);
+
+ uv__handle_close(handle);
+}
+
+
+int uv_spawn(uv_loop_t* loop,
+ uv_process_t* process,
+ const uv_process_options_t* options) {
+ int i;
+ int err = 0;
+ WCHAR* path = NULL;
+ BOOL result;
+ WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
+ *env = NULL, *cwd = NULL;
+ STARTUPINFOW startup;
+ PROCESS_INFORMATION info;
+ DWORD process_flags;
+
+ if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
+ return UV_ENOTSUP;
+ }
+
+ if (options->file == NULL ||
+ options->args == NULL) {
+ return UV_EINVAL;
+ }
+
+ assert(options->file != NULL);
+ assert(!(options->flags & ~(UV_PROCESS_DETACHED |
+ UV_PROCESS_SETGID |
+ UV_PROCESS_SETUID |
+ UV_PROCESS_WINDOWS_HIDE |
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+
+ uv_process_init(loop, process);
+ process->exit_cb = options->exit_cb;
+
+ err = uv_utf8_to_utf16_alloc(options->file, &application);
+ if (err)
+ goto done;
+
+ err = make_program_args(
+ options->args,
+ options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
+ &arguments);
+ if (err)
+ goto done;
+
+ if (options->env) {
+ err = make_program_env(options->env, &env);
+ if (err)
+ goto done;
+ }
+
+ if (options->cwd) {
+ /* Explicit cwd */
+ err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
+ if (err)
+ goto done;
+
+ } else {
+ /* Inherit cwd */
+ DWORD cwd_len, r;
+
+ cwd_len = GetCurrentDirectoryW(0, NULL);
+ if (!cwd_len) {
+ err = GetLastError();
+ goto done;
+ }
+
+ cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
+ if (cwd == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = GetCurrentDirectoryW(cwd_len, cwd);
+ if (r == 0 || r >= cwd_len) {
+ err = GetLastError();
+ goto done;
+ }
+ }
+
+ /* Get PATH environment variable. */
+ {
+ DWORD path_len, r;
+
+ path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
+ if (path_len == 0) {
+ err = GetLastError();
+ goto done;
+ }
+
+ path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
+ if (path == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto done;
+ }
+
+ r = GetEnvironmentVariableW(L"PATH", path, path_len);
+ if (r == 0 || r >= path_len) {
+ err = GetLastError();
+ goto done;
+ }
+ }
+
+ err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
+ if (err)
+ goto done;
+
+ application_path = search_path(application,
+ cwd,
+ path);
+ if (application_path == NULL) {
+ /* Not found. */
+ err = ERROR_FILE_NOT_FOUND;
+ goto done;
+ }
+
+ startup.cb = sizeof(startup);
+ startup.lpReserved = NULL;
+ startup.lpDesktop = NULL;
+ startup.lpTitle = NULL;
+ startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+
+ startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
+ startup.lpReserved2 = (BYTE*) process->child_stdio_buffer;
+
+ startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
+ startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
+ startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
+
+ if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
+ /* Use SW_HIDE to avoid any potential process window. */
+ startup.wShowWindow = SW_HIDE;
+ } else {
+ startup.wShowWindow = SW_SHOWDEFAULT;
+ }
+
+ process_flags = CREATE_UNICODE_ENVIRONMENT;
+
+ if (options->flags & UV_PROCESS_DETACHED) {
+ /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That
+ * means that libuv might not let you create a fully deamonized process
+ * when run under job control. However the type of job control that libuv
+ * itself creates doesn't trickle down to subprocesses so they can still
+ * daemonize.
+ *
+ * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the
+ * CreateProcess call fail if we're under job control that doesn't allow
+ * breakaway.
+ */
+ process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
+ }
+
+ if (!CreateProcessW(application_path,
+ arguments,
+ NULL,
+ NULL,
+ 1,
+ process_flags,
+ env,
+ cwd,
+ &startup,
+ &info)) {
+ /* CreateProcessW failed. */
+ err = GetLastError();
+ goto done;
+ }
+
+ /* Spawn succeeded */
+ /* Beyond this point, failure is reported asynchronously. */
+
+ process->process_handle = info.hProcess;
+ process->pid = info.dwProcessId;
+
+ /* If the process isn't spawned as detached, assign to the global job */
+ /* object so windows will kill it when the parent process dies. */
+ if (!(options->flags & UV_PROCESS_DETACHED)) {
+ uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
+
+ if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
+ /* AssignProcessToJobObject might fail if this process is under job
+ * control and the job doesn't have the
+ * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
+ * that doesn't support nested jobs.
+ *
+ * When that happens we just swallow the error and continue without
+ * establishing a kill-child-on-parent-exit relationship, otherwise
+ * there would be no way for libuv applications run under job control
+ * to spawn processes at all.
+ */
+ DWORD err = GetLastError();
+ if (err != ERROR_ACCESS_DENIED)
+ uv_fatal_error(err, "AssignProcessToJobObject");
+ }
+ }
+
+ /* Set IPC pid to all IPC pipes. */
+ for (i = 0; i < options->stdio_count; i++) {
+ const uv_stdio_container_t* fdopt = &options->stdio[i];
+ if (fdopt->flags & UV_CREATE_PIPE &&
+ fdopt->data.stream->type == UV_NAMED_PIPE &&
+ ((uv_pipe_t*) fdopt->data.stream)->ipc) {
+ ((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId;
+ }
+ }
+
+ /* Setup notifications for when the child process exits. */
+ result = RegisterWaitForSingleObject(&process->wait_handle,
+ process->process_handle, exit_wait_callback, (void*)process, INFINITE,
+ WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+ if (!result) {
+ uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
+ }
+
+ CloseHandle(info.hThread);
+
+ assert(!err);
+
+ /* Make the handle active. It will remain active until the exit callback */
+ /* iis made or the handle is closed, whichever happens first. */
+ uv__handle_start(process);
+
+ /* Cleanup, whether we succeeded or failed. */
+ done:
+ free(application);
+ free(application_path);
+ free(arguments);
+ free(cwd);
+ free(env);
+ free(path);
+
+ if (process->child_stdio_buffer != NULL) {
+ /* Clean up child stdio handles. */
+ uv__stdio_destroy(process->child_stdio_buffer);
+ process->child_stdio_buffer = NULL;
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+static int uv__kill(HANDLE process_handle, int signum) {
+ switch (signum) {
+ case SIGTERM:
+ case SIGKILL:
+ case SIGINT: {
+ /* Unconditionally terminate the process. On Windows, killed processes */
+ /* normally return 1. */
+ DWORD status;
+ int err;
+
+ if (TerminateProcess(process_handle, 1))
+ return 0;
+
+ /* If the process already exited before TerminateProcess was called, */
+ /* TerminateProcess will fail with ERROR_ACESS_DENIED. */
+ err = GetLastError();
+ if (err == ERROR_ACCESS_DENIED &&
+ GetExitCodeProcess(process_handle, &status) &&
+ status != STILL_ACTIVE) {
+ return UV_ESRCH;
+ }
+
+ return uv_translate_sys_error(err);
+ }
+
+ case 0: {
+ /* Health check: is the process still alive? */
+ DWORD status;
+
+ if (!GetExitCodeProcess(process_handle, &status))
+ return uv_translate_sys_error(GetLastError());
+
+ if (status != STILL_ACTIVE)
+ return UV_ESRCH;
+
+ return 0;
+ }
+
+ default:
+ /* Unsupported signal. */
+ return UV_ENOSYS;
+ }
+}
+
+
+int uv_process_kill(uv_process_t* process, int signum) {
+ int err;
+
+ if (process->process_handle == INVALID_HANDLE_VALUE) {
+ return UV_EINVAL;
+ }
+
+ err = uv__kill(process->process_handle, signum);
+ if (err) {
+ return err; /* err is already translated. */
+ }
+
+ process->exit_signal = signum;
+
+ return 0;
+}
+
+
+int uv_kill(int pid, int signum) {
+ int err;
+ HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
+ PROCESS_QUERY_INFORMATION, FALSE, pid);
+
+ if (process_handle == NULL) {
+ err = GetLastError();
+ if (err == ERROR_INVALID_PARAMETER) {
+ return UV_ESRCH;
+ } else {
+ return uv_translate_sys_error(err);
+ }
+ }
+
+ err = uv__kill(process_handle, signum);
+ CloseHandle(process_handle);
+
+ return err; /* err is already translated. */
+}
diff --git a/third-party/libuv/src/win/req-inl.h b/third-party/libuv/src/win/req-inl.h
new file mode 100644
index 0000000000..353fe90b6d
--- /dev/null
+++ b/third-party/libuv/src/win/req-inl.h
@@ -0,0 +1,224 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_REQ_INL_H_
+#define UV_WIN_REQ_INL_H_
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define SET_REQ_STATUS(req, status) \
+ (req)->overlapped.Internal = (ULONG_PTR) (status)
+
+#define SET_REQ_ERROR(req, error) \
+ SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
+
+#define SET_REQ_SUCCESS(req) \
+ SET_REQ_STATUS((req), STATUS_SUCCESS)
+
+#define GET_REQ_STATUS(req) \
+ ((NTSTATUS) (req)->overlapped.Internal)
+
+#define REQ_SUCCESS(req) \
+ (NT_SUCCESS(GET_REQ_STATUS((req))))
+
+#define GET_REQ_ERROR(req) \
+ (pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
+
+#define GET_REQ_SOCK_ERROR(req) \
+ (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
+
+
+#define REGISTER_HANDLE_REQ(loop, handle, req) \
+ do { \
+ INCREASE_ACTIVE_COUNT((loop), (handle)); \
+ uv__req_register((loop), (req)); \
+ } while (0)
+
+#define UNREGISTER_HANDLE_REQ(loop, handle, req) \
+ do { \
+ DECREASE_ACTIVE_COUNT((loop), (handle)); \
+ uv__req_unregister((loop), (req)); \
+ } while (0)
+
+
+#define UV_SUCCEEDED_WITHOUT_IOCP(result) \
+ ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP))
+
+#define UV_SUCCEEDED_WITH_IOCP(result) \
+ ((result) || (GetLastError() == ERROR_IO_PENDING))
+
+
+#define POST_COMPLETION_FOR_REQ(loop, req) \
+ if (!PostQueuedCompletionStatus((loop)->iocp, \
+ 0, \
+ 0, \
+ &((req)->overlapped))) { \
+ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
+ }
+
+
+INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
+ req->type = UV_UNKNOWN_REQ;
+ SET_REQ_SUCCESS(req);
+}
+
+
+INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
+ return CONTAINING_RECORD(overlapped, uv_req_t, overlapped);
+}
+
+
+INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
+ req->next_req = NULL;
+ if (loop->pending_reqs_tail) {
+ req->next_req = loop->pending_reqs_tail->next_req;
+ loop->pending_reqs_tail->next_req = req;
+ loop->pending_reqs_tail = req;
+ } else {
+ req->next_req = req;
+ loop->pending_reqs_tail = req;
+ }
+}
+
+
+#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
+ do { \
+ switch (((uv_handle_t*) (req)->handle_at)->type) { \
+ case UV_TCP: \
+ uv_process_tcp_##method##_req(loop, \
+ (uv_tcp_t*) ((req)->handle_at), \
+ req); \
+ break; \
+ \
+ case UV_NAMED_PIPE: \
+ uv_process_pipe_##method##_req(loop, \
+ (uv_pipe_t*) ((req)->handle_at), \
+ req); \
+ break; \
+ \
+ case UV_TTY: \
+ uv_process_tty_##method##_req(loop, \
+ (uv_tty_t*) ((req)->handle_at), \
+ req); \
+ break; \
+ \
+ default: \
+ assert(0); \
+ } \
+ } while (0)
+
+
+INLINE static void uv_process_reqs(uv_loop_t* loop) {
+ uv_req_t* req;
+ uv_req_t* first;
+ uv_req_t* next;
+
+ if (loop->pending_reqs_tail == NULL) {
+ return;
+ }
+
+ first = loop->pending_reqs_tail->next_req;
+ next = first;
+ loop->pending_reqs_tail = NULL;
+
+ while (next != NULL) {
+ req = next;
+ next = req->next_req != first ? req->next_req : NULL;
+
+ switch (req->type) {
+ case UV_READ:
+ DELEGATE_STREAM_REQ(loop, req, read, data);
+ break;
+
+ case UV_WRITE:
+ DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
+ break;
+
+ case UV_ACCEPT:
+ DELEGATE_STREAM_REQ(loop, req, accept, data);
+ break;
+
+ case UV_CONNECT:
+ DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
+ break;
+
+ case UV_SHUTDOWN:
+ /* Tcp shutdown requests don't come here. */
+ assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
+ uv_process_pipe_shutdown_req(
+ loop,
+ (uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
+ (uv_shutdown_t*) req);
+ break;
+
+ case UV_UDP_RECV:
+ uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
+ break;
+
+ case UV_UDP_SEND:
+ uv_process_udp_send_req(loop,
+ ((uv_udp_send_t*) req)->handle,
+ (uv_udp_send_t*) req);
+ break;
+
+ case UV_WAKEUP:
+ uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
+ break;
+
+ case UV_SIGNAL_REQ:
+ uv_process_signal_req(loop, (uv_signal_t*) req->data, req);
+ break;
+
+ case UV_POLL_REQ:
+ uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
+ break;
+
+ case UV_GETADDRINFO:
+ uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req);
+ break;
+
+ case UV_PROCESS_EXIT:
+ uv_process_proc_exit(loop, (uv_process_t*) req->data);
+ break;
+
+ case UV_FS:
+ uv_process_fs_req(loop, (uv_fs_t*) req);
+ break;
+
+ case UV_WORK:
+ uv_process_work_req(loop, (uv_work_t*) req);
+ break;
+
+ case UV_FS_EVENT_REQ:
+ uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+}
+
+#endif /* UV_WIN_REQ_INL_H_ */
diff --git a/third-party/libuv/src/win/req.c b/third-party/libuv/src/win/req.c
new file mode 100644
index 0000000000..111cc5e289
--- /dev/null
+++ b/third-party/libuv/src/win/req.c
@@ -0,0 +1,25 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
diff --git a/third-party/libuv/src/win/signal.c b/third-party/libuv/src/win/signal.c
new file mode 100644
index 0000000000..9dc5fccc29
--- /dev/null
+++ b/third-party/libuv/src/win/signal.c
@@ -0,0 +1,352 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * 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.
+ */
+
+#include <assert.h>
+#include <signal.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+RB_HEAD(uv_signal_tree_s, uv_signal_s);
+
+static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree);
+static ssize_t volatile uv__signal_control_handler_refs = 0;
+static CRITICAL_SECTION uv__signal_lock;
+
+
+void uv_signals_init() {
+ InitializeCriticalSection(&uv__signal_lock);
+}
+
+
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+ /* Compare signums first so all watchers with the same signnum end up */
+ /* adjacent. */
+ if (w1->signum < w2->signum) return -1;
+ if (w1->signum > w2->signum) return 1;
+
+ /* Sort by loop pointer, so we can easily look up the first item after */
+ /* { .signum = x, .loop = NULL } */
+ if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
+ if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
+
+ if ((uintptr_t) w1 < (uintptr_t) w2) return -1;
+ if ((uintptr_t) w1 > (uintptr_t) w2) return 1;
+
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare);
+
+
+/*
+ * Dispatches signal {signum} to all active uv_signal_t watchers in all loops.
+ * Returns 1 if the signal was dispatched to any watcher, or 0 if there were
+ * no active signal watchers observing this signal.
+ */
+int uv__signal_dispatch(int signum) {
+ uv_signal_t lookup;
+ uv_signal_t* handle;
+ int dispatched = 0;
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ lookup.signum = signum;
+ lookup.loop = NULL;
+
+ for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup);
+ handle != NULL && handle->signum == signum;
+ handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) {
+ unsigned long previous = InterlockedExchange(&handle->pending_signum, signum);
+
+ if (!previous) {
+ POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
+ }
+
+ dispatched = 1;
+ }
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ return dispatched;
+}
+
+
+static BOOL WINAPI uv__signal_control_handler(DWORD type) {
+ switch (type) {
+ case CTRL_C_EVENT:
+ return uv__signal_dispatch(SIGINT);
+
+ case CTRL_BREAK_EVENT:
+ return uv__signal_dispatch(SIGBREAK);
+
+ case CTRL_CLOSE_EVENT:
+ if (uv__signal_dispatch(SIGHUP)) {
+ /* Windows will terminate the process after the control handler */
+ /* returns. After that it will just terminate our process. Therefore */
+ /* block the signal handler so the main loop has some time to pick */
+ /* up the signal and do something for a few seconds. */
+ Sleep(INFINITE);
+ return TRUE;
+ }
+ return FALSE;
+
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ /* These signals are only sent to services. Services have their own */
+ /* notification mechanism, so there's no point in handling these. */
+
+ default:
+ /* We don't handle these. */
+ return FALSE;
+ }
+}
+
+
+static int uv__signal_register_control_handler() {
+ /* When this function is called, the uv__signal_lock must be held. */
+
+ /* If the console control handler has already been hooked, just add a */
+ /* reference. */
+ if (uv__signal_control_handler_refs > 0)
+ return 0;
+
+ if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
+ return GetLastError();
+
+ uv__signal_control_handler_refs++;
+
+ return 0;
+}
+
+
+static void uv__signal_unregister_control_handler() {
+ /* When this function is called, the uv__signal_lock must be held. */
+ BOOL r;
+
+ /* Don't unregister if the number of console control handlers exceeds one. */
+ /* Just remove a reference in that case. */
+ if (uv__signal_control_handler_refs > 1) {
+ uv__signal_control_handler_refs--;
+ return;
+ }
+
+ assert(uv__signal_control_handler_refs == 1);
+
+ r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE);
+ /* This should never fail; if it does it is probably a bug in libuv. */
+ assert(r);
+
+ uv__signal_control_handler_refs--;
+}
+
+
+static int uv__signal_register(int signum) {
+ switch (signum) {
+ case SIGINT:
+ case SIGBREAK:
+ case SIGHUP:
+ return uv__signal_register_control_handler();
+
+ case SIGWINCH:
+ /* SIGWINCH is generated in tty.c. No need to register anything. */
+ return 0;
+
+ case SIGILL:
+ case SIGABRT_COMPAT:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGABRT:
+ /* Signal is never raised. */
+ return 0;
+
+ default:
+ /* Invalid signal. */
+ return ERROR_INVALID_PARAMETER;
+ }
+}
+
+
+static void uv__signal_unregister(int signum) {
+ switch (signum) {
+ case SIGINT:
+ case SIGBREAK:
+ case SIGHUP:
+ uv__signal_unregister_control_handler();
+ return;
+
+ case SIGWINCH:
+ /* SIGWINCH is generated in tty.c. No need to unregister anything. */
+ return;
+
+ case SIGILL:
+ case SIGABRT_COMPAT:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGABRT:
+ /* Nothing is registered for this signal. */
+ return;
+
+ default:
+ /* Libuv bug. */
+ assert(0 && "Invalid signum");
+ return;
+ }
+}
+
+
+int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
+ uv_req_t* req;
+
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
+ handle->pending_signum = 0;
+ handle->signum = 0;
+ handle->signal_cb = NULL;
+
+ req = &handle->signal_req;
+ uv_req_init(loop, req);
+ req->type = UV_SIGNAL_REQ;
+ req->data = handle;
+
+ return 0;
+}
+
+
+int uv_signal_stop(uv_signal_t* handle) {
+ uv_signal_t* removed_handle;
+
+ /* If the watcher wasn't started, this is a no-op. */
+ if (handle->signum == 0)
+ return 0;
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ uv__signal_unregister(handle->signum);
+
+ removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
+ assert(removed_handle == handle);
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ handle->signum = 0;
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+ int err;
+
+ /* If the user supplies signum == 0, then return an error already. If the */
+ /* signum is otherwise invalid then uv__signal_register will find out */
+ /* eventually. */
+ if (signum == 0) {
+ return UV_EINVAL;
+ }
+
+ /* Short circuit: if the signal watcher is already watching {signum} don't */
+ /* go through the process of deregistering and registering the handler. */
+ /* Additionally, this avoids pending signals getting lost in the (small) */
+ /* time frame that handle->signum == 0. */
+ if (signum == handle->signum) {
+ handle->signal_cb = signal_cb;
+ return 0;
+ }
+
+ /* If the signal handler was already active, stop it first. */
+ if (handle->signum != 0) {
+ int r = uv_signal_stop(handle);
+ /* uv_signal_stop is infallible. */
+ assert(r == 0);
+ }
+
+ EnterCriticalSection(&uv__signal_lock);
+
+ err = uv__signal_register(signum);
+ if (err) {
+ /* Uh-oh, didn't work. */
+ LeaveCriticalSection(&uv__signal_lock);
+ return uv_translate_sys_error(err);
+ }
+
+ handle->signum = signum;
+ RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
+
+ LeaveCriticalSection(&uv__signal_lock);
+
+ handle->signal_cb = signal_cb;
+ uv__handle_start(handle);
+
+ return 0;
+}
+
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+ uv_req_t* req) {
+ unsigned long dispatched_signum;
+
+ assert(handle->type == UV_SIGNAL);
+ assert(req->type == UV_SIGNAL_REQ);
+
+ dispatched_signum = InterlockedExchange(&handle->pending_signum, 0);
+ assert(dispatched_signum != 0);
+
+ /* Check if the pending signal equals the signum that we are watching for. */
+ /* These can get out of sync when the handler is stopped and restarted */
+ /* while the signal_req is pending. */
+ if (dispatched_signum == handle->signum)
+ handle->signal_cb(handle, dispatched_signum);
+
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ /* When it is closing, it must be stopped at this point. */
+ assert(handle->signum == 0);
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
+ uv_signal_stop(handle);
+ uv__handle_closing(handle);
+
+ if (handle->pending_signum == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) {
+ assert(handle->flags & UV__HANDLE_CLOSING);
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ assert(handle->signum == 0);
+ assert(handle->pending_signum == 0);
+
+ handle->flags |= UV_HANDLE_CLOSED;
+
+ uv__handle_close(handle);
+}
diff --git a/third-party/libuv/src/win/stream-inl.h b/third-party/libuv/src/win/stream-inl.h
new file mode 100644
index 0000000000..e4bf086368
--- /dev/null
+++ b/third-party/libuv/src/win/stream-inl.h
@@ -0,0 +1,67 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_STREAM_INL_H_
+#define UV_WIN_STREAM_INL_H_
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+INLINE static void uv_stream_init(uv_loop_t* loop,
+ uv_stream_t* handle,
+ uv_handle_type type) {
+ uv__handle_init(loop, (uv_handle_t*) handle, type);
+ handle->write_queue_size = 0;
+ handle->activecnt = 0;
+}
+
+
+INLINE static void uv_connection_init(uv_stream_t* handle) {
+ handle->flags |= UV_HANDLE_CONNECTION;
+ handle->write_reqs_pending = 0;
+
+ uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
+ handle->read_req.event_handle = NULL;
+ handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+ handle->read_req.type = UV_READ;
+ handle->read_req.data = handle;
+
+ handle->shutdown_req = NULL;
+}
+
+
+INLINE static size_t uv_count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
+ unsigned int i;
+ size_t bytes;
+
+ bytes = 0;
+ for (i = 0; i < nbufs; i++)
+ bytes += (size_t) bufs[i].len;
+
+ return bytes;
+}
+
+#endif /* UV_WIN_STREAM_INL_H_ */
diff --git a/third-party/libuv/src/win/stream.c b/third-party/libuv/src/win/stream.c
new file mode 100644
index 0000000000..2eaa74e766
--- /dev/null
+++ b/third-party/libuv/src/win/stream.c
@@ -0,0 +1,253 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
+ int err;
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (stream->type) {
+ case UV_TCP:
+ err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
+ break;
+ case UV_NAMED_PIPE:
+ err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_accept(uv_stream_t* server, uv_stream_t* client) {
+ int err;
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (server->type) {
+ case UV_TCP:
+ err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client);
+ break;
+ case UV_NAMED_PIPE:
+ err = uv_pipe_accept((uv_pipe_t*)server, client);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
+ int err;
+
+ if (handle->flags & UV_HANDLE_READING) {
+ return UV_EALREADY;
+ }
+
+ if (!(handle->flags & UV_HANDLE_READABLE)) {
+ return UV_ENOTCONN;
+ }
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (handle->type) {
+ case UV_TCP:
+ err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
+ break;
+ case UV_NAMED_PIPE:
+ err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
+ break;
+ case UV_TTY:
+ err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
+ uv_read2_cb read_cb) {
+ int err;
+
+ if (handle->flags & UV_HANDLE_READING) {
+ return UV_EALREADY;
+ }
+
+ if (!(handle->flags & UV_HANDLE_READABLE)) {
+ return UV_ENOTCONN;
+ }
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (handle->type) {
+ case UV_NAMED_PIPE:
+ err = uv_pipe_read2_start((uv_pipe_t*)handle, alloc_cb, read_cb);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_read_stop(uv_stream_t* handle) {
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_READING))
+ return 0;
+
+ err = 0;
+ if (handle->type == UV_TTY) {
+ err = uv_tty_read_stop((uv_tty_t*) handle);
+ } else {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(handle->loop, handle);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_write(uv_write_t* req,
+ uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ return UV_EPIPE;
+ }
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (handle->type) {
+ case UV_TCP:
+ err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
+ break;
+ case UV_NAMED_PIPE:
+ err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb);
+ break;
+ case UV_TTY:
+ err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_write2(uv_write_t* req,
+ uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle,
+ uv_write_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ return UV_EPIPE;
+ }
+
+ err = ERROR_INVALID_PARAMETER;
+ switch (handle->type) {
+ case UV_NAMED_PIPE:
+ err = uv_pipe_write2(loop,
+ req,
+ (uv_pipe_t*) handle,
+ bufs,
+ nbufs,
+ send_handle,
+ cb);
+ break;
+ default:
+ assert(0);
+ }
+
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_try_write(uv_stream_t* stream,
+ const uv_buf_t bufs[],
+ unsigned int nbufs) {
+ /* NOTE: Won't work with overlapped writes */
+ return UV_ENOSYS;
+}
+
+
+int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
+ uv_loop_t* loop = handle->loop;
+
+ if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+ return UV_EPIPE;
+ }
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_SHUTDOWN;
+ req->handle = handle;
+ req->cb = cb;
+
+ handle->flags &= ~UV_HANDLE_WRITABLE;
+ handle->shutdown_req = req;
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+
+ return 0;
+}
+
+
+int uv_is_readable(const uv_stream_t* handle) {
+ return !!(handle->flags & UV_HANDLE_READABLE);
+}
+
+
+int uv_is_writable(const uv_stream_t* handle) {
+ return !!(handle->flags & UV_HANDLE_WRITABLE);
+}
+
+
+int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
+ if (blocking != 0)
+ handle->flags |= UV_HANDLE_BLOCKING_WRITES;
+ else
+ handle->flags &= ~UV_HANDLE_BLOCKING_WRITES;
+
+ return 0;
+}
diff --git a/third-party/libuv/src/win/tcp.c b/third-party/libuv/src/win/tcp.c
new file mode 100644
index 0000000000..8fa2146a06
--- /dev/null
+++ b/third-party/libuv/src/win/tcp.c
@@ -0,0 +1,1417 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+/*
+ * Threshold of active tcp streams for which to preallocate tcp read buffers.
+ * (Due to node slab allocator performing poorly under this pattern,
+ * the optimization is temporarily disabled (threshold=0). This will be
+ * revisited once node allocator is improved.)
+ */
+const unsigned int uv_active_tcp_streams_threshold = 0;
+
+/*
+ * Number of simultaneous pending AcceptEx calls.
+ */
+const unsigned int uv_simultaneous_server_accepts = 32;
+
+/* A zero-size buffer for use by uv_tcp_read */
+static char uv_zero_[] = "";
+
+static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
+ if (setsockopt(socket,
+ IPPROTO_TCP,
+ TCP_NODELAY,
+ (const char*)&enable,
+ sizeof enable) == -1) {
+ return WSAGetLastError();
+ }
+ return 0;
+}
+
+
+static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
+ if (setsockopt(socket,
+ SOL_SOCKET,
+ SO_KEEPALIVE,
+ (const char*)&enable,
+ sizeof enable) == -1) {
+ return WSAGetLastError();
+ }
+
+ if (enable && setsockopt(socket,
+ IPPROTO_TCP,
+ TCP_KEEPALIVE,
+ (const char*)&delay,
+ sizeof delay) == -1) {
+ return WSAGetLastError();
+ }
+
+ return 0;
+}
+
+
+static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
+ SOCKET socket, int family, int imported) {
+ DWORD yes = 1;
+ int non_ifs_lsp;
+ int err;
+
+ assert(handle->socket == INVALID_SOCKET);
+
+ /* Set the socket to nonblocking mode */
+ if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+
+ /* Associate it with the I/O completion port. */
+ /* Use uv_handle_t pointer as completion key. */
+ if (CreateIoCompletionPort((HANDLE)socket,
+ loop->iocp,
+ (ULONG_PTR)socket,
+ 0) == NULL) {
+ if (imported) {
+ handle->flags |= UV_HANDLE_EMULATE_IOCP;
+ } else {
+ return GetLastError();
+ }
+ }
+
+ if (family == AF_INET6) {
+ non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
+ } else {
+ non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
+ }
+
+ if (pSetFileCompletionNotificationModes &&
+ !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) {
+ if (pSetFileCompletionNotificationModes((HANDLE) socket,
+ FILE_SKIP_SET_EVENT_ON_HANDLE |
+ FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
+ handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
+ } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+ return GetLastError();
+ }
+ }
+
+ if (handle->flags & UV_HANDLE_TCP_NODELAY) {
+ err = uv__tcp_nodelay(handle, socket, 1);
+ if (err)
+ return err;
+ }
+
+ /* TODO: Use stored delay. */
+ if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) {
+ err = uv__tcp_keepalive(handle, socket, 1, 60);
+ if (err)
+ return err;
+ }
+
+ handle->socket = socket;
+
+ if (family == AF_INET6) {
+ handle->flags |= UV_HANDLE_IPV6;
+ } else {
+ assert(!(handle->flags & UV_HANDLE_IPV6));
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
+ uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
+
+ handle->accept_reqs = NULL;
+ handle->pending_accepts = NULL;
+ handle->socket = INVALID_SOCKET;
+ handle->reqs_pending = 0;
+ handle->func_acceptex = NULL;
+ handle->func_connectex = NULL;
+ handle->processed_accepts = 0;
+
+ return 0;
+}
+
+
+void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
+ int err;
+ unsigned int i;
+ uv_tcp_accept_t* req;
+
+ if (handle->flags & UV_HANDLE_CONNECTION &&
+ handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+
+ UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
+
+ err = 0;
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ err = ERROR_OPERATION_ABORTED;
+ } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ }
+
+ if (handle->shutdown_req->cb) {
+ handle->shutdown_req->cb(handle->shutdown_req,
+ uv_translate_sys_error(err));
+ }
+
+ handle->shutdown_req = NULL;
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+
+ if (handle->flags & UV__HANDLE_CLOSING &&
+ handle->reqs_pending == 0) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+ if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
+ closesocket(handle->socket);
+ handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
+ }
+
+ if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) {
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ for (i = 0; i < uv_simultaneous_server_accepts; i++) {
+ req = &handle->accept_reqs[i];
+ if (req->wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(req->wait_handle);
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ }
+ if (req->event_handle) {
+ CloseHandle(req->event_handle);
+ req->event_handle = NULL;
+ }
+ }
+ }
+
+ free(handle->accept_reqs);
+ handle->accept_reqs = NULL;
+ }
+
+ if (handle->flags & UV_HANDLE_CONNECTION &&
+ handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(handle->read_req.wait_handle);
+ handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+ }
+ if (handle->read_req.event_handle) {
+ CloseHandle(handle->read_req.event_handle);
+ handle->read_req.event_handle = NULL;
+ }
+ }
+
+ uv__handle_close(handle);
+ loop->active_tcp_streams--;
+ }
+}
+
+
+static int uv_tcp_try_bind(uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ DWORD err;
+ int r;
+
+ if (handle->socket == INVALID_SOCKET) {
+ SOCKET sock = socket(addr->sa_family, SOCK_STREAM, 0);
+ if (sock == INVALID_SOCKET) {
+ return WSAGetLastError();
+ }
+
+ /* Make the socket non-inheritable */
+ if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
+ err = GetLastError();
+ closesocket(sock);
+ return err;
+ }
+
+ err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0);
+ if (err) {
+ closesocket(sock);
+ return err;
+ }
+ }
+
+#ifdef IPV6_V6ONLY
+ if (addr->sa_family == AF_INET6) {
+ int on;
+
+ on = (flags & UV_TCP_IPV6ONLY) != 0;
+
+ /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+ /* available, or when run on XP/2003 which have no support for dualstack */
+ /* sockets. For now we're silently ignoring the error. */
+ setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
+ }
+#endif
+
+ r = bind(handle->socket, addr, addrlen);
+
+ if (r == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ if (err == WSAEADDRINUSE) {
+ /* Some errors are not to be reported until connect() or listen() */
+ handle->bind_error = err;
+ handle->flags |= UV_HANDLE_BIND_ERROR;
+ } else {
+ return err;
+ }
+ }
+
+ handle->flags |= UV_HANDLE_BOUND;
+
+ return 0;
+}
+
+
+static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
+ uv_req_t* req;
+ uv_tcp_t* handle;
+
+ req = (uv_req_t*) context;
+ assert(req != NULL);
+ handle = (uv_tcp_t*)req->data;
+ assert(handle != NULL);
+ assert(!timed_out);
+
+ if (!PostQueuedCompletionStatus(handle->loop->iocp,
+ req->overlapped.InternalHigh,
+ 0,
+ &req->overlapped)) {
+ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+ }
+}
+
+
+static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
+ uv_write_t* req;
+ uv_tcp_t* handle;
+
+ req = (uv_write_t*) context;
+ assert(req != NULL);
+ handle = (uv_tcp_t*)req->handle;
+ assert(handle != NULL);
+ assert(!timed_out);
+
+ if (!PostQueuedCompletionStatus(handle->loop->iocp,
+ req->overlapped.InternalHigh,
+ 0,
+ &req->overlapped)) {
+ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+ }
+}
+
+
+static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
+ uv_loop_t* loop = handle->loop;
+ BOOL success;
+ DWORD bytes;
+ SOCKET accept_socket;
+ short family;
+
+ assert(handle->flags & UV_HANDLE_LISTENING);
+ assert(req->accept_socket == INVALID_SOCKET);
+
+ /* choose family and extension function */
+ if (handle->flags & UV_HANDLE_IPV6) {
+ family = AF_INET6;
+ } else {
+ family = AF_INET;
+ }
+
+ /* Open a socket for the accepted connection. */
+ accept_socket = socket(family, SOCK_STREAM, 0);
+ if (accept_socket == INVALID_SOCKET) {
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->reqs_pending++;
+ return;
+ }
+
+ /* Make the socket non-inheritable */
+ if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->reqs_pending++;
+ closesocket(accept_socket);
+ return;
+ }
+
+ /* Prepare the overlapped structure. */
+ memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ }
+
+ success = handle->func_acceptex(handle->socket,
+ accept_socket,
+ (void*)req->accept_buffer,
+ 0,
+ sizeof(struct sockaddr_storage),
+ sizeof(struct sockaddr_storage),
+ &bytes,
+ &req->overlapped);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
+ /* Process the req without IOCP. */
+ req->accept_socket = accept_socket;
+ handle->reqs_pending++;
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
+ /* The req will be processed with IOCP. */
+ req->accept_socket = accept_socket;
+ handle->reqs_pending++;
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+ req->wait_handle == INVALID_HANDLE_VALUE &&
+ !RegisterWaitForSingleObject(&req->wait_handle,
+ req->event_handle, post_completion, (void*) req,
+ INFINITE, WT_EXECUTEINWAITTHREAD)) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->reqs_pending++;
+ return;
+ }
+ } else {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->reqs_pending++;
+ /* Destroy the preallocated client socket. */
+ closesocket(accept_socket);
+ /* Destroy the event handle */
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ CloseHandle(req->overlapped.hEvent);
+ req->event_handle = NULL;
+ }
+ }
+}
+
+
+static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
+ uv_read_t* req;
+ uv_buf_t buf;
+ int result;
+ DWORD bytes, flags;
+
+ assert(handle->flags & UV_HANDLE_READING);
+ assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+ req = &handle->read_req;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ /*
+ * Preallocate a read buffer if the number of active streams is below
+ * the threshold.
+ */
+ if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
+ handle->flags &= ~UV_HANDLE_ZERO_READ;
+ handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer);
+ if (handle->read_buffer.len == 0) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer);
+ return;
+ }
+ assert(handle->read_buffer.base != NULL);
+ buf = handle->read_buffer;
+ } else {
+ handle->flags |= UV_HANDLE_ZERO_READ;
+ buf.base = (char*) &uv_zero_;
+ buf.len = 0;
+ }
+
+ /* Prepare the overlapped structure. */
+ memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ assert(req->event_handle);
+ req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ }
+
+ flags = 0;
+ result = WSARecv(handle->socket,
+ (WSABUF*)&buf,
+ 1,
+ &bytes,
+ &flags,
+ &req->overlapped,
+ NULL);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+ /* Process the req without IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ req->overlapped.InternalHigh = bytes;
+ handle->reqs_pending++;
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+ /* The req will be processed with IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+ req->wait_handle == INVALID_HANDLE_VALUE &&
+ !RegisterWaitForSingleObject(&req->wait_handle,
+ req->event_handle, post_completion, (void*) req,
+ INFINITE, WT_EXECUTEINWAITTHREAD)) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ }
+ } else {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ handle->reqs_pending++;
+ }
+}
+
+
+int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ unsigned int i, simultaneous_accepts;
+ uv_tcp_accept_t* req;
+ int err;
+
+ assert(backlog > 0);
+
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ handle->connection_cb = cb;
+ }
+
+ if (handle->flags & UV_HANDLE_READING) {
+ return WSAEISCONN;
+ }
+
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return handle->bind_error;
+ }
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ err = uv_tcp_try_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip4_any_,
+ sizeof(uv_addr_ip4_any_),
+ 0);
+ if (err)
+ return err;
+ }
+
+ if (!handle->func_acceptex) {
+ if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) {
+ return WSAEAFNOSUPPORT;
+ }
+ }
+
+ if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
+ listen(handle->socket, backlog) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+
+ handle->flags |= UV_HANDLE_LISTENING;
+ handle->connection_cb = cb;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+
+ simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
+ : uv_simultaneous_server_accepts;
+
+ if(!handle->accept_reqs) {
+ handle->accept_reqs = (uv_tcp_accept_t*)
+ malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
+ if (!handle->accept_reqs) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ for (i = 0; i < simultaneous_accepts; i++) {
+ req = &handle->accept_reqs[i];
+ uv_req_init(loop, (uv_req_t*)req);
+ req->type = UV_ACCEPT;
+ req->accept_socket = INVALID_SOCKET;
+ req->data = handle;
+
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+ if (!req->event_handle) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+ } else {
+ req->event_handle = NULL;
+ }
+
+ uv_tcp_queue_accept(handle, req);
+ }
+
+ /* Initialize other unused requests too, because uv_tcp_endgame */
+ /* doesn't know how how many requests were intialized, so it will */
+ /* try to clean up {uv_simultaneous_server_accepts} requests. */
+ for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
+ req = &handle->accept_reqs[i];
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_ACCEPT;
+ req->accept_socket = INVALID_SOCKET;
+ req->data = handle;
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
+ uv_loop_t* loop = server->loop;
+ int err = 0;
+ int family;
+
+ uv_tcp_accept_t* req = server->pending_accepts;
+
+ if (!req) {
+ /* No valid connections found, so we error out. */
+ return WSAEWOULDBLOCK;
+ }
+
+ if (req->accept_socket == INVALID_SOCKET) {
+ return WSAENOTCONN;
+ }
+
+ if (server->flags & UV_HANDLE_IPV6) {
+ family = AF_INET6;
+ } else {
+ family = AF_INET;
+ }
+
+ err = uv_tcp_set_socket(client->loop,
+ client,
+ req->accept_socket,
+ family,
+ 0);
+ if (err) {
+ closesocket(req->accept_socket);
+ } else {
+ uv_connection_init((uv_stream_t*) client);
+ /* AcceptEx() implicitly binds the accepted socket. */
+ client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ }
+
+ /* Prepare the req to pick up a new connection */
+ server->pending_accepts = req->next_pending;
+ req->next_pending = NULL;
+ req->accept_socket = INVALID_SOCKET;
+
+ if (!(server->flags & UV__HANDLE_CLOSING)) {
+ /* Check if we're in a middle of changing the number of pending accepts. */
+ if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
+ uv_tcp_queue_accept(server, req);
+ } else {
+ /* We better be switching to a single pending accept. */
+ assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
+
+ server->processed_accepts++;
+
+ if (server->processed_accepts >= uv_simultaneous_server_accepts) {
+ server->processed_accepts = 0;
+ /*
+ * All previously queued accept requests are now processed.
+ * We now switch to queueing just a single accept.
+ */
+ uv_tcp_queue_accept(server, &server->accept_reqs[0]);
+ server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+ server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+ }
+ }
+ }
+
+ loop->active_tcp_streams++;
+
+ return err;
+}
+
+
+int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
+ uv_loop_t* loop = handle->loop;
+
+ handle->flags |= UV_HANDLE_READING;
+ handle->read_cb = read_cb;
+ handle->alloc_cb = alloc_cb;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+
+ /* If reading was stopped and then started again, there could still be a */
+ /* read request pending. */
+ if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+ !handle->read_req.event_handle) {
+ handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
+ if (!handle->read_req.event_handle) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+ }
+ uv_tcp_queue_read(loop, handle);
+ }
+
+ return 0;
+}
+
+
+static int uv_tcp_try_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_connect_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ const struct sockaddr* bind_addr;
+ BOOL success;
+ DWORD bytes;
+ int err;
+
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return handle->bind_error;
+ }
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ if (addrlen == sizeof(uv_addr_ip4_any_)) {
+ bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
+ } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
+ bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
+ } else {
+ abort();
+ }
+ err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0);
+ if (err)
+ return err;
+ }
+
+ if (!handle->func_connectex) {
+ if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) {
+ return WSAEAFNOSUPPORT;
+ }
+ }
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_CONNECT;
+ req->handle = (uv_stream_t*) handle;
+ req->cb = cb;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ success = handle->func_connectex(handle->socket,
+ addr,
+ addrlen,
+ NULL,
+ 0,
+ &bytes,
+ &req->overlapped);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
+ /* Process the req without IOCP. */
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
+ /* The req will be processed with IOCP. */
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ } else {
+ return WSAGetLastError();
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
+ int* namelen) {
+ int result;
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return UV_EINVAL;
+ }
+
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return uv_translate_sys_error(handle->bind_error);
+ }
+
+ result = getsockname(handle->socket, name, namelen);
+ if (result != 0) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
+ int* namelen) {
+ int result;
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return UV_EINVAL;
+ }
+
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return uv_translate_sys_error(handle->bind_error);
+ }
+
+ result = getpeername(handle->socket, name, namelen);
+ if (result != 0) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_write(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_tcp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb) {
+ int result;
+ DWORD bytes;
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_WRITE;
+ req->handle = (uv_stream_t*) handle;
+ req->cb = cb;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ /* Prepare the overlapped structure. */
+ memset(&(req->overlapped), 0, sizeof(req->overlapped));
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+ if (!req->event_handle) {
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+ req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+ req->wait_handle = INVALID_HANDLE_VALUE;
+ }
+
+ result = WSASend(handle->socket,
+ (WSABUF*) bufs,
+ nbufs,
+ &bytes,
+ 0,
+ &req->overlapped,
+ NULL);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+ /* Request completed immediately. */
+ req->queued_bytes = 0;
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+ /* Request queued by the kernel. */
+ req->queued_bytes = uv_count_bufs(bufs, nbufs);
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ handle->write_queue_size += req->queued_bytes;
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+ !RegisterWaitForSingleObject(&req->wait_handle,
+ req->event_handle, post_write_completion, (void*) req,
+ INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ }
+ } else {
+ /* Send failed due to an error. */
+ return WSAGetLastError();
+ }
+
+ return 0;
+}
+
+
+void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_req_t* req) {
+ DWORD bytes, flags, err;
+ uv_buf_t buf;
+
+ assert(handle->type == UV_TCP);
+
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+ if (!REQ_SUCCESS(req)) {
+ /* An error occurred doing the read. */
+ if ((handle->flags & UV_HANDLE_READING) ||
+ !(handle->flags & UV_HANDLE_ZERO_READ)) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
+ uv_buf_init(NULL, 0) : handle->read_buffer;
+
+ err = GET_REQ_SOCK_ERROR(req);
+
+ if (err == WSAECONNABORTED) {
+ /*
+ * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
+ */
+ err = WSAECONNRESET;
+ }
+
+ handle->read_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(err),
+ &buf);
+ }
+ } else {
+ if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+ /* The read was done with a non-zero buffer length. */
+ if (req->overlapped.InternalHigh > 0) {
+ /* Successful read */
+ handle->read_cb((uv_stream_t*)handle,
+ req->overlapped.InternalHigh,
+ &handle->read_buffer);
+ /* Read again only if bytes == buf.len */
+ if (req->overlapped.InternalHigh < handle->read_buffer.len) {
+ goto done;
+ }
+ } else {
+ /* Connection closed */
+ if (handle->flags & UV_HANDLE_READING) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ }
+ handle->flags &= ~UV_HANDLE_READABLE;
+
+ buf.base = 0;
+ buf.len = 0;
+ handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer);
+ goto done;
+ }
+ }
+
+ /* Do nonblocking reads until the buffer is empty */
+ while (handle->flags & UV_HANDLE_READING) {
+ handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
+ if (buf.len == 0) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+ break;
+ }
+ assert(buf.base != NULL);
+
+ flags = 0;
+ if (WSARecv(handle->socket,
+ (WSABUF*)&buf,
+ 1,
+ &bytes,
+ &flags,
+ NULL,
+ NULL) != SOCKET_ERROR) {
+ if (bytes > 0) {
+ /* Successful read */
+ handle->read_cb((uv_stream_t*)handle, bytes, &buf);
+ /* Read again only if bytes == buf.len */
+ if (bytes < buf.len) {
+ break;
+ }
+ } else {
+ /* Connection closed */
+ handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE);
+ DECREASE_ACTIVE_COUNT(loop, handle);
+
+ handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf);
+ break;
+ }
+ } else {
+ err = WSAGetLastError();
+ if (err == WSAEWOULDBLOCK) {
+ /* Read buffer was completely empty, report a 0-byte read. */
+ handle->read_cb((uv_stream_t*)handle, 0, &buf);
+ } else {
+ /* Ouch! serious error. */
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+
+ if (err == WSAECONNABORTED) {
+ /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */
+ /* Unix. */
+ err = WSAECONNRESET;
+ }
+
+ handle->read_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(err),
+ &buf);
+ }
+ break;
+ }
+ }
+
+done:
+ /* Post another read if still reading and not closing. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_tcp_queue_read(loop, handle);
+ }
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_write_t* req) {
+ int err;
+
+ assert(handle->type == UV_TCP);
+
+ assert(handle->write_queue_size >= req->queued_bytes);
+ handle->write_queue_size -= req->queued_bytes;
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+ if (req->wait_handle != INVALID_HANDLE_VALUE) {
+ UnregisterWait(req->wait_handle);
+ }
+ if (req->event_handle) {
+ CloseHandle(req->event_handle);
+ }
+ }
+
+ if (req->cb) {
+ err = GET_REQ_SOCK_ERROR(req);
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ handle->write_reqs_pending--;
+ if (handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_req_t* raw_req) {
+ uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req;
+ int err;
+
+ assert(handle->type == UV_TCP);
+
+ /* If handle->accepted_socket is not a valid socket, then */
+ /* uv_queue_accept must have failed. This is a serious error. We stop */
+ /* accepting connections and report this error to the connection */
+ /* callback. */
+ if (req->accept_socket == INVALID_SOCKET) {
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ handle->flags &= ~UV_HANDLE_LISTENING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ if (handle->connection_cb) {
+ err = GET_REQ_SOCK_ERROR(req);
+ handle->connection_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(err));
+ }
+ }
+ } else if (REQ_SUCCESS(req) &&
+ setsockopt(req->accept_socket,
+ SOL_SOCKET,
+ SO_UPDATE_ACCEPT_CONTEXT,
+ (char*)&handle->socket,
+ sizeof(handle->socket)) == 0) {
+ req->next_pending = handle->pending_accepts;
+ handle->pending_accepts = req;
+
+ /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
+ if (handle->connection_cb) {
+ handle->connection_cb((uv_stream_t*)handle, 0);
+ }
+ } else {
+ /* Error related to accepted socket is ignored because the server */
+ /* socket may still be healthy. If the server socket is broken */
+ /* uv_queue_accept will detect it. */
+ closesocket(req->accept_socket);
+ req->accept_socket = INVALID_SOCKET;
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ uv_tcp_queue_accept(handle, req);
+ }
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
+ uv_connect_t* req) {
+ int err;
+
+ assert(handle->type == UV_TCP);
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ err = 0;
+ if (REQ_SUCCESS(req)) {
+ if (setsockopt(handle->socket,
+ SOL_SOCKET,
+ SO_UPDATE_CONNECT_CONTEXT,
+ NULL,
+ 0) == 0) {
+ uv_connection_init((uv_stream_t*)handle);
+ handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ loop->active_tcp_streams++;
+ } else {
+ err = WSAGetLastError();
+ }
+ } else {
+ err = GET_REQ_SOCK_ERROR(req);
+ }
+ req->cb(req, uv_translate_sys_error(err));
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
+ int tcp_connection) {
+ int err;
+
+ SOCKET socket = WSASocketW(AF_INET,
+ SOCK_STREAM,
+ IPPROTO_IP,
+ socket_protocol_info,
+ 0,
+ WSA_FLAG_OVERLAPPED);
+
+ if (socket == INVALID_SOCKET) {
+ return WSAGetLastError();
+ }
+
+ if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
+ err = GetLastError();
+ closesocket(socket);
+ return err;
+ }
+
+ err = uv_tcp_set_socket(tcp->loop,
+ tcp,
+ socket,
+ socket_protocol_info->iAddressFamily,
+ 1);
+ if (err) {
+ closesocket(socket);
+ return err;
+ }
+
+ if (tcp_connection) {
+ uv_connection_init((uv_stream_t*)tcp);
+ tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ }
+
+ tcp->flags |= UV_HANDLE_BOUND;
+ tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
+
+ tcp->loop->active_tcp_streams++;
+ return 0;
+}
+
+
+int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
+ int err;
+
+ if (handle->socket != INVALID_SOCKET) {
+ err = uv__tcp_nodelay(handle, handle->socket, enable);
+ if (err)
+ return err;
+ }
+
+ if (enable) {
+ handle->flags |= UV_HANDLE_TCP_NODELAY;
+ } else {
+ handle->flags &= ~UV_HANDLE_TCP_NODELAY;
+ }
+
+ return 0;
+}
+
+
+int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
+ int err;
+
+ if (handle->socket != INVALID_SOCKET) {
+ err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
+ if (err)
+ return err;
+ }
+
+ if (enable) {
+ handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
+ } else {
+ handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
+ }
+
+ /* TODO: Store delay if handle->socket isn't created yet. */
+
+ return 0;
+}
+
+
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+ LPWSAPROTOCOL_INFOW protocol_info) {
+ if (!(handle->flags & UV_HANDLE_CONNECTION)) {
+ /*
+ * We're about to share the socket with another process. Because
+ * this is a listening socket, we assume that the other process will
+ * be accepting connections on it. So, before sharing the socket
+ * with another process, we call listen here in the parent process.
+ */
+
+ if (!(handle->flags & UV_HANDLE_LISTENING)) {
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* Report any deferred bind errors now. */
+ if (handle->flags & UV_HANDLE_BIND_ERROR) {
+ return handle->bind_error;
+ }
+
+ if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+ }
+ }
+
+ if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) {
+ return WSAGetLastError();
+ }
+
+ handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
+
+ return 0;
+}
+
+
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+ if (handle->flags & UV_HANDLE_CONNECTION) {
+ return UV_EINVAL;
+ }
+
+ /* Check if we're already in the desired mode. */
+ if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) ||
+ (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
+ return 0;
+ }
+
+ /* Don't allow switching from single pending accept to many. */
+ if (enable) {
+ return UV_ENOTSUP;
+ }
+
+ /* Check if we're in a middle of changing the number of pending accepts. */
+ if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) {
+ return 0;
+ }
+
+ handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+
+ /* Flip the changing flag if we have already queued multiple accepts. */
+ if (handle->flags & UV_HANDLE_LISTENING) {
+ handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+ }
+
+ return 0;
+}
+
+
+static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
+ SOCKET socket = tcp->socket;
+ int non_ifs_lsp;
+
+ /* Check if we have any non-IFS LSPs stacked on top of TCP */
+ non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
+ uv_tcp_non_ifs_lsp_ipv4;
+
+ /* If there are non-ifs LSPs then try to obtain a base handle for the */
+ /* socket. This will always fail on Windows XP/3k. */
+ if (non_ifs_lsp) {
+ DWORD bytes;
+ if (WSAIoctl(socket,
+ SIO_BASE_HANDLE,
+ NULL,
+ 0,
+ &socket,
+ sizeof socket,
+ &bytes,
+ NULL,
+ NULL) != 0) {
+ /* Failed. We can't do CancelIo. */
+ return -1;
+ }
+ }
+
+ assert(socket != 0 && socket != INVALID_SOCKET);
+
+ if (!CancelIo((HANDLE) socket)) {
+ return GetLastError();
+ }
+
+ /* It worked. */
+ return 0;
+}
+
+
+void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
+ int close_socket = 1;
+
+ if (tcp->flags & UV_HANDLE_READ_PENDING) {
+ /* In order for winsock to do a graceful close there must not be any */
+ /* any pending reads, or the socket must be shut down for writing */
+ if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
+ /* Just do shutdown on non-shared sockets, which ensures graceful close. */
+ shutdown(tcp->socket, SD_SEND);
+
+ } else if (uv_tcp_try_cancel_io(tcp) == 0) {
+ /* In case of a shared socket, we try to cancel all outstanding I/O, */
+ /* If that works, don't close the socket yet - wait for the read req to */
+ /* return and close the socket in uv_tcp_endgame. */
+ close_socket = 0;
+
+ } else {
+ /* When cancelling isn't possible - which could happen when an LSP is */
+ /* present on an old Windows version, we will have to close the socket */
+ /* with a read pending. That is not nice because trailing sent bytes */
+ /* may not make it to the other side. */
+ }
+
+ } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
+ tcp->accept_reqs != NULL) {
+ /* Under normal circumstances closesocket() will ensure that all pending */
+ /* accept reqs are canceled. However, when the socket is shared the */
+ /* presence of another reference to the socket in another process will */
+ /* keep the accept reqs going, so we have to ensure that these are */
+ /* canceled. */
+ if (uv_tcp_try_cancel_io(tcp) != 0) {
+ /* When cancellation is not possible, there is another option: we can */
+ /* close the incoming sockets, which will also cancel the accept */
+ /* operations. However this is not cool because we might inadvertedly */
+ /* close a socket that just accepted a new connection, which will */
+ /* cause the connection to be aborted. */
+ unsigned int i;
+ for (i = 0; i < uv_simultaneous_server_accepts; i++) {
+ uv_tcp_accept_t* req = &tcp->accept_reqs[i];
+ if (req->accept_socket != INVALID_SOCKET &&
+ !HasOverlappedIoCompleted(&req->overlapped)) {
+ closesocket(req->accept_socket);
+ req->accept_socket = INVALID_SOCKET;
+ }
+ }
+ }
+ }
+
+ if (tcp->flags & UV_HANDLE_READING) {
+ tcp->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, tcp);
+ }
+
+ if (tcp->flags & UV_HANDLE_LISTENING) {
+ tcp->flags &= ~UV_HANDLE_LISTENING;
+ DECREASE_ACTIVE_COUNT(loop, tcp);
+ }
+
+ if (close_socket) {
+ closesocket(tcp->socket);
+ tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
+ }
+
+ tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(tcp);
+
+ if (tcp->reqs_pending == 0) {
+ uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
+ }
+}
+
+
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
+ WSAPROTOCOL_INFOW protocol_info;
+ int opt_len;
+ int err;
+
+ /* Detect the address family of the socket. */
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(sock,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /* Make the socket non-inheritable */
+ if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ err = uv_tcp_set_socket(handle->loop,
+ handle,
+ sock,
+ protocol_info.iAddressFamily,
+ 1);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+
+ return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__tcp_bind(uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ int err;
+
+ err = uv_tcp_try_bind(handle, addr, addrlen, flags);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__tcp_connect(uv_connect_t* req,
+ uv_tcp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_connect_cb cb) {
+ int err;
+
+ err = uv_tcp_try_connect(req, handle, addr, addrlen, cb);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ return 0;
+}
diff --git a/third-party/libuv/src/win/thread.c b/third-party/libuv/src/win/thread.c
new file mode 100644
index 0000000000..5178f8f9ab
--- /dev/null
+++ b/third-party/libuv/src/win/thread.c
@@ -0,0 +1,716 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
+#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
+
+#ifdef _MSC_VER /* msvc */
+# define inline __inline
+# define NOINLINE __declspec (noinline)
+#else /* gcc */
+# define inline inline
+# define NOINLINE __attribute__ ((noinline))
+#endif
+
+
+inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock);
+inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock);
+inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock);
+
+inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock);
+inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock);
+inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock);
+inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock);
+
+
+inline static int uv_cond_fallback_init(uv_cond_t* cond);
+inline static void uv_cond_fallback_destroy(uv_cond_t* cond);
+inline static void uv_cond_fallback_signal(uv_cond_t* cond);
+inline static void uv_cond_fallback_broadcast(uv_cond_t* cond);
+inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+inline static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout);
+
+inline static int uv_cond_condvar_init(uv_cond_t* cond);
+inline static void uv_cond_condvar_destroy(uv_cond_t* cond);
+inline static void uv_cond_condvar_signal(uv_cond_t* cond);
+inline static void uv_cond_condvar_broadcast(uv_cond_t* cond);
+inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+inline static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout);
+
+
+static NOINLINE void uv__once_inner(uv_once_t* guard,
+ void (*callback)(void)) {
+ DWORD result;
+ HANDLE existing_event, created_event;
+
+ created_event = CreateEvent(NULL, 1, 0, NULL);
+ if (created_event == 0) {
+ /* Could fail in a low-memory situation? */
+ uv_fatal_error(GetLastError(), "CreateEvent");
+ }
+
+ existing_event = InterlockedCompareExchangePointer(&guard->event,
+ created_event,
+ NULL);
+
+ if (existing_event == NULL) {
+ /* We won the race */
+ callback();
+
+ result = SetEvent(created_event);
+ assert(result);
+ guard->ran = 1;
+
+ } else {
+ /* We lost the race. Destroy the event we created and wait for the */
+ /* existing one todv become signaled. */
+ CloseHandle(created_event);
+ result = WaitForSingleObject(existing_event, INFINITE);
+ assert(result == WAIT_OBJECT_0);
+ }
+}
+
+
+void uv_once(uv_once_t* guard, void (*callback)(void)) {
+ /* Fast case - avoid WaitForSingleObject. */
+ if (guard->ran) {
+ return;
+ }
+
+ uv__once_inner(guard, callback);
+}
+
+
+int uv_thread_join(uv_thread_t *tid) {
+ if (WaitForSingleObject(*tid, INFINITE))
+ return uv_translate_sys_error(GetLastError());
+ else {
+ CloseHandle(*tid);
+ *tid = 0;
+ return 0;
+ }
+}
+
+
+int uv_mutex_init(uv_mutex_t* mutex) {
+ InitializeCriticalSection(mutex);
+ return 0;
+}
+
+
+void uv_mutex_destroy(uv_mutex_t* mutex) {
+ DeleteCriticalSection(mutex);
+}
+
+
+void uv_mutex_lock(uv_mutex_t* mutex) {
+ EnterCriticalSection(mutex);
+}
+
+
+int uv_mutex_trylock(uv_mutex_t* mutex) {
+ if (TryEnterCriticalSection(mutex))
+ return 0;
+ else
+ return UV_EAGAIN;
+}
+
+
+void uv_mutex_unlock(uv_mutex_t* mutex) {
+ LeaveCriticalSection(mutex);
+}
+
+
+int uv_rwlock_init(uv_rwlock_t* rwlock) {
+ uv__once_init();
+
+ if (HAVE_SRWLOCK_API())
+ return uv__rwlock_srwlock_init(rwlock);
+ else
+ return uv__rwlock_fallback_init(rwlock);
+}
+
+
+void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ uv__rwlock_srwlock_destroy(rwlock);
+ else
+ uv__rwlock_fallback_destroy(rwlock);
+}
+
+
+void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ uv__rwlock_srwlock_rdlock(rwlock);
+ else
+ uv__rwlock_fallback_rdlock(rwlock);
+}
+
+
+int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ return uv__rwlock_srwlock_tryrdlock(rwlock);
+ else
+ return uv__rwlock_fallback_tryrdlock(rwlock);
+}
+
+
+void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ uv__rwlock_srwlock_rdunlock(rwlock);
+ else
+ uv__rwlock_fallback_rdunlock(rwlock);
+}
+
+
+void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ uv__rwlock_srwlock_wrlock(rwlock);
+ else
+ uv__rwlock_fallback_wrlock(rwlock);
+}
+
+
+int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ return uv__rwlock_srwlock_trywrlock(rwlock);
+ else
+ return uv__rwlock_fallback_trywrlock(rwlock);
+}
+
+
+void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
+ if (HAVE_SRWLOCK_API())
+ uv__rwlock_srwlock_wrunlock(rwlock);
+ else
+ uv__rwlock_fallback_wrunlock(rwlock);
+}
+
+
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+ *sem = CreateSemaphore(NULL, value, INT_MAX, NULL);
+ if (*sem == NULL)
+ return uv_translate_sys_error(GetLastError());
+ else
+ return 0;
+}
+
+
+void uv_sem_destroy(uv_sem_t* sem) {
+ if (!CloseHandle(*sem))
+ abort();
+}
+
+
+void uv_sem_post(uv_sem_t* sem) {
+ if (!ReleaseSemaphore(*sem, 1, NULL))
+ abort();
+}
+
+
+void uv_sem_wait(uv_sem_t* sem) {
+ if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0)
+ abort();
+}
+
+
+int uv_sem_trywait(uv_sem_t* sem) {
+ DWORD r = WaitForSingleObject(*sem, 0);
+
+ if (r == WAIT_OBJECT_0)
+ return 0;
+
+ if (r == WAIT_TIMEOUT)
+ return UV_EAGAIN;
+
+ abort();
+ return -1; /* Satisfy the compiler. */
+}
+
+
+inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) {
+ pInitializeSRWLock(&rwlock->srwlock_);
+ return 0;
+}
+
+
+inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) {
+ (void) rwlock;
+}
+
+
+inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) {
+ pAcquireSRWLockShared(&rwlock->srwlock_);
+}
+
+
+inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) {
+ if (pTryAcquireSRWLockShared(&rwlock->srwlock_))
+ return 0;
+ else
+ return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */
+}
+
+
+inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) {
+ pReleaseSRWLockShared(&rwlock->srwlock_);
+}
+
+
+inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) {
+ pAcquireSRWLockExclusive(&rwlock->srwlock_);
+}
+
+
+inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) {
+ if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_))
+ return 0;
+ else
+ return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */
+}
+
+
+inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) {
+ pReleaseSRWLockExclusive(&rwlock->srwlock_);
+}
+
+
+inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) {
+ int err;
+
+ err = uv_mutex_init(&rwlock->fallback_.read_mutex_);
+ if (err)
+ return err;
+
+ err = uv_mutex_init(&rwlock->fallback_.write_mutex_);
+ if (err) {
+ uv_mutex_destroy(&rwlock->fallback_.read_mutex_);
+ return err;
+ }
+
+ rwlock->fallback_.num_readers_ = 0;
+
+ return 0;
+}
+
+
+inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) {
+ uv_mutex_destroy(&rwlock->fallback_.read_mutex_);
+ uv_mutex_destroy(&rwlock->fallback_.write_mutex_);
+}
+
+
+inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) {
+ uv_mutex_lock(&rwlock->fallback_.read_mutex_);
+
+ if (++rwlock->fallback_.num_readers_ == 1)
+ uv_mutex_lock(&rwlock->fallback_.write_mutex_);
+
+ uv_mutex_unlock(&rwlock->fallback_.read_mutex_);
+}
+
+
+inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) {
+ int err;
+
+ err = uv_mutex_trylock(&rwlock->fallback_.read_mutex_);
+ if (err)
+ goto out;
+
+ err = 0;
+ if (rwlock->fallback_.num_readers_ == 0)
+ err = uv_mutex_trylock(&rwlock->fallback_.write_mutex_);
+
+ if (err == 0)
+ rwlock->fallback_.num_readers_++;
+
+ uv_mutex_unlock(&rwlock->fallback_.read_mutex_);
+
+out:
+ return err;
+}
+
+
+inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) {
+ uv_mutex_lock(&rwlock->fallback_.read_mutex_);
+
+ if (--rwlock->fallback_.num_readers_ == 0)
+ uv_mutex_unlock(&rwlock->fallback_.write_mutex_);
+
+ uv_mutex_unlock(&rwlock->fallback_.read_mutex_);
+}
+
+
+inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) {
+ uv_mutex_lock(&rwlock->fallback_.write_mutex_);
+}
+
+
+inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) {
+ return uv_mutex_trylock(&rwlock->fallback_.write_mutex_);
+}
+
+
+inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) {
+ uv_mutex_unlock(&rwlock->fallback_.write_mutex_);
+}
+
+
+
+/* This condition variable implementation is based on the SetEvent solution
+ * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * We could not use the SignalObjectAndWait solution (section 3.4) because
+ * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
+ * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
+ */
+
+inline static int uv_cond_fallback_init(uv_cond_t* cond) {
+ int err;
+
+ /* Initialize the count to 0. */
+ cond->fallback.waiters_count = 0;
+
+ InitializeCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* Create an auto-reset event. */
+ cond->fallback.signal_event = CreateEvent(NULL, /* no security */
+ FALSE, /* auto-reset event */
+ FALSE, /* non-signaled initially */
+ NULL); /* unnamed */
+ if (!cond->fallback.signal_event) {
+ err = GetLastError();
+ goto error2;
+ }
+
+ /* Create a manual-reset event. */
+ cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */
+ TRUE, /* manual-reset */
+ FALSE, /* non-signaled */
+ NULL); /* unnamed */
+ if (!cond->fallback.broadcast_event) {
+ err = GetLastError();
+ goto error;
+ }
+
+ return 0;
+
+error:
+ CloseHandle(cond->fallback.signal_event);
+error2:
+ DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+ return uv_translate_sys_error(err);
+}
+
+
+inline static int uv_cond_condvar_init(uv_cond_t* cond) {
+ pInitializeConditionVariable(&cond->cond_var);
+ return 0;
+}
+
+
+int uv_cond_init(uv_cond_t* cond) {
+ uv__once_init();
+
+ if (HAVE_CONDVAR_API())
+ return uv_cond_condvar_init(cond);
+ else
+ return uv_cond_fallback_init(cond);
+}
+
+
+inline static void uv_cond_fallback_destroy(uv_cond_t* cond) {
+ if (!CloseHandle(cond->fallback.broadcast_event))
+ abort();
+ if (!CloseHandle(cond->fallback.signal_event))
+ abort();
+ DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+}
+
+
+inline static void uv_cond_condvar_destroy(uv_cond_t* cond) {
+ /* nothing to do */
+}
+
+
+void uv_cond_destroy(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_destroy(cond);
+ else
+ uv_cond_fallback_destroy(cond);
+}
+
+
+inline static void uv_cond_fallback_signal(uv_cond_t* cond) {
+ int have_waiters;
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ have_waiters = cond->fallback.waiters_count > 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ if (have_waiters)
+ SetEvent(cond->fallback.signal_event);
+}
+
+
+inline static void uv_cond_condvar_signal(uv_cond_t* cond) {
+ pWakeConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_signal(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_signal(cond);
+ else
+ uv_cond_fallback_signal(cond);
+}
+
+
+inline static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
+ int have_waiters;
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ have_waiters = cond->fallback.waiters_count > 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ if (have_waiters)
+ SetEvent(cond->fallback.broadcast_event);
+}
+
+
+inline static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
+ pWakeAllConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_broadcast(uv_cond_t* cond) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_broadcast(cond);
+ else
+ uv_cond_fallback_broadcast(cond);
+}
+
+
+inline int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
+ DWORD dwMilliseconds) {
+ DWORD result;
+ int last_waiter;
+ HANDLE handles[2] = {
+ cond->fallback.signal_event,
+ cond->fallback.broadcast_event
+ };
+
+ /* Avoid race conditions. */
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ cond->fallback.waiters_count++;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* It's ok to release the <mutex> here since Win32 manual-reset events */
+ /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */
+ /* bug. */
+ uv_mutex_unlock(mutex);
+
+ /* Wait for either event to become signaled due to <uv_cond_signal> being */
+ /* called or <uv_cond_broadcast> being called. */
+ result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
+
+ EnterCriticalSection(&cond->fallback.waiters_count_lock);
+ cond->fallback.waiters_count--;
+ last_waiter = result == WAIT_OBJECT_0 + 1
+ && cond->fallback.waiters_count == 0;
+ LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+ /* Some thread called <pthread_cond_broadcast>. */
+ if (last_waiter) {
+ /* We're the last waiter to be notified or to stop waiting, so reset the */
+ /* the manual-reset event. */
+ ResetEvent(cond->fallback.broadcast_event);
+ }
+
+ /* Reacquire the <mutex>. */
+ uv_mutex_lock(mutex);
+
+ if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1)
+ return 0;
+
+ if (result == WAIT_TIMEOUT)
+ return UV_ETIMEDOUT;
+
+ abort();
+ return -1; /* Satisfy the compiler. */
+}
+
+
+inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (uv_cond_wait_helper(cond, mutex, INFINITE))
+ abort();
+}
+
+
+inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
+ abort();
+}
+
+
+void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+ if (HAVE_CONDVAR_API())
+ uv_cond_condvar_wait(cond, mutex);
+ else
+ uv_cond_fallback_wait(cond, mutex);
+}
+
+
+inline static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout) {
+ return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
+}
+
+
+inline static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex, uint64_t timeout) {
+ if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
+ return 0;
+ if (GetLastError() != ERROR_TIMEOUT)
+ abort();
+ return UV_ETIMEDOUT;
+}
+
+
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
+ uint64_t timeout) {
+ if (HAVE_CONDVAR_API())
+ return uv_cond_condvar_timedwait(cond, mutex, timeout);
+ else
+ return uv_cond_fallback_timedwait(cond, mutex, timeout);
+}
+
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+ int err;
+
+ barrier->n = count;
+ barrier->count = 0;
+
+ err = uv_mutex_init(&barrier->mutex);
+ if (err)
+ return err;
+
+ err = uv_sem_init(&barrier->turnstile1, 0);
+ if (err)
+ goto error2;
+
+ err = uv_sem_init(&barrier->turnstile2, 1);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ uv_sem_destroy(&barrier->turnstile1);
+error2:
+ uv_mutex_destroy(&barrier->mutex);
+ return err;
+
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+ uv_sem_destroy(&barrier->turnstile2);
+ uv_sem_destroy(&barrier->turnstile1);
+ uv_mutex_destroy(&barrier->mutex);
+}
+
+
+void uv_barrier_wait(uv_barrier_t* barrier) {
+ uv_mutex_lock(&barrier->mutex);
+ if (++barrier->count == barrier->n) {
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile1);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile1);
+
+ uv_mutex_lock(&barrier->mutex);
+ if (--barrier->count == 0) {
+ uv_sem_wait(&barrier->turnstile1);
+ uv_sem_post(&barrier->turnstile2);
+ }
+ uv_mutex_unlock(&barrier->mutex);
+
+ uv_sem_wait(&barrier->turnstile2);
+ uv_sem_post(&barrier->turnstile2);
+}
+
+
+int uv_key_create(uv_key_t* key) {
+ key->tls_index = TlsAlloc();
+ if (key->tls_index == TLS_OUT_OF_INDEXES)
+ return UV_ENOMEM;
+ return 0;
+}
+
+
+void uv_key_delete(uv_key_t* key) {
+ if (TlsFree(key->tls_index) == FALSE)
+ abort();
+ key->tls_index = TLS_OUT_OF_INDEXES;
+}
+
+
+void* uv_key_get(uv_key_t* key) {
+ void* value;
+
+ value = TlsGetValue(key->tls_index);
+ if (value == NULL)
+ if (GetLastError() != ERROR_SUCCESS)
+ abort();
+
+ return value;
+}
+
+
+void uv_key_set(uv_key_t* key, void* value) {
+ if (TlsSetValue(key->tls_index, value) == FALSE)
+ abort();
+}
diff --git a/third-party/libuv/src/win/threadpool.c b/third-party/libuv/src/win/threadpool.c
new file mode 100644
index 0000000000..9539844c66
--- /dev/null
+++ b/third-party/libuv/src/win/threadpool.c
@@ -0,0 +1,81 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+
+static void uv_work_req_init(uv_loop_t* loop, uv_work_t* req,
+ uv_work_cb work_cb, uv_after_work_cb after_work_cb) {
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_WORK;
+ req->loop = loop;
+ req->work_cb = work_cb;
+ req->after_work_cb = after_work_cb;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+}
+
+
+static DWORD WINAPI uv_work_thread_proc(void* parameter) {
+ uv_work_t* req = (uv_work_t*)parameter;
+ uv_loop_t* loop = req->loop;
+
+ assert(req != NULL);
+ assert(req->type == UV_WORK);
+ assert(req->work_cb);
+
+ req->work_cb(req);
+
+ POST_COMPLETION_FOR_REQ(loop, req);
+
+ return 0;
+}
+
+
+int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
+ uv_after_work_cb after_work_cb) {
+ if (work_cb == NULL)
+ return UV_EINVAL;
+
+ uv_work_req_init(loop, req, work_cb, after_work_cb);
+
+ if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ uv__req_register(loop, req);
+ return 0;
+}
+
+
+int uv_cancel(uv_req_t* req) {
+ return UV_ENOSYS;
+}
+
+
+void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
+ uv__req_unregister(loop, req);
+ if(req->after_work_cb)
+ req->after_work_cb(req, 0);
+}
diff --git a/third-party/libuv/src/win/timer.c b/third-party/libuv/src/win/timer.c
new file mode 100644
index 0000000000..6c53ea37e0
--- /dev/null
+++ b/third-party/libuv/src/win/timer.c
@@ -0,0 +1,254 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "tree.h"
+#include "handle-inl.h"
+
+
+void uv_update_time(uv_loop_t* loop) {
+ DWORD ticks;
+ ULARGE_INTEGER time;
+
+ ticks = GetTickCount();
+
+ time.QuadPart = loop->time;
+
+ /* GetTickCount() can conceivably wrap around, so when the current tick */
+ /* count is lower than the last tick count, we'll assume it has wrapped. */
+ /* uv_poll must make sure that the timer can never overflow more than */
+ /* once between two subsequent uv_update_time calls. */
+ time.LowPart = ticks;
+ if (ticks < loop->last_tick_count)
+ time.HighPart++;
+
+ /* Remember the last tick count. */
+ loop->last_tick_count = ticks;
+
+ /* The GetTickCount() resolution isn't too good. Sometimes it'll happen */
+ /* that GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx() has */
+ /* waited for a couple of ms but this is not reflected in the GetTickCount */
+ /* result yet. Therefore whenever GetQueuedCompletionStatus times out */
+ /* we'll add the number of ms that it has waited to the current loop time. */
+ /* When that happened the loop time might be a little ms farther than what */
+ /* we've just computed, and we shouldn't update the loop time. */
+ if (loop->time < time.QuadPart)
+ loop->time = time.QuadPart;
+}
+
+
+void uv__time_forward(uv_loop_t* loop, uint64_t msecs) {
+ loop->time += msecs;
+}
+
+
+static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
+ if (a->due < b->due)
+ return -1;
+ if (a->due > b->due)
+ return 1;
+ /*
+ * compare start_id when both has the same due. start_id is
+ * allocated with loop->timer_counter in uv_timer_start().
+ */
+ if (a->start_id < b->start_id)
+ return -1;
+ if (a->start_id > b->start_id)
+ return 1;
+ return 0;
+}
+
+
+RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
+
+
+int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER);
+ handle->timer_cb = NULL;
+ handle->repeat = 0;
+
+ return 0;
+}
+
+
+void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ uv__handle_close(handle);
+ }
+}
+
+
+static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) {
+ uint64_t clamped_timeout;
+
+ clamped_timeout = loop_time + timeout;
+ if (clamped_timeout < timeout)
+ clamped_timeout = (uint64_t) -1;
+
+ return clamped_timeout;
+}
+
+
+int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
+ uint64_t repeat) {
+ uv_loop_t* loop = handle->loop;
+ uv_timer_t* old;
+
+ if (handle->flags & UV_HANDLE_ACTIVE) {
+ RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
+ }
+
+ handle->timer_cb = timer_cb;
+ handle->due = get_clamped_due_time(loop->time, timeout);
+ handle->repeat = repeat;
+ handle->flags |= UV_HANDLE_ACTIVE;
+ uv__handle_start(handle);
+
+ /* start_id is the second index to be compared in uv__timer_cmp() */
+ handle->start_id = handle->loop->timer_counter++;
+
+ old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle);
+ assert(old == NULL);
+
+ return 0;
+}
+
+
+int uv_timer_stop(uv_timer_t* handle) {
+ uv_loop_t* loop = handle->loop;
+
+ if (!(handle->flags & UV_HANDLE_ACTIVE))
+ return 0;
+
+ RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
+
+ handle->flags &= ~UV_HANDLE_ACTIVE;
+ uv__handle_stop(handle);
+
+ return 0;
+}
+
+
+int uv_timer_again(uv_timer_t* handle) {
+ uv_loop_t* loop = handle->loop;
+
+ /* If timer_cb is NULL that means that the timer was never started. */
+ if (!handle->timer_cb) {
+ return UV_EINVAL;
+ }
+
+ if (handle->flags & UV_HANDLE_ACTIVE) {
+ RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
+ handle->flags &= ~UV_HANDLE_ACTIVE;
+ uv__handle_stop(handle);
+ }
+
+ if (handle->repeat) {
+ handle->due = get_clamped_due_time(loop->time, handle->repeat);
+
+ if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
+ uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
+ }
+
+ handle->flags |= UV_HANDLE_ACTIVE;
+ uv__handle_start(handle);
+ }
+
+ return 0;
+}
+
+
+void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
+ assert(handle->type == UV_TIMER);
+ handle->repeat = repeat;
+}
+
+
+uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
+ assert(handle->type == UV_TIMER);
+ return handle->repeat;
+}
+
+
+DWORD uv_get_poll_timeout(uv_loop_t* loop) {
+ uv_timer_t* timer;
+ int64_t delta;
+
+ /* Check if there are any running timers */
+ timer = RB_MIN(uv_timer_tree_s, &loop->timers);
+ if (timer) {
+ uv_update_time(loop);
+
+ delta = timer->due - loop->time;
+ if (delta >= UINT_MAX >> 1) {
+ /* A timeout value of UINT_MAX means infinite, so that's no good. But */
+ /* more importantly, there's always the risk that GetTickCount wraps. */
+ /* uv_update_time can detect this, but we must make sure that the */
+ /* tick counter never overflows twice between two subsequent */
+ /* uv_update_time calls. We do this by never sleeping more than half */
+ /* the time it takes to wrap the counter - which is huge overkill, */
+ /* but hey, it's not so bad to wake up every 25 days. */
+ return UINT_MAX >> 1;
+ } else if (delta < 0) {
+ /* Negative timeout values are not allowed */
+ return 0;
+ } else {
+ return (DWORD)delta;
+ }
+ } else {
+ /* No timers */
+ return INFINITE;
+ }
+}
+
+
+void uv_process_timers(uv_loop_t* loop) {
+ uv_timer_t* timer;
+
+ /* Call timer callbacks */
+ for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
+ timer != NULL && timer->due <= loop->time;
+ timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
+ RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
+
+ if (timer->repeat != 0) {
+ /* If it is a repeating timer, reschedule with repeat timeout. */
+ timer->due = get_clamped_due_time(timer->due, timer->repeat);
+ if (timer->due < loop->time) {
+ timer->due = loop->time;
+ }
+ if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
+ uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
+ }
+ } else {
+ /* If non-repeating, mark the timer as inactive. */
+ timer->flags &= ~UV_HANDLE_ACTIVE;
+ uv__handle_stop(timer);
+ }
+
+ timer->timer_cb((uv_timer_t*) timer, 0);
+ }
+}
diff --git a/third-party/libuv/src/win/tty.c b/third-party/libuv/src/win/tty.c
new file mode 100644
index 0000000000..8855af350e
--- /dev/null
+++ b/third-party/libuv/src/win/tty.c
@@ -0,0 +1,1873 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+#define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
+
+#define ANSI_NORMAL 0x00
+#define ANSI_ESCAPE_SEEN 0x02
+#define ANSI_CSI 0x04
+#define ANSI_ST_CONTROL 0x08
+#define ANSI_IGNORE 0x10
+#define ANSI_IN_ARG 0x20
+#define ANSI_IN_STRING 0x40
+#define ANSI_BACKSLASH_SEEN 0x80
+
+
+static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
+
+
+/* Null uv_buf_t */
+static const uv_buf_t uv_null_buf_ = { 0, NULL };
+
+
+/*
+ * The console virtual window.
+ *
+ * Normally cursor movement in windows is relative to the console screen buffer,
+ * e.g. the application is allowed to overwrite the 'history'. This is very
+ * inconvenient, it makes absolute cursor movement pretty useless. There is
+ * also the concept of 'client rect' which is defined by the actual size of
+ * the console window and the scroll position of the screen buffer, but it's
+ * very volatile because it changes when the user scrolls.
+ *
+ * To make cursor movement behave sensibly we define a virtual window to which
+ * cursor movement is confined. The virtual window is always as wide as the
+ * console screen buffer, but it's height is defined by the size of the
+ * console window. The top of the virtual window aligns with the position
+ * of the caret when the first stdout/err handle is created, unless that would
+ * mean that it would extend beyond the bottom of the screen buffer - in that
+ * that case it's located as far down as possible.
+ *
+ * When the user writes a long text or many newlines, such that the output
+ * reaches beyond the bottom of the virtual window, the virtual window is
+ * shifted downwards, but not resized.
+ *
+ * Since all tty i/o happens on the same console, this window is shared
+ * between all stdout/stderr handles.
+ */
+
+static int uv_tty_virtual_offset = -1;
+static int uv_tty_virtual_height = -1;
+static int uv_tty_virtual_width = -1;
+
+static CRITICAL_SECTION uv_tty_output_lock;
+
+static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
+
+
+void uv_console_init() {
+ InitializeCriticalSection(&uv_tty_output_lock);
+}
+
+
+int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
+ HANDLE handle;
+ CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+
+ handle = (HANDLE) _get_osfhandle(fd);
+ if (handle == INVALID_HANDLE_VALUE) {
+ return UV_EBADF;
+ }
+
+ if (!readable) {
+ /* Obtain the screen buffer info with the output handle. */
+ if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /* Obtain the the tty_output_lock because the virtual window state is */
+ /* shared between all uv_tty_t handles. */
+ EnterCriticalSection(&uv_tty_output_lock);
+
+ /* Store the global tty output handle. This handle is used by TTY read */
+ /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
+ /* is received. */
+ uv_tty_output_handle = handle;
+
+ uv_tty_update_virtual_window(&screen_buffer_info);
+
+ LeaveCriticalSection(&uv_tty_output_lock);
+ }
+
+
+ uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY);
+ uv_connection_init((uv_stream_t*) tty);
+
+ tty->handle = handle;
+ tty->reqs_pending = 0;
+ tty->flags |= UV_HANDLE_BOUND;
+
+ if (readable) {
+ /* Initialize TTY input specific fields. */
+ tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
+ tty->read_line_handle = NULL;
+ tty->read_line_buffer = uv_null_buf_;
+ tty->read_raw_wait = NULL;
+
+ /* Init keycode-to-vt100 mapper state. */
+ tty->last_key_len = 0;
+ tty->last_key_offset = 0;
+ tty->last_utf16_high_surrogate = 0;
+ memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
+ } else {
+ /* TTY output specific fields. */
+ tty->flags |= UV_HANDLE_WRITABLE;
+
+ /* Init utf8-to-utf16 conversion state. */
+ tty->utf8_bytes_left = 0;
+ tty->utf8_codepoint = 0;
+
+ /* Initialize eol conversion state */
+ tty->previous_eol = 0;
+
+ /* Init ANSI parser state. */
+ tty->ansi_parser_state = ANSI_NORMAL;
+ }
+
+ return 0;
+}
+
+
+int uv_tty_set_mode(uv_tty_t* tty, int mode) {
+ DWORD flags;
+ unsigned char was_reading;
+ uv_alloc_cb alloc_cb;
+ uv_read_cb read_cb;
+ int err;
+
+ if (!(tty->flags & UV_HANDLE_TTY_READABLE)) {
+ return UV_EINVAL;
+ }
+
+ if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
+ return 0;
+ }
+
+ if (mode) {
+ /* Raw input */
+ flags = ENABLE_WINDOW_INPUT;
+ } else {
+ /* Line-buffered mode. */
+ flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ }
+
+ if (!SetConsoleMode(tty->handle, flags)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /* If currently reading, stop, and restart reading. */
+ if (tty->flags & UV_HANDLE_READING) {
+ was_reading = 1;
+ alloc_cb = tty->alloc_cb;
+ read_cb = tty->read_cb;
+
+ if (was_reading) {
+ err = uv_tty_read_stop(tty);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+ }
+ } else {
+ was_reading = 0;
+ }
+
+ /* Update flag. */
+ tty->flags &= ~UV_HANDLE_TTY_RAW;
+ tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
+
+ /* If we just stopped reading, restart. */
+ if (was_reading) {
+ err = uv_tty_read_start(tty, alloc_cb, read_cb);
+ if (err) {
+ return uv_translate_sys_error(err);
+ }
+ }
+
+ return 0;
+}
+
+
+int uv_is_tty(uv_file file) {
+ DWORD result;
+ return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0;
+}
+
+
+int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ if (!GetConsoleScreenBufferInfo(tty->handle, &info)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ EnterCriticalSection(&uv_tty_output_lock);
+ uv_tty_update_virtual_window(&info);
+ LeaveCriticalSection(&uv_tty_output_lock);
+
+ *width = uv_tty_virtual_width;
+ *height = uv_tty_virtual_height;
+
+ return 0;
+}
+
+
+static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
+ uv_loop_t* loop;
+ uv_tty_t* handle;
+ uv_req_t* req;
+
+ assert(data);
+ assert(!didTimeout);
+
+ req = (uv_req_t*) data;
+ handle = (uv_tty_t*) req->data;
+ loop = handle->loop;
+
+ UnregisterWait(handle->read_raw_wait);
+ handle->read_raw_wait = NULL;
+
+ SET_REQ_SUCCESS(req);
+ POST_COMPLETION_FOR_REQ(loop, req);
+}
+
+
+static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) {
+ uv_read_t* req;
+ BOOL r;
+
+ assert(handle->flags & UV_HANDLE_READING);
+ assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+ assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
+
+ handle->read_line_buffer = uv_null_buf_;
+
+ req = &handle->read_req;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ r = RegisterWaitForSingleObject(&handle->read_raw_wait,
+ handle->handle,
+ uv_tty_post_raw_read,
+ (void*) req,
+ INFINITE,
+ WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+ if (!r) {
+ handle->read_raw_wait = NULL;
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ }
+
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+}
+
+
+static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
+ uv_loop_t* loop;
+ uv_tty_t* handle;
+ uv_req_t* req;
+ DWORD bytes, read_bytes;
+
+ assert(data);
+
+ req = (uv_req_t*) data;
+ handle = (uv_tty_t*) req->data;
+ loop = handle->loop;
+
+ assert(handle->read_line_buffer.base != NULL);
+ assert(handle->read_line_buffer.len > 0);
+
+ /* ReadConsole can't handle big buffers. */
+ if (handle->read_line_buffer.len < 8192) {
+ bytes = handle->read_line_buffer.len;
+ } else {
+ bytes = 8192;
+ }
+
+ /* Todo: Unicode */
+ if (ReadConsoleA(handle->read_line_handle,
+ (void*) handle->read_line_buffer.base,
+ bytes,
+ &read_bytes,
+ NULL)) {
+ SET_REQ_SUCCESS(req);
+ req->overlapped.InternalHigh = read_bytes;
+ } else {
+ SET_REQ_ERROR(req, GetLastError());
+ }
+
+ POST_COMPLETION_FOR_REQ(loop, req);
+ return 0;
+}
+
+
+static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
+ uv_read_t* req;
+ BOOL r;
+
+ assert(handle->flags & UV_HANDLE_READING);
+ assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+ assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
+
+ req = &handle->read_req;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->read_line_buffer);
+ if (handle->read_line_buffer.len == 0) {
+ handle->read_cb((uv_stream_t*) handle,
+ UV_ENOBUFS,
+ &handle->read_line_buffer);
+ return;
+ }
+ assert(handle->read_line_buffer.base != NULL);
+
+ /* Duplicate the console handle, so if we want to cancel the read, we can */
+ /* just close this handle duplicate. */
+ if (handle->read_line_handle == NULL) {
+ HANDLE this_process = GetCurrentProcess();
+ r = DuplicateHandle(this_process,
+ handle->handle,
+ this_process,
+ &handle->read_line_handle,
+ 0,
+ 0,
+ DUPLICATE_SAME_ACCESS);
+ if (!r) {
+ handle->read_line_handle = NULL;
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ goto out;
+ }
+ }
+
+ r = QueueUserWorkItem(uv_tty_line_read_thread,
+ (void*) req,
+ WT_EXECUTELONGFUNCTION);
+ if (!r) {
+ SET_REQ_ERROR(req, GetLastError());
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ }
+
+ out:
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+}
+
+
+static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) {
+ if (handle->flags & UV_HANDLE_TTY_RAW) {
+ uv_tty_queue_read_raw(loop, handle);
+ } else {
+ uv_tty_queue_read_line(loop, handle);
+ }
+}
+
+
+static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl,
+ size_t* len) {
+#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \
+ case (vk): \
+ if (shift && ctrl) { \
+ *len = sizeof shift_ctrl_str; \
+ return "\033" shift_ctrl_str; \
+ } else if (shift) { \
+ *len = sizeof shift_str ; \
+ return "\033" shift_str; \
+ } else if (ctrl) { \
+ *len = sizeof ctrl_str; \
+ return "\033" ctrl_str; \
+ } else { \
+ *len = sizeof normal_str; \
+ return "\033" normal_str; \
+ }
+
+ switch (code) {
+ /* These mappings are the same as Cygwin's. Unmodified and alt-modified */
+ /* keypad keys comply with linux console, modifiers comply with xterm */
+ /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */
+ /* f6..f12 with and without modifiers comply with rxvt. */
+ VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~")
+ VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~")
+ VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B")
+ VK_CASE(VK_NEXT, "[6~", "[6;2~", "[6;5~", "[6;6~")
+ VK_CASE(VK_LEFT, "[D", "[1;2D", "[1;5D", "[1;6D")
+ VK_CASE(VK_CLEAR, "[G", "[1;2G", "[1;5G", "[1;6G")
+ VK_CASE(VK_RIGHT, "[C", "[1;2C", "[1;5C", "[1;6C")
+ VK_CASE(VK_UP, "[A", "[1;2A", "[1;5A", "[1;6A")
+ VK_CASE(VK_HOME, "[1~", "[1;2~", "[1;5~", "[1;6~")
+ VK_CASE(VK_PRIOR, "[5~", "[5;2~", "[5;5~", "[5;6~")
+ VK_CASE(VK_DELETE, "[3~", "[3;2~", "[3;5~", "[3;6~")
+ VK_CASE(VK_NUMPAD0, "[2~", "[2;2~", "[2;5~", "[2;6~")
+ VK_CASE(VK_NUMPAD1, "[4~", "[4;2~", "[4;5~", "[4;6~")
+ VK_CASE(VK_NUMPAD2, "[B", "[1;2B", "[1;5B", "[1;6B")
+ VK_CASE(VK_NUMPAD3, "[6~", "[6;2~", "[6;5~", "[6;6~")
+ VK_CASE(VK_NUMPAD4, "[D", "[1;2D", "[1;5D", "[1;6D")
+ VK_CASE(VK_NUMPAD5, "[G", "[1;2G", "[1;5G", "[1;6G")
+ VK_CASE(VK_NUMPAD6, "[C", "[1;2C", "[1;5C", "[1;6C")
+ VK_CASE(VK_NUMPAD7, "[A", "[1;2A", "[1;5A", "[1;6A")
+ VK_CASE(VK_NUMPAD8, "[1~", "[1;2~", "[1;5~", "[1;6~")
+ VK_CASE(VK_NUMPAD9, "[5~", "[5;2~", "[5;5~", "[5;6~")
+ VK_CASE(VK_DECIMAL, "[3~", "[3;2~", "[3;5~", "[3;6~")
+ VK_CASE(VK_F1, "[[A", "[23~", "[11^", "[23^" )
+ VK_CASE(VK_F2, "[[B", "[24~", "[12^", "[24^" )
+ VK_CASE(VK_F3, "[[C", "[25~", "[13^", "[25^" )
+ VK_CASE(VK_F4, "[[D", "[26~", "[14^", "[26^" )
+ VK_CASE(VK_F5, "[[E", "[28~", "[15^", "[28^" )
+ VK_CASE(VK_F6, "[17~", "[29~", "[17^", "[29^" )
+ VK_CASE(VK_F7, "[18~", "[31~", "[18^", "[31^" )
+ VK_CASE(VK_F8, "[19~", "[32~", "[19^", "[32^" )
+ VK_CASE(VK_F9, "[20~", "[33~", "[20^", "[33^" )
+ VK_CASE(VK_F10, "[21~", "[34~", "[21^", "[34^" )
+ VK_CASE(VK_F11, "[23~", "[23$", "[23^", "[23@" )
+ VK_CASE(VK_F12, "[24~", "[24$", "[24^", "[24@" )
+
+ default:
+ *len = 0;
+ return NULL;
+ }
+#undef VK_CASE
+}
+
+
+void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* req) {
+ /* Shortcut for handle->last_input_record.Event.KeyEvent. */
+#define KEV handle->last_input_record.Event.KeyEvent
+
+ DWORD records_left, records_read;
+ uv_buf_t buf;
+ off_t buf_used;
+
+ assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+ if (!(handle->flags & UV_HANDLE_READING) ||
+ !(handle->flags & UV_HANDLE_TTY_RAW)) {
+ goto out;
+ }
+
+ if (!REQ_SUCCESS(req)) {
+ /* An error occurred while waiting for the event. */
+ if ((handle->flags & UV_HANDLE_READING)) {
+ handle->flags &= ~UV_HANDLE_READING;
+ handle->read_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(GET_REQ_ERROR(req)),
+ &uv_null_buf_);
+ }
+ goto out;
+ }
+
+ /* Fetch the number of events */
+ if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb((uv_stream_t*)handle,
+ uv_translate_sys_error(GetLastError()),
+ &uv_null_buf_);
+ goto out;
+ }
+
+ /* Windows sends a lot of events that we're not interested in, so buf */
+ /* will be allocated on demand, when there's actually something to emit. */
+ buf = uv_null_buf_;
+ buf_used = 0;
+
+ while ((records_left > 0 || handle->last_key_len > 0) &&
+ (handle->flags & UV_HANDLE_READING)) {
+ if (handle->last_key_len == 0) {
+ /* Read the next input record */
+ if (!ReadConsoleInputW(handle->handle,
+ &handle->last_input_record,
+ 1,
+ &records_read)) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb((uv_stream_t*) handle,
+ uv_translate_sys_error(GetLastError()),
+ &buf);
+ goto out;
+ }
+ records_left--;
+
+ /* If the window was resized, recompute the virtual window size. This */
+ /* will trigger a SIGWINCH signal if the window size changed in an */
+ /* way that matters to libuv. */
+ if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ EnterCriticalSection(&uv_tty_output_lock);
+
+ if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
+ GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
+ uv_tty_update_virtual_window(&info);
+ }
+
+ LeaveCriticalSection(&uv_tty_output_lock);
+
+ continue;
+ }
+
+ /* Ignore other events that are not key or resize events. */
+ if (handle->last_input_record.EventType != KEY_EVENT) {
+ continue;
+ }
+
+ /* Ignore keyup events, unless the left alt key was held and a valid */
+ /* unicode character was emitted. */
+ if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
+ KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
+ continue;
+ }
+
+ /* Ignore keypresses to numpad number keys if the left alt is held */
+ /* because the user is composing a character, or windows simulating */
+ /* this. */
+ if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
+ !(KEV.dwControlKeyState & ENHANCED_KEY) &&
+ (KEV.wVirtualKeyCode == VK_INSERT ||
+ KEV.wVirtualKeyCode == VK_END ||
+ KEV.wVirtualKeyCode == VK_DOWN ||
+ KEV.wVirtualKeyCode == VK_NEXT ||
+ KEV.wVirtualKeyCode == VK_LEFT ||
+ KEV.wVirtualKeyCode == VK_CLEAR ||
+ KEV.wVirtualKeyCode == VK_RIGHT ||
+ KEV.wVirtualKeyCode == VK_HOME ||
+ KEV.wVirtualKeyCode == VK_UP ||
+ KEV.wVirtualKeyCode == VK_PRIOR ||
+ KEV.wVirtualKeyCode == VK_NUMPAD0 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD1 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD2 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD3 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD4 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD5 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD6 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD7 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD8 ||
+ KEV.wVirtualKeyCode == VK_NUMPAD9)) {
+ continue;
+ }
+
+ if (KEV.uChar.UnicodeChar != 0) {
+ int prefix_len, char_len;
+
+ /* Character key pressed */
+ if (KEV.uChar.UnicodeChar >= 0xD800 &&
+ KEV.uChar.UnicodeChar < 0xDC00) {
+ /* UTF-16 high surrogate */
+ handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
+ continue;
+ }
+
+ /* Prefix with \u033 if alt was held, but alt was not used as part */
+ /* a compose sequence. */
+ if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+ && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
+ RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
+ handle->last_key[0] = '\033';
+ prefix_len = 1;
+ } else {
+ prefix_len = 0;
+ }
+
+ if (KEV.uChar.UnicodeChar >= 0xDC00 &&
+ KEV.uChar.UnicodeChar < 0xE000) {
+ /* UTF-16 surrogate pair */
+ WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate,
+ KEV.uChar.UnicodeChar};
+ char_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16_buffer,
+ 2,
+ &handle->last_key[prefix_len],
+ sizeof handle->last_key,
+ NULL,
+ NULL);
+ } else {
+ /* Single UTF-16 character */
+ char_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ &KEV.uChar.UnicodeChar,
+ 1,
+ &handle->last_key[prefix_len],
+ sizeof handle->last_key,
+ NULL,
+ NULL);
+ }
+
+ /* Whatever happened, the last character wasn't a high surrogate. */
+ handle->last_utf16_high_surrogate = 0;
+
+ /* If the utf16 character(s) couldn't be converted something must */
+ /* be wrong. */
+ if (!char_len) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb((uv_stream_t*) handle,
+ uv_translate_sys_error(GetLastError()),
+ &buf);
+ goto out;
+ }
+
+ handle->last_key_len = (unsigned char) (prefix_len + char_len);
+ handle->last_key_offset = 0;
+ continue;
+
+ } else {
+ /* Function key pressed */
+ const char* vt100;
+ size_t prefix_len, vt100_len;
+
+ vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode,
+ !!(KEV.dwControlKeyState & SHIFT_PRESSED),
+ !!(KEV.dwControlKeyState & (
+ LEFT_CTRL_PRESSED |
+ RIGHT_CTRL_PRESSED)),
+ &vt100_len);
+
+ /* If we were unable to map to a vt100 sequence, just ignore. */
+ if (!vt100) {
+ continue;
+ }
+
+ /* Prefix with \x033 when the alt key was held. */
+ if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
+ handle->last_key[0] = '\033';
+ prefix_len = 1;
+ } else {
+ prefix_len = 0;
+ }
+
+ /* Copy the vt100 sequence to the handle buffer. */
+ assert(prefix_len + vt100_len < sizeof handle->last_key);
+ memcpy(&handle->last_key[prefix_len], vt100, vt100_len);
+
+ handle->last_key_len = (unsigned char) (prefix_len + vt100_len);
+ handle->last_key_offset = 0;
+ continue;
+ }
+ } else {
+ /* Copy any bytes left from the last keypress to the user buffer. */
+ if (handle->last_key_offset < handle->last_key_len) {
+ /* Allocate a buffer if needed */
+ if (buf_used == 0) {
+ handle->alloc_cb((uv_handle_t*) handle, 1024, &buf);
+ if (buf.len == 0) {
+ handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+ goto out;
+ }
+ assert(buf.base != NULL);
+ }
+
+ buf.base[buf_used++] = handle->last_key[handle->last_key_offset++];
+
+ /* If the buffer is full, emit it */
+ if (buf_used == buf.len) {
+ handle->read_cb((uv_stream_t*) handle, buf_used, &buf);
+ buf = uv_null_buf_;
+ buf_used = 0;
+ }
+
+ continue;
+ }
+
+ /* Apply dwRepeat from the last input record. */
+ if (--KEV.wRepeatCount > 0) {
+ handle->last_key_offset = 0;
+ continue;
+ }
+
+ handle->last_key_len = 0;
+ continue;
+ }
+ }
+
+ /* Send the buffer back to the user */
+ if (buf_used > 0) {
+ handle->read_cb((uv_stream_t*) handle, buf_used, &buf);
+ }
+
+ out:
+ /* Wait for more input events. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_tty_queue_read(loop, handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+
+#undef KEV
+}
+
+
+
+void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* req) {
+ uv_buf_t buf;
+
+ assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
+
+ buf = handle->read_line_buffer;
+
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
+ handle->read_line_buffer = uv_null_buf_;
+
+ if (!REQ_SUCCESS(req)) {
+ /* Read was not successful */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ handle->read_line_handle != NULL) {
+ /* Real error */
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb((uv_stream_t*) handle,
+ uv_translate_sys_error(GET_REQ_ERROR(req)),
+ &buf);
+ } else {
+ /* The read was cancelled, or whatever we don't care */
+ handle->read_cb((uv_stream_t*) handle, 0, &buf);
+ }
+
+ } else {
+ /* Read successful */
+ /* TODO: read unicode, convert to utf-8 */
+ DWORD bytes = req->overlapped.InternalHigh;
+ handle->read_cb((uv_stream_t*) handle, bytes, &buf);
+ }
+
+ /* Wait for more input events. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_tty_queue_read(loop, handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* req) {
+ assert(handle->type == UV_TTY);
+ assert(handle->flags & UV_HANDLE_TTY_READABLE);
+
+ /* If the read_line_buffer member is zero, it must have been an raw read. */
+ /* Otherwise it was a line-buffered read. */
+ /* FIXME: This is quite obscure. Use a flag or something. */
+ if (handle->read_line_buffer.len == 0) {
+ uv_process_tty_read_raw_req(loop, handle, req);
+ } else {
+ uv_process_tty_read_line_req(loop, handle, req);
+ }
+}
+
+
+int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
+ uv_loop_t* loop = handle->loop;
+
+ if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ handle->flags |= UV_HANDLE_READING;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+ handle->read_cb = read_cb;
+ handle->alloc_cb = alloc_cb;
+
+ /* If reading was stopped and then started again, there could still be a */
+ /* read request pending. */
+ if (handle->flags & UV_HANDLE_READ_PENDING) {
+ return 0;
+ }
+
+ /* Maybe the user stopped reading half-way while processing key events. */
+ /* Short-circuit if this could be the case. */
+ if (handle->last_key_len > 0) {
+ SET_REQ_SUCCESS(&handle->read_req);
+ uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
+ return 0;
+ }
+
+ uv_tty_queue_read(loop, handle);
+
+ return 0;
+}
+
+
+int uv_tty_read_stop(uv_tty_t* handle) {
+ handle->flags &= ~UV_HANDLE_READING;
+ DECREASE_ACTIVE_COUNT(handle->loop, handle);
+
+ /* Cancel raw read */
+ if ((handle->flags & UV_HANDLE_READ_PENDING) &&
+ (handle->flags & UV_HANDLE_TTY_RAW)) {
+ /* Write some bullshit event to force the console wait to return. */
+ INPUT_RECORD record;
+ DWORD written;
+ memset(&record, 0, sizeof record);
+ if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
+ return GetLastError();
+ }
+ }
+
+ /* Cancel line-buffered read */
+ if (handle->read_line_handle != NULL) {
+ /* Closing this handle will cancel the ReadConsole operation */
+ CloseHandle(handle->read_line_handle);
+ handle->read_line_handle = NULL;
+ }
+
+
+ return 0;
+}
+
+
+static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
+ int old_virtual_width = uv_tty_virtual_width;
+ int old_virtual_height = uv_tty_virtual_height;
+
+ uv_tty_virtual_width = info->dwSize.X;
+ uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
+
+ /* Recompute virtual window offset row. */
+ if (uv_tty_virtual_offset == -1) {
+ uv_tty_virtual_offset = info->dwCursorPosition.Y;
+ } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y -
+ uv_tty_virtual_height + 1) {
+ /* If suddenly find the cursor outside of the virtual window, it must */
+ /* have somehow scrolled. Update the virtual window offset. */
+ uv_tty_virtual_offset = info->dwCursorPosition.Y -
+ uv_tty_virtual_height + 1;
+ }
+ if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) {
+ uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height;
+ }
+ if (uv_tty_virtual_offset < 0) {
+ uv_tty_virtual_offset = 0;
+ }
+
+ /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */
+ /* if this was the first time the virtual window size was computed. */
+ if (old_virtual_width != -1 && old_virtual_height != -1 &&
+ (uv_tty_virtual_width != old_virtual_width ||
+ uv_tty_virtual_height != old_virtual_height)) {
+ uv__signal_dispatch(SIGWINCH);
+ }
+}
+
+
+static COORD uv_tty_make_real_coord(uv_tty_t* handle,
+ CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y,
+ unsigned char y_relative) {
+ COORD result;
+
+ uv_tty_update_virtual_window(info);
+
+ /* Adjust y position */
+ if (y_relative) {
+ y = info->dwCursorPosition.Y + y;
+ } else {
+ y = uv_tty_virtual_offset + y;
+ }
+ /* Clip y to virtual client rectangle */
+ if (y < uv_tty_virtual_offset) {
+ y = uv_tty_virtual_offset;
+ } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) {
+ y = uv_tty_virtual_offset + uv_tty_virtual_height - 1;
+ }
+
+ /* Adjust x */
+ if (x_relative) {
+ x = info->dwCursorPosition.X + x;
+ }
+ /* Clip x */
+ if (x < 0) {
+ x = 0;
+ } else if (x >= uv_tty_virtual_width) {
+ x = uv_tty_virtual_width - 1;
+ }
+
+ result.X = (unsigned short) x;
+ result.Y = (unsigned short) y;
+ return result;
+}
+
+
+static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length,
+ DWORD* error) {
+ DWORD written;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ if (!WriteConsoleW(handle->handle,
+ (void*) buffer,
+ length,
+ &written,
+ NULL)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative,
+ int y, unsigned char y_relative, DWORD* error) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ COORD pos;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ retry:
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ }
+
+ pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative);
+
+ if (!SetConsoleCursorPosition(handle->handle, pos)) {
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ /* The console may be resized - retry */
+ goto retry;
+ } else {
+ *error = GetLastError();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
+ const COORD origin = {0, 0};
+ const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ DWORD count, written;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ /* Reset original text attributes. */
+ if (!SetConsoleTextAttribute(handle->handle, char_attrs)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ /* Move the cursor position to (0, 0). */
+ if (!SetConsoleCursorPosition(handle->handle, origin)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ /* Clear the screen buffer. */
+ retry:
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ count = info.dwSize.X * info.dwSize.Y;
+
+ if (!(FillConsoleOutputCharacterW(handle->handle,
+ L'\x20',
+ count,
+ origin,
+ &written) &&
+ FillConsoleOutputAttribute(handle->handle,
+ char_attrs,
+ written,
+ origin,
+ &written))) {
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ /* The console may be resized - retry */
+ goto retry;
+ } else {
+ *error = GetLastError();
+ return -1;
+ }
+ }
+
+ /* Move the virtual window up to the top. */
+ uv_tty_virtual_offset = 0;
+ uv_tty_update_virtual_window(&info);
+
+ return 0;
+}
+
+
+static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
+ DWORD* error) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ COORD start, end;
+ DWORD count, written;
+
+ int x1, x2, y1, y2;
+ int x1r, x2r, y1r, y2r;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ if (dir == 0) {
+ /* Clear from current position */
+ x1 = 0;
+ x1r = 1;
+ } else {
+ /* Clear from column 0 */
+ x1 = 0;
+ x1r = 0;
+ }
+
+ if (dir == 1) {
+ /* Clear to current position */
+ x2 = 0;
+ x2r = 1;
+ } else {
+ /* Clear to end of row. We pretend the console is 65536 characters wide, */
+ /* uv_tty_make_real_coord will clip it to the actual console width. */
+ x2 = 0xffff;
+ x2r = 0;
+ }
+
+ if (!entire_screen) {
+ /* Stay on our own row */
+ y1 = y2 = 0;
+ y1r = y2r = 1;
+ } else {
+ /* Apply columns direction to row */
+ y1 = x1;
+ y1r = x1r;
+ y2 = x2;
+ y2r = x2r;
+ }
+
+ retry:
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r);
+ end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r);
+ count = (end.Y * info.dwSize.X + end.X) -
+ (start.Y * info.dwSize.X + start.X) + 1;
+
+ if (!(FillConsoleOutputCharacterW(handle->handle,
+ L'\x20',
+ count,
+ start,
+ &written) &&
+ FillConsoleOutputAttribute(handle->handle,
+ info.wAttributes,
+ written,
+ start,
+ &written))) {
+ if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ /* The console may be resized - retry */
+ goto retry;
+ } else {
+ *error = GetLastError();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
+ unsigned short argc = handle->ansi_csi_argc;
+ unsigned short* argv = handle->ansi_csi_argv;
+ int i;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ char fg_color = -1, bg_color = -1;
+ char fg_bright = -1, bg_bright = -1;
+
+ if (argc == 0) {
+ /* Reset mode */
+ fg_color = 7;
+ bg_color = 0;
+ fg_bright = 0;
+ bg_bright = 0;
+ }
+
+ for (i = 0; i < argc; i++) {
+ short arg = argv[i];
+
+ if (arg == 0) {
+ /* Reset mode */
+ fg_color = 7;
+ bg_color = 0;
+ fg_bright = 0;
+ bg_bright = 0;
+
+ } else if (arg == 1) {
+ /* Foreground bright on */
+ fg_bright = 1;
+
+ } else if (arg == 2) {
+ /* Both bright off */
+ fg_bright = 0;
+ bg_bright = 0;
+
+ } else if (arg == 5) {
+ /* Background bright on */
+ bg_bright = 1;
+
+ } else if (arg == 21 || arg == 22) {
+ /* Foreground bright off */
+ fg_bright = 0;
+
+ } else if (arg == 25) {
+ /* Background bright off */
+ bg_bright = 0;
+
+ } else if (arg >= 30 && arg <= 37) {
+ /* Set foreground color */
+ fg_color = arg - 30;
+
+ } else if (arg == 39) {
+ /* Default text color */
+ fg_color = 7;
+ fg_bright = 0;
+
+ } else if (arg >= 40 && arg <= 47) {
+ /* Set background color */
+ bg_color = arg - 40;
+
+ } else if (arg == 49) {
+ /* Default background color */
+ bg_color = 0;
+ bg_bright = 0;
+
+ } else if (arg >= 90 && arg <= 97) {
+ /* Set bold foreground color */
+ fg_bright = 1;
+ fg_color = arg - 90;
+
+ } else if (arg >= 100 && arg <= 107) {
+ /* Set bold background color */
+ bg_bright = 1;
+ bg_color = arg - 100;
+
+ }
+ }
+
+ if (fg_color == -1 && bg_color == -1 && fg_bright == -1 &&
+ bg_bright == -1) {
+ /* Nothing changed */
+ return 0;
+ }
+
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ if (fg_color != -1) {
+ info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
+ if (fg_color & 1) info.wAttributes |= FOREGROUND_RED;
+ if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN;
+ if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE;
+ }
+
+ if (fg_bright != -1) {
+ if (fg_bright) {
+ info.wAttributes |= FOREGROUND_INTENSITY;
+ } else {
+ info.wAttributes &= ~FOREGROUND_INTENSITY;
+ }
+ }
+
+ if (bg_color != -1) {
+ info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
+ if (bg_color & 1) info.wAttributes |= BACKGROUND_RED;
+ if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN;
+ if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE;
+ }
+
+ if (bg_bright != -1) {
+ if (bg_bright) {
+ info.wAttributes |= BACKGROUND_INTENSITY;
+ } else {
+ info.wAttributes &= ~BACKGROUND_INTENSITY;
+ }
+ }
+
+ if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes,
+ DWORD* error) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ uv_tty_update_virtual_window(&info);
+
+ handle->saved_position.X = info.dwCursorPosition.X;
+ handle->saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
+ handle->flags |= UV_HANDLE_TTY_SAVED_POSITION;
+
+ if (save_attributes) {
+ handle->saved_attributes = info.wAttributes &
+ (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
+ handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES;
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_restore_state(uv_tty_t* handle,
+ unsigned char restore_attributes, DWORD* error) {
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ WORD new_attributes;
+
+ if (*error != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) {
+ if (uv_tty_move_caret(handle,
+ handle->saved_position.X,
+ 0,
+ handle->saved_position.Y,
+ 0,
+ error) != 0) {
+ return -1;
+ }
+ }
+
+ if (restore_attributes &&
+ (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) {
+ if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+ *error = GetLastError();
+ return -1;
+ }
+
+ new_attributes = info.wAttributes;
+ new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
+ new_attributes |= handle->saved_attributes;
+
+ if (!SetConsoleTextAttribute(handle->handle, new_attributes)) {
+ *error = GetLastError();
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int uv_tty_write_bufs(uv_tty_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ DWORD* error) {
+ /* We can only write 8k characters at a time. Windows can't handle */
+ /* much more characters in a single console write anyway. */
+ WCHAR utf16_buf[8192];
+ DWORD utf16_buf_used = 0;
+ unsigned int i;
+
+#define FLUSH_TEXT() \
+ do { \
+ if (utf16_buf_used > 0) { \
+ uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \
+ utf16_buf_used = 0; \
+ } \
+ } while (0)
+
+ /* Cache for fast access */
+ unsigned char utf8_bytes_left = handle->utf8_bytes_left;
+ unsigned int utf8_codepoint = handle->utf8_codepoint;
+ unsigned char previous_eol = handle->previous_eol;
+ unsigned char ansi_parser_state = handle->ansi_parser_state;
+
+ /* Store the error here. If we encounter an error, stop trying to do i/o */
+ /* but keep parsing the buffer so we leave the parser in a consistent */
+ /* state. */
+ *error = ERROR_SUCCESS;
+
+ EnterCriticalSection(&uv_tty_output_lock);
+
+ for (i = 0; i < nbufs; i++) {
+ uv_buf_t buf = bufs[i];
+ unsigned int j;
+
+ for (j = 0; j < buf.len; j++) {
+ unsigned char c = buf.base[j];
+
+ /* Run the character through the utf8 decoder We happily accept non */
+ /* shortest form encodings and invalid code points - there's no real */
+ /* harm that can be done. */
+ if (utf8_bytes_left == 0) {
+ /* Read utf-8 start byte */
+ DWORD first_zero_bit;
+ unsigned char not_c = ~c;
+#ifdef _MSC_VER /* msvc */
+ if (_BitScanReverse(&first_zero_bit, not_c)) {
+#else /* assume gcc */
+ if (c != 0) {
+ first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c);
+#endif
+ if (first_zero_bit == 7) {
+ /* Ascii - pass right through */
+ utf8_codepoint = (unsigned int) c;
+
+ } else if (first_zero_bit <= 5) {
+ /* Multibyte sequence */
+ utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c;
+ utf8_bytes_left = (char) (6 - first_zero_bit);
+
+ } else {
+ /* Invalid continuation */
+ utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+ }
+
+ } else {
+ /* 0xff -- invalid */
+ utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+ }
+
+ } else if ((c & 0xc0) == 0x80) {
+ /* Valid continuation of utf-8 multibyte sequence */
+ utf8_bytes_left--;
+ utf8_codepoint <<= 6;
+ utf8_codepoint |= ((unsigned int) c & 0x3f);
+
+ } else {
+ /* Start byte where continuation was expected. */
+ utf8_bytes_left = 0;
+ utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+ /* Patch buf offset so this character will be parsed again as a */
+ /* start byte. */
+ j--;
+ }
+
+ /* Maybe we need to parse more bytes to find a character. */
+ if (utf8_bytes_left != 0) {
+ continue;
+ }
+
+ /* Parse vt100/ansi escape codes */
+ if (ansi_parser_state == ANSI_NORMAL) {
+ switch (utf8_codepoint) {
+ case '\033':
+ ansi_parser_state = ANSI_ESCAPE_SEEN;
+ continue;
+
+ case 0233:
+ ansi_parser_state = ANSI_CSI;
+ handle->ansi_csi_argc = 0;
+ continue;
+ }
+
+ } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) {
+ switch (utf8_codepoint) {
+ case '[':
+ ansi_parser_state = ANSI_CSI;
+ handle->ansi_csi_argc = 0;
+ continue;
+
+ case '^':
+ case '_':
+ case 'P':
+ case ']':
+ /* Not supported, but we'll have to parse until we see a stop */
+ /* code, e.g. ESC \ or BEL. */
+ ansi_parser_state = ANSI_ST_CONTROL;
+ continue;
+
+ case '\033':
+ /* Ignore double escape. */
+ continue;
+
+ case 'c':
+ /* Full console reset. */
+ FLUSH_TEXT();
+ uv_tty_reset(handle, error);
+ ansi_parser_state = ANSI_NORMAL;
+ continue;
+
+ case '7':
+ /* Save the cursor position and text attributes. */
+ FLUSH_TEXT();
+ uv_tty_save_state(handle, 1, error);
+ ansi_parser_state = ANSI_NORMAL;
+ continue;
+
+ case '8':
+ /* Restore the cursor position and text attributes */
+ FLUSH_TEXT();
+ uv_tty_restore_state(handle, 1, error);
+ ansi_parser_state = ANSI_NORMAL;
+ continue;
+
+ default:
+ if (utf8_codepoint >= '@' && utf8_codepoint <= '_') {
+ /* Single-char control. */
+ ansi_parser_state = ANSI_NORMAL;
+ continue;
+ } else {
+ /* Invalid - proceed as normal, */
+ ansi_parser_state = ANSI_NORMAL;
+ }
+ }
+
+ } else if (ansi_parser_state & ANSI_CSI) {
+ if (!(ansi_parser_state & ANSI_IGNORE)) {
+ if (utf8_codepoint >= '0' && utf8_codepoint <= '9') {
+ /* Parsing a numerical argument */
+
+ if (!(ansi_parser_state & ANSI_IN_ARG)) {
+ /* We were not currently parsing a number */
+
+ /* Check for too many arguments */
+ if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) {
+ ansi_parser_state |= ANSI_IGNORE;
+ continue;
+ }
+
+ ansi_parser_state |= ANSI_IN_ARG;
+ handle->ansi_csi_argc++;
+ handle->ansi_csi_argv[handle->ansi_csi_argc - 1] =
+ (unsigned short) utf8_codepoint - '0';
+ continue;
+ } else {
+ /* We were already parsing a number. Parse next digit. */
+ uint32_t value = 10 *
+ handle->ansi_csi_argv[handle->ansi_csi_argc - 1];
+
+ /* Check for overflow. */
+ if (value > UINT16_MAX) {
+ ansi_parser_state |= ANSI_IGNORE;
+ continue;
+ }
+
+ handle->ansi_csi_argv[handle->ansi_csi_argc - 1] =
+ (unsigned short) value + (utf8_codepoint - '0');
+ continue;
+ }
+
+ } else if (utf8_codepoint == ';') {
+ /* Denotes the end of an argument. */
+ if (ansi_parser_state & ANSI_IN_ARG) {
+ ansi_parser_state &= ~ANSI_IN_ARG;
+ continue;
+
+ } else {
+ /* If ANSI_IN_ARG is not set, add another argument and */
+ /* default it to 0. */
+ /* Check for too many arguments */
+ if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) {
+ ansi_parser_state |= ANSI_IGNORE;
+ continue;
+ }
+
+ handle->ansi_csi_argc++;
+ handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = 0;
+ continue;
+ }
+
+ } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
+ (handle->ansi_csi_argc > 0 || utf8_codepoint != '[')) {
+ int x, y, d;
+
+ /* Command byte */
+ switch (utf8_codepoint) {
+ case 'A':
+ /* cursor up */
+ FLUSH_TEXT();
+ y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ uv_tty_move_caret(handle, 0, 1, y, 1, error);
+ break;
+
+ case 'B':
+ /* cursor down */
+ FLUSH_TEXT();
+ y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ uv_tty_move_caret(handle, 0, 1, y, 1, error);
+ break;
+
+ case 'C':
+ /* cursor forward */
+ FLUSH_TEXT();
+ x = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ uv_tty_move_caret(handle, x, 1, 0, 1, error);
+ break;
+
+ case 'D':
+ /* cursor back */
+ FLUSH_TEXT();
+ x = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ uv_tty_move_caret(handle, x, 1, 0, 1, error);
+ break;
+
+ case 'E':
+ /* cursor next line */
+ FLUSH_TEXT();
+ y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1;
+ uv_tty_move_caret(handle, 0, 0, y, 1, error);
+ break;
+
+ case 'F':
+ /* cursor previous line */
+ FLUSH_TEXT();
+ y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1);
+ uv_tty_move_caret(handle, 0, 0, y, 1, error);
+ break;
+
+ case 'G':
+ /* cursor horizontal move absolute */
+ FLUSH_TEXT();
+ x = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
+ ? handle->ansi_csi_argv[0] - 1 : 0;
+ uv_tty_move_caret(handle, x, 0, 0, 1, error);
+ break;
+
+ case 'H':
+ case 'f':
+ /* cursor move absolute */
+ FLUSH_TEXT();
+ y = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
+ ? handle->ansi_csi_argv[0] - 1 : 0;
+ x = (handle->ansi_csi_argc >= 2 && handle->ansi_csi_argv[1])
+ ? handle->ansi_csi_argv[1] - 1 : 0;
+ uv_tty_move_caret(handle, x, 0, y, 0, error);
+ break;
+
+ case 'J':
+ /* Erase screen */
+ FLUSH_TEXT();
+ d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0;
+ if (d >= 0 && d <= 2) {
+ uv_tty_clear(handle, d, 1, error);
+ }
+ break;
+
+ case 'K':
+ /* Erase line */
+ FLUSH_TEXT();
+ d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0;
+ if (d >= 0 && d <= 2) {
+ uv_tty_clear(handle, d, 0, error);
+ }
+ break;
+
+ case 'm':
+ /* Set style */
+ FLUSH_TEXT();
+ uv_tty_set_style(handle, error);
+ break;
+
+ case 's':
+ /* Save the cursor position. */
+ FLUSH_TEXT();
+ uv_tty_save_state(handle, 0, error);
+ break;
+
+ case 'u':
+ /* Restore the cursor position */
+ FLUSH_TEXT();
+ uv_tty_restore_state(handle, 0, error);
+ break;
+ }
+
+ /* Sequence ended - go back to normal state. */
+ ansi_parser_state = ANSI_NORMAL;
+ continue;
+
+ } else {
+ /* We don't support commands that use private mode characters or */
+ /* intermediaries. Ignore the rest of the sequence. */
+ ansi_parser_state |= ANSI_IGNORE;
+ continue;
+ }
+ } else {
+ /* We're ignoring this command. Stop only on command character. */
+ if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
+ ansi_parser_state = ANSI_NORMAL;
+ }
+ continue;
+ }
+
+ } else if (ansi_parser_state & ANSI_ST_CONTROL) {
+ /* Unsupported control code */
+ /* Ignore everything until we see BEL or ESC \ */
+ if (ansi_parser_state & ANSI_IN_STRING) {
+ if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) {
+ if (utf8_codepoint == '"') {
+ ansi_parser_state &= ~ANSI_IN_STRING;
+ } else if (utf8_codepoint == '\\') {
+ ansi_parser_state |= ANSI_BACKSLASH_SEEN;
+ }
+ } else {
+ ansi_parser_state &= ~ANSI_BACKSLASH_SEEN;
+ }
+ } else {
+ if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' &&
+ (ansi_parser_state & ANSI_ESCAPE_SEEN))) {
+ /* End of sequence */
+ ansi_parser_state = ANSI_NORMAL;
+ } else if (utf8_codepoint == '\033') {
+ /* Escape character */
+ ansi_parser_state |= ANSI_ESCAPE_SEEN;
+ } else if (utf8_codepoint == '"') {
+ /* String starting */
+ ansi_parser_state |= ANSI_IN_STRING;
+ ansi_parser_state &= ~ANSI_ESCAPE_SEEN;
+ ansi_parser_state &= ~ANSI_BACKSLASH_SEEN;
+ } else {
+ ansi_parser_state &= ~ANSI_ESCAPE_SEEN;
+ }
+ }
+ continue;
+ } else {
+ /* Inconsistent state */
+ abort();
+ }
+
+ /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */
+ /* windows console doesn't really support UTF-16, so just emit the */
+ /* replacement character. */
+ if (utf8_codepoint > 0xffff) {
+ utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+ }
+
+ if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) {
+ /* EOL conversion - emit \r\n, when we see either \r or \n. */
+ /* If a \n immediately follows a \r or vice versa, ignore it. */
+ if (previous_eol == 0 || utf8_codepoint == previous_eol) {
+ /* If there's no room in the utf16 buf, flush it first. */
+ if (2 > ARRAY_SIZE(utf16_buf) - utf16_buf_used) {
+ uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error);
+ utf16_buf_used = 0;
+ }
+
+ utf16_buf[utf16_buf_used++] = L'\r';
+ utf16_buf[utf16_buf_used++] = L'\n';
+ previous_eol = (char) utf8_codepoint;
+ } else {
+ /* Ignore this newline, but don't ignore later ones. */
+ previous_eol = 0;
+ }
+
+ } else if (utf8_codepoint <= 0xffff) {
+ /* Encode character into utf-16 buffer. */
+
+ /* If there's no room in the utf16 buf, flush it first. */
+ if (1 > ARRAY_SIZE(utf16_buf) - utf16_buf_used) {
+ uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error);
+ utf16_buf_used = 0;
+ }
+
+ utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint;
+ previous_eol = 0;
+ }
+ }
+ }
+
+ /* Flush remaining characters */
+ FLUSH_TEXT();
+
+ /* Copy cached values back to struct. */
+ handle->utf8_bytes_left = utf8_bytes_left;
+ handle->utf8_codepoint = utf8_codepoint;
+ handle->previous_eol = previous_eol;
+ handle->ansi_parser_state = ansi_parser_state;
+
+ LeaveCriticalSection(&uv_tty_output_lock);
+
+ if (*error == STATUS_SUCCESS) {
+ return 0;
+ } else {
+ return -1;
+ }
+
+#undef FLUSH_TEXT
+}
+
+
+int uv_tty_write(uv_loop_t* loop,
+ uv_write_t* req,
+ uv_tty_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_write_cb cb) {
+ DWORD error;
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_WRITE;
+ req->handle = (uv_stream_t*) handle;
+ req->cb = cb;
+
+ handle->reqs_pending++;
+ handle->write_reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+
+ req->queued_bytes = 0;
+
+ if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) {
+ SET_REQ_SUCCESS(req);
+ } else {
+ SET_REQ_ERROR(req, error);
+ }
+
+ uv_insert_pending_req(loop, (uv_req_t*) req);
+
+ return 0;
+}
+
+
+void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_write_t* req) {
+ int err;
+
+ handle->write_queue_size -= req->queued_bytes;
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (req->cb) {
+ err = GET_REQ_ERROR(req);
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ handle->write_reqs_pending--;
+ if (handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+ uv_want_endgame(loop, (uv_handle_t*)handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_tty_close(uv_tty_t* handle) {
+ CloseHandle(handle->handle);
+
+ if (handle->flags & UV_HANDLE_READING)
+ uv_tty_read_stop(handle);
+
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+ uv__handle_closing(handle);
+
+ if (handle->reqs_pending == 0) {
+ uv_want_endgame(handle->loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
+ if (!(handle->flags && UV_HANDLE_TTY_READABLE) &&
+ handle->shutdown_req != NULL &&
+ handle->write_reqs_pending == 0) {
+ UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
+
+ /* TTY shutdown is really just a no-op */
+ if (handle->shutdown_req->cb) {
+ if (handle->flags & UV__HANDLE_CLOSING) {
+ handle->shutdown_req->cb(handle->shutdown_req, UV_ECANCELED);
+ } else {
+ handle->shutdown_req->cb(handle->shutdown_req, 0);
+ }
+ }
+
+ handle->shutdown_req = NULL;
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+ return;
+ }
+
+ if (handle->flags & UV__HANDLE_CLOSING &&
+ handle->reqs_pending == 0) {
+ /* The console handle duplicate used for line reading should be destroyed */
+ /* by uv_tty_read_stop. */
+ assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
+ handle->read_line_handle == NULL);
+
+ /* The wait handle used for raw reading should be unregistered when the */
+ /* wait callback runs. */
+ assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
+ handle->read_raw_wait == NULL);
+
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ uv__handle_close(handle);
+ }
+}
+
+
+/* TODO: remove me */
+void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_req_t* raw_req) {
+ abort();
+}
+
+
+/* TODO: remove me */
+void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
+ uv_connect_t* req) {
+ abort();
+}
+
+
+int uv_tty_reset_mode(void) {
+ /* Not necessary to do anything. */
+ return 0;
+}
diff --git a/third-party/libuv/src/win/udp.c b/third-party/libuv/src/win/udp.c
new file mode 100644
index 0000000000..31812e4642
--- /dev/null
+++ b/third-party/libuv/src/win/udp.c
@@ -0,0 +1,749 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+/*
+ * Threshold of active udp streams for which to preallocate udp read buffers.
+ */
+const unsigned int uv_active_udp_streams_threshold = 0;
+
+/* A zero-size buffer for use by uv_udp_read */
+static char uv_zero_[] = "";
+
+int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
+ int* namelen) {
+ int result;
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ return UV_EINVAL;
+ }
+
+ result = getsockname(handle->socket, name, namelen);
+ if (result != 0) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
+ int family) {
+ DWORD yes = 1;
+ WSAPROTOCOL_INFOW info;
+ int opt_len;
+
+ assert(handle->socket == INVALID_SOCKET);
+
+ /* Set SO_REUSEADDR on the socket. */
+ if (setsockopt(socket,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (char*) &yes,
+ sizeof yes) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+
+ /* Set the socket to nonblocking mode */
+ if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+
+ /* Make the socket non-inheritable */
+ if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
+ return GetLastError();
+ }
+
+ /* Associate it with the I/O completion port. */
+ /* Use uv_handle_t pointer as completion key. */
+ if (CreateIoCompletionPort((HANDLE)socket,
+ loop->iocp,
+ (ULONG_PTR)socket,
+ 0) == NULL) {
+ return GetLastError();
+ }
+
+ if (pSetFileCompletionNotificationModes) {
+ /* All know windowses that support SetFileCompletionNotificationModes */
+ /* have a bug that makes it impossible to use this function in */
+ /* conjunction with datagram sockets. We can work around that but only */
+ /* if the user is using the default UDP driver (AFD) and has no other */
+ /* LSPs stacked on top. Here we check whether that is the case. */
+ opt_len = (int) sizeof info;
+ if (getsockopt(socket,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &info,
+ &opt_len) == SOCKET_ERROR) {
+ return GetLastError();
+ }
+
+ if (info.ProtocolChain.ChainLen == 1) {
+ if (pSetFileCompletionNotificationModes((HANDLE)socket,
+ FILE_SKIP_SET_EVENT_ON_HANDLE |
+ FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
+ handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
+ handle->func_wsarecv = uv_wsarecv_workaround;
+ handle->func_wsarecvfrom = uv_wsarecvfrom_workaround;
+ } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+ return GetLastError();
+ }
+ }
+ }
+
+ handle->socket = socket;
+
+ if (family == AF_INET6) {
+ handle->flags |= UV_HANDLE_IPV6;
+ } else {
+ assert(!(handle->flags & UV_HANDLE_IPV6));
+ }
+
+ return 0;
+}
+
+
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
+
+ handle->socket = INVALID_SOCKET;
+ handle->reqs_pending = 0;
+ handle->activecnt = 0;
+ handle->func_wsarecv = WSARecv;
+ handle->func_wsarecvfrom = WSARecvFrom;
+
+ uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
+ handle->recv_req.type = UV_UDP_RECV;
+ handle->recv_req.data = handle;
+
+ return 0;
+}
+
+
+void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
+ uv_udp_recv_stop(handle);
+ closesocket(handle->socket);
+
+ uv__handle_closing(handle);
+
+ if (handle->reqs_pending == 0) {
+ uv_want_endgame(loop, (uv_handle_t*) handle);
+ }
+}
+
+
+void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
+ if (handle->flags & UV__HANDLE_CLOSING &&
+ handle->reqs_pending == 0) {
+ assert(!(handle->flags & UV_HANDLE_CLOSED));
+ uv__handle_close(handle);
+ }
+}
+
+
+static int uv_udp_try_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ int r;
+ int err;
+ DWORD no = 0;
+
+ if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) {
+ /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if (handle->socket == INVALID_SOCKET) {
+ SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0);
+ if (sock == INVALID_SOCKET) {
+ return WSAGetLastError();
+ }
+
+ err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family);
+ if (err) {
+ closesocket(sock);
+ return err;
+ }
+
+ if (addr->sa_family == AF_INET6)
+ handle->flags |= UV_HANDLE_IPV6;
+ }
+
+ if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
+ /* On windows IPV6ONLY is on by default. */
+ /* If the user doesn't specify it libuv turns it off. */
+
+ /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+ /* available, or when run on XP/2003 which have no support for dualstack */
+ /* sockets. For now we're silently ignoring the error. */
+ setsockopt(handle->socket,
+ IPPROTO_IPV6,
+ IPV6_V6ONLY,
+ (char*) &no,
+ sizeof no);
+ }
+
+ r = bind(handle->socket, addr, addrlen);
+ if (r == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+
+ handle->flags |= UV_HANDLE_BOUND;
+
+ return 0;
+}
+
+
+static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
+ uv_req_t* req;
+ uv_buf_t buf;
+ DWORD bytes, flags;
+ int result;
+
+ assert(handle->flags & UV_HANDLE_READING);
+ assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+ req = &handle->recv_req;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ /*
+ * Preallocate a read buffer if the number of active streams is below
+ * the threshold.
+ */
+ if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
+ handle->flags &= ~UV_HANDLE_ZERO_READ;
+
+ handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer);
+ if (handle->recv_buffer.len == 0) {
+ handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0);
+ return;
+ }
+ assert(handle->recv_buffer.base != NULL);
+
+ buf = handle->recv_buffer;
+ memset(&handle->recv_from, 0, sizeof handle->recv_from);
+ handle->recv_from_len = sizeof handle->recv_from;
+ flags = 0;
+
+ result = handle->func_wsarecvfrom(handle->socket,
+ (WSABUF*) &buf,
+ 1,
+ &bytes,
+ &flags,
+ (struct sockaddr*) &handle->recv_from,
+ &handle->recv_from_len,
+ &req->overlapped,
+ NULL);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+ /* Process the req without IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ req->overlapped.InternalHigh = bytes;
+ handle->reqs_pending++;
+ uv_insert_pending_req(loop, req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+ /* The req will be processed with IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+ } else {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, req);
+ handle->reqs_pending++;
+ }
+
+ } else {
+ handle->flags |= UV_HANDLE_ZERO_READ;
+
+ buf.base = (char*) uv_zero_;
+ buf.len = 0;
+ flags = MSG_PEEK;
+
+ result = handle->func_wsarecv(handle->socket,
+ (WSABUF*) &buf,
+ 1,
+ &bytes,
+ &flags,
+ &req->overlapped,
+ NULL);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+ /* Process the req without IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ req->overlapped.InternalHigh = bytes;
+ handle->reqs_pending++;
+ uv_insert_pending_req(loop, req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+ /* The req will be processed with IOCP. */
+ handle->flags |= UV_HANDLE_READ_PENDING;
+ handle->reqs_pending++;
+ } else {
+ /* Make this req pending reporting an error. */
+ SET_REQ_ERROR(req, WSAGetLastError());
+ uv_insert_pending_req(loop, req);
+ handle->reqs_pending++;
+ }
+ }
+}
+
+
+int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+ uv_udp_recv_cb recv_cb) {
+ uv_loop_t* loop = handle->loop;
+ int err;
+
+ if (handle->flags & UV_HANDLE_READING) {
+ return WSAEALREADY;
+ }
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ err = uv_udp_try_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip4_any_,
+ sizeof(uv_addr_ip4_any_),
+ 0);
+ if (err)
+ return err;
+ }
+
+ handle->flags |= UV_HANDLE_READING;
+ INCREASE_ACTIVE_COUNT(loop, handle);
+ loop->active_udp_streams++;
+
+ handle->recv_cb = recv_cb;
+ handle->alloc_cb = alloc_cb;
+
+ /* If reading was stopped and then started again, there could still be a */
+ /* recv request pending. */
+ if (!(handle->flags & UV_HANDLE_READ_PENDING))
+ uv_udp_queue_recv(loop, handle);
+
+ return 0;
+}
+
+
+int uv__udp_recv_stop(uv_udp_t* handle) {
+ if (handle->flags & UV_HANDLE_READING) {
+ handle->flags &= ~UV_HANDLE_READING;
+ handle->loop->active_udp_streams--;
+ DECREASE_ACTIVE_COUNT(loop, handle);
+ }
+
+ return 0;
+}
+
+
+static int uv__send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_udp_send_cb cb) {
+ uv_loop_t* loop = handle->loop;
+ DWORD result, bytes;
+
+ uv_req_init(loop, (uv_req_t*) req);
+ req->type = UV_UDP_SEND;
+ req->handle = handle;
+ req->cb = cb;
+ memset(&req->overlapped, 0, sizeof(req->overlapped));
+
+ result = WSASendTo(handle->socket,
+ (WSABUF*)bufs,
+ nbufs,
+ &bytes,
+ 0,
+ addr,
+ addrlen,
+ &req->overlapped,
+ NULL);
+
+ if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+ /* Request completed immediately. */
+ req->queued_bytes = 0;
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ uv_insert_pending_req(loop, (uv_req_t*)req);
+ } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+ /* Request queued by the kernel. */
+ req->queued_bytes = uv_count_bufs(bufs, nbufs);
+ handle->reqs_pending++;
+ REGISTER_HANDLE_REQ(loop, handle, req);
+ } else {
+ /* Send failed due to an error. */
+ return WSAGetLastError();
+ }
+
+ return 0;
+}
+
+
+void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
+ uv_req_t* req) {
+ uv_buf_t buf;
+ int partial;
+
+ assert(handle->type == UV_UDP);
+
+ handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+ if (!REQ_SUCCESS(req)) {
+ DWORD err = GET_REQ_SOCK_ERROR(req);
+ if (err == WSAEMSGSIZE) {
+ /* Not a real error, it just indicates that the received packet */
+ /* was bigger than the receive buffer. */
+ } else if (err == WSAECONNRESET || err == WSAENETRESET) {
+ /* A previous sendto operation failed; ignore this error. If */
+ /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */
+ /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */
+ /* immediately queue a new receive. */
+ if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+ goto done;
+ }
+ } else {
+ /* A real error occurred. Report the error to the user only if we're */
+ /* currently reading. */
+ if (handle->flags & UV_HANDLE_READING) {
+ uv_udp_recv_stop(handle);
+ buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
+ uv_buf_init(NULL, 0) : handle->recv_buffer;
+ handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
+ }
+ goto done;
+ }
+ }
+
+ if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+ /* Successful read */
+ partial = !REQ_SUCCESS(req);
+ handle->recv_cb(handle,
+ req->overlapped.InternalHigh,
+ &handle->recv_buffer,
+ (const struct sockaddr*) &handle->recv_from,
+ partial ? UV_UDP_PARTIAL : 0);
+ } else if (handle->flags & UV_HANDLE_READING) {
+ DWORD bytes, err, flags;
+ struct sockaddr_storage from;
+ int from_len;
+
+ /* Do a nonblocking receive */
+ /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
+ handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
+ if (buf.len == 0) {
+ handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
+ goto done;
+ }
+ assert(buf.base != NULL);
+
+ memset(&from, 0, sizeof from);
+ from_len = sizeof from;
+
+ flags = 0;
+
+ if (WSARecvFrom(handle->socket,
+ (WSABUF*)&buf,
+ 1,
+ &bytes,
+ &flags,
+ (struct sockaddr*) &from,
+ &from_len,
+ NULL,
+ NULL) != SOCKET_ERROR) {
+
+ /* Message received */
+ handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0);
+ } else {
+ err = WSAGetLastError();
+ if (err == WSAEMSGSIZE) {
+ /* Message truncated */
+ handle->recv_cb(handle,
+ bytes,
+ &buf,
+ (const struct sockaddr*) &from,
+ UV_UDP_PARTIAL);
+ } else if (err == WSAEWOULDBLOCK) {
+ /* Kernel buffer empty */
+ handle->recv_cb(handle, 0, &buf, NULL, 0);
+ } else if (err != WSAECONNRESET && err != WSAENETRESET) {
+ /* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */
+ /* just indicates that a previous sendto operation failed. */
+ uv_udp_recv_stop(handle);
+ handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
+ }
+ }
+ }
+
+done:
+ /* Post another read if still reading and not closing. */
+ if ((handle->flags & UV_HANDLE_READING) &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
+ uv_udp_queue_recv(loop, handle);
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
+ uv_udp_send_t* req) {
+ int err;
+
+ assert(handle->type == UV_UDP);
+
+ UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+ if (req->cb) {
+ err = 0;
+ if (!REQ_SUCCESS(req)) {
+ err = GET_REQ_SOCK_ERROR(req);
+ }
+ req->cb(req, uv_translate_sys_error(err));
+ }
+
+ DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
+ const char* interface_addr, uv_membership membership) {
+ int err;
+ int optname;
+ struct ip_mreq mreq;
+
+ /* If the socket is unbound, bind to inaddr_any. */
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ err = uv_udp_try_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip4_any_,
+ sizeof(uv_addr_ip4_any_),
+ 0);
+ if (err)
+ return uv_translate_sys_error(err);
+ }
+
+ if (handle->flags & UV_HANDLE_IPV6) {
+ return UV_ENOSYS;
+ }
+
+ memset(&mreq, 0, sizeof mreq);
+
+ if (interface_addr) {
+ mreq.imr_interface.s_addr = inet_addr(interface_addr);
+ } else {
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ }
+
+ mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
+
+ switch (membership) {
+ case UV_JOIN_GROUP:
+ optname = IP_ADD_MEMBERSHIP;
+ break;
+ case UV_LEAVE_GROUP:
+ optname = IP_DROP_MEMBERSHIP;
+ break;
+ default:
+ return UV_EINVAL;
+ }
+
+ if (setsockopt(handle->socket,
+ IPPROTO_IP,
+ optname,
+ (char*) &mreq,
+ sizeof mreq) == SOCKET_ERROR) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
+ BOOL optval = (BOOL) value;
+ int err;
+
+ /* If the socket is unbound, bind to inaddr_any. */
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ err = uv_udp_try_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip4_any_,
+ sizeof(uv_addr_ip4_any_),
+ 0);
+ if (err)
+ return uv_translate_sys_error(err);
+ }
+
+ if (setsockopt(handle->socket,
+ SOL_SOCKET,
+ SO_BROADCAST,
+ (char*) &optval,
+ sizeof optval)) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+ WSAPROTOCOL_INFOW protocol_info;
+ int opt_len;
+ int err;
+
+ /* Detect the address family of the socket. */
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(sock,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ err = uv_udp_set_socket(handle->loop,
+ handle,
+ sock,
+ protocol_info.iAddressFamily);
+ return uv_translate_sys_error(err);
+}
+
+
+#define SOCKOPT_SETTER(name, option4, option6, validate) \
+ int uv_udp_set_##name(uv_udp_t* handle, int value) { \
+ DWORD optval = (DWORD) value; \
+ int err; \
+ \
+ if (!(validate(value))) { \
+ return UV_EINVAL; \
+ } \
+ \
+ /* If the socket is unbound, bind to inaddr_any. */ \
+ if (!(handle->flags & UV_HANDLE_BOUND)) { \
+ err = uv_udp_try_bind(handle, \
+ (const struct sockaddr*) &uv_addr_ip4_any_, \
+ sizeof(uv_addr_ip4_any_), \
+ 0); \
+ if (err) \
+ return uv_translate_sys_error(err); \
+ } \
+ \
+ if (!(handle->flags & UV_HANDLE_IPV6)) { \
+ /* Set IPv4 socket option */ \
+ if (setsockopt(handle->socket, \
+ IPPROTO_IP, \
+ option4, \
+ (char*) &optval, \
+ sizeof optval)) { \
+ return uv_translate_sys_error(WSAGetLastError()); \
+ } \
+ } else { \
+ /* Set IPv6 socket option */ \
+ if (setsockopt(handle->socket, \
+ IPPROTO_IPV6, \
+ option6, \
+ (char*) &optval, \
+ sizeof optval)) { \
+ return uv_translate_sys_error(WSAGetLastError()); \
+ } \
+ } \
+ return 0; \
+ }
+
+#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255)
+#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255)
+#define VALIDATE_MULTICAST_LOOP(value) (1)
+
+SOCKOPT_SETTER(ttl,
+ IP_TTL,
+ IPV6_HOPLIMIT,
+ VALIDATE_TTL)
+SOCKOPT_SETTER(multicast_ttl,
+ IP_MULTICAST_TTL,
+ IPV6_MULTICAST_HOPS,
+ VALIDATE_MULTICAST_TTL)
+SOCKOPT_SETTER(multicast_loop,
+ IP_MULTICAST_LOOP,
+ IPV6_MULTICAST_LOOP,
+ VALIDATE_MULTICAST_LOOP)
+
+#undef SOCKOPT_SETTER
+#undef VALIDATE_TTL
+#undef VALIDATE_MULTICAST_TTL
+#undef VALIDATE_MULTICAST_LOOP
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__udp_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
+ int err;
+
+ err = uv_udp_try_bind(handle, addr, addrlen, flags);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__udp_send(uv_udp_send_t* req,
+ uv_udp_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ uv_udp_send_cb send_cb) {
+ const struct sockaddr* bind_addr;
+ int err;
+
+ if (!(handle->flags & UV_HANDLE_BOUND)) {
+ if (addrlen == sizeof(uv_addr_ip4_any_)) {
+ bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
+ } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
+ bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
+ } else {
+ abort();
+ }
+ err = uv_udp_try_bind(handle, bind_addr, addrlen, 0);
+ if (err)
+ return uv_translate_sys_error(err);
+ }
+
+ err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ return 0;
+}
diff --git a/third-party/libuv/src/win/util.c b/third-party/libuv/src/win/util.c
new file mode 100644
index 0000000000..266b881640
--- /dev/null
+++ b/third-party/libuv/src/win/util.c
@@ -0,0 +1,990 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <direct.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <wchar.h>
+
+#include "uv.h"
+#include "internal.h"
+
+#include <winsock2.h>
+#include <winperf.h>
+#include <iphlpapi.h>
+#include <psapi.h>
+#include <tlhelp32.h>
+
+
+/*
+ * Max title length; the only thing MSDN tells us about the maximum length
+ * of the console title is that it is smaller than 64K. However in practice
+ * it is much smaller, and there is no way to figure out what the exact length
+ * of the title is or can be, at least not on XP. To make it even more
+ * annoying, GetConsoleTitle failes when the buffer to be read into is bigger
+ * than the actual maximum length. So we make a conservative guess here;
+ * just don't put the novel you're writing in the title, unless the plot
+ * survives truncation.
+ */
+#define MAX_TITLE_LENGTH 8192
+
+/* The number of nanoseconds in one second. */
+#undef NANOSEC
+#define NANOSEC 1000000000
+
+
+/* Cached copy of the process title, plus a mutex guarding it. */
+static char *process_title;
+static CRITICAL_SECTION process_title_lock;
+
+/* Frequency (ticks per nanosecond) of the high-resolution clock. */
+static double hrtime_frequency_ = 0;
+
+
+/*
+ * One-time intialization code for functionality defined in util.c.
+ */
+void uv__util_init() {
+ LARGE_INTEGER perf_frequency;
+
+ /* Initialize process title access mutex. */
+ InitializeCriticalSection(&process_title_lock);
+
+ /* Retrieve high-resolution timer frequency. */
+ if (QueryPerformanceFrequency(&perf_frequency))
+ hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
+ else
+ hrtime_frequency_= 0;
+}
+
+
+int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
+ char* utf8Buffer, size_t utf8Size) {
+ return WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16Buffer,
+ utf16Size,
+ utf8Buffer,
+ utf8Size,
+ NULL,
+ NULL);
+}
+
+
+int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
+ size_t utf16Size) {
+ return MultiByteToWideChar(CP_UTF8,
+ 0,
+ utf8Buffer,
+ -1,
+ utf16Buffer,
+ utf16Size);
+}
+
+
+int uv_exepath(char* buffer, size_t* size_ptr) {
+ int utf8_len, utf16_buffer_len, utf16_len;
+ WCHAR* utf16_buffer;
+ int err;
+
+ if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
+ return UV_EINVAL;
+ }
+
+ if (*size_ptr > 32768) {
+ /* Windows paths can never be longer than this. */
+ utf16_buffer_len = 32768;
+ } else {
+ utf16_buffer_len = (int) *size_ptr;
+ }
+
+ utf16_buffer = (WCHAR*) malloc(sizeof(WCHAR) * utf16_buffer_len);
+ if (!utf16_buffer) {
+ return UV_ENOMEM;
+ }
+
+ /* Get the path as UTF-16. */
+ utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
+ if (utf16_len <= 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ /* utf16_len contains the length, *not* including the terminating null. */
+ utf16_buffer[utf16_len] = L'\0';
+
+ /* Convert to UTF-8 */
+ utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16_buffer,
+ -1,
+ buffer,
+ *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
+ NULL,
+ NULL);
+ if (utf8_len == 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ free(utf16_buffer);
+
+ /* utf8_len *does* include the terminating null at this point, but the */
+ /* returned size shouldn't. */
+ *size_ptr = utf8_len - 1;
+ return 0;
+
+ error:
+ free(utf16_buffer);
+ return uv_translate_sys_error(err);
+}
+
+
+int uv_cwd(char* buffer, size_t size) {
+ DWORD utf16_len;
+ WCHAR utf16_buffer[MAX_PATH];
+ int r;
+
+ if (buffer == NULL || size == 0) {
+ return UV_EINVAL;
+ }
+
+ utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+ if (utf16_len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (utf16_len > MAX_PATH) {
+ /* This should be impossible; however the CRT has a code path to deal */
+ /* with this scenario, so I added a check anyway. */
+ return UV_EIO;
+ }
+
+ /* utf16_len contains the length, *not* including the terminating null. */
+ utf16_buffer[utf16_len] = L'\0';
+
+ /* The returned directory should not have a trailing slash, unless it */
+ /* points at a drive root, like c:\. Remove it if needed.*/
+ if (utf16_buffer[utf16_len - 1] == L'\\' &&
+ !(utf16_len == 3 && utf16_buffer[1] == L':')) {
+ utf16_len--;
+ utf16_buffer[utf16_len] = L'\0';
+ }
+
+ /* Convert to UTF-8 */
+ r = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16_buffer,
+ -1,
+ buffer,
+ size > INT_MAX ? INT_MAX : (int) size,
+ NULL,
+ NULL);
+ if (r == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv_chdir(const char* dir) {
+ WCHAR utf16_buffer[MAX_PATH];
+ size_t utf16_len;
+ WCHAR drive_letter, env_var[4];
+
+ if (dir == NULL) {
+ return UV_EINVAL;
+ }
+
+ if (MultiByteToWideChar(CP_UTF8,
+ 0,
+ dir,
+ -1,
+ utf16_buffer,
+ MAX_PATH) == 0) {
+ DWORD error = GetLastError();
+ /* The maximum length of the current working directory is 260 chars, */
+ /* including terminating null. If it doesn't fit, the path name must be */
+ /* too long. */
+ if (error == ERROR_INSUFFICIENT_BUFFER) {
+ return UV_ENAMETOOLONG;
+ } else {
+ return uv_translate_sys_error(error);
+ }
+ }
+
+ if (!SetCurrentDirectoryW(utf16_buffer)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ /* Windows stores the drive-local path in an "hidden" environment variable, */
+ /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */
+ /* update this, so we'll have to do it. */
+ utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+ if (utf16_len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (utf16_len > MAX_PATH) {
+ return UV_EIO;
+ }
+
+ /* The returned directory should not have a trailing slash, unless it */
+ /* points at a drive root, like c:\. Remove it if needed. */
+ if (utf16_buffer[utf16_len - 1] == L'\\' &&
+ !(utf16_len == 3 && utf16_buffer[1] == L':')) {
+ utf16_len--;
+ utf16_buffer[utf16_len] = L'\0';
+ }
+
+ if (utf16_len < 2 || utf16_buffer[1] != L':') {
+ /* Doesn't look like a drive letter could be there - probably an UNC */
+ /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */
+ drive_letter = 0;
+ } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
+ drive_letter = utf16_buffer[0];
+ } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') {
+ /* Convert to uppercase. */
+ drive_letter = utf16_buffer[0] - L'a' + L'A';
+ } else {
+ /* Not valid. */
+ drive_letter = 0;
+ }
+
+ if (drive_letter != 0) {
+ /* Construct the environment variable name and set it. */
+ env_var[0] = L'=';
+ env_var[1] = drive_letter;
+ env_var[2] = L':';
+ env_var[3] = L'\0';
+
+ if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
+ return uv_translate_sys_error(GetLastError());
+ }
+ }
+
+ return 0;
+}
+
+
+void uv_loadavg(double avg[3]) {
+ /* Can't be implemented */
+ avg[0] = avg[1] = avg[2] = 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ MEMORYSTATUSEX memory_status;
+ memory_status.dwLength = sizeof(memory_status);
+
+ if(!GlobalMemoryStatusEx(&memory_status))
+ {
+ return -1;
+ }
+
+ return (uint64_t)memory_status.ullAvailPhys;
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ MEMORYSTATUSEX memory_status;
+ memory_status.dwLength = sizeof(memory_status);
+
+ if(!GlobalMemoryStatusEx(&memory_status))
+ {
+ return -1;
+ }
+
+ return (uint64_t)memory_status.ullTotalPhys;
+}
+
+
+int uv_parent_pid() {
+ int parent_pid = -1;
+ HANDLE handle;
+ PROCESSENTRY32 pe;
+ int current_pid = GetCurrentProcessId();
+
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+
+ if (Process32First(handle, &pe)) {
+ do {
+ if (pe.th32ProcessID == current_pid) {
+ parent_pid = pe.th32ParentProcessID;
+ break;
+ }
+ } while( Process32Next(handle, &pe));
+ }
+
+ CloseHandle(handle);
+ return parent_pid;
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+ return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+ int err;
+ int length;
+ WCHAR* title_w = NULL;
+
+ uv__once_init();
+
+ /* Find out how big the buffer for the wide-char title must be */
+ length = uv_utf8_to_utf16(title, NULL, 0);
+ if (!length) {
+ err = GetLastError();
+ goto done;
+ }
+
+ /* Convert to wide-char string */
+ title_w = (WCHAR*)malloc(sizeof(WCHAR) * length);
+ if (!title_w) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ length = uv_utf8_to_utf16(title, title_w, length);
+ if (!length) {
+ err = GetLastError();
+ goto done;
+ };
+
+ /* If the title must be truncated insert a \0 terminator there */
+ if (length > MAX_TITLE_LENGTH) {
+ title_w[MAX_TITLE_LENGTH - 1] = L'\0';
+ }
+
+ if (!SetConsoleTitleW(title_w)) {
+ err = GetLastError();
+ goto done;
+ }
+
+ EnterCriticalSection(&process_title_lock);
+ free(process_title);
+ process_title = strdup(title);
+ LeaveCriticalSection(&process_title_lock);
+
+ err = 0;
+
+done:
+ free(title_w);
+ return uv_translate_sys_error(err);
+}
+
+
+static int uv__get_process_title() {
+ WCHAR title_w[MAX_TITLE_LENGTH];
+ int length;
+
+ if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
+ return -1;
+ }
+
+ /* Find out what the size of the buffer is that we need */
+ length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
+ if (!length) {
+ return -1;
+ }
+
+ assert(!process_title);
+ process_title = (char*)malloc(length);
+ if (!process_title) {
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ }
+
+ /* Do utf16 -> utf8 conversion here */
+ if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
+ free(process_title);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+ uv__once_init();
+
+ EnterCriticalSection(&process_title_lock);
+ /*
+ * If the process_title was never read before nor explicitly set,
+ * we must query it with getConsoleTitleW
+ */
+ if (!process_title && uv__get_process_title() == -1) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ assert(process_title);
+ strncpy(buffer, process_title, size);
+ LeaveCriticalSection(&process_title_lock);
+
+ return 0;
+}
+
+
+uint64_t uv_hrtime(void) {
+ LARGE_INTEGER counter;
+
+ uv__once_init();
+
+ /* If the performance frequency is zero, there's no support. */
+ if (hrtime_frequency_ == 0) {
+ /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
+ return 0;
+ }
+
+ if (!QueryPerformanceCounter(&counter)) {
+ /* uv__set_sys_error(loop, GetLastError()); */
+ return 0;
+ }
+
+ /* Because we have no guarantee about the order of magnitude of the
+ * performance counter frequency, integer math could cause this computation
+ * to overflow. Therefore we resort to floating point math.
+ */
+ return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ HANDLE current_process;
+ PROCESS_MEMORY_COUNTERS pmc;
+
+ current_process = GetCurrentProcess();
+
+ if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ *rss = pmc.WorkingSetSize;
+
+ return 0;
+}
+
+
+int uv_uptime(double* uptime) {
+ BYTE stack_buffer[4096];
+ BYTE* malloced_buffer = NULL;
+ BYTE* buffer = (BYTE*) stack_buffer;
+ size_t buffer_size = sizeof(stack_buffer);
+ DWORD data_size;
+
+ PERF_DATA_BLOCK* data_block;
+ PERF_OBJECT_TYPE* object_type;
+ PERF_COUNTER_DEFINITION* counter_definition;
+
+ DWORD i;
+
+ for (;;) {
+ LONG result;
+
+ data_size = (DWORD) buffer_size;
+ result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
+ L"2",
+ NULL,
+ NULL,
+ buffer,
+ &data_size);
+ if (result == ERROR_SUCCESS) {
+ break;
+ } else if (result != ERROR_MORE_DATA) {
+ *uptime = 0;
+ return uv_translate_sys_error(result);
+ }
+
+ free(malloced_buffer);
+
+ buffer_size *= 2;
+ /* Don't let the buffer grow infinitely. */
+ if (buffer_size > 1 << 20) {
+ goto internalError;
+ }
+
+ buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
+ if (malloced_buffer == NULL) {
+ *uptime = 0;
+ return UV_ENOMEM;
+ }
+ }
+
+ if (data_size < sizeof(*data_block))
+ goto internalError;
+
+ data_block = (PERF_DATA_BLOCK*) buffer;
+
+ if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
+ goto internalError;
+
+ if (data_size < data_block->HeaderLength + sizeof(*object_type))
+ goto internalError;
+
+ object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);
+
+ if (object_type->NumInstances != PERF_NO_INSTANCES)
+ goto internalError;
+
+ counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
+ data_block->HeaderLength + object_type->HeaderLength);
+ for (i = 0; i < object_type->NumCounters; i++) {
+ if ((BYTE*) counter_definition + sizeof(*counter_definition) >
+ buffer + data_size) {
+ break;
+ }
+
+ if (counter_definition->CounterNameTitleIndex == 674 &&
+ counter_definition->CounterSize == sizeof(uint64_t)) {
+ if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
+ !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
+ goto internalError;
+ } else {
+ BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
+ counter_definition->CounterOffset;
+ uint64_t value = *((uint64_t*) address);
+ *uptime = (double) (object_type->PerfTime.QuadPart - value) /
+ (double) object_type->PerfFreq.QuadPart;
+ free(malloced_buffer);
+ return 0;
+ }
+ }
+
+ counter_definition = (PERF_COUNTER_DEFINITION*)
+ ((BYTE*) counter_definition + counter_definition->ByteLength);
+ }
+
+ /* If we get here, the uptime value was not found. */
+ free(malloced_buffer);
+ *uptime = 0;
+ return UV_ENOSYS;
+
+ internalError:
+ free(malloced_buffer);
+ *uptime = 0;
+ return UV_EIO;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
+ uv_cpu_info_t* cpu_infos;
+ SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
+ DWORD sppi_size;
+ SYSTEM_INFO system_info;
+ DWORD cpu_count, r, i;
+ NTSTATUS status;
+ ULONG result_size;
+ int err;
+ uv_cpu_info_t* cpu_info;
+
+ cpu_infos = NULL;
+ cpu_count = 0;
+ sppi = NULL;
+
+ uv__once_init();
+
+ GetSystemInfo(&system_info);
+ cpu_count = system_info.dwNumberOfProcessors;
+
+ cpu_infos = calloc(cpu_count, sizeof *cpu_infos);
+ if (cpu_infos == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto error;
+ }
+
+ sppi_size = cpu_count * sizeof(*sppi);
+ sppi = malloc(sppi_size);
+ if (sppi == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto error;
+ }
+
+ status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
+ sppi,
+ sppi_size,
+ &result_size);
+ if (!NT_SUCCESS(status)) {
+ err = pRtlNtStatusToDosError(status);
+ goto error;
+ }
+
+ assert(result_size == sppi_size);
+
+ for (i = 0; i < cpu_count; i++) {
+ WCHAR key_name[128];
+ HKEY processor_key;
+ DWORD cpu_speed;
+ DWORD cpu_speed_size = sizeof(cpu_speed);
+ WCHAR cpu_brand[256];
+ DWORD cpu_brand_size = sizeof(cpu_brand);
+ int len;
+
+ len = _snwprintf(key_name,
+ ARRAY_SIZE(key_name),
+ L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
+ i);
+
+ assert(len > 0 && len < ARRAY_SIZE(key_name));
+
+ r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ key_name,
+ 0,
+ KEY_QUERY_VALUE,
+ &processor_key);
+ if (r != ERROR_SUCCESS) {
+ err = GetLastError();
+ goto error;
+ }
+
+ if (RegQueryValueExW(processor_key,
+ L"~MHz",
+ NULL,
+ NULL,
+ (BYTE*) &cpu_speed,
+ &cpu_speed_size) != ERROR_SUCCESS) {
+ err = GetLastError();
+ RegCloseKey(processor_key);
+ goto error;
+ }
+
+ if (RegQueryValueExW(processor_key,
+ L"ProcessorNameString",
+ NULL,
+ NULL,
+ (BYTE*) &cpu_brand,
+ &cpu_brand_size) != ERROR_SUCCESS) {
+ err = GetLastError();
+ RegCloseKey(processor_key);
+ goto error;
+ }
+
+ RegCloseKey(processor_key);
+
+ cpu_info = &cpu_infos[i];
+ cpu_info->speed = cpu_speed;
+ cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
+ cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
+ sppi[i].IdleTime.QuadPart) / 10000;
+ cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
+ cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
+ cpu_info->cpu_times.nice = 0;
+
+
+ len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ cpu_brand,
+ cpu_brand_size / sizeof(WCHAR),
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (len == 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ assert(len > 0);
+
+ /* Allocate 1 extra byte for the null terminator. */
+ cpu_info->model = malloc(len + 1);
+ if (cpu_info->model == NULL) {
+ err = ERROR_OUTOFMEMORY;
+ goto error;
+ }
+
+ if (WideCharToMultiByte(CP_UTF8,
+ 0,
+ cpu_brand,
+ cpu_brand_size / sizeof(WCHAR),
+ cpu_info->model,
+ len,
+ NULL,
+ NULL) == 0) {
+ err = GetLastError();
+ goto error;
+ }
+
+ /* Ensure that cpu_info->model is null terminated. */
+ cpu_info->model[len] = '\0';
+ }
+
+ free(sppi);
+
+ *cpu_count_ptr = cpu_count;
+ *cpu_infos_ptr = cpu_infos;
+
+ return 0;
+
+ error:
+ /* This is safe because the cpu_infos array is zeroed on allocation. */
+ for (i = 0; i < cpu_count; i++)
+ free(cpu_infos[i].model);
+
+ free(cpu_infos);
+ free(sppi);
+
+ return uv_translate_sys_error(err);
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(cpu_infos[i].model);
+ }
+
+ free(cpu_infos);
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
+ int* count_ptr) {
+ IP_ADAPTER_ADDRESSES* win_address_buf;
+ ULONG win_address_buf_size;
+ IP_ADAPTER_ADDRESSES* win_address;
+
+ uv_interface_address_t* uv_address_buf;
+ char* name_buf;
+ size_t uv_address_buf_size;
+ uv_interface_address_t* uv_address;
+
+ int count;
+
+ /* Fetch the size of the adapters reported by windows, and then get the */
+ /* list itself. */
+ win_address_buf_size = 0;
+ win_address_buf = NULL;
+
+ for (;;) {
+ ULONG r;
+
+ /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */
+ /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
+ /* win_address_buf_size. */
+ r = GetAdaptersAddresses(AF_UNSPEC,
+ GAA_FLAG_INCLUDE_PREFIX,
+ NULL,
+ win_address_buf,
+ &win_address_buf_size);
+
+ if (r == ERROR_SUCCESS)
+ break;
+
+ free(win_address_buf);
+
+ switch (r) {
+ case ERROR_BUFFER_OVERFLOW:
+ /* This happens when win_address_buf is NULL or too small to hold */
+ /* all adapters. */
+ win_address_buf = malloc(win_address_buf_size);
+ if (win_address_buf == NULL)
+ return UV_ENOMEM;
+
+ continue;
+
+ case ERROR_NO_DATA: {
+ /* No adapters were found. */
+ uv_address_buf = malloc(1);
+ if (uv_address_buf == NULL)
+ return UV_ENOMEM;
+
+ *count_ptr = 0;
+ *addresses_ptr = uv_address_buf;
+
+ return 0;
+ }
+
+ case ERROR_ADDRESS_NOT_ASSOCIATED:
+ return UV_EAGAIN;
+
+ case ERROR_INVALID_PARAMETER:
+ /* MSDN says:
+ * "This error is returned for any of the following conditions: the
+ * SizePointer parameter is NULL, the Address parameter is not
+ * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for
+ * the parameters requested is greater than ULONG_MAX."
+ * Since the first two conditions are not met, it must be that the
+ * adapter data is too big.
+ */
+ return UV_ENOBUFS;
+
+ default:
+ /* Other (unspecified) errors can happen, but we don't have any */
+ /* special meaning for them. */
+ assert(r != ERROR_SUCCESS);
+ return uv_translate_sys_error(r);
+ }
+ }
+
+ /* Count the number of enabled interfaces and compute how much space is */
+ /* needed to store their info. */
+ count = 0;
+ uv_address_buf_size = 0;
+
+ for (win_address = win_address_buf;
+ win_address != NULL;
+ win_address = win_address->Next) {
+ /* Use IP_ADAPTER_UNICAST_ADDRESS_XP to retain backwards compatibility */
+ /* with Windows XP */
+ IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
+ int name_size;
+
+ /* Interfaces that are not 'up' should not be reported. Also skip */
+ /* interfaces that have no associated unicast address, as to avoid */
+ /* allocating space for the name for this interface. */
+ if (win_address->OperStatus != IfOperStatusUp ||
+ win_address->FirstUnicastAddress == NULL)
+ continue;
+
+ /* Compute the size of the interface name. */
+ name_size = WideCharToMultiByte(CP_UTF8,
+ 0,
+ win_address->FriendlyName,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ FALSE);
+ if (name_size <= 0) {
+ free(win_address_buf);
+ return uv_translate_sys_error(GetLastError());
+ }
+ uv_address_buf_size += name_size;
+
+ /* Count the number of addresses associated with this interface, and */
+ /* compute the size. */
+ for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
+ win_address->FirstUnicastAddress;
+ unicast_address != NULL;
+ unicast_address = unicast_address->Next) {
+ count++;
+ uv_address_buf_size += sizeof(uv_interface_address_t);
+ }
+ }
+
+ /* Allocate space to store interface data plus adapter names. */
+ uv_address_buf = malloc(uv_address_buf_size);
+ if (uv_address_buf == NULL) {
+ free(win_address_buf);
+ return UV_ENOMEM;
+ }
+
+ /* Compute the start of the uv_interface_address_t array, and the place in */
+ /* the buffer where the interface names will be stored. */
+ uv_address = uv_address_buf;
+ name_buf = (char*) (uv_address_buf + count);
+
+ /* Fill out the output buffer. */
+ for (win_address = win_address_buf;
+ win_address != NULL;
+ win_address = win_address->Next) {
+ IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
+ IP_ADAPTER_PREFIX* prefix;
+ int name_size;
+ size_t max_name_size;
+
+ if (win_address->OperStatus != IfOperStatusUp ||
+ win_address->FirstUnicastAddress == NULL)
+ continue;
+
+ /* Convert the interface name to UTF8. */
+ max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
+ if (max_name_size > (size_t) INT_MAX)
+ max_name_size = INT_MAX;
+ name_size = WideCharToMultiByte(CP_UTF8,
+ 0,
+ win_address->FriendlyName,
+ -1,
+ name_buf,
+ (int) max_name_size,
+ NULL,
+ FALSE);
+ if (name_size <= 0) {
+ free(win_address_buf);
+ free(uv_address_buf);
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ prefix = win_address->FirstPrefix;
+
+ /* Add an uv_interface_address_t element for every unicast address. */
+ /* Walk the prefix list in tandem with the address list. */
+ for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
+ win_address->FirstUnicastAddress;
+ unicast_address != NULL && prefix != NULL;
+ unicast_address = unicast_address->Next, prefix = prefix->Next) {
+ struct sockaddr* sa;
+ ULONG prefix_len;
+
+ sa = unicast_address->Address.lpSockaddr;
+ prefix_len = prefix->PrefixLength;
+
+ memset(uv_address, 0, sizeof *uv_address);
+
+ uv_address->name = name_buf;
+
+ if (win_address->PhysicalAddressLength == sizeof(uv_address->phys_addr)) {
+ memcpy(uv_address->phys_addr,
+ win_address->PhysicalAddress,
+ sizeof(uv_address->phys_addr));
+ }
+
+ uv_address->is_internal =
+ (win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
+
+ if (sa->sa_family == AF_INET6) {
+ uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
+
+ uv_address->netmask.netmask6.sin6_family = AF_INET6;
+ memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3);
+ uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] =
+ 0xff << (8 - prefix_len % 8);
+
+ } else {
+ uv_address->address.address4 = *((struct sockaddr_in *) sa);
+
+ uv_address->netmask.netmask4.sin_family = AF_INET;
+ uv_address->netmask.netmask4.sin_addr.s_addr =
+ htonl(0xffffffff << (32 - prefix_len));
+ }
+
+ uv_address++;
+ }
+
+ name_buf += name_size;
+ }
+
+ free(win_address_buf);
+
+ *addresses_ptr = uv_address_buf;
+ *count_ptr = count;
+
+ return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+ int count) {
+ free(addresses);
+}
diff --git a/third-party/libuv/src/win/winapi.c b/third-party/libuv/src/win/winapi.c
new file mode 100644
index 0000000000..3e439ea5b2
--- /dev/null
+++ b/third-party/libuv/src/win/winapi.c
@@ -0,0 +1,159 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/* Ntdll function pointers */
+sRtlNtStatusToDosError pRtlNtStatusToDosError;
+sNtDeviceIoControlFile pNtDeviceIoControlFile;
+sNtQueryInformationFile pNtQueryInformationFile;
+sNtSetInformationFile pNtSetInformationFile;
+sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+sNtQuerySystemInformation pNtQuerySystemInformation;
+
+
+/* Kernel32 function pointers */
+sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
+sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
+sCreateSymbolicLinkW pCreateSymbolicLinkW;
+sCancelIoEx pCancelIoEx;
+sInitializeSRWLock pInitializeSRWLock;
+sAcquireSRWLockShared pAcquireSRWLockShared;
+sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
+sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
+sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
+sReleaseSRWLockShared pReleaseSRWLockShared;
+sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
+sInitializeConditionVariable pInitializeConditionVariable;
+sSleepConditionVariableCS pSleepConditionVariableCS;
+sSleepConditionVariableSRW pSleepConditionVariableSRW;
+sWakeAllConditionVariable pWakeAllConditionVariable;
+sWakeConditionVariable pWakeConditionVariable;
+
+
+void uv_winapi_init() {
+ HMODULE ntdll_module;
+ HMODULE kernel32_module;
+
+ ntdll_module = GetModuleHandleA("ntdll.dll");
+ if (ntdll_module == NULL) {
+ uv_fatal_error(GetLastError(), "GetModuleHandleA");
+ }
+
+ pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
+ ntdll_module,
+ "RtlNtStatusToDosError");
+ if (pRtlNtStatusToDosError == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress(
+ ntdll_module,
+ "NtDeviceIoControlFile");
+ if (pNtDeviceIoControlFile == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress(
+ ntdll_module,
+ "NtQueryInformationFile");
+ if (pNtQueryInformationFile == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress(
+ ntdll_module,
+ "NtSetInformationFile");
+ if (pNtSetInformationFile == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile)
+ GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
+ if (pNtQueryVolumeInformationFile == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
+ ntdll_module,
+ "NtQuerySystemInformation");
+ if (pNtQuerySystemInformation == NULL) {
+ uv_fatal_error(GetLastError(), "GetProcAddress");
+ }
+
+ kernel32_module = GetModuleHandleA("kernel32.dll");
+ if (kernel32_module == NULL) {
+ uv_fatal_error(GetLastError(), "GetModuleHandleA");
+ }
+
+ pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress(
+ kernel32_module,
+ "GetQueuedCompletionStatusEx");
+
+ pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
+ GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");
+
+ pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
+ GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
+
+ pCancelIoEx = (sCancelIoEx)
+ GetProcAddress(kernel32_module, "CancelIoEx");
+
+ pInitializeSRWLock = (sInitializeSRWLock)
+ GetProcAddress(kernel32_module, "InitializeSRWLock");
+
+ pAcquireSRWLockShared = (sAcquireSRWLockShared)
+ GetProcAddress(kernel32_module, "AcquireSRWLockShared");
+
+ pAcquireSRWLockExclusive = (sAcquireSRWLockExclusive)
+ GetProcAddress(kernel32_module, "AcquireSRWLockExclusive");
+
+ pTryAcquireSRWLockShared = (sTryAcquireSRWLockShared)
+ GetProcAddress(kernel32_module, "TryAcquireSRWLockShared");
+
+ pTryAcquireSRWLockExclusive = (sTryAcquireSRWLockExclusive)
+ GetProcAddress(kernel32_module, "TryAcquireSRWLockExclusive");
+
+ pReleaseSRWLockShared = (sReleaseSRWLockShared)
+ GetProcAddress(kernel32_module, "ReleaseSRWLockShared");
+
+ pReleaseSRWLockExclusive = (sReleaseSRWLockExclusive)
+ GetProcAddress(kernel32_module, "ReleaseSRWLockExclusive");
+
+ pInitializeConditionVariable = (sInitializeConditionVariable)
+ GetProcAddress(kernel32_module, "InitializeConditionVariable");
+
+ pSleepConditionVariableCS = (sSleepConditionVariableCS)
+ GetProcAddress(kernel32_module, "SleepConditionVariableCS");
+
+ pSleepConditionVariableSRW = (sSleepConditionVariableSRW)
+ GetProcAddress(kernel32_module, "SleepConditionVariableSRW");
+
+ pWakeAllConditionVariable = (sWakeAllConditionVariable)
+ GetProcAddress(kernel32_module, "WakeAllConditionVariable");
+
+ pWakeConditionVariable = (sWakeConditionVariable)
+ GetProcAddress(kernel32_module, "WakeConditionVariable");
+}
diff --git a/third-party/libuv/src/win/winapi.h b/third-party/libuv/src/win/winapi.h
new file mode 100644
index 0000000000..21d7fe4ac3
--- /dev/null
+++ b/third-party/libuv/src/win/winapi.h
@@ -0,0 +1,4648 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_WINAPI_H_
+#define UV_WIN_WINAPI_H_
+
+#include <windows.h>
+
+
+/*
+ * Ntdll headers
+ */
+#ifndef STATUS_SEVERITY_SUCCESS
+# define STATUS_SEVERITY_SUCCESS 0x0
+#endif
+
+#ifndef STATUS_SEVERITY_INFORMATIONAL
+# define STATUS_SEVERITY_INFORMATIONAL 0x1
+#endif
+
+#ifndef STATUS_SEVERITY_WARNING
+# define STATUS_SEVERITY_WARNING 0x2
+#endif
+
+#ifndef STATUS_SEVERITY_ERROR
+# define STATUS_SEVERITY_ERROR 0x3
+#endif
+
+#ifndef FACILITY_NTWIN32
+# define FACILITY_NTWIN32 0x7
+#endif
+
+#ifndef NT_SUCCESS
+# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0)
+#endif
+
+#ifndef NT_INFORMATION
+# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1)
+#endif
+
+#ifndef NT_WARNING
+# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2)
+#endif
+
+#ifndef NT_ERROR
+# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3)
+#endif
+
+#ifndef STATUS_SUCCESS
+# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L)
+#endif
+
+#ifndef STATUS_WAIT_0
+# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L)
+#endif
+
+#ifndef STATUS_WAIT_1
+# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L)
+#endif
+
+#ifndef STATUS_WAIT_2
+# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L)
+#endif
+
+#ifndef STATUS_WAIT_3
+# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L)
+#endif
+
+#ifndef STATUS_WAIT_63
+# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL)
+#endif
+
+#ifndef STATUS_ABANDONED
+# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L)
+#endif
+
+#ifndef STATUS_ABANDONED_WAIT_0
+# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L)
+#endif
+
+#ifndef STATUS_ABANDONED_WAIT_63
+# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL)
+#endif
+
+#ifndef STATUS_USER_APC
+# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L)
+#endif
+
+#ifndef STATUS_KERNEL_APC
+# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L)
+#endif
+
+#ifndef STATUS_ALERTED
+# define STATUS_ALERTED ((NTSTATUS) 0x00000101L)
+#endif
+
+#ifndef STATUS_TIMEOUT
+# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L)
+#endif
+
+#ifndef STATUS_PENDING
+# define STATUS_PENDING ((NTSTATUS) 0x00000103L)
+#endif
+
+#ifndef STATUS_REPARSE
+# define STATUS_REPARSE ((NTSTATUS) 0x00000104L)
+#endif
+
+#ifndef STATUS_MORE_ENTRIES
+# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L)
+#endif
+
+#ifndef STATUS_NOT_ALL_ASSIGNED
+# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L)
+#endif
+
+#ifndef STATUS_SOME_NOT_MAPPED
+# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L)
+#endif
+
+#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS
+# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L)
+#endif
+
+#ifndef STATUS_VOLUME_MOUNTED
+# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L)
+#endif
+
+#ifndef STATUS_RXACT_COMMITTED
+# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL)
+#endif
+
+#ifndef STATUS_NOTIFY_CLEANUP
+# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL)
+#endif
+
+#ifndef STATUS_NOTIFY_ENUM_DIR
+# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL)
+#endif
+
+#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT
+# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL)
+#endif
+
+#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED
+# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_TRANSITION
+# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO
+# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE
+# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_GUARD_PAGE
+# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_PAGING_FILE
+# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L)
+#endif
+
+#ifndef STATUS_CACHE_PAGE_LOCKED
+# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L)
+#endif
+
+#ifndef STATUS_CRASH_DUMP
+# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L)
+#endif
+
+#ifndef STATUS_BUFFER_ALL_ZEROS
+# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L)
+#endif
+
+#ifndef STATUS_REPARSE_OBJECT
+# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L)
+#endif
+
+#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED
+# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L)
+#endif
+
+#ifndef STATUS_TRANSLATION_COMPLETE
+# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L)
+#endif
+
+#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY
+# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L)
+#endif
+
+#ifndef STATUS_NOTHING_TO_TERMINATE
+# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L)
+#endif
+
+#ifndef STATUS_PROCESS_NOT_IN_JOB
+# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L)
+#endif
+
+#ifndef STATUS_PROCESS_IN_JOB
+# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L)
+#endif
+
+#ifndef STATUS_VOLSNAP_HIBERNATE_READY
+# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L)
+#endif
+
+#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY
+# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L)
+#endif
+
+#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED
+# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L)
+#endif
+
+#ifndef STATUS_INTERRUPT_STILL_CONNECTED
+# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L)
+#endif
+
+#ifndef STATUS_PROCESS_CLONED
+# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L)
+#endif
+
+#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS
+# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL)
+#endif
+
+#ifndef STATUS_FILE_LOCKED_WITH_WRITERS
+# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL)
+#endif
+
+#ifndef STATUS_RESOURCEMANAGER_READ_ONLY
+# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_EMPTY
+# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_FULL
+# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA
+# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L)
+#endif
+
+#ifndef STATUS_RING_NEWLY_EMPTY
+# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L)
+#endif
+
+#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT
+# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L)
+#endif
+
+#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE
+# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L)
+#endif
+
+#ifndef STATUS_OPLOCK_HANDLE_CLOSED
+# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L)
+#endif
+
+#ifndef STATUS_WAIT_FOR_OPLOCK
+# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_EXISTS
+# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L)
+#endif
+
+#ifndef STATUS_THREAD_WAS_SUSPENDED
+# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L)
+#endif
+
+#ifndef STATUS_WORKING_SET_LIMIT_RANGE
+# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L)
+#endif
+
+#ifndef STATUS_IMAGE_NOT_AT_BASE
+# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L)
+#endif
+
+#ifndef STATUS_RXACT_STATE_CREATED
+# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L)
+#endif
+
+#ifndef STATUS_SEGMENT_NOTIFICATION
+# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L)
+#endif
+
+#ifndef STATUS_LOCAL_USER_SESSION_KEY
+# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L)
+#endif
+
+#ifndef STATUS_BAD_CURRENT_DIRECTORY
+# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L)
+#endif
+
+#ifndef STATUS_SERIAL_MORE_WRITES
+# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L)
+#endif
+
+#ifndef STATUS_REGISTRY_RECOVERED
+# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L)
+#endif
+
+#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP
+# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL)
+#endif
+
+#ifndef STATUS_FT_WRITE_RECOVERY
+# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL)
+#endif
+
+#ifndef STATUS_SERIAL_COUNTER_TIMEOUT
+# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL)
+#endif
+
+#ifndef STATUS_NULL_LM_PASSWORD
+# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL)
+#endif
+
+#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH
+# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL)
+#endif
+
+#ifndef STATUS_RECEIVE_PARTIAL
+# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL)
+#endif
+
+#ifndef STATUS_RECEIVE_EXPEDITED
+# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L)
+#endif
+
+#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED
+# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L)
+#endif
+
+#ifndef STATUS_EVENT_DONE
+# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L)
+#endif
+
+#ifndef STATUS_EVENT_PENDING
+# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L)
+#endif
+
+#ifndef STATUS_CHECKING_FILE_SYSTEM
+# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L)
+#endif
+
+#ifndef STATUS_FATAL_APP_EXIT
+# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L)
+#endif
+
+#ifndef STATUS_PREDEFINED_HANDLE
+# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L)
+#endif
+
+#ifndef STATUS_WAS_UNLOCKED
+# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L)
+#endif
+
+#ifndef STATUS_SERVICE_NOTIFICATION
+# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L)
+#endif
+
+#ifndef STATUS_WAS_LOCKED
+# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L)
+#endif
+
+#ifndef STATUS_LOG_HARD_ERROR
+# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL)
+#endif
+
+#ifndef STATUS_ALREADY_WIN32
+# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL)
+#endif
+
+#ifndef STATUS_WX86_UNSIMULATE
+# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL)
+#endif
+
+#ifndef STATUS_WX86_CONTINUE
+# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL)
+#endif
+
+#ifndef STATUS_WX86_SINGLE_STEP
+# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL)
+#endif
+
+#ifndef STATUS_WX86_BREAKPOINT
+# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_CONTINUE
+# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE
+# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_CHAIN
+# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L)
+#endif
+
+#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE
+# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L)
+#endif
+
+#ifndef STATUS_NO_YIELD_PERFORMED
+# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L)
+#endif
+
+#ifndef STATUS_TIMER_RESUME_IGNORED
+# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L)
+#endif
+
+#ifndef STATUS_ARBITRATION_UNHANDLED
+# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L)
+#endif
+
+#ifndef STATUS_CARDBUS_NOT_SUPPORTED
+# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L)
+#endif
+
+#ifndef STATUS_WX86_CREATEWX86TIB
+# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L)
+#endif
+
+#ifndef STATUS_MP_PROCESSOR_MISMATCH
+# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L)
+#endif
+
+#ifndef STATUS_HIBERNATED
+# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL)
+#endif
+
+#ifndef STATUS_RESUME_HIBERNATION
+# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL)
+#endif
+
+#ifndef STATUS_FIRMWARE_UPDATED
+# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL)
+#endif
+
+#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES
+# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL)
+#endif
+
+#ifndef STATUS_MESSAGE_RETRIEVED
+# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL)
+#endif
+
+#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION
+# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL)
+#endif
+
+#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST
+# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L)
+#endif
+
+#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION
+# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L)
+#endif
+
+#ifndef STATUS_ACCESS_AUDIT_BY_POLICY
+# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L)
+#endif
+
+#ifndef STATUS_ABANDON_HIBERFILE
+# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L)
+#endif
+
+#ifndef STATUS_BIZRULES_NOT_ENABLED
+# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L)
+#endif
+
+#ifndef STATUS_GUARD_PAGE_VIOLATION
+# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L)
+#endif
+
+#ifndef STATUS_DATATYPE_MISALIGNMENT
+# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L)
+#endif
+
+#ifndef STATUS_BREAKPOINT
+# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L)
+#endif
+
+#ifndef STATUS_SINGLE_STEP
+# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L)
+#endif
+
+#ifndef STATUS_BUFFER_OVERFLOW
+# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L)
+#endif
+
+#ifndef STATUS_NO_MORE_FILES
+# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L)
+#endif
+
+#ifndef STATUS_WAKE_SYSTEM_DEBUGGER
+# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L)
+#endif
+
+#ifndef STATUS_HANDLES_CLOSED
+# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL)
+#endif
+
+#ifndef STATUS_NO_INHERITANCE
+# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL)
+#endif
+
+#ifndef STATUS_GUID_SUBSTITUTION_MADE
+# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL)
+#endif
+
+#ifndef STATUS_PARTIAL_COPY
+# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL)
+#endif
+
+#ifndef STATUS_DEVICE_PAPER_EMPTY
+# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL)
+#endif
+
+#ifndef STATUS_DEVICE_POWERED_OFF
+# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL)
+#endif
+
+#ifndef STATUS_DEVICE_OFF_LINE
+# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L)
+#endif
+
+#ifndef STATUS_DEVICE_BUSY
+# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L)
+#endif
+
+#ifndef STATUS_NO_MORE_EAS
+# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L)
+#endif
+
+#ifndef STATUS_INVALID_EA_NAME
+# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L)
+#endif
+
+#ifndef STATUS_EA_LIST_INCONSISTENT
+# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L)
+#endif
+
+#ifndef STATUS_INVALID_EA_FLAG
+# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L)
+#endif
+
+#ifndef STATUS_VERIFY_REQUIRED
+# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L)
+#endif
+
+#ifndef STATUS_EXTRANEOUS_INFORMATION
+# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L)
+#endif
+
+#ifndef STATUS_RXACT_COMMIT_NECESSARY
+# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L)
+#endif
+
+#ifndef STATUS_NO_MORE_ENTRIES
+# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL)
+#endif
+
+#ifndef STATUS_FILEMARK_DETECTED
+# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL)
+#endif
+
+#ifndef STATUS_MEDIA_CHANGED
+# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL)
+#endif
+
+#ifndef STATUS_BUS_RESET
+# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL)
+#endif
+
+#ifndef STATUS_END_OF_MEDIA
+# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL)
+#endif
+
+#ifndef STATUS_BEGINNING_OF_MEDIA
+# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL)
+#endif
+
+#ifndef STATUS_MEDIA_CHECK
+# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L)
+#endif
+
+#ifndef STATUS_SETMARK_DETECTED
+# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L)
+#endif
+
+#ifndef STATUS_NO_DATA_DETECTED
+# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L)
+#endif
+
+#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES
+# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L)
+#endif
+
+#ifndef STATUS_SERVER_HAS_OPEN_HANDLES
+# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L)
+#endif
+
+#ifndef STATUS_ALREADY_DISCONNECTED
+# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L)
+#endif
+
+#ifndef STATUS_LONGJUMP
+# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L)
+#endif
+
+#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED
+# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L)
+#endif
+
+#ifndef STATUS_PLUGPLAY_QUERY_VETOED
+# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L)
+#endif
+
+#ifndef STATUS_UNWIND_CONSOLIDATE
+# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L)
+#endif
+
+#ifndef STATUS_REGISTRY_HIVE_RECOVERED
+# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL)
+#endif
+
+#ifndef STATUS_DLL_MIGHT_BE_INSECURE
+# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL)
+#endif
+
+#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE
+# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL)
+#endif
+
+#ifndef STATUS_STOPPED_ON_SYMLINK
+# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL)
+#endif
+
+#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK
+# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL)
+#endif
+
+#ifndef STATUS_NO_ACE_CONDITION
+# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL)
+#endif
+
+#ifndef STATUS_UNSUCCESSFUL
+# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L)
+#endif
+
+#ifndef STATUS_NOT_IMPLEMENTED
+# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L)
+#endif
+
+#ifndef STATUS_INVALID_INFO_CLASS
+# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L)
+#endif
+
+#ifndef STATUS_INFO_LENGTH_MISMATCH
+# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L)
+#endif
+
+#ifndef STATUS_ACCESS_VIOLATION
+# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L)
+#endif
+
+#ifndef STATUS_IN_PAGE_ERROR
+# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L)
+#endif
+
+#ifndef STATUS_PAGEFILE_QUOTA
+# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L)
+#endif
+
+#ifndef STATUS_INVALID_HANDLE
+# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L)
+#endif
+
+#ifndef STATUS_BAD_INITIAL_STACK
+# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L)
+#endif
+
+#ifndef STATUS_BAD_INITIAL_PC
+# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL)
+#endif
+
+#ifndef STATUS_INVALID_CID
+# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL)
+#endif
+
+#ifndef STATUS_TIMER_NOT_CANCELED
+# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER
+# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL)
+#endif
+
+#ifndef STATUS_NO_SUCH_DEVICE
+# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL)
+#endif
+
+#ifndef STATUS_NO_SUCH_FILE
+# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_REQUEST
+# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L)
+#endif
+
+#ifndef STATUS_END_OF_FILE
+# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L)
+#endif
+
+#ifndef STATUS_WRONG_VOLUME
+# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L)
+#endif
+
+#ifndef STATUS_NO_MEDIA_IN_DEVICE
+# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L)
+#endif
+
+#ifndef STATUS_UNRECOGNIZED_MEDIA
+# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L)
+#endif
+
+#ifndef STATUS_NONEXISTENT_SECTOR
+# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L)
+#endif
+
+#ifndef STATUS_MORE_PROCESSING_REQUIRED
+# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L)
+#endif
+
+#ifndef STATUS_NO_MEMORY
+# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L)
+#endif
+
+#ifndef STATUS_CONFLICTING_ADDRESSES
+# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L)
+#endif
+
+#ifndef STATUS_NOT_MAPPED_VIEW
+# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_FREE_VM
+# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL)
+#endif
+
+#ifndef STATUS_UNABLE_TO_DELETE_SECTION
+# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL)
+#endif
+
+#ifndef STATUS_INVALID_SYSTEM_SERVICE
+# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL)
+#endif
+
+#ifndef STATUS_ILLEGAL_INSTRUCTION
+# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL)
+#endif
+
+#ifndef STATUS_INVALID_LOCK_SEQUENCE
+# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL)
+#endif
+
+#ifndef STATUS_INVALID_VIEW_SIZE
+# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL)
+#endif
+
+#ifndef STATUS_INVALID_FILE_FOR_SECTION
+# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L)
+#endif
+
+#ifndef STATUS_ALREADY_COMMITTED
+# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L)
+#endif
+
+#ifndef STATUS_ACCESS_DENIED
+# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L)
+#endif
+
+#ifndef STATUS_BUFFER_TOO_SMALL
+# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L)
+#endif
+
+#ifndef STATUS_OBJECT_TYPE_MISMATCH
+# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L)
+#endif
+
+#ifndef STATUS_NONCONTINUABLE_EXCEPTION
+# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L)
+#endif
+
+#ifndef STATUS_INVALID_DISPOSITION
+# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L)
+#endif
+
+#ifndef STATUS_UNWIND
+# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L)
+#endif
+
+#ifndef STATUS_BAD_STACK
+# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L)
+#endif
+
+#ifndef STATUS_INVALID_UNWIND_TARGET
+# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L)
+#endif
+
+#ifndef STATUS_NOT_LOCKED
+# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL)
+#endif
+
+#ifndef STATUS_PARITY_ERROR
+# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL)
+#endif
+
+#ifndef STATUS_UNABLE_TO_DECOMMIT_VM
+# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL)
+#endif
+
+#ifndef STATUS_NOT_COMMITTED
+# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL)
+#endif
+
+#ifndef STATUS_INVALID_PORT_ATTRIBUTES
+# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL)
+#endif
+
+#ifndef STATUS_PORT_MESSAGE_TOO_LONG
+# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_MIX
+# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L)
+#endif
+
+#ifndef STATUS_INVALID_QUOTA_LOWER
+# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L)
+#endif
+
+#ifndef STATUS_DISK_CORRUPT_ERROR
+# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_INVALID
+# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_NOT_FOUND
+# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_COLLISION
+# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L)
+#endif
+
+#ifndef STATUS_PORT_DISCONNECTED
+# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L)
+#endif
+
+#ifndef STATUS_DEVICE_ALREADY_ATTACHED
+# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_INVALID
+# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_NOT_FOUND
+# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD
+# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL)
+#endif
+
+#ifndef STATUS_DATA_OVERRUN
+# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL)
+#endif
+
+#ifndef STATUS_DATA_LATE_ERROR
+# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL)
+#endif
+
+#ifndef STATUS_DATA_ERROR
+# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL)
+#endif
+
+#ifndef STATUS_CRC_ERROR
+# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL)
+#endif
+
+#ifndef STATUS_SECTION_TOO_BIG
+# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L)
+#endif
+
+#ifndef STATUS_PORT_CONNECTION_REFUSED
+# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L)
+#endif
+
+#ifndef STATUS_INVALID_PORT_HANDLE
+# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L)
+#endif
+
+#ifndef STATUS_SHARING_VIOLATION
+# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L)
+#endif
+
+#ifndef STATUS_QUOTA_EXCEEDED
+# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L)
+#endif
+
+#ifndef STATUS_INVALID_PAGE_PROTECTION
+# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L)
+#endif
+
+#ifndef STATUS_MUTANT_NOT_OWNED
+# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L)
+#endif
+
+#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED
+# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L)
+#endif
+
+#ifndef STATUS_PORT_ALREADY_SET
+# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L)
+#endif
+
+#ifndef STATUS_SECTION_NOT_IMAGE
+# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L)
+#endif
+
+#ifndef STATUS_SUSPEND_COUNT_EXCEEDED
+# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL)
+#endif
+
+#ifndef STATUS_THREAD_IS_TERMINATING
+# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL)
+#endif
+
+#ifndef STATUS_BAD_WORKING_SET_LIMIT
+# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_FILE_MAP
+# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL)
+#endif
+
+#ifndef STATUS_SECTION_PROTECTION
+# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL)
+#endif
+
+#ifndef STATUS_EAS_NOT_SUPPORTED
+# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL)
+#endif
+
+#ifndef STATUS_EA_TOO_LARGE
+# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L)
+#endif
+
+#ifndef STATUS_NONEXISTENT_EA_ENTRY
+# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L)
+#endif
+
+#ifndef STATUS_NO_EAS_ON_FILE
+# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L)
+#endif
+
+#ifndef STATUS_EA_CORRUPT_ERROR
+# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L)
+#endif
+
+#ifndef STATUS_FILE_LOCK_CONFLICT
+# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L)
+#endif
+
+#ifndef STATUS_LOCK_NOT_GRANTED
+# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L)
+#endif
+
+#ifndef STATUS_DELETE_PENDING
+# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L)
+#endif
+
+#ifndef STATUS_CTL_FILE_NOT_SUPPORTED
+# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L)
+#endif
+
+#ifndef STATUS_UNKNOWN_REVISION
+# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L)
+#endif
+
+#ifndef STATUS_REVISION_MISMATCH
+# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L)
+#endif
+
+#ifndef STATUS_INVALID_OWNER
+# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL)
+#endif
+
+#ifndef STATUS_INVALID_PRIMARY_GROUP
+# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL)
+#endif
+
+#ifndef STATUS_NO_IMPERSONATION_TOKEN
+# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL)
+#endif
+
+#ifndef STATUS_CANT_DISABLE_MANDATORY
+# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL)
+#endif
+
+#ifndef STATUS_NO_LOGON_SERVERS
+# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL)
+#endif
+
+#ifndef STATUS_NO_SUCH_LOGON_SESSION
+# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL)
+#endif
+
+#ifndef STATUS_NO_SUCH_PRIVILEGE
+# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L)
+#endif
+
+#ifndef STATUS_PRIVILEGE_NOT_HELD
+# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L)
+#endif
+
+#ifndef STATUS_INVALID_ACCOUNT_NAME
+# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L)
+#endif
+
+#ifndef STATUS_USER_EXISTS
+# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L)
+#endif
+
+#ifndef STATUS_NO_SUCH_USER
+# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L)
+#endif
+
+#ifndef STATUS_GROUP_EXISTS
+# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L)
+#endif
+
+#ifndef STATUS_NO_SUCH_GROUP
+# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L)
+#endif
+
+#ifndef STATUS_MEMBER_IN_GROUP
+# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L)
+#endif
+
+#ifndef STATUS_MEMBER_NOT_IN_GROUP
+# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L)
+#endif
+
+#ifndef STATUS_LAST_ADMIN
+# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L)
+#endif
+
+#ifndef STATUS_WRONG_PASSWORD
+# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL)
+#endif
+
+#ifndef STATUS_ILL_FORMED_PASSWORD
+# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL)
+#endif
+
+#ifndef STATUS_PASSWORD_RESTRICTION
+# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL)
+#endif
+
+#ifndef STATUS_LOGON_FAILURE
+# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL)
+#endif
+
+#ifndef STATUS_ACCOUNT_RESTRICTION
+# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL)
+#endif
+
+#ifndef STATUS_INVALID_LOGON_HOURS
+# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL)
+#endif
+
+#ifndef STATUS_INVALID_WORKSTATION
+# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L)
+#endif
+
+#ifndef STATUS_PASSWORD_EXPIRED
+# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L)
+#endif
+
+#ifndef STATUS_ACCOUNT_DISABLED
+# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L)
+#endif
+
+#ifndef STATUS_NONE_MAPPED
+# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L)
+#endif
+
+#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED
+# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L)
+#endif
+
+#ifndef STATUS_LUIDS_EXHAUSTED
+# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L)
+#endif
+
+#ifndef STATUS_INVALID_SUB_AUTHORITY
+# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L)
+#endif
+
+#ifndef STATUS_INVALID_ACL
+# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L)
+#endif
+
+#ifndef STATUS_INVALID_SID
+# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L)
+#endif
+
+#ifndef STATUS_INVALID_SECURITY_DESCR
+# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L)
+#endif
+
+#ifndef STATUS_PROCEDURE_NOT_FOUND
+# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_FORMAT
+# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL)
+#endif
+
+#ifndef STATUS_NO_TOKEN
+# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL)
+#endif
+
+#ifndef STATUS_BAD_INHERITANCE_ACL
+# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL)
+#endif
+
+#ifndef STATUS_RANGE_NOT_LOCKED
+# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL)
+#endif
+
+#ifndef STATUS_DISK_FULL
+# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
+#endif
+
+#ifndef STATUS_SERVER_DISABLED
+# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L)
+#endif
+
+#ifndef STATUS_SERVER_NOT_DISABLED
+# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L)
+#endif
+
+#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED
+# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L)
+#endif
+
+#ifndef STATUS_GUIDS_EXHAUSTED
+# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L)
+#endif
+
+#ifndef STATUS_INVALID_ID_AUTHORITY
+# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L)
+#endif
+
+#ifndef STATUS_AGENTS_EXHAUSTED
+# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L)
+#endif
+
+#ifndef STATUS_INVALID_VOLUME_LABEL
+# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L)
+#endif
+
+#ifndef STATUS_SECTION_NOT_EXTENDED
+# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L)
+#endif
+
+#ifndef STATUS_NOT_MAPPED_DATA
+# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L)
+#endif
+
+#ifndef STATUS_RESOURCE_DATA_NOT_FOUND
+# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L)
+#endif
+
+#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND
+# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL)
+#endif
+
+#ifndef STATUS_RESOURCE_NAME_NOT_FOUND
+# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL)
+#endif
+
+#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED
+# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL)
+#endif
+
+#ifndef STATUS_FLOAT_DENORMAL_OPERAND
+# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL)
+#endif
+
+#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO
+# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL)
+#endif
+
+#ifndef STATUS_FLOAT_INEXACT_RESULT
+# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL)
+#endif
+
+#ifndef STATUS_FLOAT_INVALID_OPERATION
+# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L)
+#endif
+
+#ifndef STATUS_FLOAT_OVERFLOW
+# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L)
+#endif
+
+#ifndef STATUS_FLOAT_STACK_CHECK
+# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L)
+#endif
+
+#ifndef STATUS_FLOAT_UNDERFLOW
+# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L)
+#endif
+
+#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO
+# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L)
+#endif
+
+#ifndef STATUS_INTEGER_OVERFLOW
+# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L)
+#endif
+
+#ifndef STATUS_PRIVILEGED_INSTRUCTION
+# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L)
+#endif
+
+#ifndef STATUS_TOO_MANY_PAGING_FILES
+# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L)
+#endif
+
+#ifndef STATUS_FILE_INVALID
+# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L)
+#endif
+
+#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED
+# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCES
+# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
+#endif
+
+#ifndef STATUS_DFS_EXIT_PATH_FOUND
+# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL)
+#endif
+
+#ifndef STATUS_DEVICE_DATA_ERROR
+# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_CONNECTED
+# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL)
+#endif
+
+#ifndef STATUS_DEVICE_POWER_FAILURE
+# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL)
+#endif
+
+#ifndef STATUS_FREE_VM_NOT_AT_BASE
+# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL)
+#endif
+
+#ifndef STATUS_MEMORY_NOT_ALLOCATED
+# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L)
+#endif
+
+#ifndef STATUS_WORKING_SET_QUOTA
+# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L)
+#endif
+
+#ifndef STATUS_MEDIA_WRITE_PROTECTED
+# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_READY
+# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)
+#endif
+
+#ifndef STATUS_INVALID_GROUP_ATTRIBUTES
+# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L)
+#endif
+
+#ifndef STATUS_BAD_IMPERSONATION_LEVEL
+# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L)
+#endif
+
+#ifndef STATUS_CANT_OPEN_ANONYMOUS
+# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L)
+#endif
+
+#ifndef STATUS_BAD_VALIDATION_CLASS
+# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L)
+#endif
+
+#ifndef STATUS_BAD_TOKEN_TYPE
+# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L)
+#endif
+
+#ifndef STATUS_BAD_MASTER_BOOT_RECORD
+# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L)
+#endif
+
+#ifndef STATUS_INSTRUCTION_MISALIGNMENT
+# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL)
+#endif
+
+#ifndef STATUS_INSTANCE_NOT_AVAILABLE
+# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL)
+#endif
+
+#ifndef STATUS_PIPE_NOT_AVAILABLE
+# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL)
+#endif
+
+#ifndef STATUS_INVALID_PIPE_STATE
+# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL)
+#endif
+
+#ifndef STATUS_PIPE_BUSY
+# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL)
+#endif
+
+#ifndef STATUS_ILLEGAL_FUNCTION
+# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL)
+#endif
+
+#ifndef STATUS_PIPE_DISCONNECTED
+# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L)
+#endif
+
+#ifndef STATUS_PIPE_CLOSING
+# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L)
+#endif
+
+#ifndef STATUS_PIPE_CONNECTED
+# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L)
+#endif
+
+#ifndef STATUS_PIPE_LISTENING
+# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L)
+#endif
+
+#ifndef STATUS_INVALID_READ_MODE
+# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L)
+#endif
+
+#ifndef STATUS_IO_TIMEOUT
+# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L)
+#endif
+
+#ifndef STATUS_FILE_FORCED_CLOSED
+# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L)
+#endif
+
+#ifndef STATUS_PROFILING_NOT_STARTED
+# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L)
+#endif
+
+#ifndef STATUS_PROFILING_NOT_STOPPED
+# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L)
+#endif
+
+#ifndef STATUS_COULD_NOT_INTERPRET
+# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L)
+#endif
+
+#ifndef STATUS_FILE_IS_A_DIRECTORY
+# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED
+# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL)
+#endif
+
+#ifndef STATUS_REMOTE_NOT_LISTENING
+# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL)
+#endif
+
+#ifndef STATUS_DUPLICATE_NAME
+# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL)
+#endif
+
+#ifndef STATUS_BAD_NETWORK_PATH
+# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL)
+#endif
+
+#ifndef STATUS_NETWORK_BUSY
+# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL)
+#endif
+
+#ifndef STATUS_DEVICE_DOES_NOT_EXIST
+# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L)
+#endif
+
+#ifndef STATUS_TOO_MANY_COMMANDS
+# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L)
+#endif
+
+#ifndef STATUS_ADAPTER_HARDWARE_ERROR
+# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L)
+#endif
+
+#ifndef STATUS_INVALID_NETWORK_RESPONSE
+# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_NETWORK_ERROR
+# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L)
+#endif
+
+#ifndef STATUS_BAD_REMOTE_ADAPTER
+# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L)
+#endif
+
+#ifndef STATUS_PRINT_QUEUE_FULL
+# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L)
+#endif
+
+#ifndef STATUS_NO_SPOOL_SPACE
+# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L)
+#endif
+
+#ifndef STATUS_PRINT_CANCELLED
+# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L)
+#endif
+
+#ifndef STATUS_NETWORK_NAME_DELETED
+# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L)
+#endif
+
+#ifndef STATUS_NETWORK_ACCESS_DENIED
+# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL)
+#endif
+
+#ifndef STATUS_BAD_DEVICE_TYPE
+# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL)
+#endif
+
+#ifndef STATUS_BAD_NETWORK_NAME
+# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL)
+#endif
+
+#ifndef STATUS_TOO_MANY_NAMES
+# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL)
+#endif
+
+#ifndef STATUS_TOO_MANY_SESSIONS
+# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL)
+#endif
+
+#ifndef STATUS_SHARING_PAUSED
+# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL)
+#endif
+
+#ifndef STATUS_REQUEST_NOT_ACCEPTED
+# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L)
+#endif
+
+#ifndef STATUS_REDIRECTOR_PAUSED
+# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L)
+#endif
+
+#ifndef STATUS_NET_WRITE_FAULT
+# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L)
+#endif
+
+#ifndef STATUS_PROFILING_AT_LIMIT
+# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L)
+#endif
+
+#ifndef STATUS_NOT_SAME_DEVICE
+# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L)
+#endif
+
+#ifndef STATUS_FILE_RENAMED
+# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L)
+#endif
+
+#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED
+# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L)
+#endif
+
+#ifndef STATUS_NO_SECURITY_ON_OBJECT
+# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L)
+#endif
+
+#ifndef STATUS_CANT_WAIT
+# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L)
+#endif
+
+#ifndef STATUS_PIPE_EMPTY
+# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L)
+#endif
+
+#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO
+# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL)
+#endif
+
+#ifndef STATUS_CANT_TERMINATE_SELF
+# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL)
+#endif
+
+#ifndef STATUS_INVALID_SERVER_STATE
+# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL)
+#endif
+
+#ifndef STATUS_INVALID_DOMAIN_STATE
+# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL)
+#endif
+
+#ifndef STATUS_INVALID_DOMAIN_ROLE
+# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL)
+#endif
+
+#ifndef STATUS_NO_SUCH_DOMAIN
+# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL)
+#endif
+
+#ifndef STATUS_DOMAIN_EXISTS
+# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L)
+#endif
+
+#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED
+# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L)
+#endif
+
+#ifndef STATUS_OPLOCK_NOT_GRANTED
+# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L)
+#endif
+
+#ifndef STATUS_INVALID_OPLOCK_PROTOCOL
+# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L)
+#endif
+
+#ifndef STATUS_INTERNAL_DB_CORRUPTION
+# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L)
+#endif
+
+#ifndef STATUS_INTERNAL_ERROR
+# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L)
+#endif
+
+#ifndef STATUS_GENERIC_NOT_MAPPED
+# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L)
+#endif
+
+#ifndef STATUS_BAD_DESCRIPTOR_FORMAT
+# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L)
+#endif
+
+#ifndef STATUS_INVALID_USER_BUFFER
+# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_IO_ERROR
+# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR
+# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR
+# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR
+# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL)
+#endif
+
+#ifndef STATUS_NOT_LOGON_PROCESS
+# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL)
+#endif
+
+#ifndef STATUS_LOGON_SESSION_EXISTS
+# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_1
+# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_2
+# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_3
+# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_4
+# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_5
+# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_6
+# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_7
+# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_8
+# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_9
+# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_10
+# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_11
+# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_12
+# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL)
+#endif
+
+#ifndef STATUS_REDIRECTOR_NOT_STARTED
+# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL)
+#endif
+
+#ifndef STATUS_REDIRECTOR_STARTED
+# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL)
+#endif
+
+#ifndef STATUS_STACK_OVERFLOW
+# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL)
+#endif
+
+#ifndef STATUS_NO_SUCH_PACKAGE
+# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL)
+#endif
+
+#ifndef STATUS_BAD_FUNCTION_TABLE
+# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL)
+#endif
+
+#ifndef STATUS_VARIABLE_NOT_FOUND
+# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L)
+#endif
+
+#ifndef STATUS_DIRECTORY_NOT_EMPTY
+# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L)
+#endif
+
+#ifndef STATUS_FILE_CORRUPT_ERROR
+# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L)
+#endif
+
+#ifndef STATUS_NOT_A_DIRECTORY
+# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L)
+#endif
+
+#ifndef STATUS_BAD_LOGON_SESSION_STATE
+# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L)
+#endif
+
+#ifndef STATUS_LOGON_SESSION_COLLISION
+# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L)
+#endif
+
+#ifndef STATUS_NAME_TOO_LONG
+# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L)
+#endif
+
+#ifndef STATUS_FILES_OPEN
+# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L)
+#endif
+
+#ifndef STATUS_CONNECTION_IN_USE
+# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L)
+#endif
+
+#ifndef STATUS_MESSAGE_NOT_FOUND
+# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L)
+#endif
+
+#ifndef STATUS_PROCESS_IS_TERMINATING
+# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL)
+#endif
+
+#ifndef STATUS_INVALID_LOGON_TYPE
+# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL)
+#endif
+
+#ifndef STATUS_NO_GUID_TRANSLATION
+# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL)
+#endif
+
+#ifndef STATUS_CANNOT_IMPERSONATE
+# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL)
+#endif
+
+#ifndef STATUS_IMAGE_ALREADY_LOADED
+# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL)
+#endif
+
+#ifndef STATUS_ABIOS_NOT_PRESENT
+# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL)
+#endif
+
+#ifndef STATUS_ABIOS_LID_NOT_EXIST
+# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L)
+#endif
+
+#ifndef STATUS_ABIOS_LID_ALREADY_OWNED
+# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L)
+#endif
+
+#ifndef STATUS_ABIOS_NOT_LID_OWNER
+# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_COMMAND
+# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_LID
+# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L)
+#endif
+
+#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE
+# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_SELECTOR
+# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L)
+#endif
+
+#ifndef STATUS_NO_LDT
+# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_SIZE
+# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_OFFSET
+# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_DESCRIPTOR
+# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_NE_FORMAT
+# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL)
+#endif
+
+#ifndef STATUS_RXACT_INVALID_STATE
+# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL)
+#endif
+
+#ifndef STATUS_RXACT_COMMIT_FAILURE
+# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL)
+#endif
+
+#ifndef STATUS_MAPPED_FILE_SIZE_ZERO
+# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL)
+#endif
+
+#ifndef STATUS_TOO_MANY_OPENED_FILES
+# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL)
+#endif
+
+#ifndef STATUS_CANCELLED
+# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
+#endif
+
+#ifndef STATUS_CANNOT_DELETE
+# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L)
+#endif
+
+#ifndef STATUS_INVALID_COMPUTER_NAME
+# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L)
+#endif
+
+#ifndef STATUS_FILE_DELETED
+# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L)
+#endif
+
+#ifndef STATUS_SPECIAL_ACCOUNT
+# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L)
+#endif
+
+#ifndef STATUS_SPECIAL_GROUP
+# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L)
+#endif
+
+#ifndef STATUS_SPECIAL_USER
+# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L)
+#endif
+
+#ifndef STATUS_MEMBERS_PRIMARY_GROUP
+# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L)
+#endif
+
+#ifndef STATUS_FILE_CLOSED
+# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L)
+#endif
+
+#ifndef STATUS_TOO_MANY_THREADS
+# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L)
+#endif
+
+#ifndef STATUS_THREAD_NOT_IN_PROCESS
+# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL)
+#endif
+
+#ifndef STATUS_TOKEN_ALREADY_IN_USE
+# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL)
+#endif
+
+#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED
+# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL)
+#endif
+
+#ifndef STATUS_COMMITMENT_LIMIT
+# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_LE_FORMAT
+# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_NOT_MZ
+# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_PROTECT
+# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_16
+# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L)
+#endif
+
+#ifndef STATUS_LOGON_SERVER_CONFLICT
+# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L)
+#endif
+
+#ifndef STATUS_TIME_DIFFERENCE_AT_DC
+# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L)
+#endif
+
+#ifndef STATUS_SYNCHRONIZATION_REQUIRED
+# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L)
+#endif
+
+#ifndef STATUS_DLL_NOT_FOUND
+# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L)
+#endif
+
+#ifndef STATUS_OPEN_FAILED
+# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L)
+#endif
+
+#ifndef STATUS_IO_PRIVILEGE_FAILED
+# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L)
+#endif
+
+#ifndef STATUS_ORDINAL_NOT_FOUND
+# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L)
+#endif
+
+#ifndef STATUS_ENTRYPOINT_NOT_FOUND
+# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L)
+#endif
+
+#ifndef STATUS_CONTROL_C_EXIT
+# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL)
+#endif
+
+#ifndef STATUS_LOCAL_DISCONNECT
+# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL)
+#endif
+
+#ifndef STATUS_REMOTE_DISCONNECT
+# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL)
+#endif
+
+#ifndef STATUS_REMOTE_RESOURCES
+# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL)
+#endif
+
+#ifndef STATUS_LINK_FAILED
+# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL)
+#endif
+
+#ifndef STATUS_LINK_TIMEOUT
+# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL)
+#endif
+
+#ifndef STATUS_INVALID_CONNECTION
+# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS
+# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L)
+#endif
+
+#ifndef STATUS_DLL_INIT_FAILED
+# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L)
+#endif
+
+#ifndef STATUS_MISSING_SYSTEMFILE
+# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L)
+#endif
+
+#ifndef STATUS_UNHANDLED_EXCEPTION
+# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L)
+#endif
+
+#ifndef STATUS_APP_INIT_FAILURE
+# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L)
+#endif
+
+#ifndef STATUS_PAGEFILE_CREATE_FAILED
+# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L)
+#endif
+
+#ifndef STATUS_NO_PAGEFILE
+# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L)
+#endif
+
+#ifndef STATUS_INVALID_LEVEL
+# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L)
+#endif
+
+#ifndef STATUS_WRONG_PASSWORD_CORE
+# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L)
+#endif
+
+#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT
+# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL)
+#endif
+
+#ifndef STATUS_PIPE_BROKEN
+# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL)
+#endif
+
+#ifndef STATUS_REGISTRY_CORRUPT
+# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL)
+#endif
+
+#ifndef STATUS_REGISTRY_IO_FAILED
+# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL)
+#endif
+
+#ifndef STATUS_NO_EVENT_PAIR
+# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL)
+#endif
+
+#ifndef STATUS_UNRECOGNIZED_VOLUME
+# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL)
+#endif
+
+#ifndef STATUS_SERIAL_NO_DEVICE_INITED
+# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L)
+#endif
+
+#ifndef STATUS_NO_SUCH_ALIAS
+# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L)
+#endif
+
+#ifndef STATUS_MEMBER_NOT_IN_ALIAS
+# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L)
+#endif
+
+#ifndef STATUS_MEMBER_IN_ALIAS
+# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L)
+#endif
+
+#ifndef STATUS_ALIAS_EXISTS
+# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L)
+#endif
+
+#ifndef STATUS_LOGON_NOT_GRANTED
+# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L)
+#endif
+
+#ifndef STATUS_TOO_MANY_SECRETS
+# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L)
+#endif
+
+#ifndef STATUS_SECRET_TOO_LONG
+# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L)
+#endif
+
+#ifndef STATUS_INTERNAL_DB_ERROR
+# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L)
+#endif
+
+#ifndef STATUS_FULLSCREEN_MODE
+# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L)
+#endif
+
+#ifndef STATUS_TOO_MANY_CONTEXT_IDS
+# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL)
+#endif
+
+#ifndef STATUS_LOGON_TYPE_NOT_GRANTED
+# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL)
+#endif
+
+#ifndef STATUS_NOT_REGISTRY_FILE
+# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL)
+#endif
+
+#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED
+# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL)
+#endif
+
+#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR
+# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL)
+#endif
+
+#ifndef STATUS_FT_MISSING_MEMBER
+# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL)
+#endif
+
+#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY
+# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L)
+#endif
+
+#ifndef STATUS_ILLEGAL_CHARACTER
+# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L)
+#endif
+
+#ifndef STATUS_UNMAPPABLE_CHARACTER
+# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L)
+#endif
+
+#ifndef STATUS_UNDEFINED_CHARACTER
+# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L)
+#endif
+
+#ifndef STATUS_FLOPPY_VOLUME
+# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L)
+#endif
+
+#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND
+# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L)
+#endif
+
+#ifndef STATUS_FLOPPY_WRONG_CYLINDER
+# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L)
+#endif
+
+#ifndef STATUS_FLOPPY_UNKNOWN_ERROR
+# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L)
+#endif
+
+#ifndef STATUS_FLOPPY_BAD_REGISTERS
+# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L)
+#endif
+
+#ifndef STATUS_DISK_RECALIBRATE_FAILED
+# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L)
+#endif
+
+#ifndef STATUS_DISK_OPERATION_FAILED
+# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL)
+#endif
+
+#ifndef STATUS_DISK_RESET_FAILED
+# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL)
+#endif
+
+#ifndef STATUS_SHARED_IRQ_BUSY
+# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL)
+#endif
+
+#ifndef STATUS_FT_ORPHANING
+# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL)
+#endif
+
+#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT
+# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL)
+#endif
+
+#ifndef STATUS_PARTITION_FAILURE
+# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L)
+#endif
+
+#ifndef STATUS_INVALID_BLOCK_LENGTH
+# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_PARTITIONED
+# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_LOCK_MEDIA
+# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA
+# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L)
+#endif
+
+#ifndef STATUS_EOM_OVERFLOW
+# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L)
+#endif
+
+#ifndef STATUS_NO_MEDIA
+# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L)
+#endif
+
+#ifndef STATUS_NO_SUCH_MEMBER
+# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL)
+#endif
+
+#ifndef STATUS_INVALID_MEMBER
+# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL)
+#endif
+
+#ifndef STATUS_KEY_DELETED
+# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL)
+#endif
+
+#ifndef STATUS_NO_LOG_SPACE
+# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL)
+#endif
+
+#ifndef STATUS_TOO_MANY_SIDS
+# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL)
+#endif
+
+#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED
+# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL)
+#endif
+
+#ifndef STATUS_KEY_HAS_CHILDREN
+# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L)
+#endif
+
+#ifndef STATUS_CHILD_MUST_BE_VOLATILE
+# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L)
+#endif
+
+#ifndef STATUS_DEVICE_CONFIGURATION_ERROR
+# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L)
+#endif
+
+#ifndef STATUS_DRIVER_INTERNAL_ERROR
+# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_STATE
+# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L)
+#endif
+
+#ifndef STATUS_IO_DEVICE_ERROR
+# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L)
+#endif
+
+#ifndef STATUS_DEVICE_PROTOCOL_ERROR
+# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L)
+#endif
+
+#ifndef STATUS_BACKUP_CONTROLLER
+# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L)
+#endif
+
+#ifndef STATUS_LOG_FILE_FULL
+# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L)
+#endif
+
+#ifndef STATUS_TOO_LATE
+# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L)
+#endif
+
+#ifndef STATUS_NO_TRUST_LSA_SECRET
+# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL)
+#endif
+
+#ifndef STATUS_NO_TRUST_SAM_ACCOUNT
+# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL)
+#endif
+
+#ifndef STATUS_TRUSTED_DOMAIN_FAILURE
+# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL)
+#endif
+
+#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE
+# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL)
+#endif
+
+#ifndef STATUS_EVENTLOG_FILE_CORRUPT
+# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL)
+#endif
+
+#ifndef STATUS_EVENTLOG_CANT_START
+# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL)
+#endif
+
+#ifndef STATUS_TRUST_FAILURE
+# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L)
+#endif
+
+#ifndef STATUS_MUTANT_LIMIT_EXCEEDED
+# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L)
+#endif
+
+#ifndef STATUS_NETLOGON_NOT_STARTED
+# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L)
+#endif
+
+#ifndef STATUS_ACCOUNT_EXPIRED
+# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L)
+#endif
+
+#ifndef STATUS_POSSIBLE_DEADLOCK
+# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L)
+#endif
+
+#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT
+# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L)
+#endif
+
+#ifndef STATUS_REMOTE_SESSION_LIMIT
+# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L)
+#endif
+
+#ifndef STATUS_EVENTLOG_FILE_CHANGED
+# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L)
+#endif
+
+#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
+# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L)
+#endif
+
+#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L)
+#endif
+
+#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT
+# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL)
+#endif
+
+#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT
+# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL)
+#endif
+
+#ifndef STATUS_FS_DRIVER_REQUIRED
+# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL)
+#endif
+
+#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL
+# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING
+# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL)
+#endif
+
+#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME
+# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL)
+#endif
+
+#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT
+# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L)
+#endif
+
+#ifndef STATUS_INVALID_LOCK_RANGE
+# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L)
+#endif
+
+#ifndef STATUS_INVALID_ACE_CONDITION
+# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L)
+#endif
+
+#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT
+# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L)
+#endif
+
+#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED
+# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L)
+#endif
+
+#ifndef STATUS_NETWORK_OPEN_RESTRICTION
+# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L)
+#endif
+
+#ifndef STATUS_NO_USER_SESSION_KEY
+# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L)
+#endif
+
+#ifndef STATUS_USER_SESSION_DELETED
+# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L)
+#endif
+
+#ifndef STATUS_RESOURCE_LANG_NOT_FOUND
+# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L)
+#endif
+
+#ifndef STATUS_INSUFF_SERVER_RESOURCES
+# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L)
+#endif
+
+#ifndef STATUS_INVALID_BUFFER_SIZE
+# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS_COMPONENT
+# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS_WILDCARD
+# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L)
+#endif
+
+#ifndef STATUS_TOO_MANY_ADDRESSES
+# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L)
+#endif
+
+#ifndef STATUS_ADDRESS_ALREADY_EXISTS
+# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL)
+#endif
+
+#ifndef STATUS_ADDRESS_CLOSED
+# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL)
+#endif
+
+#ifndef STATUS_CONNECTION_DISCONNECTED
+# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL)
+#endif
+
+#ifndef STATUS_CONNECTION_RESET
+# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL)
+#endif
+
+#ifndef STATUS_TOO_MANY_NODES
+# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL)
+#endif
+
+#ifndef STATUS_TRANSACTION_ABORTED
+# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL)
+#endif
+
+#ifndef STATUS_TRANSACTION_TIMED_OUT
+# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L)
+#endif
+
+#ifndef STATUS_TRANSACTION_NO_RELEASE
+# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L)
+#endif
+
+#ifndef STATUS_TRANSACTION_NO_MATCH
+# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L)
+#endif
+
+#ifndef STATUS_TRANSACTION_RESPONDED
+# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L)
+#endif
+
+#ifndef STATUS_TRANSACTION_INVALID_ID
+# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L)
+#endif
+
+#ifndef STATUS_TRANSACTION_INVALID_TYPE
+# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L)
+#endif
+
+#ifndef STATUS_NOT_SERVER_SESSION
+# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L)
+#endif
+
+#ifndef STATUS_NOT_CLIENT_SESSION
+# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L)
+#endif
+
+#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE
+# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L)
+#endif
+
+#ifndef STATUS_DEBUG_ATTACH_FAILED
+# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L)
+#endif
+
+#ifndef STATUS_SYSTEM_PROCESS_TERMINATED
+# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL)
+#endif
+
+#ifndef STATUS_DATA_NOT_ACCEPTED
+# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL)
+#endif
+
+#ifndef STATUS_NO_BROWSER_SERVERS_FOUND
+# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL)
+#endif
+
+#ifndef STATUS_VDM_HARD_ERROR
+# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL)
+#endif
+
+#ifndef STATUS_DRIVER_CANCEL_TIMEOUT
+# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL)
+#endif
+
+#ifndef STATUS_REPLY_MESSAGE_MISMATCH
+# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL)
+#endif
+
+#ifndef STATUS_MAPPED_ALIGNMENT
+# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L)
+#endif
+
+#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH
+# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA
+# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L)
+#endif
+
+#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID
+# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L)
+#endif
+
+#ifndef STATUS_PASSWORD_MUST_CHANGE
+# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L)
+#endif
+
+#ifndef STATUS_NOT_FOUND
+# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L)
+#endif
+
+#ifndef STATUS_NOT_TINY_STREAM
+# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L)
+#endif
+
+#ifndef STATUS_RECOVERY_FAILURE
+# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L)
+#endif
+
+#ifndef STATUS_STACK_OVERFLOW_READ
+# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L)
+#endif
+
+#ifndef STATUS_FAIL_CHECK
+# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L)
+#endif
+
+#ifndef STATUS_DUPLICATE_OBJECTID
+# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL)
+#endif
+
+#ifndef STATUS_OBJECTID_EXISTS
+# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL)
+#endif
+
+#ifndef STATUS_CONVERT_TO_LARGE
+# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL)
+#endif
+
+#ifndef STATUS_RETRY
+# define STATUS_RETRY ((NTSTATUS) 0xC000022DL)
+#endif
+
+#ifndef STATUS_FOUND_OUT_OF_SCOPE
+# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL)
+#endif
+
+#ifndef STATUS_ALLOCATE_BUCKET
+# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL)
+#endif
+
+#ifndef STATUS_PROPSET_NOT_FOUND
+# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L)
+#endif
+
+#ifndef STATUS_MARSHALL_OVERFLOW
+# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L)
+#endif
+
+#ifndef STATUS_INVALID_VARIANT
+# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L)
+#endif
+
+#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND
+# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L)
+#endif
+
+#ifndef STATUS_ACCOUNT_LOCKED_OUT
+# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L)
+#endif
+
+#ifndef STATUS_HANDLE_NOT_CLOSABLE
+# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L)
+#endif
+
+#ifndef STATUS_CONNECTION_REFUSED
+# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L)
+#endif
+
+#ifndef STATUS_GRACEFUL_DISCONNECT
+# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L)
+#endif
+
+#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED
+# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L)
+#endif
+
+#ifndef STATUS_ADDRESS_NOT_ASSOCIATED
+# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L)
+#endif
+
+#ifndef STATUS_CONNECTION_INVALID
+# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL)
+#endif
+
+#ifndef STATUS_CONNECTION_ACTIVE
+# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL)
+#endif
+
+#ifndef STATUS_NETWORK_UNREACHABLE
+# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL)
+#endif
+
+#ifndef STATUS_HOST_UNREACHABLE
+# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL)
+#endif
+
+#ifndef STATUS_PROTOCOL_UNREACHABLE
+# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL)
+#endif
+
+#ifndef STATUS_PORT_UNREACHABLE
+# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL)
+#endif
+
+#ifndef STATUS_REQUEST_ABORTED
+# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L)
+#endif
+
+#ifndef STATUS_CONNECTION_ABORTED
+# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L)
+#endif
+
+#ifndef STATUS_BAD_COMPRESSION_BUFFER
+# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L)
+#endif
+
+#ifndef STATUS_USER_MAPPED_FILE
+# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L)
+#endif
+
+#ifndef STATUS_AUDIT_FAILED
+# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L)
+#endif
+
+#ifndef STATUS_TIMER_RESOLUTION_NOT_SET
+# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L)
+#endif
+
+#ifndef STATUS_CONNECTION_COUNT_LIMIT
+# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L)
+#endif
+
+#ifndef STATUS_LOGIN_TIME_RESTRICTION
+# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L)
+#endif
+
+#ifndef STATUS_LOGIN_WKSTA_RESTRICTION
+# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L)
+#endif
+
+#ifndef STATUS_IMAGE_MP_UP_MISMATCH
+# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_LOGON_INFO
+# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L)
+#endif
+
+#ifndef STATUS_BAD_DLL_ENTRYPOINT
+# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L)
+#endif
+
+#ifndef STATUS_BAD_SERVICE_ENTRYPOINT
+# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L)
+#endif
+
+#ifndef STATUS_LPC_REPLY_LOST
+# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L)
+#endif
+
+#ifndef STATUS_IP_ADDRESS_CONFLICT1
+# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L)
+#endif
+
+#ifndef STATUS_IP_ADDRESS_CONFLICT2
+# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L)
+#endif
+
+#ifndef STATUS_REGISTRY_QUOTA_LIMIT
+# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L)
+#endif
+
+#ifndef STATUS_PATH_NOT_COVERED
+# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L)
+#endif
+
+#ifndef STATUS_NO_CALLBACK_ACTIVE
+# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L)
+#endif
+
+#ifndef STATUS_LICENSE_QUOTA_EXCEEDED
+# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L)
+#endif
+
+#ifndef STATUS_PWD_TOO_SHORT
+# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL)
+#endif
+
+#ifndef STATUS_PWD_TOO_RECENT
+# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL)
+#endif
+
+#ifndef STATUS_PWD_HISTORY_CONFLICT
+# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL)
+#endif
+
+#ifndef STATUS_PLUGPLAY_NO_DEVICE
+# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL)
+#endif
+
+#ifndef STATUS_UNSUPPORTED_COMPRESSION
+# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL)
+#endif
+
+#ifndef STATUS_INVALID_HW_PROFILE
+# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L)
+#endif
+
+#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH
+# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L)
+#endif
+
+#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND
+# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L)
+#endif
+
+#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
+# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L)
+#endif
+
+#ifndef STATUS_RESOURCE_NOT_OWNED
+# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L)
+#endif
+
+#ifndef STATUS_TOO_MANY_LINKS
+# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L)
+#endif
+
+#ifndef STATUS_QUOTA_LIST_INCONSISTENT
+# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L)
+#endif
+
+#ifndef STATUS_FILE_IS_OFFLINE
+# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L)
+#endif
+
+#ifndef STATUS_EVALUATION_EXPIRATION
+# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L)
+#endif
+
+#ifndef STATUS_ILLEGAL_DLL_RELOCATION
+# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L)
+#endif
+
+#ifndef STATUS_LICENSE_VIOLATION
+# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL)
+#endif
+
+#ifndef STATUS_DLL_INIT_FAILED_LOGOFF
+# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL)
+#endif
+
+#ifndef STATUS_DRIVER_UNABLE_TO_LOAD
+# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL)
+#endif
+
+#ifndef STATUS_DFS_UNAVAILABLE
+# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL)
+#endif
+
+#ifndef STATUS_VOLUME_DISMOUNTED
+# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL)
+#endif
+
+#ifndef STATUS_WX86_INTERNAL_ERROR
+# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL)
+#endif
+
+#ifndef STATUS_WX86_FLOAT_STACK_CHECK
+# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L)
+#endif
+
+#ifndef STATUS_VALIDATE_CONTINUE
+# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L)
+#endif
+
+#ifndef STATUS_NO_MATCH
+# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L)
+#endif
+
+#ifndef STATUS_NO_MORE_MATCHES
+# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L)
+#endif
+
+#ifndef STATUS_NOT_A_REPARSE_POINT
+# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_INVALID
+# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_MISMATCH
+# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_DATA_INVALID
+# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED
+# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L)
+#endif
+
+#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED
+# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L)
+#endif
+
+#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT
+# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L)
+#endif
+
+#ifndef STATUS_RANGE_LIST_CONFLICT
+# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L)
+#endif
+
+#ifndef STATUS_SOURCE_ELEMENT_EMPTY
+# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L)
+#endif
+
+#ifndef STATUS_DESTINATION_ELEMENT_FULL
+# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L)
+#endif
+
+#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS
+# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L)
+#endif
+
+#ifndef STATUS_MAGAZINE_NOT_PRESENT
+# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L)
+#endif
+
+#ifndef STATUS_REINITIALIZATION_NEEDED
+# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L)
+#endif
+
+#ifndef STATUS_DEVICE_REQUIRES_CLEANING
+# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L)
+#endif
+
+#ifndef STATUS_DEVICE_DOOR_OPEN
+# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L)
+#endif
+
+#ifndef STATUS_ENCRYPTION_FAILED
+# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL)
+#endif
+
+#ifndef STATUS_DECRYPTION_FAILED
+# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL)
+#endif
+
+#ifndef STATUS_RANGE_NOT_FOUND
+# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL)
+#endif
+
+#ifndef STATUS_NO_RECOVERY_POLICY
+# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL)
+#endif
+
+#ifndef STATUS_NO_EFS
+# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL)
+#endif
+
+#ifndef STATUS_WRONG_EFS
+# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL)
+#endif
+
+#ifndef STATUS_NO_USER_KEYS
+# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L)
+#endif
+
+#ifndef STATUS_FILE_NOT_ENCRYPTED
+# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L)
+#endif
+
+#ifndef STATUS_NOT_EXPORT_FORMAT
+# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L)
+#endif
+
+#ifndef STATUS_FILE_ENCRYPTED
+# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L)
+#endif
+
+#ifndef STATUS_WAKE_SYSTEM
+# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L)
+#endif
+
+#ifndef STATUS_WMI_GUID_NOT_FOUND
+# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L)
+#endif
+
+#ifndef STATUS_WMI_INSTANCE_NOT_FOUND
+# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L)
+#endif
+
+#ifndef STATUS_WMI_ITEMID_NOT_FOUND
+# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L)
+#endif
+
+#ifndef STATUS_WMI_TRY_AGAIN
+# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L)
+#endif
+
+#ifndef STATUS_SHARED_POLICY
+# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L)
+#endif
+
+#ifndef STATUS_POLICY_OBJECT_NOT_FOUND
+# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL)
+#endif
+
+#ifndef STATUS_POLICY_ONLY_IN_DS
+# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL)
+#endif
+
+#ifndef STATUS_VOLUME_NOT_UPGRADED
+# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL)
+#endif
+
+#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE
+# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL)
+#endif
+
+#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR
+# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL)
+#endif
+
+#ifndef STATUS_NO_TRACKING_SERVICE
+# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL)
+#endif
+
+#ifndef STATUS_SERVER_SID_MISMATCH
+# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L)
+#endif
+
+#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE
+# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L)
+#endif
+
+#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX
+# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L)
+#endif
+
+#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED
+# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L)
+#endif
+
+#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS
+# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L)
+#endif
+
+#ifndef STATUS_DS_BUSY
+# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L)
+#endif
+
+#ifndef STATUS_DS_UNAVAILABLE
+# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L)
+#endif
+
+#ifndef STATUS_DS_NO_RIDS_ALLOCATED
+# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L)
+#endif
+
+#ifndef STATUS_DS_NO_MORE_RIDS
+# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L)
+#endif
+
+#ifndef STATUS_DS_INCORRECT_ROLE_OWNER
+# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L)
+#endif
+
+#ifndef STATUS_DS_RIDMGR_INIT_ERROR
+# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL)
+#endif
+
+#ifndef STATUS_DS_OBJ_CLASS_VIOLATION
+# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL)
+#endif
+
+#ifndef STATUS_DS_CANT_ON_NON_LEAF
+# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL)
+#endif
+
+#ifndef STATUS_DS_CANT_ON_RDN
+# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL)
+#endif
+
+#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS
+# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL)
+#endif
+
+#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED
+# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL)
+#endif
+
+#ifndef STATUS_DS_GC_NOT_AVAILABLE
+# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L)
+#endif
+
+#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED
+# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L)
+#endif
+
+#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT
+# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L)
+#endif
+
+#ifndef STATUS_CANT_ENABLE_DENY_ONLY
+# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L)
+#endif
+
+#ifndef STATUS_FLOAT_MULTIPLE_FAULTS
+# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L)
+#endif
+
+#ifndef STATUS_FLOAT_MULTIPLE_TRAPS
+# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L)
+#endif
+
+#ifndef STATUS_DEVICE_REMOVED
+# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L)
+#endif
+
+#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS
+# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L)
+#endif
+
+#ifndef STATUS_JOURNAL_NOT_ACTIVE
+# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L)
+#endif
+
+#ifndef STATUS_NOINTERFACE
+# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L)
+#endif
+
+#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED
+# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L)
+#endif
+
+#ifndef STATUS_DRIVER_FAILED_SLEEP
+# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L)
+#endif
+
+#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED
+# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L)
+#endif
+
+#ifndef STATUS_CORRUPT_SYSTEM_FILE
+# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L)
+#endif
+
+#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR
+# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L)
+#endif
+
+#ifndef STATUS_WMI_READ_ONLY
+# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L)
+#endif
+
+#ifndef STATUS_WMI_SET_FAILURE
+# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L)
+#endif
+
+#ifndef STATUS_COMMITMENT_MINIMUM
+# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L)
+#endif
+
+#ifndef STATUS_REG_NAT_CONSUMPTION
+# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L)
+#endif
+
+#ifndef STATUS_TRANSPORT_FULL
+# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL)
+#endif
+
+#ifndef STATUS_DS_SAM_INIT_FAILURE
+# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL)
+#endif
+
+#ifndef STATUS_ONLY_IF_CONNECTED
+# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL)
+#endif
+
+#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION
+# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL)
+#endif
+
+#ifndef STATUS_PNP_RESTART_ENUMERATION
+# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL)
+#endif
+
+#ifndef STATUS_JOURNAL_ENTRY_DELETED
+# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL)
+#endif
+
+#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID
+# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L)
+#endif
+
+#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE
+# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L)
+#endif
+
+#ifndef STATUS_PNP_REBOOT_REQUIRED
+# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L)
+#endif
+
+#ifndef STATUS_POWER_STATE_INVALID
+# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L)
+#endif
+
+#ifndef STATUS_DS_INVALID_GROUP_TYPE
+# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L)
+#endif
+
+#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN
+# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L)
+#endif
+
+#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN
+# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L)
+#endif
+
+#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER
+# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL)
+#endif
+
+#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER
+# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL)
+#endif
+
+#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS
+# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL)
+#endif
+
+#ifndef STATUS_WMI_NOT_SUPPORTED
+# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_POWER
+# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL)
+#endif
+
+#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD
+# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL)
+#endif
+
+#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY
+# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L)
+#endif
+
+#ifndef STATUS_DS_CANT_START
+# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L)
+#endif
+
+#ifndef STATUS_DS_INIT_FAILURE
+# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L)
+#endif
+
+#ifndef STATUS_SAM_INIT_FAILURE
+# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L)
+#endif
+
+#ifndef STATUS_DS_GC_REQUIRED
+# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L)
+#endif
+
+#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY
+# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L)
+#endif
+
+#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS
+# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L)
+#endif
+
+#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED
+# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L)
+#endif
+
+#ifndef STATUS_MULTIPLE_FAULT_VIOLATION
+# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L)
+#endif
+
+#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED
+# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L)
+#endif
+
+#ifndef STATUS_CANNOT_MAKE
+# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL)
+#endif
+
+#ifndef STATUS_SYSTEM_SHUTDOWN
+# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL)
+#endif
+
+#ifndef STATUS_DS_INIT_FAILURE_CONSOLE
+# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL)
+#endif
+
+#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE
+# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL)
+#endif
+
+#ifndef STATUS_UNFINISHED_CONTEXT_DELETED
+# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL)
+#endif
+
+#ifndef STATUS_NO_TGT_REPLY
+# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL)
+#endif
+
+#ifndef STATUS_OBJECTID_NOT_FOUND
+# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L)
+#endif
+
+#ifndef STATUS_NO_IP_ADDRESSES
+# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L)
+#endif
+
+#ifndef STATUS_WRONG_CREDENTIAL_HANDLE
+# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L)
+#endif
+
+#ifndef STATUS_CRYPTO_SYSTEM_INVALID
+# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L)
+#endif
+
+#ifndef STATUS_MAX_REFERRALS_EXCEEDED
+# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L)
+#endif
+
+#ifndef STATUS_MUST_BE_KDC
+# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L)
+#endif
+
+#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED
+# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L)
+#endif
+
+#ifndef STATUS_TOO_MANY_PRINCIPALS
+# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L)
+#endif
+
+#ifndef STATUS_NO_PA_DATA
+# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L)
+#endif
+
+#ifndef STATUS_PKINIT_NAME_MISMATCH
+# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L)
+#endif
+
+#ifndef STATUS_SMARTCARD_LOGON_REQUIRED
+# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL)
+#endif
+
+#ifndef STATUS_KDC_INVALID_REQUEST
+# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL)
+#endif
+
+#ifndef STATUS_KDC_UNABLE_TO_REFER
+# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL)
+#endif
+
+#ifndef STATUS_KDC_UNKNOWN_ETYPE
+# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL)
+#endif
+
+#ifndef STATUS_SHUTDOWN_IN_PROGRESS
+# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL)
+#endif
+
+#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS
+# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED_ON_SBS
+# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L)
+#endif
+
+#ifndef STATUS_WMI_GUID_DISCONNECTED
+# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L)
+#endif
+
+#ifndef STATUS_WMI_ALREADY_DISABLED
+# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L)
+#endif
+
+#ifndef STATUS_WMI_ALREADY_ENABLED
+# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L)
+#endif
+
+#ifndef STATUS_MFT_TOO_FRAGMENTED
+# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L)
+#endif
+
+#ifndef STATUS_COPY_PROTECTION_FAILURE
+# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L)
+#endif
+
+#ifndef STATUS_CSS_AUTHENTICATION_FAILURE
+# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L)
+#endif
+
+#ifndef STATUS_CSS_KEY_NOT_PRESENT
+# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L)
+#endif
+
+#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED
+# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L)
+#endif
+
+#ifndef STATUS_CSS_SCRAMBLED_SECTOR
+# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L)
+#endif
+
+#ifndef STATUS_CSS_REGION_MISMATCH
+# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL)
+#endif
+
+#ifndef STATUS_CSS_RESETS_EXHAUSTED
+# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL)
+#endif
+
+#ifndef STATUS_PKINIT_FAILURE
+# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L)
+#endif
+
+#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE
+# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L)
+#endif
+
+#ifndef STATUS_NO_KERB_KEY
+# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L)
+#endif
+
+#ifndef STATUS_HOST_DOWN
+# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L)
+#endif
+
+#ifndef STATUS_UNSUPPORTED_PREAUTH
+# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L)
+#endif
+
+#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG
+# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L)
+#endif
+
+#ifndef STATUS_PORT_NOT_SET
+# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L)
+#endif
+
+#ifndef STATUS_DEBUGGER_INACTIVE
+# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L)
+#endif
+
+#ifndef STATUS_DS_VERSION_CHECK_FAILURE
+# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L)
+#endif
+
+#ifndef STATUS_AUDITING_DISABLED
+# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L)
+#endif
+
+#ifndef STATUS_PRENT4_MACHINE_ACCOUNT
+# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L)
+#endif
+
+#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER
+# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_32
+# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_64
+# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL)
+#endif
+
+#ifndef STATUS_BAD_BINDINGS
+# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL)
+#endif
+
+#ifndef STATUS_NETWORK_SESSION_EXPIRED
+# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL)
+#endif
+
+#ifndef STATUS_APPHELP_BLOCK
+# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL)
+#endif
+
+#ifndef STATUS_ALL_SIDS_FILTERED
+# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL)
+#endif
+
+#ifndef STATUS_NOT_SAFE_MODE_DRIVER
+# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT
+# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH
+# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER
+# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER
+# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L)
+#endif
+
+#ifndef STATUS_FAILED_DRIVER_ENTRY
+# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L)
+#endif
+
+#ifndef STATUS_DEVICE_ENUMERATION_ERROR
+# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L)
+#endif
+
+#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED
+# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER
+# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L)
+#endif
+
+#ifndef STATUS_MCA_OCCURED
+# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL)
+#endif
+
+#ifndef STATUS_DRIVER_BLOCKED_CRITICAL
+# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL)
+#endif
+
+#ifndef STATUS_DRIVER_BLOCKED
+# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL)
+#endif
+
+#ifndef STATUS_DRIVER_DATABASE_ERROR
+# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL)
+#endif
+
+#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE
+# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL)
+#endif
+
+#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL
+# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL)
+#endif
+
+#ifndef STATUS_DS_SHUTTING_DOWN
+# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L)
+#endif
+
+#ifndef STATUS_NO_SECRETS
+# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY
+# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L)
+#endif
+
+#ifndef STATUS_FAILED_STACK_SWITCH
+# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L)
+#endif
+
+#ifndef STATUS_HEAP_CORRUPTION
+# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L)
+#endif
+
+#ifndef STATUS_SMARTCARD_WRONG_PIN
+# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CARD_BLOCKED
+# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED
+# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_CARD
+# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER
+# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_CERTIFICATE
+# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_KEYSET
+# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L)
+#endif
+
+#ifndef STATUS_SMARTCARD_IO_ERROR
+# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L)
+#endif
+
+#ifndef STATUS_DOWNGRADE_DETECTED
+# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CERT_REVOKED
+# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L)
+#endif
+
+#ifndef STATUS_ISSUING_CA_UNTRUSTED
+# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL)
+#endif
+
+#ifndef STATUS_REVOCATION_OFFLINE_C
+# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL)
+#endif
+
+#ifndef STATUS_PKINIT_CLIENT_FAILURE
+# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL)
+#endif
+
+#ifndef STATUS_SMARTCARD_CERT_EXPIRED
+# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL)
+#endif
+
+#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD
+# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL)
+#endif
+
+#ifndef STATUS_SMARTCARD_SILENT_CONTEXT
+# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL)
+#endif
+
+#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED
+# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L)
+#endif
+
+#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED
+# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L)
+#endif
+
+#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED
+# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L)
+#endif
+
+#ifndef STATUS_DS_NAME_NOT_UNIQUE
+# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L)
+#endif
+
+#ifndef STATUS_DS_DUPLICATE_ID_FOUND
+# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L)
+#endif
+
+#ifndef STATUS_DS_GROUP_CONVERSION_ERROR
+# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L)
+#endif
+
+#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE
+# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L)
+#endif
+
+#ifndef STATUS_USER2USER_REQUIRED
+# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L)
+#endif
+
+#ifndef STATUS_STACK_BUFFER_OVERRUN
+# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L)
+#endif
+
+#ifndef STATUS_NO_S4U_PROT_SUPPORT
+# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL)
+#endif
+
+#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE
+# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL)
+#endif
+
+#ifndef STATUS_REVOCATION_OFFLINE_KDC
+# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL)
+#endif
+
+#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC
+# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL)
+#endif
+
+#ifndef STATUS_KDC_CERT_EXPIRED
+# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL)
+#endif
+
+#ifndef STATUS_KDC_CERT_REVOKED
+# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL)
+#endif
+
+#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED
+# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L)
+#endif
+
+#ifndef STATUS_HIBERNATION_FAILURE
+# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L)
+#endif
+
+#ifndef STATUS_DELAY_LOAD_FAILED
+# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L)
+#endif
+
+#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED
+# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L)
+#endif
+
+#ifndef STATUS_VDM_DISALLOWED
+# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L)
+#endif
+
+#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD
+# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE
+# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L)
+#endif
+
+#ifndef STATUS_INVALID_CRUNTIME_PARAMETER
+# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L)
+#endif
+
+#ifndef STATUS_NTLM_BLOCKED
+# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L)
+#endif
+
+#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST
+# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L)
+#endif
+
+#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST
+# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL)
+#endif
+
+#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST
+# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL)
+#endif
+
+#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME
+# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL)
+#endif
+
+#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION
+# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL)
+#endif
+
+#ifndef STATUS_ASSERTION_FAILURE
+# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L)
+#endif
+
+#ifndef STATUS_VERIFIER_STOP
+# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L)
+#endif
+
+#ifndef STATUS_CALLBACK_POP_STACK
+# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED
+# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L)
+#endif
+
+#ifndef STATUS_HIVE_UNLOADED
+# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L)
+#endif
+
+#ifndef STATUS_COMPRESSION_DISABLED
+# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L)
+#endif
+
+#ifndef STATUS_FILE_SYSTEM_LIMITATION
+# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_HASH
+# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L)
+#endif
+
+#ifndef STATUS_NOT_CAPABLE
+# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L)
+#endif
+
+#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE
+# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL)
+#endif
+
+#ifndef STATUS_IMPLEMENTATION_LIMIT
+# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL)
+#endif
+
+#ifndef STATUS_ELEVATION_REQUIRED
+# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL)
+#endif
+
+#ifndef STATUS_NO_SECURITY_CONTEXT
+# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL)
+#endif
+
+#ifndef STATUS_PKU2U_CERT_FAILURE
+# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL)
+#endif
+
+#ifndef STATUS_BEYOND_VDL
+# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L)
+#endif
+
+#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS
+# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L)
+#endif
+
+#ifndef STATUS_PTE_CHANGED
+# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L)
+#endif
+
+#ifndef STATUS_PURGE_FAILED
+# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L)
+#endif
+
+#ifndef STATUS_CRED_REQUIRES_CONFIRMATION
+# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE
+# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER
+# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE
+# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE
+# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE
+# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L)
+#endif
+
+#ifndef STATUS_INVALID_LABEL
+# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L)
+#endif
+
+#ifndef STATUS_DRIVER_PROCESS_TERMINATED
+# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L)
+#endif
+
+#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE
+# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L)
+#endif
+
+#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND
+# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L)
+#endif
+
+#ifndef STATUS_RESTART_BOOT_APPLICATION
+# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES
+# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L)
+#endif
+
+#ifndef STATUS_INVALID_TASK_NAME
+# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L)
+#endif
+
+#ifndef STATUS_INVALID_TASK_INDEX
+# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L)
+#endif
+
+#ifndef STATUS_THREAD_ALREADY_IN_TASK
+# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L)
+#endif
+
+#ifndef STATUS_CALLBACK_BYPASS
+# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L)
+#endif
+
+#ifndef STATUS_FAIL_FAST_EXCEPTION
+# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L)
+#endif
+
+#ifndef STATUS_IMAGE_CERT_REVOKED
+# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L)
+#endif
+
+#ifndef STATUS_PORT_CLOSED
+# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L)
+#endif
+
+#ifndef STATUS_MESSAGE_LOST
+# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L)
+#endif
+
+#ifndef STATUS_INVALID_MESSAGE
+# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L)
+#endif
+
+#ifndef STATUS_REQUEST_CANCELED
+# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L)
+#endif
+
+#ifndef STATUS_RECURSIVE_DISPATCH
+# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L)
+#endif
+
+#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED
+# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L)
+#endif
+
+#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE
+# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L)
+#endif
+
+#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED
+# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L)
+#endif
+
+#ifndef STATUS_RESOURCE_IN_USE
+# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L)
+#endif
+
+#ifndef STATUS_HARDWARE_MEMORY_ERROR
+# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L)
+#endif
+
+#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION
+# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL)
+#endif
+
+#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL)
+#endif
+
+#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION
+# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING
+# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L)
+#endif
+
+#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING
+# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L)
+#endif
+
+#ifndef STATUS_PROCESS_IS_PROTECTED
+# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L)
+#endif
+
+#ifndef STATUS_MCA_EXCEPTION
+# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L)
+#endif
+
+#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE
+# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L)
+#endif
+
+#ifndef STATUS_SYMLINK_CLASS_DISABLED
+# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L)
+#endif
+
+#ifndef STATUS_INVALID_IDN_NORMALIZATION
+# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L)
+#endif
+
+#ifndef STATUS_NO_UNICODE_TRANSLATION
+# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L)
+#endif
+
+#ifndef STATUS_ALREADY_REGISTERED
+# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L)
+#endif
+
+#ifndef STATUS_CONTEXT_MISMATCH
+# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L)
+#endif
+
+#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST
+# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY
+# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL)
+#endif
+
+#ifndef STATUS_INVALID_THREAD
+# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION
+# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK
+# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_LANG
+# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK
+# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY
+# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L)
+#endif
+
+#ifndef STATUS_DISK_REPAIR_DISABLED
+# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L)
+#endif
+
+#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS
+# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L)
+#endif
+
+#ifndef STATUS_DISK_QUOTA_EXCEEDED
+# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L)
+#endif
+
+#ifndef STATUS_DATA_LOST_REPAIR
+# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L)
+#endif
+
+#ifndef STATUS_CONTENT_BLOCKED
+# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L)
+#endif
+
+#ifndef STATUS_BAD_CLUSTERS
+# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L)
+#endif
+
+#ifndef STATUS_VOLUME_DIRTY
+# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L)
+#endif
+
+#ifndef STATUS_FILE_CHECKED_OUT
+# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L)
+#endif
+
+#ifndef STATUS_CHECKOUT_REQUIRED
+# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L)
+#endif
+
+#ifndef STATUS_BAD_FILE_TYPE
+# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L)
+#endif
+
+#ifndef STATUS_FILE_TOO_LARGE
+# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L)
+#endif
+
+#ifndef STATUS_FORMS_AUTH_REQUIRED
+# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L)
+#endif
+
+#ifndef STATUS_VIRUS_INFECTED
+# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L)
+#endif
+
+#ifndef STATUS_VIRUS_DELETED
+# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L)
+#endif
+
+#ifndef STATUS_BAD_MCFG_TABLE
+# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L)
+#endif
+
+#ifndef STATUS_CANNOT_BREAK_OPLOCK
+# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L)
+#endif
+
+#ifndef STATUS_WOW_ASSERTION
+# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L)
+#endif
+
+#ifndef STATUS_INVALID_SIGNATURE
+# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L)
+#endif
+
+#ifndef STATUS_HMAC_NOT_SUPPORTED
+# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L)
+#endif
+
+#ifndef STATUS_AUTH_TAG_MISMATCH
+# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L)
+#endif
+
+#ifndef STATUS_IPSEC_QUEUE_OVERFLOW
+# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L)
+#endif
+
+#ifndef STATUS_ND_QUEUE_OVERFLOW
+# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L)
+#endif
+
+#ifndef STATUS_HOPLIMIT_EXCEEDED
+# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L)
+#endif
+
+#ifndef STATUS_PROTOCOL_NOT_SUPPORTED
+# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L)
+#endif
+
+#ifndef STATUS_FASTPATH_REJECTED
+# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED
+# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR
+# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR
+# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L)
+#endif
+
+#ifndef STATUS_XML_PARSE_ERROR
+# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L)
+#endif
+
+#ifndef STATUS_XMLDSIG_ERROR
+# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L)
+#endif
+
+#ifndef STATUS_WRONG_COMPARTMENT
+# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L)
+#endif
+
+#ifndef STATUS_AUTHIP_FAILURE
+# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L)
+#endif
+
+#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS
+# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L)
+#endif
+
+#ifndef STATUS_DS_OID_NOT_FOUND
+# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L)
+#endif
+
+#ifndef STATUS_HASH_NOT_SUPPORTED
+# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L)
+#endif
+
+#ifndef STATUS_HASH_NOT_PRESENT
+# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L)
+#endif
+
+/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */
+/* DDK got it wrong! */
+#ifdef NTSTATUS_FROM_WIN32
+# undef NTSTATUS_FROM_WIN32
+#endif
+#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \
+ ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \
+ (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING)))
+
+#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY
+# define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100
+#endif
+#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY
+# define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200
+#endif
+#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION
+# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
+#endif
+#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK
+# define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800
+#endif
+#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
+# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000
+#endif
+#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
+# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
+#endif
+
+#ifndef DEVICE_TYPE
+# define DEVICE_TYPE DWORD
+#endif
+
+/* from ntifs.h */
+/* MinGW already has it, mingw-w64 does not. */
+#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
+ typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ } DUMMYUNIONNAME;
+ } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+#endif
+
+typedef struct _IO_STATUS_BLOCK {
+ union {
+ NTSTATUS Status;
+ PVOID Pointer;
+ } DUMMYUNIONNAME;
+ ULONG_PTR Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+typedef enum _FILE_INFORMATION_CLASS {
+ FileDirectoryInformation = 1,
+ FileFullDirectoryInformation,
+ FileBothDirectoryInformation,
+ FileBasicInformation,
+ FileStandardInformation,
+ FileInternalInformation,
+ FileEaInformation,
+ FileAccessInformation,
+ FileNameInformation,
+ FileRenameInformation,
+ FileLinkInformation,
+ FileNamesInformation,
+ FileDispositionInformation,
+ FilePositionInformation,
+ FileFullEaInformation,
+ FileModeInformation,
+ FileAlignmentInformation,
+ FileAllInformation,
+ FileAllocationInformation,
+ FileEndOfFileInformation,
+ FileAlternateNameInformation,
+ FileStreamInformation,
+ FilePipeInformation,
+ FilePipeLocalInformation,
+ FilePipeRemoteInformation,
+ FileMailslotQueryInformation,
+ FileMailslotSetInformation,
+ FileCompressionInformation,
+ FileObjectIdInformation,
+ FileCompletionInformation,
+ FileMoveClusterInformation,
+ FileQuotaInformation,
+ FileReparsePointInformation,
+ FileNetworkOpenInformation,
+ FileAttributeTagInformation,
+ FileTrackingInformation,
+ FileIdBothDirectoryInformation,
+ FileIdFullDirectoryInformation,
+ FileValidDataLengthInformation,
+ FileShortNameInformation,
+ FileIoCompletionNotificationInformation,
+ FileIoStatusBlockRangeInformation,
+ FileIoPriorityHintInformation,
+ FileSfioReserveInformation,
+ FileSfioVolumeInformation,
+ FileHardLinkInformation,
+ FileProcessIdsUsingFileInformation,
+ FileNormalizedNameInformation,
+ FileNetworkPhysicalNameInformation,
+ FileIdGlobalTxDirectoryInformation,
+ FileIsRemoteDeviceInformation,
+ FileAttributeCacheInformation,
+ FileNumaNodeInformation,
+ FileStandardLinkInformation,
+ FileRemoteProtocolInformation,
+ FileMaximumInformation
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+typedef struct _FILE_BASIC_INFORMATION {
+ LARGE_INTEGER CreationTime;
+ LARGE_INTEGER LastAccessTime;
+ LARGE_INTEGER LastWriteTime;
+ LARGE_INTEGER ChangeTime;
+ DWORD FileAttributes;
+} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
+
+typedef struct _FILE_STANDARD_INFORMATION {
+ LARGE_INTEGER AllocationSize;
+ LARGE_INTEGER EndOfFile;
+ ULONG NumberOfLinks;
+ BOOLEAN DeletePending;
+ BOOLEAN Directory;
+} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
+
+typedef struct _FILE_INTERNAL_INFORMATION {
+ LARGE_INTEGER IndexNumber;
+} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
+
+typedef struct _FILE_EA_INFORMATION {
+ ULONG EaSize;
+} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
+
+typedef struct _FILE_ACCESS_INFORMATION {
+ ACCESS_MASK AccessFlags;
+} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
+
+typedef struct _FILE_POSITION_INFORMATION {
+ LARGE_INTEGER CurrentByteOffset;
+} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
+
+typedef struct _FILE_MODE_INFORMATION {
+ ULONG Mode;
+} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
+
+typedef struct _FILE_ALIGNMENT_INFORMATION {
+ ULONG AlignmentRequirement;
+} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
+
+typedef struct _FILE_NAME_INFORMATION {
+ ULONG FileNameLength;
+ WCHAR FileName[1];
+} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
+
+typedef struct _FILE_END_OF_FILE_INFORMATION {
+ LARGE_INTEGER EndOfFile;
+} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
+
+typedef struct _FILE_ALL_INFORMATION {
+ FILE_BASIC_INFORMATION BasicInformation;
+ FILE_STANDARD_INFORMATION StandardInformation;
+ FILE_INTERNAL_INFORMATION InternalInformation;
+ FILE_EA_INFORMATION EaInformation;
+ FILE_ACCESS_INFORMATION AccessInformation;
+ FILE_POSITION_INFORMATION PositionInformation;
+ FILE_MODE_INFORMATION ModeInformation;
+ FILE_ALIGNMENT_INFORMATION AlignmentInformation;
+ FILE_NAME_INFORMATION NameInformation;
+} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
+
+typedef struct _FILE_DISPOSITION_INFORMATION {
+ BOOLEAN DeleteFile;
+} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
+
+typedef struct _FILE_PIPE_LOCAL_INFORMATION {
+ ULONG NamedPipeType;
+ ULONG NamedPipeConfiguration;
+ ULONG MaximumInstances;
+ ULONG CurrentInstances;
+ ULONG InboundQuota;
+ ULONG ReadDataAvailable;
+ ULONG OutboundQuota;
+ ULONG WriteQuotaAvailable;
+ ULONG NamedPipeState;
+ ULONG NamedPipeEnd;
+} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
+
+#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
+
+typedef enum _FS_INFORMATION_CLASS {
+ FileFsVolumeInformation = 1,
+ FileFsLabelInformation = 2,
+ FileFsSizeInformation = 3,
+ FileFsDeviceInformation = 4,
+ FileFsAttributeInformation = 5,
+ FileFsControlInformation = 6,
+ FileFsFullSizeInformation = 7,
+ FileFsObjectIdInformation = 8,
+ FileFsDriverPathInformation = 9,
+ FileFsVolumeFlagsInformation = 10,
+ FileFsSectorSizeInformation = 11
+} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
+
+typedef struct _FILE_FS_VOLUME_INFORMATION {
+ LARGE_INTEGER VolumeCreationTime;
+ ULONG VolumeSerialNumber;
+ ULONG VolumeLabelLength;
+ BOOLEAN SupportsObjects;
+ WCHAR VolumeLabel[1];
+} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
+
+typedef struct _FILE_FS_LABEL_INFORMATION {
+ ULONG VolumeLabelLength;
+ WCHAR VolumeLabel[1];
+} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION;
+
+typedef struct _FILE_FS_SIZE_INFORMATION {
+ LARGE_INTEGER TotalAllocationUnits;
+ LARGE_INTEGER AvailableAllocationUnits;
+ ULONG SectorsPerAllocationUnit;
+ ULONG BytesPerSector;
+} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
+
+typedef struct _FILE_FS_DEVICE_INFORMATION {
+ DEVICE_TYPE DeviceType;
+ ULONG Characteristics;
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
+
+typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
+ ULONG FileSystemAttributes;
+ LONG MaximumComponentNameLength;
+ ULONG FileSystemNameLength;
+ WCHAR FileSystemName[1];
+} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
+
+typedef struct _FILE_FS_CONTROL_INFORMATION {
+ LARGE_INTEGER FreeSpaceStartFiltering;
+ LARGE_INTEGER FreeSpaceThreshold;
+ LARGE_INTEGER FreeSpaceStopFiltering;
+ LARGE_INTEGER DefaultQuotaThreshold;
+ LARGE_INTEGER DefaultQuotaLimit;
+ ULONG FileSystemControlFlags;
+} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION;
+
+typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
+ LARGE_INTEGER TotalAllocationUnits;
+ LARGE_INTEGER CallerAvailableAllocationUnits;
+ LARGE_INTEGER ActualAvailableAllocationUnits;
+ ULONG SectorsPerAllocationUnit;
+ ULONG BytesPerSector;
+} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
+
+typedef struct _FILE_FS_OBJECTID_INFORMATION {
+ UCHAR ObjectId[16];
+ UCHAR ExtendedInfo[48];
+} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;
+
+typedef struct _FILE_FS_DRIVER_PATH_INFORMATION {
+ BOOLEAN DriverInPath;
+ ULONG DriverNameLength;
+ WCHAR DriverName[1];
+} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION;
+
+typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION {
+ ULONG Flags;
+} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION;
+
+typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION {
+ ULONG LogicalBytesPerSector;
+ ULONG PhysicalBytesPerSectorForAtomicity;
+ ULONG PhysicalBytesPerSectorForPerformance;
+ ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity;
+ ULONG Flags;
+ ULONG ByteOffsetForSectorAlignment;
+ ULONG ByteOffsetForPartitionAlignment;
+} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION;
+
+typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
+ LARGE_INTEGER IdleTime;
+ LARGE_INTEGER KernelTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER DpcTime;
+ LARGE_INTEGER InterruptTime;
+ ULONG InterruptCount;
+} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
+
+#ifndef SystemProcessorPerformanceInformation
+# define SystemProcessorPerformanceInformation 8
+#endif
+
+#ifndef FILE_DEVICE_FILE_SYSTEM
+# define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#endif
+
+#ifndef FILE_DEVICE_NETWORK
+# define FILE_DEVICE_NETWORK 0x00000012
+#endif
+
+#ifndef METHOD_BUFFERED
+# define METHOD_BUFFERED 0
+#endif
+
+#ifndef METHOD_IN_DIRECT
+# define METHOD_IN_DIRECT 1
+#endif
+
+#ifndef METHOD_OUT_DIRECT
+# define METHOD_OUT_DIRECT 2
+#endif
+
+#ifndef METHOD_NEITHER
+#define METHOD_NEITHER 3
+#endif
+
+#ifndef METHOD_DIRECT_TO_HARDWARE
+# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT
+#endif
+
+#ifndef METHOD_DIRECT_FROM_HARDWARE
+# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT
+#endif
+
+#ifndef FILE_ANY_ACCESS
+# define FILE_ANY_ACCESS 0
+#endif
+
+#ifndef FILE_SPECIAL_ACCESS
+# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
+#endif
+
+#ifndef FILE_READ_ACCESS
+# define FILE_READ_ACCESS 0x0001
+#endif
+
+#ifndef FILE_WRITE_ACCESS
+# define FILE_WRITE_ACCESS 0x0002
+#endif
+
+#ifndef CTL_CODE
+# define CTL_CODE(device_type, function, method, access) \
+ (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method))
+#endif
+
+#ifndef FSCTL_SET_REPARSE_POINT
+# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \
+ 41, \
+ METHOD_BUFFERED, \
+ FILE_SPECIAL_ACCESS)
+#endif
+
+#ifndef FSCTL_GET_REPARSE_POINT
+# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \
+ 42, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+#endif
+
+#ifndef FSCTL_DELETE_REPARSE_POINT
+# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \
+ 43, \
+ METHOD_BUFFERED, \
+ FILE_SPECIAL_ACCESS)
+#endif
+
+#ifndef IO_REPARSE_TAG_SYMLINK
+# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+#endif
+
+typedef VOID (NTAPI *PIO_APC_ROUTINE)
+ (PVOID ApcContext,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG Reserved);
+
+typedef ULONG (NTAPI *sRtlNtStatusToDosError)
+ (NTSTATUS Status);
+
+typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile)
+ (HANDLE FileHandle,
+ HANDLE Event,
+ PIO_APC_ROUTINE ApcRoutine,
+ PVOID ApcContext,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ ULONG IoControlCode,
+ PVOID InputBuffer,
+ ULONG InputBufferLength,
+ PVOID OutputBuffer,
+ ULONG OutputBufferLength);
+
+typedef NTSTATUS (NTAPI *sNtQueryInformationFile)
+ (HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtSetInformationFile)
+ (HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FileInformation,
+ ULONG Length,
+ FILE_INFORMATION_CLASS FileInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile)
+ (HANDLE FileHandle,
+ PIO_STATUS_BLOCK IoStatusBlock,
+ PVOID FsInformation,
+ ULONG Length,
+ FS_INFORMATION_CLASS FsInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
+ (UINT SystemInformationClass,
+ PVOID SystemInformation,
+ ULONG SystemInformationLength,
+ PULONG ReturnLength);
+
+
+/*
+ * Kernel32 headers
+ */
+#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
+# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
+#endif
+
+#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE
+# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
+#endif
+
+#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
+# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
+#endif
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+ typedef struct _OVERLAPPED_ENTRY {
+ ULONG_PTR lpCompletionKey;
+ LPOVERLAPPED lpOverlapped;
+ ULONG_PTR Internal;
+ DWORD dwNumberOfBytesTransferred;
+ } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
+#endif
+
+/* from wincon.h */
+#ifndef ENABLE_INSERT_MODE
+# define ENABLE_INSERT_MODE 0x20
+#endif
+
+#ifndef ENABLE_QUICK_EDIT_MODE
+# define ENABLE_QUICK_EDIT_MODE 0x40
+#endif
+
+#ifndef ENABLE_EXTENDED_FLAGS
+# define ENABLE_EXTENDED_FLAGS 0x80
+#endif
+
+/* from winerror.h */
+#ifndef ERROR_SYMLINK_NOT_SUPPORTED
+# define ERROR_SYMLINK_NOT_SUPPORTED 1464
+#endif
+
+typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx)
+ (HANDLE CompletionPort,
+ LPOVERLAPPED_ENTRY lpCompletionPortEntries,
+ ULONG ulCount,
+ PULONG ulNumEntriesRemoved,
+ DWORD dwMilliseconds,
+ BOOL fAlertable);
+
+typedef BOOL (WINAPI* sSetFileCompletionNotificationModes)
+ (HANDLE FileHandle,
+ UCHAR Flags);
+
+typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
+ (LPCWSTR lpSymlinkFileName,
+ LPCWSTR lpTargetFileName,
+ DWORD dwFlags);
+
+typedef BOOL (WINAPI* sCancelIoEx)
+ (HANDLE hFile,
+ LPOVERLAPPED lpOverlapped);
+
+typedef VOID (WINAPI* sInitializeSRWLock)
+ (PSRWLOCK SRWLock);
+
+typedef VOID (WINAPI* sAcquireSRWLockShared)
+ (PSRWLOCK SRWLock);
+
+typedef VOID (WINAPI* sAcquireSRWLockExclusive)
+ (PSRWLOCK SRWLock);
+
+typedef BOOL (WINAPI* sTryAcquireSRWLockShared)
+ (PSRWLOCK SRWLock);
+
+typedef BOOL (WINAPI* sTryAcquireSRWLockExclusive)
+ (PSRWLOCK SRWLock);
+
+typedef VOID (WINAPI* sReleaseSRWLockShared)
+ (PSRWLOCK SRWLock);
+
+typedef VOID (WINAPI* sReleaseSRWLockExclusive)
+ (PSRWLOCK SRWLock);
+
+typedef VOID (WINAPI* sInitializeConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI* sSleepConditionVariableCS)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+
+typedef BOOL (WINAPI* sSleepConditionVariableSRW)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PSRWLOCK SRWLock,
+ DWORD dwMilliseconds,
+ ULONG Flags);
+
+typedef VOID (WINAPI* sWakeAllConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef VOID (WINAPI* sWakeConditionVariable)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+
+/* Ntdll function pointers */
+extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
+extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
+extern sNtQueryInformationFile pNtQueryInformationFile;
+extern sNtSetInformationFile pNtSetInformationFile;
+extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+extern sNtQuerySystemInformation pNtQuerySystemInformation;
+
+
+/* Kernel32 function pointers */
+extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
+extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
+extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
+extern sCancelIoEx pCancelIoEx;
+extern sInitializeSRWLock pInitializeSRWLock;
+extern sAcquireSRWLockShared pAcquireSRWLockShared;
+extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
+extern sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
+extern sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
+extern sReleaseSRWLockShared pReleaseSRWLockShared;
+extern sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
+extern sInitializeConditionVariable pInitializeConditionVariable;
+extern sSleepConditionVariableCS pSleepConditionVariableCS;
+extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
+extern sWakeAllConditionVariable pWakeAllConditionVariable;
+extern sWakeConditionVariable pWakeConditionVariable;
+
+#endif /* UV_WIN_WINAPI_H_ */
diff --git a/third-party/libuv/src/win/winsock.c b/third-party/libuv/src/win/winsock.c
new file mode 100644
index 0000000000..938b6d031a
--- /dev/null
+++ b/third-party/libuv/src/win/winsock.c
@@ -0,0 +1,560 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/* Whether there are any non-IFS LSPs stacked on TCP */
+int uv_tcp_non_ifs_lsp_ipv4;
+int uv_tcp_non_ifs_lsp_ipv6;
+
+/* Ip address used to bind to any port at any interface */
+struct sockaddr_in uv_addr_ip4_any_;
+struct sockaddr_in6 uv_addr_ip6_any_;
+
+
+/*
+ * Retrieves the pointer to a winsock extension function.
+ */
+static BOOL uv_get_extension_function(SOCKET socket, GUID guid,
+ void **target) {
+ DWORD result, bytes;
+
+ result = WSAIoctl(socket,
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guid,
+ sizeof(guid),
+ (void*)target,
+ sizeof(*target),
+ &bytes,
+ NULL,
+ NULL);
+
+ if (result == SOCKET_ERROR) {
+ *target = NULL;
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+
+BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) {
+ const GUID wsaid_acceptex = WSAID_ACCEPTEX;
+ return uv_get_extension_function(socket, wsaid_acceptex, (void**)target);
+}
+
+
+BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
+ const GUID wsaid_connectex = WSAID_CONNECTEX;
+ return uv_get_extension_function(socket, wsaid_connectex, (void**)target);
+}
+
+
+static int error_means_no_support(DWORD error) {
+ return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
+ error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
+}
+
+
+void uv_winsock_init() {
+ WSADATA wsa_data;
+ int errorno;
+ SOCKET dummy;
+ WSAPROTOCOL_INFOW protocol_info;
+ int opt_len;
+
+ /* Initialize winsock */
+ errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ if (errorno != 0) {
+ uv_fatal_error(errorno, "WSAStartup");
+ }
+
+ /* Set implicit binding address used by connectEx */
+ if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) {
+ abort();
+ }
+
+ if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) {
+ abort();
+ }
+
+ /* Detect non-IFS LSPs */
+ dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+ if (dummy != INVALID_SOCKET) {
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(dummy,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR)
+ uv_fatal_error(WSAGetLastError(), "getsockopt");
+
+ if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
+ uv_tcp_non_ifs_lsp_ipv4 = 1;
+
+ if (closesocket(dummy) == SOCKET_ERROR)
+ uv_fatal_error(WSAGetLastError(), "closesocket");
+
+ } else if (!error_means_no_support(WSAGetLastError())) {
+ /* Any error other than "socket type not supported" is fatal. */
+ uv_fatal_error(WSAGetLastError(), "socket");
+ }
+
+ /* Detect IPV6 support and non-IFS LSPs */
+ dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
+
+ if (dummy != INVALID_SOCKET) {
+ opt_len = (int) sizeof protocol_info;
+ if (getsockopt(dummy,
+ SOL_SOCKET,
+ SO_PROTOCOL_INFOW,
+ (char*) &protocol_info,
+ &opt_len) == SOCKET_ERROR)
+ uv_fatal_error(WSAGetLastError(), "getsockopt");
+
+ if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
+ uv_tcp_non_ifs_lsp_ipv6 = 1;
+
+ if (closesocket(dummy) == SOCKET_ERROR)
+ uv_fatal_error(WSAGetLastError(), "closesocket");
+
+ } else if (!error_means_no_support(WSAGetLastError())) {
+ /* Any error other than "socket type not supported" is fatal. */
+ uv_fatal_error(WSAGetLastError(), "socket");
+ }
+}
+
+
+int uv_ntstatus_to_winsock_error(NTSTATUS status) {
+ switch (status) {
+ case STATUS_SUCCESS:
+ return ERROR_SUCCESS;
+
+ case STATUS_PENDING:
+ return ERROR_IO_PENDING;
+
+ case STATUS_INVALID_HANDLE:
+ case STATUS_OBJECT_TYPE_MISMATCH:
+ return WSAENOTSOCK;
+
+ case STATUS_INSUFFICIENT_RESOURCES:
+ case STATUS_PAGEFILE_QUOTA:
+ case STATUS_COMMITMENT_LIMIT:
+ case STATUS_WORKING_SET_QUOTA:
+ case STATUS_NO_MEMORY:
+ case STATUS_CONFLICTING_ADDRESSES:
+ case STATUS_QUOTA_EXCEEDED:
+ case STATUS_TOO_MANY_PAGING_FILES:
+ case STATUS_REMOTE_RESOURCES:
+ case STATUS_TOO_MANY_ADDRESSES:
+ return WSAENOBUFS;
+
+ case STATUS_SHARING_VIOLATION:
+ case STATUS_ADDRESS_ALREADY_EXISTS:
+ return WSAEADDRINUSE;
+
+ case STATUS_LINK_TIMEOUT:
+ case STATUS_IO_TIMEOUT:
+ case STATUS_TIMEOUT:
+ return WSAETIMEDOUT;
+
+ case STATUS_GRACEFUL_DISCONNECT:
+ return WSAEDISCON;
+
+ case STATUS_REMOTE_DISCONNECT:
+ case STATUS_CONNECTION_RESET:
+ case STATUS_LINK_FAILED:
+ case STATUS_CONNECTION_DISCONNECTED:
+ case STATUS_PORT_UNREACHABLE:
+ case STATUS_HOPLIMIT_EXCEEDED:
+ return WSAECONNRESET;
+
+ case STATUS_LOCAL_DISCONNECT:
+ case STATUS_TRANSACTION_ABORTED:
+ case STATUS_CONNECTION_ABORTED:
+ return WSAECONNABORTED;
+
+ case STATUS_BAD_NETWORK_PATH:
+ case STATUS_NETWORK_UNREACHABLE:
+ case STATUS_PROTOCOL_UNREACHABLE:
+ return WSAENETUNREACH;
+
+ case STATUS_HOST_UNREACHABLE:
+ return WSAEHOSTUNREACH;
+
+ case STATUS_CANCELLED:
+ case STATUS_REQUEST_ABORTED:
+ return WSAEINTR;
+
+ case STATUS_BUFFER_OVERFLOW:
+ case STATUS_INVALID_BUFFER_SIZE:
+ return WSAEMSGSIZE;
+
+ case STATUS_BUFFER_TOO_SMALL:
+ case STATUS_ACCESS_VIOLATION:
+ return WSAEFAULT;
+
+ case STATUS_DEVICE_NOT_READY:
+ case STATUS_REQUEST_NOT_ACCEPTED:
+ return WSAEWOULDBLOCK;
+
+ case STATUS_INVALID_NETWORK_RESPONSE:
+ case STATUS_NETWORK_BUSY:
+ case STATUS_NO_SUCH_DEVICE:
+ case STATUS_NO_SUCH_FILE:
+ case STATUS_OBJECT_PATH_NOT_FOUND:
+ case STATUS_OBJECT_NAME_NOT_FOUND:
+ case STATUS_UNEXPECTED_NETWORK_ERROR:
+ return WSAENETDOWN;
+
+ case STATUS_INVALID_CONNECTION:
+ return WSAENOTCONN;
+
+ case STATUS_REMOTE_NOT_LISTENING:
+ case STATUS_CONNECTION_REFUSED:
+ return WSAECONNREFUSED;
+
+ case STATUS_PIPE_DISCONNECTED:
+ return WSAESHUTDOWN;
+
+ case STATUS_INVALID_ADDRESS:
+ case STATUS_INVALID_ADDRESS_COMPONENT:
+ return WSAEADDRNOTAVAIL;
+
+ case STATUS_NOT_SUPPORTED:
+ case STATUS_NOT_IMPLEMENTED:
+ return WSAEOPNOTSUPP;
+
+ case STATUS_ACCESS_DENIED:
+ return WSAEACCES;
+
+ default:
+ if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
+ (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
+ /* It's a windows error that has been previously mapped to an */
+ /* ntstatus code. */
+ return (DWORD) (status & 0xffff);
+ } else {
+ /* The default fallback for unmappable ntstatus codes. */
+ return WSAEINVAL;
+ }
+ }
+}
+
+
+/*
+ * This function provides a workaround for a bug in the winsock implementation
+ * of WSARecv. The problem is that when SetFileCompletionNotificationModes is
+ * used to avoid IOCP notifications of completed reads, WSARecv does not
+ * reliably indicate whether we can expect a completion package to be posted
+ * when the receive buffer is smaller than the received datagram.
+ *
+ * However it is desirable to use SetFileCompletionNotificationModes because
+ * it yields a massive performance increase.
+ *
+ * This function provides a workaround for that bug, but it only works for the
+ * specific case that we need it for. E.g. it assumes that the "avoid iocp"
+ * bit has been set, and supports only overlapped operation. It also requires
+ * the user to use the default msafd driver, doesn't work when other LSPs are
+ * stacked on top of it.
+ */
+int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
+ NTSTATUS status;
+ void* apc_context;
+ IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
+ AFD_RECV_INFO info;
+ DWORD error;
+
+ if (overlapped == NULL || completion_routine != NULL) {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ info.BufferArray = buffers;
+ info.BufferCount = buffer_count;
+ info.AfdFlags = AFD_OVERLAPPED;
+ info.TdiFlags = TDI_RECEIVE_NORMAL;
+
+ if (*flags & MSG_PEEK) {
+ info.TdiFlags |= TDI_RECEIVE_PEEK;
+ }
+
+ if (*flags & MSG_PARTIAL) {
+ info.TdiFlags |= TDI_RECEIVE_PARTIAL;
+ }
+
+ if (!((intptr_t) overlapped->hEvent & 1)) {
+ apc_context = (void*) overlapped;
+ } else {
+ apc_context = NULL;
+ }
+
+ iosb->Status = STATUS_PENDING;
+ iosb->Pointer = 0;
+
+ status = pNtDeviceIoControlFile((HANDLE) socket,
+ overlapped->hEvent,
+ NULL,
+ apc_context,
+ iosb,
+ IOCTL_AFD_RECEIVE,
+ &info,
+ sizeof(info),
+ NULL,
+ 0);
+
+ *flags = 0;
+ *bytes = (DWORD) iosb->Information;
+
+ switch (status) {
+ case STATUS_SUCCESS:
+ error = ERROR_SUCCESS;
+ break;
+
+ case STATUS_PENDING:
+ error = WSA_IO_PENDING;
+ break;
+
+ case STATUS_BUFFER_OVERFLOW:
+ error = WSAEMSGSIZE;
+ break;
+
+ case STATUS_RECEIVE_EXPEDITED:
+ error = ERROR_SUCCESS;
+ *flags = MSG_OOB;
+ break;
+
+ case STATUS_RECEIVE_PARTIAL_EXPEDITED:
+ error = ERROR_SUCCESS;
+ *flags = MSG_PARTIAL | MSG_OOB;
+ break;
+
+ case STATUS_RECEIVE_PARTIAL:
+ error = ERROR_SUCCESS;
+ *flags = MSG_PARTIAL;
+ break;
+
+ default:
+ error = uv_ntstatus_to_winsock_error(status);
+ break;
+ }
+
+ WSASetLastError(error);
+
+ if (error == ERROR_SUCCESS) {
+ return 0;
+ } else {
+ return SOCKET_ERROR;
+ }
+}
+
+
+/* See description of uv_wsarecv_workaround. */
+int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
+ int* addr_len, WSAOVERLAPPED *overlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
+ NTSTATUS status;
+ void* apc_context;
+ IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
+ AFD_RECV_DATAGRAM_INFO info;
+ DWORD error;
+
+ if (overlapped == NULL || addr == NULL || addr_len == NULL ||
+ completion_routine != NULL) {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ info.BufferArray = buffers;
+ info.BufferCount = buffer_count;
+ info.AfdFlags = AFD_OVERLAPPED;
+ info.TdiFlags = TDI_RECEIVE_NORMAL;
+ info.Address = addr;
+ info.AddressLength = addr_len;
+
+ if (*flags & MSG_PEEK) {
+ info.TdiFlags |= TDI_RECEIVE_PEEK;
+ }
+
+ if (*flags & MSG_PARTIAL) {
+ info.TdiFlags |= TDI_RECEIVE_PARTIAL;
+ }
+
+ if (!((intptr_t) overlapped->hEvent & 1)) {
+ apc_context = (void*) overlapped;
+ } else {
+ apc_context = NULL;
+ }
+
+ iosb->Status = STATUS_PENDING;
+ iosb->Pointer = 0;
+
+ status = pNtDeviceIoControlFile((HANDLE) socket,
+ overlapped->hEvent,
+ NULL,
+ apc_context,
+ iosb,
+ IOCTL_AFD_RECEIVE_DATAGRAM,
+ &info,
+ sizeof(info),
+ NULL,
+ 0);
+
+ *flags = 0;
+ *bytes = (DWORD) iosb->Information;
+
+ switch (status) {
+ case STATUS_SUCCESS:
+ error = ERROR_SUCCESS;
+ break;
+
+ case STATUS_PENDING:
+ error = WSA_IO_PENDING;
+ break;
+
+ case STATUS_BUFFER_OVERFLOW:
+ error = WSAEMSGSIZE;
+ break;
+
+ case STATUS_RECEIVE_EXPEDITED:
+ error = ERROR_SUCCESS;
+ *flags = MSG_OOB;
+ break;
+
+ case STATUS_RECEIVE_PARTIAL_EXPEDITED:
+ error = ERROR_SUCCESS;
+ *flags = MSG_PARTIAL | MSG_OOB;
+ break;
+
+ case STATUS_RECEIVE_PARTIAL:
+ error = ERROR_SUCCESS;
+ *flags = MSG_PARTIAL;
+ break;
+
+ default:
+ error = uv_ntstatus_to_winsock_error(status);
+ break;
+ }
+
+ WSASetLastError(error);
+
+ if (error == ERROR_SUCCESS) {
+ return 0;
+ } else {
+ return SOCKET_ERROR;
+ }
+}
+
+
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
+ OVERLAPPED* overlapped) {
+ IO_STATUS_BLOCK iosb;
+ IO_STATUS_BLOCK* iosb_ptr;
+ HANDLE event = NULL;
+ void* apc_context;
+ NTSTATUS status;
+ DWORD error;
+
+ if (overlapped != NULL) {
+ /* Overlapped operation. */
+ iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal;
+ event = overlapped->hEvent;
+
+ /* Do not report iocp completion if hEvent is tagged. */
+ if ((uintptr_t) event & 1) {
+ event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1);
+ apc_context = NULL;
+ } else {
+ apc_context = overlapped;
+ }
+
+ } else {
+ /* Blocking operation. */
+ iosb_ptr = &iosb;
+ event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (event == NULL) {
+ return SOCKET_ERROR;
+ }
+ apc_context = NULL;
+ }
+
+ iosb_ptr->Status = STATUS_PENDING;
+ status = pNtDeviceIoControlFile((HANDLE) socket,
+ event,
+ NULL,
+ apc_context,
+ iosb_ptr,
+ IOCTL_AFD_POLL,
+ info,
+ sizeof *info,
+ info,
+ sizeof *info);
+
+ if (overlapped == NULL) {
+ /* If this is a blocking operation, wait for the event to become */
+ /* signaled, and then grab the real status from the io status block. */
+ if (status == STATUS_PENDING) {
+ DWORD r = WaitForSingleObject(event, INFINITE);
+
+ if (r == WAIT_FAILED) {
+ DWORD saved_error = GetLastError();
+ CloseHandle(event);
+ WSASetLastError(saved_error);
+ return SOCKET_ERROR;
+ }
+
+ status = iosb.Status;
+ }
+
+ CloseHandle(event);
+ }
+
+ switch (status) {
+ case STATUS_SUCCESS:
+ error = ERROR_SUCCESS;
+ break;
+
+ case STATUS_PENDING:
+ error = WSA_IO_PENDING;
+ break;
+
+ default:
+ error = uv_ntstatus_to_winsock_error(status);
+ break;
+ }
+
+ WSASetLastError(error);
+
+ if (error == ERROR_SUCCESS) {
+ return 0;
+ } else {
+ return SOCKET_ERROR;
+ }
+}
diff --git a/third-party/libuv/src/win/winsock.h b/third-party/libuv/src/win/winsock.h
new file mode 100644
index 0000000000..957d08ec19
--- /dev/null
+++ b/third-party/libuv/src/win/winsock.h
@@ -0,0 +1,171 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef UV_WIN_WINSOCK_H_
+#define UV_WIN_WINSOCK_H_
+
+#include <winsock2.h>
+#include <iptypes.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#include "winapi.h"
+
+
+/*
+ * MinGW is missing these too
+ */
+#ifndef SO_UPDATE_CONNECT_CONTEXT
+# define SO_UPDATE_CONNECT_CONTEXT 0x7010
+#endif
+
+#ifndef TCP_KEEPALIVE
+# define TCP_KEEPALIVE 3
+#endif
+
+#ifndef IPV6_V6ONLY
+# define IPV6_V6ONLY 27
+#endif
+
+#ifndef IPV6_HOPLIMIT
+# define IPV6_HOPLIMIT 21
+#endif
+
+#ifndef SIO_BASE_HANDLE
+# define SIO_BASE_HANDLE 0x48000022
+#endif
+
+/*
+ * TDI defines that are only in the DDK.
+ * We only need receive flags so far.
+ */
+#ifndef TDI_RECEIVE_NORMAL
+ #define TDI_RECEIVE_BROADCAST 0x00000004
+ #define TDI_RECEIVE_MULTICAST 0x00000008
+ #define TDI_RECEIVE_PARTIAL 0x00000010
+ #define TDI_RECEIVE_NORMAL 0x00000020
+ #define TDI_RECEIVE_EXPEDITED 0x00000040
+ #define TDI_RECEIVE_PEEK 0x00000080
+ #define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100
+ #define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200
+ #define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400
+ #define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800
+ #define TDI_RECEIVE_CONTROL_INFO 0x00001000
+ #define TDI_RECEIVE_FORCE_INDICATION 0x00002000
+ #define TDI_RECEIVE_NO_PUSH 0x00004000
+#endif
+
+/*
+ * The "Auxiliary Function Driver" is the windows kernel-mode driver that does
+ * TCP, UDP etc. Winsock is just a layer that dispatches requests to it.
+ * Having these definitions allows us to bypass winsock and make an AFD kernel
+ * call directly, avoiding a bug in winsock's recvfrom implementation.
+ */
+
+#define AFD_NO_FAST_IO 0x00000001
+#define AFD_OVERLAPPED 0x00000002
+#define AFD_IMMEDIATE 0x00000004
+
+#define AFD_POLL_RECEIVE_BIT 0
+#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT)
+#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1
+#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT)
+#define AFD_POLL_SEND_BIT 2
+#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT)
+#define AFD_POLL_DISCONNECT_BIT 3
+#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT)
+#define AFD_POLL_ABORT_BIT 4
+#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT)
+#define AFD_POLL_LOCAL_CLOSE_BIT 5
+#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT)
+#define AFD_POLL_CONNECT_BIT 6
+#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT)
+#define AFD_POLL_ACCEPT_BIT 7
+#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT)
+#define AFD_POLL_CONNECT_FAIL_BIT 8
+#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT)
+#define AFD_POLL_QOS_BIT 9
+#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT)
+#define AFD_POLL_GROUP_QOS_BIT 10
+#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT)
+
+#define AFD_NUM_POLL_EVENTS 11
+#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1)
+
+typedef struct _AFD_RECV_DATAGRAM_INFO {
+ LPWSABUF BufferArray;
+ ULONG BufferCount;
+ ULONG AfdFlags;
+ ULONG TdiFlags;
+ struct sockaddr* Address;
+ int* AddressLength;
+} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO;
+
+typedef struct _AFD_RECV_INFO {
+ LPWSABUF BufferArray;
+ ULONG BufferCount;
+ ULONG AfdFlags;
+ ULONG TdiFlags;
+} AFD_RECV_INFO, *PAFD_RECV_INFO;
+
+
+#define _AFD_CONTROL_CODE(operation, method) \
+ ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method)
+
+#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK
+
+#define AFD_RECEIVE 5
+#define AFD_RECEIVE_DATAGRAM 6
+#define AFD_POLL 9
+
+#define IOCTL_AFD_RECEIVE \
+ _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER)
+
+#define IOCTL_AFD_RECEIVE_DATAGRAM \
+ _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER)
+
+#define IOCTL_AFD_POLL \
+ _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
+ /* FIXME: __C89_NAMELESS was removed */
+ /* __C89_NAMELESS */ union {
+ ULONGLONG Alignment;
+ /* __C89_NAMELESS */ struct {
+ ULONG Length;
+ DWORD Flags;
+ };
+ };
+ struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next;
+ SOCKET_ADDRESS Address;
+ IP_PREFIX_ORIGIN PrefixOrigin;
+ IP_SUFFIX_ORIGIN SuffixOrigin;
+ IP_DAD_STATE DadState;
+ ULONG ValidLifetime;
+ ULONG PreferredLifetime;
+ ULONG LeaseLifetime;
+} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP;
+
+#endif
+
+#endif /* UV_WIN_WINSOCK_H_ */
diff --git a/third-party/libuv/test/benchmark-async-pummel.c b/third-party/libuv/test/benchmark-async-pummel.c
new file mode 100644
index 0000000000..4761c1928e
--- /dev/null
+++ b/third-party/libuv/test/benchmark-async-pummel.c
@@ -0,0 +1,119 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_PINGS (1000 * 1000)
+#define ACCESS_ONCE(type, var) (*(volatile type*) &(var))
+
+static unsigned int callbacks;
+static volatile int done;
+
+static const char running[] = "running";
+static const char stop[] = "stop";
+static const char stopped[] = "stopped";
+
+
+static void async_cb(uv_async_t* handle, int status) {
+ if (++callbacks == NUM_PINGS) {
+ /* Tell the pummel thread to stop. */
+ ACCESS_ONCE(const char*, handle->data) = stop;
+
+ /* Wait for for the pummel thread to acknowledge that it has stoppped. */
+ while (ACCESS_ONCE(const char*, handle->data) != stopped)
+ uv_sleep(0);
+
+ uv_close((uv_handle_t*) handle, NULL);
+ }
+}
+
+
+static void pummel(void* arg) {
+ uv_async_t* handle = (uv_async_t*) arg;
+
+ while (ACCESS_ONCE(const char*, handle->data) == running)
+ uv_async_send(handle);
+
+ /* Acknowledge that we've seen handle->data change. */
+ ACCESS_ONCE(const char*, handle->data) = stopped;
+}
+
+
+static int test_async_pummel(int nthreads) {
+ uv_thread_t* tids;
+ uv_async_t handle;
+ uint64_t time;
+ int i;
+
+ tids = calloc(nthreads, sizeof(tids[0]));
+ ASSERT(tids != NULL);
+
+ ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb));
+ ACCESS_ONCE(const char*, handle.data) = running;
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_create(tids + i, pummel, &handle));
+
+ time = uv_hrtime();
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ time = uv_hrtime() - time;
+ done = 1;
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_join(tids + i));
+
+ printf("async_pummel_%d: %s callbacks in %.2f seconds (%s/sec)\n",
+ nthreads,
+ fmt(callbacks),
+ time / 1e9,
+ fmt(callbacks / (time / 1e9)));
+
+ free(tids);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(async_pummel_1) {
+ return test_async_pummel(1);
+}
+
+
+BENCHMARK_IMPL(async_pummel_2) {
+ return test_async_pummel(2);
+}
+
+
+BENCHMARK_IMPL(async_pummel_4) {
+ return test_async_pummel(4);
+}
+
+
+BENCHMARK_IMPL(async_pummel_8) {
+ return test_async_pummel(8);
+}
diff --git a/third-party/libuv/test/benchmark-async.c b/third-party/libuv/test/benchmark-async.c
new file mode 100644
index 0000000000..33d9ab446a
--- /dev/null
+++ b/third-party/libuv/test/benchmark-async.c
@@ -0,0 +1,141 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_PINGS (1000 * 1000)
+
+struct ctx {
+ uv_loop_t* loop;
+ uv_thread_t thread;
+ uv_async_t main_async; /* wake up main thread */
+ uv_async_t worker_async; /* wake up worker */
+ unsigned int nthreads;
+ unsigned int main_sent;
+ unsigned int main_seen;
+ unsigned int worker_sent;
+ unsigned int worker_seen;
+};
+
+
+static void worker_async_cb(uv_async_t* handle, int status) {
+ struct ctx* ctx = container_of(handle, struct ctx, worker_async);
+
+ ASSERT(0 == uv_async_send(&ctx->main_async));
+ ctx->worker_sent++;
+ ctx->worker_seen++;
+
+ if (ctx->worker_sent >= NUM_PINGS)
+ uv_close((uv_handle_t*) &ctx->worker_async, NULL);
+}
+
+
+static void main_async_cb(uv_async_t* handle, int status) {
+ struct ctx* ctx = container_of(handle, struct ctx, main_async);
+
+ ASSERT(0 == uv_async_send(&ctx->worker_async));
+ ctx->main_sent++;
+ ctx->main_seen++;
+
+ if (ctx->main_sent >= NUM_PINGS)
+ uv_close((uv_handle_t*) &ctx->main_async, NULL);
+}
+
+
+static void worker(void* arg) {
+ struct ctx* ctx = arg;
+ ASSERT(0 == uv_async_send(&ctx->main_async));
+ ASSERT(0 == uv_run(ctx->loop, UV_RUN_DEFAULT));
+}
+
+
+static int test_async(int nthreads) {
+ struct ctx* threads;
+ struct ctx* ctx;
+ uint64_t time;
+ int i;
+
+ threads = calloc(nthreads, sizeof(threads[0]));
+ ASSERT(threads != NULL);
+
+ for (i = 0; i < nthreads; i++) {
+ ctx = threads + i;
+ ctx->nthreads = nthreads;
+ ctx->loop = uv_loop_new();
+ ASSERT(ctx->loop != NULL);
+ ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb));
+ ASSERT(0 == uv_async_init(uv_default_loop(),
+ &ctx->main_async,
+ main_async_cb));
+ ASSERT(0 == uv_thread_create(&ctx->thread, worker, ctx));
+ }
+
+ time = uv_hrtime();
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ for (i = 0; i < nthreads; i++)
+ ASSERT(0 == uv_thread_join(&threads[i].thread));
+
+ time = uv_hrtime() - time;
+
+ for (i = 0; i < nthreads; i++) {
+ ctx = threads + i;
+ ASSERT(ctx->worker_sent == NUM_PINGS);
+ ASSERT(ctx->worker_seen == NUM_PINGS);
+ ASSERT(ctx->main_sent == (unsigned int) NUM_PINGS);
+ ASSERT(ctx->main_seen == (unsigned int) NUM_PINGS);
+ }
+
+ printf("async%d: %.2f sec (%s/sec)\n",
+ nthreads,
+ time / 1e9,
+ fmt(NUM_PINGS / (time / 1e9)));
+
+ free(threads);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(async1) {
+ return test_async(1);
+}
+
+
+BENCHMARK_IMPL(async2) {
+ return test_async(2);
+}
+
+
+BENCHMARK_IMPL(async4) {
+ return test_async(4);
+}
+
+
+BENCHMARK_IMPL(async8) {
+ return test_async(8);
+}
diff --git a/third-party/libuv/test/benchmark-fs-stat.c b/third-party/libuv/test/benchmark-fs-stat.c
new file mode 100644
index 0000000000..5c87de0043
--- /dev/null
+++ b/third-party/libuv/test/benchmark-fs-stat.c
@@ -0,0 +1,136 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_SYNC_REQS (10 * 1e5)
+#define NUM_ASYNC_REQS (1 * (int) 1e5)
+#define MAX_CONCURRENT_REQS 32
+
+#define sync_stat(req, path) \
+ do { \
+ uv_fs_stat(uv_default_loop(), (req), (path), NULL); \
+ uv_fs_req_cleanup((req)); \
+ } \
+ while (0)
+
+struct async_req {
+ const char* path;
+ uv_fs_t fs_req;
+ int* count;
+};
+
+
+static void warmup(const char* path) {
+ uv_fs_t reqs[MAX_CONCURRENT_REQS];
+ unsigned int i;
+
+ /* warm up the thread pool */
+ for (i = 0; i < ARRAY_SIZE(reqs); i++)
+ uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ /* warm up the OS dirent cache */
+ for (i = 0; i < 16; i++)
+ sync_stat(reqs + 0, path);
+}
+
+
+static void sync_bench(const char* path) {
+ uint64_t before;
+ uint64_t after;
+ uv_fs_t req;
+ int i;
+
+ /* do the sync benchmark */
+ before = uv_hrtime();
+
+ for (i = 0; i < NUM_SYNC_REQS; i++)
+ sync_stat(&req, path);
+
+ after = uv_hrtime();
+
+ printf("%s stats (sync): %.2fs (%s/s)\n",
+ fmt(1.0 * NUM_SYNC_REQS),
+ (after - before) / 1e9,
+ fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9)));
+ fflush(stdout);
+}
+
+
+static void stat_cb(uv_fs_t* fs_req) {
+ struct async_req* req = container_of(fs_req, struct async_req, fs_req);
+ uv_fs_req_cleanup(&req->fs_req);
+ if (*req->count == 0) return;
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
+ (*req->count)--;
+}
+
+
+static void async_bench(const char* path) {
+ struct async_req reqs[MAX_CONCURRENT_REQS];
+ struct async_req* req;
+ uint64_t before;
+ uint64_t after;
+ int count;
+ int i;
+
+ for (i = 1; i <= MAX_CONCURRENT_REQS; i++) {
+ count = NUM_ASYNC_REQS;
+
+ for (req = reqs; req < reqs + i; req++) {
+ req->path = path;
+ req->count = &count;
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
+ }
+
+ before = uv_hrtime();
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ after = uv_hrtime();
+
+ printf("%s stats (%d concurrent): %.2fs (%s/s)\n",
+ fmt(1.0 * NUM_ASYNC_REQS),
+ i,
+ (after - before) / 1e9,
+ fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9)));
+ fflush(stdout);
+ }
+}
+
+
+/* This benchmark aims to measure the overhead of doing I/O syscalls from
+ * the thread pool. The stat() syscall was chosen because its results are
+ * easy for the operating system to cache, taking the actual I/O overhead
+ * out of the equation.
+ */
+BENCHMARK_IMPL(fs_stat) {
+ const char path[] = ".";
+ warmup(path);
+ sync_bench(path);
+ async_bench(path);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-getaddrinfo.c b/third-party/libuv/test/benchmark-getaddrinfo.c
new file mode 100644
index 0000000000..c7f99a2fcb
--- /dev/null
+++ b/third-party/libuv/test/benchmark-getaddrinfo.c
@@ -0,0 +1,91 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdlib.h>
+
+#define CONCURRENT_CALLS 10
+#define TOTAL_CALLS 10000
+
+static const char* name = "localhost";
+
+static uv_loop_t* loop;
+
+static uv_getaddrinfo_t handles[CONCURRENT_CALLS];
+
+static int calls_initiated = 0;
+static int calls_completed = 0;
+static int64_t start_time;
+static int64_t end_time;
+
+
+static void getaddrinfo_initiate(uv_getaddrinfo_t* handle);
+
+
+static void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status,
+ struct addrinfo* res) {
+ ASSERT(status == 0);
+ calls_completed++;
+ if (calls_initiated < TOTAL_CALLS) {
+ getaddrinfo_initiate(handle);
+ }
+
+ uv_freeaddrinfo(res);
+}
+
+
+static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) {
+ int r;
+
+ calls_initiated++;
+
+ r = uv_getaddrinfo(loop, handle, &getaddrinfo_cb, name, NULL, NULL);
+ ASSERT(r == 0);
+}
+
+
+BENCHMARK_IMPL(getaddrinfo) {
+ int i;
+
+ loop = uv_default_loop();
+
+ uv_update_time(loop);
+ start_time = uv_now(loop);
+
+ for (i = 0; i < CONCURRENT_CALLS; i++) {
+ getaddrinfo_initiate(&handles[i]);
+ }
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ uv_update_time(loop);
+ end_time = uv_now(loop);
+
+ ASSERT(calls_initiated == TOTAL_CALLS);
+ ASSERT(calls_completed == TOTAL_CALLS);
+
+ LOGF("getaddrinfo: %.0f req/s\n",
+ (double) calls_completed / (double) (end_time - start_time) * 1000.0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-list.h b/third-party/libuv/test/benchmark-list.h
new file mode 100644
index 0000000000..1e843071c0
--- /dev/null
+++ b/third-party/libuv/test/benchmark-list.h
@@ -0,0 +1,163 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+BENCHMARK_DECLARE (sizes)
+BENCHMARK_DECLARE (loop_count)
+BENCHMARK_DECLARE (loop_count_timed)
+BENCHMARK_DECLARE (ping_pongs)
+BENCHMARK_DECLARE (tcp_write_batch)
+BENCHMARK_DECLARE (tcp4_pound_100)
+BENCHMARK_DECLARE (tcp4_pound_1000)
+BENCHMARK_DECLARE (pipe_pound_100)
+BENCHMARK_DECLARE (pipe_pound_1000)
+BENCHMARK_DECLARE (tcp_pump100_client)
+BENCHMARK_DECLARE (tcp_pump1_client)
+BENCHMARK_DECLARE (pipe_pump100_client)
+BENCHMARK_DECLARE (pipe_pump1_client)
+
+BENCHMARK_DECLARE (tcp_multi_accept2)
+BENCHMARK_DECLARE (tcp_multi_accept4)
+BENCHMARK_DECLARE (tcp_multi_accept8)
+
+/* Run until X packets have been sent/received. */
+BENCHMARK_DECLARE (udp_pummel_1v1)
+BENCHMARK_DECLARE (udp_pummel_1v10)
+BENCHMARK_DECLARE (udp_pummel_1v100)
+BENCHMARK_DECLARE (udp_pummel_1v1000)
+BENCHMARK_DECLARE (udp_pummel_10v10)
+BENCHMARK_DECLARE (udp_pummel_10v100)
+BENCHMARK_DECLARE (udp_pummel_10v1000)
+BENCHMARK_DECLARE (udp_pummel_100v100)
+BENCHMARK_DECLARE (udp_pummel_100v1000)
+BENCHMARK_DECLARE (udp_pummel_1000v1000)
+
+/* Run until X seconds have elapsed. */
+BENCHMARK_DECLARE (udp_timed_pummel_1v1)
+BENCHMARK_DECLARE (udp_timed_pummel_1v10)
+BENCHMARK_DECLARE (udp_timed_pummel_1v100)
+BENCHMARK_DECLARE (udp_timed_pummel_1v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_10v10)
+BENCHMARK_DECLARE (udp_timed_pummel_10v100)
+BENCHMARK_DECLARE (udp_timed_pummel_10v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_100v100)
+BENCHMARK_DECLARE (udp_timed_pummel_100v1000)
+BENCHMARK_DECLARE (udp_timed_pummel_1000v1000)
+
+BENCHMARK_DECLARE (getaddrinfo)
+BENCHMARK_DECLARE (fs_stat)
+BENCHMARK_DECLARE (async1)
+BENCHMARK_DECLARE (async2)
+BENCHMARK_DECLARE (async4)
+BENCHMARK_DECLARE (async8)
+BENCHMARK_DECLARE (async_pummel_1)
+BENCHMARK_DECLARE (async_pummel_2)
+BENCHMARK_DECLARE (async_pummel_4)
+BENCHMARK_DECLARE (async_pummel_8)
+BENCHMARK_DECLARE (spawn)
+BENCHMARK_DECLARE (thread_create)
+BENCHMARK_DECLARE (million_async)
+BENCHMARK_DECLARE (million_timers)
+HELPER_DECLARE (tcp4_blackhole_server)
+HELPER_DECLARE (tcp_pump_server)
+HELPER_DECLARE (pipe_pump_server)
+HELPER_DECLARE (tcp4_echo_server)
+HELPER_DECLARE (pipe_echo_server)
+HELPER_DECLARE (dns_server)
+
+TASK_LIST_START
+ BENCHMARK_ENTRY (sizes)
+ BENCHMARK_ENTRY (loop_count)
+ BENCHMARK_ENTRY (loop_count_timed)
+
+ BENCHMARK_ENTRY (ping_pongs)
+ BENCHMARK_HELPER (ping_pongs, tcp4_echo_server)
+
+ BENCHMARK_ENTRY (tcp_write_batch)
+ BENCHMARK_HELPER (tcp_write_batch, tcp4_blackhole_server)
+
+ BENCHMARK_ENTRY (tcp_pump100_client)
+ BENCHMARK_HELPER (tcp_pump100_client, tcp_pump_server)
+
+ BENCHMARK_ENTRY (tcp_pump1_client)
+ BENCHMARK_HELPER (tcp_pump1_client, tcp_pump_server)
+
+ BENCHMARK_ENTRY (tcp4_pound_100)
+ BENCHMARK_HELPER (tcp4_pound_100, tcp4_echo_server)
+
+ BENCHMARK_ENTRY (tcp4_pound_1000)
+ BENCHMARK_HELPER (tcp4_pound_1000, tcp4_echo_server)
+
+ BENCHMARK_ENTRY (pipe_pump100_client)
+ BENCHMARK_HELPER (pipe_pump100_client, pipe_pump_server)
+
+ BENCHMARK_ENTRY (pipe_pump1_client)
+ BENCHMARK_HELPER (pipe_pump1_client, pipe_pump_server)
+
+ BENCHMARK_ENTRY (pipe_pound_100)
+ BENCHMARK_HELPER (pipe_pound_100, pipe_echo_server)
+
+ BENCHMARK_ENTRY (pipe_pound_1000)
+ BENCHMARK_HELPER (pipe_pound_1000, pipe_echo_server)
+
+ BENCHMARK_ENTRY (tcp_multi_accept2)
+ BENCHMARK_ENTRY (tcp_multi_accept4)
+ BENCHMARK_ENTRY (tcp_multi_accept8)
+
+ BENCHMARK_ENTRY (udp_pummel_1v1)
+ BENCHMARK_ENTRY (udp_pummel_1v10)
+ BENCHMARK_ENTRY (udp_pummel_1v100)
+ BENCHMARK_ENTRY (udp_pummel_1v1000)
+ BENCHMARK_ENTRY (udp_pummel_10v10)
+ BENCHMARK_ENTRY (udp_pummel_10v100)
+ BENCHMARK_ENTRY (udp_pummel_10v1000)
+ BENCHMARK_ENTRY (udp_pummel_100v100)
+ BENCHMARK_ENTRY (udp_pummel_100v1000)
+ BENCHMARK_ENTRY (udp_pummel_1000v1000)
+
+ BENCHMARK_ENTRY (udp_timed_pummel_1v1)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v10)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_1v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v10)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_10v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_100v100)
+ BENCHMARK_ENTRY (udp_timed_pummel_100v1000)
+ BENCHMARK_ENTRY (udp_timed_pummel_1000v1000)
+
+ BENCHMARK_ENTRY (getaddrinfo)
+
+ BENCHMARK_ENTRY (fs_stat)
+
+ BENCHMARK_ENTRY (async1)
+ BENCHMARK_ENTRY (async2)
+ BENCHMARK_ENTRY (async4)
+ BENCHMARK_ENTRY (async8)
+ BENCHMARK_ENTRY (async_pummel_1)
+ BENCHMARK_ENTRY (async_pummel_2)
+ BENCHMARK_ENTRY (async_pummel_4)
+ BENCHMARK_ENTRY (async_pummel_8)
+
+ BENCHMARK_ENTRY (spawn)
+ BENCHMARK_ENTRY (thread_create)
+ BENCHMARK_ENTRY (million_async)
+ BENCHMARK_ENTRY (million_timers)
+TASK_LIST_END
diff --git a/third-party/libuv/test/benchmark-loop-count.c b/third-party/libuv/test/benchmark-loop-count.c
new file mode 100644
index 0000000000..b4ee0ed5ff
--- /dev/null
+++ b/third-party/libuv/test/benchmark-loop-count.c
@@ -0,0 +1,90 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_TICKS (2 * 1000 * 1000)
+
+static unsigned long ticks;
+static uv_idle_t idle_handle;
+static uv_timer_t timer_handle;
+
+
+static void idle_cb(uv_idle_t* handle, int status) {
+ if (++ticks == NUM_TICKS)
+ uv_idle_stop(handle);
+}
+
+
+static void idle2_cb(uv_idle_t* handle, int status) {
+ ticks++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_idle_stop(&idle_handle);
+ uv_timer_stop(&timer_handle);
+}
+
+
+BENCHMARK_IMPL(loop_count) {
+ uv_loop_t* loop = uv_default_loop();
+ uint64_t ns;
+
+ uv_idle_init(loop, &idle_handle);
+ uv_idle_start(&idle_handle, idle_cb);
+
+ ns = uv_hrtime();
+ uv_run(loop, UV_RUN_DEFAULT);
+ ns = uv_hrtime() - ns;
+
+ ASSERT(ticks == NUM_TICKS);
+
+ LOGF("loop_count: %d ticks in %.2fs (%.0f/s)\n",
+ NUM_TICKS,
+ ns / 1e9,
+ NUM_TICKS / (ns / 1e9));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(loop_count_timed) {
+ uv_loop_t* loop = uv_default_loop();
+
+ uv_idle_init(loop, &idle_handle);
+ uv_idle_start(&idle_handle, idle2_cb);
+
+ uv_timer_init(loop, &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 5000, 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ LOGF("loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-million-async.c b/third-party/libuv/test/benchmark-million-async.c
new file mode 100644
index 0000000000..69cc803436
--- /dev/null
+++ b/third-party/libuv/test/benchmark-million-async.c
@@ -0,0 +1,112 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+struct async_container {
+ unsigned async_events;
+ unsigned handles_seen;
+ uv_async_t async_handles[1024 * 1024];
+};
+
+static volatile int done;
+static uv_thread_t thread_id;
+static struct async_container* container;
+
+
+static unsigned fastrand(void) {
+ static unsigned g = 0;
+ g = g * 214013 + 2531011;
+ return g;
+}
+
+
+static void thread_cb(void* arg) {
+ unsigned i;
+
+ while (done == 0) {
+ i = fastrand() % ARRAY_SIZE(container->async_handles);
+ uv_async_send(container->async_handles + i);
+ }
+}
+
+
+static void async_cb(uv_async_t* handle, int status) {
+ container->async_events++;
+ handle->data = handle;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ unsigned i;
+
+ done = 1;
+ ASSERT(0 == uv_thread_join(&thread_id));
+
+ for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+ uv_async_t* handle = container->async_handles + i;
+
+ if (handle->data != NULL)
+ container->handles_seen++;
+
+ uv_close((uv_handle_t*) handle, NULL);
+ }
+
+ uv_close((uv_handle_t*) handle, NULL);
+}
+
+
+BENCHMARK_IMPL(million_async) {
+ uv_timer_t timer_handle;
+ uv_async_t* handle;
+ uv_loop_t* loop;
+ int timeout;
+ unsigned i;
+
+ loop = uv_default_loop();
+ timeout = 5000;
+
+ container = malloc(sizeof(*container));
+ ASSERT(container != NULL);
+ container->async_events = 0;
+ container->handles_seen = 0;
+
+ for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) {
+ handle = container->async_handles + i;
+ ASSERT(0 == uv_async_init(loop, handle, async_cb));
+ handle->data = NULL;
+ }
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0));
+ ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n",
+ fmt(container->async_events),
+ timeout / 1000.,
+ fmt(container->async_events / (timeout / 1000.)),
+ fmt(container->handles_seen));
+ free(container);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-million-timers.c b/third-party/libuv/test/benchmark-million-timers.c
new file mode 100644
index 0000000000..64f4a1038e
--- /dev/null
+++ b/third-party/libuv/test/benchmark-million-timers.c
@@ -0,0 +1,85 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#define NUM_TIMERS (10 * 1000 * 1000)
+
+static int timer_cb_called;
+static int close_cb_called;
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ timer_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+BENCHMARK_IMPL(million_timers) {
+ uv_timer_t* timers;
+ uv_loop_t* loop;
+ uint64_t before_all;
+ uint64_t before_run;
+ uint64_t after_run;
+ uint64_t after_all;
+ int timeout;
+ int i;
+
+ timers = malloc(NUM_TIMERS * sizeof(timers[0]));
+ ASSERT(timers != NULL);
+
+ loop = uv_default_loop();
+ timeout = 0;
+
+ before_all = uv_hrtime();
+ for (i = 0; i < NUM_TIMERS; i++) {
+ if (i % 1000 == 0) timeout++;
+ ASSERT(0 == uv_timer_init(loop, timers + i));
+ ASSERT(0 == uv_timer_start(timers + i, timer_cb, timeout, 0));
+ }
+
+ before_run = uv_hrtime();
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ after_run = uv_hrtime();
+
+ for (i = 0; i < NUM_TIMERS; i++)
+ uv_close((uv_handle_t*) (timers + i), close_cb);
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ after_all = uv_hrtime();
+
+ ASSERT(timer_cb_called == NUM_TIMERS);
+ ASSERT(close_cb_called == NUM_TIMERS);
+ free(timers);
+
+ LOGF("%.2f seconds total\n", (after_all - before_all) / 1e9);
+ LOGF("%.2f seconds init\n", (before_run - before_all) / 1e9);
+ LOGF("%.2f seconds dispatch\n", (after_run - before_run) / 1e9);
+ LOGF("%.2f seconds cleanup\n", (after_all - after_run) / 1e9);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-multi-accept.c b/third-party/libuv/test/benchmark-multi-accept.c
new file mode 100644
index 0000000000..d71235ef3b
--- /dev/null
+++ b/third-party/libuv/test/benchmark-multi-accept.c
@@ -0,0 +1,445 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#define IPC_PIPE_NAME TEST_PIPENAME
+#define NUM_CONNECTS (250 * 1000)
+
+union stream_handle {
+ uv_pipe_t pipe;
+ uv_tcp_t tcp;
+};
+
+/* Use as (uv_stream_t *) &handle_storage -- it's kind of clunky but it
+ * avoids aliasing warnings.
+ */
+typedef unsigned char handle_storage_t[sizeof(union stream_handle)];
+
+/* Used for passing around the listen handle, not part of the benchmark proper.
+ * We have an overabundance of server types here. It works like this:
+ *
+ * 1. The main thread starts an IPC pipe server.
+ * 2. The worker threads connect to the IPC server and obtain a listen handle.
+ * 3. The worker threads start accepting requests on the listen handle.
+ * 4. The main thread starts connecting repeatedly.
+ *
+ * Step #4 should perhaps be farmed out over several threads.
+ */
+struct ipc_server_ctx {
+ handle_storage_t server_handle;
+ unsigned int num_connects;
+ uv_pipe_t ipc_pipe;
+};
+
+struct ipc_peer_ctx {
+ handle_storage_t peer_handle;
+ uv_write_t write_req;
+};
+
+struct ipc_client_ctx {
+ uv_connect_t connect_req;
+ uv_stream_t* server_handle;
+ uv_pipe_t ipc_pipe;
+ char scratch[16];
+};
+
+/* Used in the actual benchmark. */
+struct server_ctx {
+ handle_storage_t server_handle;
+ unsigned int num_connects;
+ uv_async_t async_handle;
+ uv_thread_t thread_id;
+ uv_sem_t semaphore;
+};
+
+struct client_ctx {
+ handle_storage_t client_handle;
+ unsigned int num_connects;
+ uv_connect_t connect_req;
+ uv_idle_t idle_handle;
+};
+
+static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status);
+static void ipc_write_cb(uv_write_t* req, int status);
+static void ipc_close_cb(uv_handle_t* handle);
+static void ipc_connect_cb(uv_connect_t* req, int status);
+static void ipc_read2_cb(uv_pipe_t* ipc_pipe,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type type);
+static void ipc_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf);
+
+static void sv_async_cb(uv_async_t* handle, int status);
+static void sv_connection_cb(uv_stream_t* server_handle, int status);
+static void sv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
+static void sv_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf);
+
+static void cl_connect_cb(uv_connect_t* req, int status);
+static void cl_idle_cb(uv_idle_t* handle, int status);
+static void cl_close_cb(uv_handle_t* handle);
+
+static struct sockaddr_in listen_addr;
+
+
+static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) {
+ struct ipc_server_ctx* sc;
+ struct ipc_peer_ctx* pc;
+ uv_loop_t* loop;
+ uv_buf_t buf;
+
+ loop = ipc_pipe->loop;
+ buf = uv_buf_init("PING", 4);
+ sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe);
+ pc = calloc(1, sizeof(*pc));
+ ASSERT(pc != NULL);
+
+ if (ipc_pipe->type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle));
+ else if (ipc_pipe->type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) &pc->peer_handle, 1));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept(ipc_pipe, (uv_stream_t*) &pc->peer_handle));
+ ASSERT(0 == uv_write2(&pc->write_req,
+ (uv_stream_t*) &pc->peer_handle,
+ &buf,
+ 1,
+ (uv_stream_t*) &sc->server_handle,
+ ipc_write_cb));
+
+ if (--sc->num_connects == 0)
+ uv_close((uv_handle_t*) ipc_pipe, NULL);
+}
+
+
+static void ipc_write_cb(uv_write_t* req, int status) {
+ struct ipc_peer_ctx* ctx;
+ ctx = container_of(req, struct ipc_peer_ctx, write_req);
+ uv_close((uv_handle_t*) &ctx->peer_handle, ipc_close_cb);
+}
+
+
+static void ipc_close_cb(uv_handle_t* handle) {
+ struct ipc_peer_ctx* ctx;
+ ctx = container_of(handle, struct ipc_peer_ctx, peer_handle);
+ free(ctx);
+}
+
+
+static void ipc_connect_cb(uv_connect_t* req, int status) {
+ struct ipc_client_ctx* ctx;
+ ctx = container_of(req, struct ipc_client_ctx, connect_req);
+ ASSERT(0 == status);
+ ASSERT(0 == uv_read2_start((uv_stream_t*) &ctx->ipc_pipe,
+ ipc_alloc_cb,
+ ipc_read2_cb));
+}
+
+
+static void ipc_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ struct ipc_client_ctx* ctx;
+ ctx = container_of(handle, struct ipc_client_ctx, ipc_pipe);
+ buf->base = ctx->scratch;
+ buf->len = sizeof(ctx->scratch);
+}
+
+
+static void ipc_read2_cb(uv_pipe_t* ipc_pipe,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type type) {
+ struct ipc_client_ctx* ctx;
+ uv_loop_t* loop;
+
+ ctx = container_of(ipc_pipe, struct ipc_client_ctx, ipc_pipe);
+ loop = ipc_pipe->loop;
+
+ if (type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) ctx->server_handle));
+ else if (type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) ctx->server_handle, 0));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept((uv_stream_t*) &ctx->ipc_pipe, ctx->server_handle));
+ uv_close((uv_handle_t*) &ctx->ipc_pipe, NULL);
+}
+
+
+/* Set up an IPC pipe server that hands out listen sockets to the worker
+ * threads. It's kind of cumbersome for such a simple operation, maybe we
+ * should revive uv_import() and uv_export().
+ */
+static void send_listen_handles(uv_handle_type type,
+ unsigned int num_servers,
+ struct server_ctx* servers) {
+ struct ipc_server_ctx ctx;
+ uv_loop_t* loop;
+ unsigned int i;
+
+ loop = uv_default_loop();
+ ctx.num_connects = num_servers;
+
+ if (type == UV_TCP) {
+ ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle));
+ ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle,
+ (const struct sockaddr*) &listen_addr,
+ 0));
+ }
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1));
+ ASSERT(0 == uv_pipe_bind(&ctx.ipc_pipe, IPC_PIPE_NAME));
+ ASSERT(0 == uv_listen((uv_stream_t*) &ctx.ipc_pipe, 128, ipc_connection_cb));
+
+ for (i = 0; i < num_servers; i++)
+ uv_sem_post(&servers[i].semaphore);
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ uv_close((uv_handle_t*) &ctx.server_handle, NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ for (i = 0; i < num_servers; i++)
+ uv_sem_wait(&servers[i].semaphore);
+}
+
+
+static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) {
+ struct ipc_client_ctx ctx;
+
+ ctx.server_handle = server_handle;
+ ctx.server_handle->data = "server handle";
+
+ ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1));
+ uv_pipe_connect(&ctx.connect_req,
+ &ctx.ipc_pipe,
+ IPC_PIPE_NAME,
+ ipc_connect_cb);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+}
+
+
+static void server_cb(void *arg) {
+ struct server_ctx *ctx;
+ uv_loop_t* loop;
+
+ ctx = arg;
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ ASSERT(0 == uv_async_init(loop, &ctx->async_handle, sv_async_cb));
+ uv_unref((uv_handle_t*) &ctx->async_handle);
+
+ /* Wait until the main thread is ready. */
+ uv_sem_wait(&ctx->semaphore);
+ get_listen_handle(loop, (uv_stream_t*) &ctx->server_handle);
+ uv_sem_post(&ctx->semaphore);
+
+ /* Now start the actual benchmark. */
+ ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle,
+ 128,
+ sv_connection_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ uv_loop_delete(loop);
+}
+
+
+static void sv_async_cb(uv_async_t* handle, int status) {
+ struct server_ctx* ctx;
+ ctx = container_of(handle, struct server_ctx, async_handle);
+ uv_close((uv_handle_t*) &ctx->server_handle, NULL);
+ uv_close((uv_handle_t*) &ctx->async_handle, NULL);
+}
+
+
+static void sv_connection_cb(uv_stream_t* server_handle, int status) {
+ handle_storage_t* storage;
+ struct server_ctx* ctx;
+
+ ctx = container_of(server_handle, struct server_ctx, server_handle);
+ ASSERT(status == 0);
+
+ storage = malloc(sizeof(*storage));
+ ASSERT(storage != NULL);
+
+ if (server_handle->type == UV_TCP)
+ ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage));
+ else if (server_handle->type == UV_NAMED_PIPE)
+ ASSERT(0 == uv_pipe_init(server_handle->loop, (uv_pipe_t*) storage, 0));
+ else
+ ASSERT(0);
+
+ ASSERT(0 == uv_accept(server_handle, (uv_stream_t*) storage));
+ ASSERT(0 == uv_read_start((uv_stream_t*) storage, sv_alloc_cb, sv_read_cb));
+ ctx->num_connects++;
+}
+
+
+static void sv_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[32];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void sv_read_cb(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ASSERT(nread == UV_EOF);
+ uv_close((uv_handle_t*) handle, (uv_close_cb) free);
+}
+
+
+static void cl_connect_cb(uv_connect_t* req, int status) {
+ struct client_ctx* ctx = container_of(req, struct client_ctx, connect_req);
+ uv_idle_start(&ctx->idle_handle, cl_idle_cb);
+ ASSERT(0 == status);
+}
+
+
+static void cl_idle_cb(uv_idle_t* handle, int status) {
+ struct client_ctx* ctx = container_of(handle, struct client_ctx, idle_handle);
+ uv_close((uv_handle_t*) &ctx->client_handle, cl_close_cb);
+ uv_idle_stop(&ctx->idle_handle);
+}
+
+
+static void cl_close_cb(uv_handle_t* handle) {
+ struct client_ctx* ctx;
+
+ ctx = container_of(handle, struct client_ctx, client_handle);
+
+ if (--ctx->num_connects == 0) {
+ uv_close((uv_handle_t*) &ctx->idle_handle, NULL);
+ return;
+ }
+
+ ASSERT(0 == uv_tcp_init(handle->loop, (uv_tcp_t*) &ctx->client_handle));
+ ASSERT(0 == uv_tcp_connect(&ctx->connect_req,
+ (uv_tcp_t*) &ctx->client_handle,
+ (const struct sockaddr*) &listen_addr,
+ cl_connect_cb));
+}
+
+
+static int test_tcp(unsigned int num_servers, unsigned int num_clients) {
+ struct server_ctx* servers;
+ struct client_ctx* clients;
+ uv_loop_t* loop;
+ uv_tcp_t* handle;
+ unsigned int i;
+ double time;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &listen_addr));
+ loop = uv_default_loop();
+
+ servers = calloc(num_servers, sizeof(servers[0]));
+ clients = calloc(num_clients, sizeof(clients[0]));
+ ASSERT(servers != NULL);
+ ASSERT(clients != NULL);
+
+ /* We're making the assumption here that from the perspective of the
+ * OS scheduler, threads are functionally equivalent to and interchangeable
+ * with full-blown processes.
+ */
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ ASSERT(0 == uv_sem_init(&ctx->semaphore, 0));
+ ASSERT(0 == uv_thread_create(&ctx->thread_id, server_cb, ctx));
+ }
+
+ send_listen_handles(UV_TCP, num_servers, servers);
+
+ for (i = 0; i < num_clients; i++) {
+ struct client_ctx* ctx = clients + i;
+ ctx->num_connects = NUM_CONNECTS / num_clients;
+ handle = (uv_tcp_t*) &ctx->client_handle;
+ handle->data = "client handle";
+ ASSERT(0 == uv_tcp_init(loop, handle));
+ ASSERT(0 == uv_tcp_connect(&ctx->connect_req,
+ handle,
+ (const struct sockaddr*) &listen_addr,
+ cl_connect_cb));
+ ASSERT(0 == uv_idle_init(loop, &ctx->idle_handle));
+ }
+
+ {
+ uint64_t t = uv_hrtime();
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ t = uv_hrtime() - t;
+ time = t / 1e9;
+ }
+
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ uv_async_send(&ctx->async_handle);
+ ASSERT(0 == uv_thread_join(&ctx->thread_id));
+ uv_sem_destroy(&ctx->semaphore);
+ }
+
+ printf("accept%u: %.0f accepts/sec (%u total)\n",
+ num_servers,
+ NUM_CONNECTS / time,
+ NUM_CONNECTS);
+
+ for (i = 0; i < num_servers; i++) {
+ struct server_ctx* ctx = servers + i;
+ printf(" thread #%u: %.0f accepts/sec (%u total, %.1f%%)\n",
+ i,
+ ctx->num_connects / time,
+ ctx->num_connects,
+ ctx->num_connects * 100.0 / NUM_CONNECTS);
+ }
+
+ free(clients);
+ free(servers);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept2) {
+ return test_tcp(2, 40);
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept4) {
+ return test_tcp(4, 40);
+}
+
+
+BENCHMARK_IMPL(tcp_multi_accept8) {
+ return test_tcp(8, 40);
+}
diff --git a/third-party/libuv/test/benchmark-ping-pongs.c b/third-party/libuv/test/benchmark-ping-pongs.c
new file mode 100644
index 0000000000..bb560d7d21
--- /dev/null
+++ b/third-party/libuv/test/benchmark-ping-pongs.c
@@ -0,0 +1,220 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Run the benchmark for this many ms */
+#define TIME 5000
+
+
+typedef struct {
+ int pongs;
+ int state;
+ uv_tcp_t tcp;
+ uv_connect_t connect_req;
+ uv_shutdown_t shutdown_req;
+} pinger_t;
+
+typedef struct buf_s {
+ uv_buf_t uv_buf_t;
+ struct buf_s* next;
+} buf_t;
+
+
+static char PING[] = "PING\n";
+
+static uv_loop_t* loop;
+
+static buf_t* buf_freelist = NULL;
+static int pinger_shutdown_cb_called;
+static int completed_pingers = 0;
+static int64_t start_time;
+
+
+static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) {
+ buf_t* ab;
+
+ ab = buf_freelist;
+ if (ab != NULL)
+ buf_freelist = ab->next;
+ else {
+ ab = malloc(size + sizeof(*ab));
+ ab->uv_buf_t.len = size;
+ ab->uv_buf_t.base = (char*) (ab + 1);
+ }
+
+ *buf = ab->uv_buf_t;
+}
+
+
+static void buf_free(const uv_buf_t* buf) {
+ buf_t* ab = (buf_t*) buf->base - 1;
+ ab->next = buf_freelist;
+ buf_freelist = ab;
+}
+
+
+static void pinger_close_cb(uv_handle_t* handle) {
+ pinger_t* pinger;
+
+ pinger = (pinger_t*)handle->data;
+ LOGF("ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
+
+ free(pinger);
+
+ completed_pingers++;
+}
+
+
+static void pinger_write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+
+ free(req);
+}
+
+
+static void pinger_write_ping(pinger_t* pinger) {
+ uv_write_t* req;
+ uv_buf_t buf;
+
+ buf = uv_buf_init(PING, sizeof(PING) - 1);
+
+ req = malloc(sizeof *req);
+ if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) {
+ FATAL("uv_write failed");
+ }
+}
+
+
+static void pinger_shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(status == 0);
+ pinger_shutdown_cb_called++;
+
+ /*
+ * The close callback has not been triggered yet. We must wait for EOF
+ * until we close the connection.
+ */
+ ASSERT(completed_pingers == 0);
+}
+
+
+static void pinger_read_cb(uv_stream_t* tcp,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ssize_t i;
+ pinger_t* pinger;
+
+ pinger = (pinger_t*)tcp->data;
+
+ if (nread < 0) {
+ ASSERT(nread == UV_EOF);
+
+ if (buf->base) {
+ buf_free(buf);
+ }
+
+ ASSERT(pinger_shutdown_cb_called == 1);
+ uv_close((uv_handle_t*)tcp, pinger_close_cb);
+
+ return;
+ }
+
+ /* Now we count the pings */
+ for (i = 0; i < nread; i++) {
+ ASSERT(buf->base[i] == PING[pinger->state]);
+ pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
+ if (pinger->state == 0) {
+ pinger->pongs++;
+ if (uv_now(loop) - start_time > TIME) {
+ uv_shutdown(&pinger->shutdown_req,
+ (uv_stream_t*) tcp,
+ pinger_shutdown_cb);
+ break;
+ } else {
+ pinger_write_ping(pinger);
+ }
+ }
+ }
+
+ buf_free(buf);
+}
+
+
+static void pinger_connect_cb(uv_connect_t* req, int status) {
+ pinger_t *pinger = (pinger_t*)req->handle->data;
+
+ ASSERT(status == 0);
+
+ pinger_write_ping(pinger);
+
+ if (uv_read_start(req->handle, buf_alloc, pinger_read_cb)) {
+ FATAL("uv_read_start failed");
+ }
+}
+
+
+static void pinger_new(void) {
+ struct sockaddr_in client_addr;
+ struct sockaddr_in server_addr;
+ pinger_t *pinger;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr));
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
+ pinger = malloc(sizeof(*pinger));
+ pinger->state = 0;
+ pinger->pongs = 0;
+
+ /* Try to connect to the server and do NUM_PINGS ping-pongs. */
+ r = uv_tcp_init(loop, &pinger->tcp);
+ ASSERT(!r);
+
+ pinger->tcp.data = pinger;
+
+ ASSERT(0 == uv_tcp_bind(&pinger->tcp,
+ (const struct sockaddr*) &client_addr,
+ 0));
+
+ r = uv_tcp_connect(&pinger->connect_req,
+ &pinger->tcp,
+ (const struct sockaddr*) &server_addr,
+ pinger_connect_cb);
+ ASSERT(!r);
+}
+
+
+BENCHMARK_IMPL(ping_pongs) {
+ loop = uv_default_loop();
+
+ start_time = uv_now(loop);
+
+ pinger_new();
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(completed_pingers == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-pound.c b/third-party/libuv/test/benchmark-pound.c
new file mode 100644
index 0000000000..587928549e
--- /dev/null
+++ b/third-party/libuv/test/benchmark-pound.c
@@ -0,0 +1,350 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+/* Update this is you're going to run > 1000 concurrent requests. */
+#define MAX_CONNS 1000
+
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
+
+#undef DEBUG
+#define DEBUG 0
+
+struct conn_rec_s;
+
+typedef void (*setup_fn)(int num, void* arg);
+typedef void (*make_connect_fn)(struct conn_rec_s* conn);
+typedef int (*connect_fn)(int num, make_connect_fn make_connect, void* arg);
+
+/* Base class for tcp_conn_rec and pipe_conn_rec.
+ * The ordering of fields matters!
+ */
+typedef struct conn_rec_s {
+ int i;
+ uv_connect_t conn_req;
+ uv_write_t write_req;
+ make_connect_fn make_connect;
+ uv_stream_t stream;
+} conn_rec;
+
+typedef struct {
+ int i;
+ uv_connect_t conn_req;
+ uv_write_t write_req;
+ make_connect_fn make_connect;
+ uv_tcp_t stream;
+} tcp_conn_rec;
+
+typedef struct {
+ int i;
+ uv_connect_t conn_req;
+ uv_write_t write_req;
+ make_connect_fn make_connect;
+ uv_pipe_t stream;
+} pipe_conn_rec;
+
+static char buffer[] = "QS";
+
+static uv_loop_t* loop;
+
+static tcp_conn_rec tcp_conns[MAX_CONNS];
+static pipe_conn_rec pipe_conns[MAX_CONNS];
+
+static uint64_t start; /* in ms */
+static int closed_streams;
+static int conns_failed;
+
+static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
+static void connect_cb(uv_connect_t* conn_req, int status);
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
+static void close_cb(uv_handle_t* handle);
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void after_write(uv_write_t* req, int status) {
+ if (status != 0) {
+ fprintf(stderr, "write error %s\n", uv_err_name(status));
+ uv_close((uv_handle_t*)req->handle, close_cb);
+ conns_failed++;
+ return;
+ }
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ conn_rec* conn;
+ uv_buf_t buf;
+ int r;
+
+ if (status != 0) {
+#if DEBUG
+ fprintf(stderr, "connect error %s\n", uv_err_name(status));
+#endif
+ uv_close((uv_handle_t*)req->handle, close_cb);
+ conns_failed++;
+ return;
+ }
+
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+
+ conn = (conn_rec*)req->data;
+ ASSERT(conn != NULL);
+
+#if DEBUG
+ printf("connect_cb %d\n", conn->i);
+#endif
+
+ r = uv_read_start(&conn->stream, alloc_cb, read_cb);
+ ASSERT(r == 0);
+
+ buf.base = buffer;
+ buf.len = sizeof(buffer) - 1;
+
+ r = uv_write(&conn->write_req, &conn->stream, &buf, 1, after_write);
+ ASSERT(r == 0);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+
+ ASSERT(stream != NULL);
+
+#if DEBUG
+ printf("read_cb %d\n", p->i);
+#endif
+
+ uv_close((uv_handle_t*)stream, close_cb);
+
+ if (nread < 0) {
+ if (nread == UV_EOF) {
+ ;
+ } else if (nread == UV_ECONNRESET) {
+ conns_failed++;
+ } else {
+ fprintf(stderr, "read error %s\n", uv_err_name(nread));
+ ASSERT(0);
+ }
+ }
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ conn_rec* p = (conn_rec*)handle->data;
+
+ ASSERT(handle != NULL);
+ closed_streams++;
+
+#if DEBUG
+ printf("close_cb %d\n", p->i);
+#endif
+
+ if (uv_now(loop) - start < 10000) {
+ p->make_connect(p);
+ }
+}
+
+
+static void tcp_do_setup(int num, void* arg) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ tcp_conns[i].i = i;
+ }
+}
+
+
+static void pipe_do_setup(int num, void* arg) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ pipe_conns[i].i = i;
+ }
+}
+
+
+static void tcp_make_connect(conn_rec* p) {
+ struct sockaddr_in addr;
+ tcp_conn_rec* tp;
+ int r;
+
+ tp = (tcp_conn_rec*) p;
+
+ r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_connect(&tp->conn_req,
+ (uv_tcp_t*) &p->stream,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ if (r) {
+ fprintf(stderr, "uv_tcp_connect error %s\n", uv_err_name(r));
+ ASSERT(0);
+ }
+
+#if DEBUG
+ printf("make connect %d\n", p->i);
+#endif
+
+ p->conn_req.data = p;
+ p->write_req.data = p;
+ p->stream.data = p;
+}
+
+
+static void pipe_make_connect(conn_rec* p) {
+ int r;
+
+ r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream, 0);
+ ASSERT(r == 0);
+
+ uv_pipe_connect(&((pipe_conn_rec*) p)->conn_req,
+ (uv_pipe_t*) &p->stream,
+ TEST_PIPENAME,
+ connect_cb);
+
+#if DEBUG
+ printf("make connect %d\n", p->i);
+#endif
+
+ p->conn_req.data = p;
+ p->write_req.data = p;
+ p->stream.data = p;
+}
+
+
+static int tcp_do_connect(int num, make_connect_fn make_connect, void* arg) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ tcp_make_connect((conn_rec*)&tcp_conns[i]);
+ tcp_conns[i].make_connect = make_connect;
+ }
+
+ return 0;
+}
+
+
+static int pipe_do_connect(int num, make_connect_fn make_connect, void* arg) {
+ int i;
+
+ for (i = 0; i < num; i++) {
+ pipe_make_connect((conn_rec*)&pipe_conns[i]);
+ pipe_conns[i].make_connect = make_connect;
+ }
+
+ return 0;
+}
+
+
+static int pound_it(int concurrency,
+ const char* type,
+ setup_fn do_setup,
+ connect_fn do_connect,
+ make_connect_fn make_connect,
+ void* arg) {
+ double secs;
+ int r;
+ uint64_t start_time; /* in ns */
+ uint64_t end_time;
+
+ loop = uv_default_loop();
+
+ uv_update_time(loop);
+ start = uv_now(loop);
+
+ /* Run benchmark for at least five seconds. */
+ start_time = uv_hrtime();
+
+ do_setup(concurrency, arg);
+
+ r = do_connect(concurrency, make_connect, arg);
+ ASSERT(!r);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ end_time = uv_hrtime();
+
+ /* Number of fractional seconds it took to run the benchmark. */
+ secs = (double)(end_time - start_time) / NANOSEC;
+
+ LOGF("%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
+ type,
+ concurrency,
+ closed_streams / secs,
+ conns_failed);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+BENCHMARK_IMPL(tcp4_pound_100) {
+ return pound_it(100,
+ "tcp",
+ tcp_do_setup,
+ tcp_do_connect,
+ tcp_make_connect,
+ NULL);
+}
+
+
+BENCHMARK_IMPL(tcp4_pound_1000) {
+ return pound_it(1000,
+ "tcp",
+ tcp_do_setup,
+ tcp_do_connect,
+ tcp_make_connect,
+ NULL);
+}
+
+
+BENCHMARK_IMPL(pipe_pound_100) {
+ return pound_it(100,
+ "pipe",
+ pipe_do_setup,
+ pipe_do_connect,
+ pipe_make_connect,
+ NULL);
+}
+
+
+BENCHMARK_IMPL(pipe_pound_1000) {
+ return pound_it(1000,
+ "pipe",
+ pipe_do_setup,
+ pipe_do_connect,
+ pipe_make_connect,
+ NULL);
+}
diff --git a/third-party/libuv/test/benchmark-pump.c b/third-party/libuv/test/benchmark-pump.c
new file mode 100644
index 0000000000..678634ff71
--- /dev/null
+++ b/third-party/libuv/test/benchmark-pump.c
@@ -0,0 +1,470 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <math.h>
+#include <stdio.h>
+
+
+static int TARGET_CONNECTIONS;
+#define WRITE_BUFFER_SIZE 8192
+#define MAX_SIMULTANEOUS_CONNECTS 100
+
+#define PRINT_STATS 0
+#define STATS_INTERVAL 1000 /* msec */
+#define STATS_COUNT 5
+
+
+static void do_write(uv_stream_t*);
+static void maybe_connect_some();
+
+static uv_req_t* req_alloc();
+static void req_free(uv_req_t* uv_req);
+
+static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf);
+static void buf_free(const uv_buf_t* buf);
+
+static uv_loop_t* loop;
+
+static uv_tcp_t tcpServer;
+static uv_pipe_t pipeServer;
+static uv_stream_t* server;
+static struct sockaddr_in listen_addr;
+static struct sockaddr_in connect_addr;
+
+static int64_t start_time;
+
+static int max_connect_socket = 0;
+static int max_read_sockets = 0;
+static int read_sockets = 0;
+static int write_sockets = 0;
+
+static int64_t nrecv = 0;
+static int64_t nrecv_total = 0;
+static int64_t nsent = 0;
+static int64_t nsent_total = 0;
+
+static int stats_left = 0;
+
+static char write_buffer[WRITE_BUFFER_SIZE];
+
+/* Make this as large as you need. */
+#define MAX_WRITE_HANDLES 1000
+
+static stream_type type;
+
+static uv_tcp_t tcp_write_handles[MAX_WRITE_HANDLES];
+static uv_pipe_t pipe_write_handles[MAX_WRITE_HANDLES];
+
+static uv_timer_t timer_handle;
+
+
+static double gbit(int64_t bytes, int64_t passed_ms) {
+ double gbits = ((double)bytes / (1024 * 1024 * 1024)) * 8;
+ return gbits / ((double)passed_ms / 1000);
+}
+
+
+static void show_stats(uv_timer_t* handle, int status) {
+ int64_t diff;
+ int i;
+
+#if PRINT_STATS
+ LOGF("connections: %d, write: %.1f gbit/s\n",
+ write_sockets,
+ gbit(nsent, STATS_INTERVAL));
+#endif
+
+ /* Exit if the show is over */
+ if (!--stats_left) {
+
+ uv_update_time(loop);
+ diff = uv_now(loop) - start_time;
+
+ LOGF("%s_pump%d_client: %.1f gbit/s\n",
+ type == TCP ? "tcp" : "pipe",
+ write_sockets,
+ gbit(nsent_total, diff));
+
+ for (i = 0; i < write_sockets; i++) {
+ if (type == TCP)
+ uv_close((uv_handle_t*) &tcp_write_handles[i], NULL);
+ else
+ uv_close((uv_handle_t*) &pipe_write_handles[i], NULL);
+ }
+
+ exit(0);
+ }
+
+ /* Reset read and write counters */
+ nrecv = 0;
+ nsent = 0;
+}
+
+
+static void read_show_stats(void) {
+ int64_t diff;
+
+ uv_update_time(loop);
+ diff = uv_now(loop) - start_time;
+
+ LOGF("%s_pump%d_server: %.1f gbit/s\n",
+ type == TCP ? "tcp" : "pipe",
+ max_read_sockets,
+ gbit(nrecv_total, diff));
+}
+
+
+
+static void read_sockets_close_cb(uv_handle_t* handle) {
+ free(handle);
+ read_sockets--;
+
+ /* If it's past the first second and everyone has closed their connection
+ * Then print stats.
+ */
+ if (uv_now(loop) - start_time > 1000 && read_sockets == 0) {
+ read_show_stats();
+ uv_close((uv_handle_t*)server, NULL);
+ }
+}
+
+
+static void start_stats_collection(void) {
+ int r;
+
+ /* Show-stats timer */
+ stats_left = STATS_COUNT;
+ r = uv_timer_init(loop, &timer_handle);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL);
+ ASSERT(r == 0);
+
+ uv_update_time(loop);
+ start_time = uv_now(loop);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t bytes, const uv_buf_t* buf) {
+ if (nrecv_total == 0) {
+ ASSERT(start_time == 0);
+ uv_update_time(loop);
+ start_time = uv_now(loop);
+ }
+
+ if (bytes < 0) {
+ uv_close((uv_handle_t*)stream, read_sockets_close_cb);
+ return;
+ }
+
+ buf_free(buf);
+
+ nrecv += bytes;
+ nrecv_total += bytes;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+
+ req_free((uv_req_t*) req);
+
+ nsent += sizeof write_buffer;
+ nsent_total += sizeof write_buffer;
+
+ do_write((uv_stream_t*) req->handle);
+}
+
+
+static void do_write(uv_stream_t* stream) {
+ uv_write_t* req;
+ uv_buf_t buf;
+ int r;
+
+ buf.base = (char*) &write_buffer;
+ buf.len = sizeof write_buffer;
+
+ req = (uv_write_t*) req_alloc();
+ r = uv_write(req, stream, &buf, 1, write_cb);
+ ASSERT(r == 0);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ int i;
+
+ if (status) LOG(uv_strerror(status));
+ ASSERT(status == 0);
+
+ write_sockets++;
+ req_free((uv_req_t*) req);
+
+ maybe_connect_some();
+
+ if (write_sockets == TARGET_CONNECTIONS) {
+ start_stats_collection();
+
+ /* Yay! start writing */
+ for (i = 0; i < write_sockets; i++) {
+ if (type == TCP)
+ do_write((uv_stream_t*) &tcp_write_handles[i]);
+ else
+ do_write((uv_stream_t*) &pipe_write_handles[i]);
+ }
+ }
+}
+
+
+static void maybe_connect_some(void) {
+ uv_connect_t* req;
+ uv_tcp_t* tcp;
+ uv_pipe_t* pipe;
+ int r;
+
+ while (max_connect_socket < TARGET_CONNECTIONS &&
+ max_connect_socket < write_sockets + MAX_SIMULTANEOUS_CONNECTS) {
+ if (type == TCP) {
+ tcp = &tcp_write_handles[max_connect_socket++];
+
+ r = uv_tcp_init(loop, tcp);
+ ASSERT(r == 0);
+
+ req = (uv_connect_t*) req_alloc();
+ r = uv_tcp_connect(req,
+ tcp,
+ (const struct sockaddr*) &connect_addr,
+ connect_cb);
+ ASSERT(r == 0);
+ } else {
+ pipe = &pipe_write_handles[max_connect_socket++];
+
+ r = uv_pipe_init(loop, pipe, 0);
+ ASSERT(r == 0);
+
+ req = (uv_connect_t*) req_alloc();
+ uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb);
+ }
+ }
+}
+
+
+static void connection_cb(uv_stream_t* s, int status) {
+ uv_stream_t* stream;
+ int r;
+
+ ASSERT(server == s);
+ ASSERT(status == 0);
+
+ if (type == TCP) {
+ stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t));
+ r = uv_tcp_init(loop, (uv_tcp_t*)stream);
+ ASSERT(r == 0);
+ } else {
+ stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t));
+ r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
+ ASSERT(r == 0);
+ }
+
+ r = uv_accept(s, stream);
+ ASSERT(r == 0);
+
+ r = uv_read_start(stream, buf_alloc, read_cb);
+ ASSERT(r == 0);
+
+ read_sockets++;
+ max_read_sockets++;
+}
+
+
+/*
+ * Request allocator
+ */
+
+typedef struct req_list_s {
+ union uv_any_req uv_req;
+ struct req_list_s* next;
+} req_list_t;
+
+
+static req_list_t* req_freelist = NULL;
+
+
+static uv_req_t* req_alloc(void) {
+ req_list_t* req;
+
+ req = req_freelist;
+ if (req != NULL) {
+ req_freelist = req->next;
+ return (uv_req_t*) req;
+ }
+
+ req = (req_list_t*) malloc(sizeof *req);
+ return (uv_req_t*) req;
+}
+
+
+static void req_free(uv_req_t* uv_req) {
+ req_list_t* req = (req_list_t*) uv_req;
+
+ req->next = req_freelist;
+ req_freelist = req;
+}
+
+
+/*
+ * Buffer allocator
+ */
+
+typedef struct buf_list_s {
+ uv_buf_t uv_buf_t;
+ struct buf_list_s* next;
+} buf_list_t;
+
+
+static buf_list_t* buf_freelist = NULL;
+
+
+static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf_list_t* ab;
+
+ ab = buf_freelist;
+ if (ab != NULL)
+ buf_freelist = ab->next;
+ else {
+ ab = malloc(size + sizeof(*ab));
+ ab->uv_buf_t.len = size;
+ ab->uv_buf_t.base = (char*) (ab + 1);
+ }
+
+ *buf = ab->uv_buf_t;
+}
+
+
+static void buf_free(const uv_buf_t* buf) {
+ buf_list_t* ab = (buf_list_t*) buf->base - 1;
+ ab->next = buf_freelist;
+ buf_freelist = ab;
+}
+
+
+HELPER_IMPL(tcp_pump_server) {
+ int r;
+
+ type = TCP;
+ loop = uv_default_loop();
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &listen_addr));
+
+ /* Server */
+ server = (uv_stream_t*)&tcpServer;
+ r = uv_tcp_init(loop, &tcpServer);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr, 0);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ return 0;
+}
+
+
+HELPER_IMPL(pipe_pump_server) {
+ int r;
+ type = PIPE;
+
+ loop = uv_default_loop();
+
+ /* Server */
+ server = (uv_stream_t*)&pipeServer;
+ r = uv_pipe_init(loop, &pipeServer, 0);
+ ASSERT(r == 0);
+ r = uv_pipe_bind(&pipeServer, TEST_PIPENAME);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void tcp_pump(int n) {
+ ASSERT(n <= MAX_WRITE_HANDLES);
+ TARGET_CONNECTIONS = n;
+ type = TCP;
+
+ loop = uv_default_loop();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &connect_addr));
+
+ /* Start making connections */
+ maybe_connect_some();
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+}
+
+
+static void pipe_pump(int n) {
+ ASSERT(n <= MAX_WRITE_HANDLES);
+ TARGET_CONNECTIONS = n;
+ type = PIPE;
+
+ loop = uv_default_loop();
+
+ /* Start making connections */
+ maybe_connect_some();
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+}
+
+
+BENCHMARK_IMPL(tcp_pump100_client) {
+ tcp_pump(100);
+ return 0;
+}
+
+
+BENCHMARK_IMPL(tcp_pump1_client) {
+ tcp_pump(1);
+ return 0;
+}
+
+
+BENCHMARK_IMPL(pipe_pump100_client) {
+ pipe_pump(100);
+ return 0;
+}
+
+
+BENCHMARK_IMPL(pipe_pump1_client) {
+ pipe_pump(1);
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-sizes.c b/third-party/libuv/test/benchmark-sizes.c
new file mode 100644
index 0000000000..8ccf10ee47
--- /dev/null
+++ b/third-party/libuv/test/benchmark-sizes.c
@@ -0,0 +1,45 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+
+BENCHMARK_IMPL(sizes) {
+ LOGF("uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t));
+ LOGF("uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t));
+ LOGF("uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t));
+ LOGF("uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t));
+ LOGF("uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t));
+ LOGF("uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t));
+ LOGF("uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t));
+ LOGF("uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t));
+ LOGF("uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t));
+ LOGF("uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t));
+ LOGF("uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t));
+ LOGF("uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t));
+ LOGF("uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t));
+ LOGF("uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t));
+ LOGF("uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t));
+ LOGF("uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t));
+ LOGF("uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t));
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-spawn.c b/third-party/libuv/test/benchmark-spawn.c
new file mode 100644
index 0000000000..9cae41a83a
--- /dev/null
+++ b/third-party/libuv/test/benchmark-spawn.c
@@ -0,0 +1,163 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* This benchmark spawns itself 1000 times. */
+
+#include "task.h"
+#include "uv.h"
+
+static uv_loop_t* loop;
+
+static int N = 1000;
+static int done;
+
+static uv_process_t process;
+static uv_process_options_t options;
+static char exepath[1024];
+static size_t exepath_size = 1024;
+static char* args[3];
+static uv_pipe_t out;
+
+#define OUTPUT_SIZE 1024
+static char output[OUTPUT_SIZE];
+static int output_used;
+
+static int process_open;
+static int pipe_open;
+
+
+static void spawn(void);
+
+
+static void maybe_spawn(void) {
+ if (process_open == 0 && pipe_open == 0) {
+ done++;
+ if (done < N) {
+ spawn();
+ }
+ }
+}
+
+
+static void process_close_cb(uv_handle_t* handle) {
+ ASSERT(process_open == 1);
+ process_open = 0;
+ maybe_spawn();
+}
+
+
+static void exit_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ ASSERT(exit_status == 42);
+ ASSERT(term_signal == 0);
+ uv_close((uv_handle_t*)process, process_close_cb);
+}
+
+
+static void on_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = output + output_used;
+ buf->len = OUTPUT_SIZE - output_used;
+}
+
+
+static void pipe_close_cb(uv_handle_t* pipe) {
+ ASSERT(pipe_open == 1);
+ pipe_open = 0;
+ maybe_spawn();
+}
+
+
+static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) {
+ if (nread > 0) {
+ ASSERT(pipe_open == 1);
+ output_used += nread;
+ } else if (nread < 0) {
+ if (nread == UV_EOF) {
+ uv_close((uv_handle_t*)pipe, pipe_close_cb);
+ }
+ }
+}
+
+
+static void spawn(void) {
+ uv_stdio_container_t stdio[2];
+ int r;
+
+ ASSERT(process_open == 0);
+ ASSERT(pipe_open == 0);
+
+ args[0] = exepath;
+ args[1] = "spawn_helper";
+ args[2] = NULL;
+ options.file = exepath;
+ options.args = args;
+ options.exit_cb = exit_cb;
+
+ uv_pipe_init(loop, &out, 0);
+
+ options.stdio = stdio;
+ options.stdio_count = 2;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+
+ r = uv_spawn(loop, &process, &options);
+ ASSERT(r == 0);
+
+ process_open = 1;
+ pipe_open = 1;
+ output_used = 0;
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+}
+
+
+BENCHMARK_IMPL(spawn) {
+ int r;
+ static int64_t start_time, end_time;
+
+ loop = uv_default_loop();
+
+ r = uv_exepath(exepath, &exepath_size);
+ ASSERT(r == 0);
+ exepath[exepath_size] = '\0';
+
+ uv_update_time(loop);
+ start_time = uv_now(loop);
+
+ spawn();
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_update_time(loop);
+ end_time = uv_now(loop);
+
+ LOGF("spawn: %.0f spawns/s\n",
+ (double) N / (double) (end_time - start_time) * 1000.0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-tcp-write-batch.c b/third-party/libuv/test/benchmark-tcp-write-batch.c
new file mode 100644
index 0000000000..96921b70db
--- /dev/null
+++ b/third-party/libuv/test/benchmark-tcp-write-batch.c
@@ -0,0 +1,144 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define WRITE_REQ_DATA "Hello, world."
+#define NUM_WRITE_REQS (1000 * 1000)
+
+typedef struct {
+ uv_write_t req;
+ uv_buf_t buf;
+} write_req;
+
+
+static write_req* write_reqs;
+static uv_tcp_t tcp_client;
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+
+static int shutdown_cb_called = 0;
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int close_cb_called = 0;
+
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void shutdown_cb(uv_shutdown_t* req, int status);
+static void close_cb(uv_handle_t* handle);
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ write_req* w;
+ int i;
+ int r;
+
+ ASSERT(req->handle == (uv_stream_t*)&tcp_client);
+
+ for (i = 0; i < NUM_WRITE_REQS; i++) {
+ w = &write_reqs[i];
+ r = uv_write(&w->req, req->handle, &w->buf, 1, write_cb);
+ ASSERT(r == 0);
+ }
+
+ r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
+ ASSERT(r == 0);
+
+ connect_cb_called++;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ write_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(req->handle == (uv_stream_t*)&tcp_client);
+ ASSERT(req->handle->write_queue_size == 0);
+
+ uv_close((uv_handle_t*)req->handle, close_cb);
+ free(write_reqs);
+
+ shutdown_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*)&tcp_client);
+ close_cb_called++;
+}
+
+
+BENCHMARK_IMPL(tcp_write_batch) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ uint64_t start;
+ uint64_t stop;
+ int i;
+ int r;
+
+ write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS);
+ ASSERT(write_reqs != NULL);
+
+ /* Prepare the data to write out. */
+ for (i = 0; i < NUM_WRITE_REQS; i++) {
+ write_reqs[i].buf = uv_buf_init(WRITE_REQ_DATA,
+ sizeof(WRITE_REQ_DATA) - 1);
+ }
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, &tcp_client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &tcp_client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ start = uv_hrtime();
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ stop = uv_hrtime();
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == NUM_WRITE_REQS);
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ printf("%ld write requests in %.2fs.\n",
+ (long)NUM_WRITE_REQS,
+ (stop - start) / 1e9);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-thread.c b/third-party/libuv/test/benchmark-thread.c
new file mode 100644
index 0000000000..b37a7fd6d0
--- /dev/null
+++ b/third-party/libuv/test/benchmark-thread.c
@@ -0,0 +1,64 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define NUM_THREADS (20 * 1000)
+
+static volatile int num_threads;
+
+
+static void thread_entry(void* arg) {
+ ASSERT(arg == (void *) 42);
+ num_threads++;
+ /* FIXME write barrier? */
+}
+
+
+BENCHMARK_IMPL(thread_create) {
+ uint64_t start_time;
+ double duration;
+ uv_thread_t tid;
+ int i, r;
+
+ start_time = uv_hrtime();
+
+ for (i = 0; i < NUM_THREADS; i++) {
+ r = uv_thread_create(&tid, thread_entry, (void *) 42);
+ ASSERT(r == 0);
+
+ r = uv_thread_join(&tid);
+ ASSERT(r == 0);
+ }
+
+ duration = (uv_hrtime() - start_time) / 1e9;
+
+ ASSERT(num_threads == NUM_THREADS);
+
+ printf("%d threads created in %.2f seconds (%.0f/s)\n",
+ NUM_THREADS, duration, NUM_THREADS / duration);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/benchmark-udp-pummel.c b/third-party/libuv/test/benchmark-udp-pummel.c
new file mode 100644
index 0000000000..d99250affc
--- /dev/null
+++ b/third-party/libuv/test/benchmark-udp-pummel.c
@@ -0,0 +1,243 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+#include "uv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define EXPECTED "RANG TANG DING DONG I AM THE JAPANESE SANDMAN"
+
+#define TEST_DURATION 5000 /* ms */
+
+#define BASE_PORT 12345
+
+struct sender_state {
+ struct sockaddr_in addr;
+ uv_udp_send_t send_req;
+ uv_udp_t udp_handle;
+};
+
+struct receiver_state {
+ struct sockaddr_in addr;
+ uv_udp_t udp_handle;
+};
+
+/* not used in timed mode */
+static unsigned int packet_counter = (unsigned int) 1e6;
+
+static int n_senders_;
+static int n_receivers_;
+static uv_buf_t bufs[5];
+static struct sender_state senders[1024];
+static struct receiver_state receivers[1024];
+
+static unsigned int send_cb_called;
+static unsigned int recv_cb_called;
+static unsigned int close_cb_called;
+static int timed;
+static int exiting;
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ struct sender_state* s;
+
+ ASSERT(req != NULL);
+
+ if (status != 0) {
+ ASSERT(status == UV_ECANCELED);
+ return;
+ }
+
+ if (exiting)
+ return;
+
+ s = container_of(req, struct sender_state, send_req);
+ ASSERT(req->handle == &s->udp_handle);
+
+ if (timed)
+ goto send;
+
+ if (packet_counter == 0) {
+ uv_close((uv_handle_t*)&s->udp_handle, NULL);
+ return;
+ }
+
+ packet_counter--;
+
+send:
+ ASSERT(0 == uv_udp_send(&s->send_req,
+ &s->udp_handle,
+ bufs,
+ ARRAY_SIZE(bufs),
+ (const struct sockaddr*) &s->addr,
+ send_cb));
+ send_cb_called++;
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ if (nread == 0)
+ return;
+
+ if (nread < 0) {
+ ASSERT(nread == UV_ECANCELED);
+ return;
+ }
+
+ ASSERT(addr->sa_family == AF_INET);
+ ASSERT(!memcmp(buf->base, EXPECTED, nread));
+
+ recv_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void timeout_cb(uv_timer_t* timer, int status) {
+ int i;
+
+ exiting = 1;
+
+ for (i = 0; i < n_senders_; i++)
+ uv_close((uv_handle_t*)&senders[i].udp_handle, close_cb);
+
+ for (i = 0; i < n_receivers_; i++)
+ uv_close((uv_handle_t*)&receivers[i].udp_handle, close_cb);
+}
+
+
+static int pummel(unsigned int n_senders,
+ unsigned int n_receivers,
+ unsigned long timeout) {
+ uv_timer_t timer_handle;
+ uint64_t duration;
+ uv_loop_t* loop;
+ unsigned int i;
+
+ ASSERT(n_senders <= ARRAY_SIZE(senders));
+ ASSERT(n_receivers <= ARRAY_SIZE(receivers));
+
+ loop = uv_default_loop();
+
+ n_senders_ = n_senders;
+ n_receivers_ = n_receivers;
+
+ if (timeout) {
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timeout_cb, timeout, 0));
+ /* Timer should not keep loop alive. */
+ uv_unref((uv_handle_t*)&timer_handle);
+ timed = 1;
+ }
+
+ for (i = 0; i < n_receivers; i++) {
+ struct receiver_state* s = receivers + i;
+ struct sockaddr_in addr;
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", BASE_PORT + i, &addr));
+ ASSERT(0 == uv_udp_init(loop, &s->udp_handle));
+ ASSERT(0 == uv_udp_bind(&s->udp_handle, (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_udp_recv_start(&s->udp_handle, alloc_cb, recv_cb));
+ uv_unref((uv_handle_t*)&s->udp_handle);
+ }
+
+ bufs[0] = uv_buf_init(EXPECTED + 0, 10);
+ bufs[1] = uv_buf_init(EXPECTED + 10, 10);
+ bufs[2] = uv_buf_init(EXPECTED + 20, 10);
+ bufs[3] = uv_buf_init(EXPECTED + 30, 10);
+ bufs[4] = uv_buf_init(EXPECTED + 40, 5);
+
+ for (i = 0; i < n_senders; i++) {
+ struct sender_state* s = senders + i;
+ ASSERT(0 == uv_ip4_addr("127.0.0.1",
+ BASE_PORT + (i % n_receivers),
+ &s->addr));
+ ASSERT(0 == uv_udp_init(loop, &s->udp_handle));
+ ASSERT(0 == uv_udp_send(&s->send_req,
+ &s->udp_handle,
+ bufs,
+ ARRAY_SIZE(bufs),
+ (const struct sockaddr*) &s->addr,
+ send_cb));
+ }
+
+ duration = uv_hrtime();
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ duration = uv_hrtime() - duration;
+ /* convert from nanoseconds to milliseconds */
+ duration = duration / (uint64_t) 1e6;
+
+ printf("udp_pummel_%dv%d: %.0f/s received, %.0f/s sent. "
+ "%u received, %u sent in %.1f seconds.\n",
+ n_receivers,
+ n_senders,
+ recv_cb_called / (duration / 1000.0),
+ send_cb_called / (duration / 1000.0),
+ recv_cb_called,
+ send_cb_called,
+ duration / 1000.0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+#define X(a, b) \
+ BENCHMARK_IMPL(udp_pummel_##a##v##b) { \
+ return pummel(a, b, 0); \
+ } \
+ BENCHMARK_IMPL(udp_timed_pummel_##a##v##b) { \
+ return pummel(a, b, TEST_DURATION); \
+ }
+
+X(1, 1)
+X(1, 10)
+X(1, 100)
+X(1, 1000)
+X(10, 10)
+X(10, 100)
+X(10, 1000)
+X(100, 10)
+X(100, 100)
+X(100, 1000)
+X(1000, 1000)
+
+#undef X
diff --git a/third-party/libuv/test/blackhole-server.c b/third-party/libuv/test/blackhole-server.c
new file mode 100644
index 0000000000..ad878b35c6
--- /dev/null
+++ b/third-party/libuv/test/blackhole-server.c
@@ -0,0 +1,121 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ uv_tcp_t handle;
+ uv_shutdown_t shutdown_req;
+} conn_rec;
+
+static uv_tcp_t tcp_server;
+
+static void connection_cb(uv_stream_t* stream, int status);
+static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
+static void shutdown_cb(uv_shutdown_t* req, int status);
+static void close_cb(uv_handle_t* handle);
+
+
+static void connection_cb(uv_stream_t* stream, int status) {
+ conn_rec* conn;
+ int r;
+
+ ASSERT(status == 0);
+ ASSERT(stream == (uv_stream_t*)&tcp_server);
+
+ conn = malloc(sizeof *conn);
+ ASSERT(conn != NULL);
+
+ r = uv_tcp_init(stream->loop, &conn->handle);
+ ASSERT(r == 0);
+
+ r = uv_accept(stream, (uv_stream_t*)&conn->handle);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&conn->handle, alloc_cb, read_cb);
+ ASSERT(r == 0);
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ conn_rec* conn;
+ int r;
+
+ if (nread >= 0)
+ return;
+
+ ASSERT(nread == UV_EOF);
+
+ conn = container_of(stream, conn_rec, handle);
+
+ r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb);
+ ASSERT(r == 0);
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ conn_rec* conn = container_of(req, conn_rec, shutdown_req);
+ uv_close((uv_handle_t*)&conn->handle, close_cb);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ conn_rec* conn = container_of(handle, conn_rec, handle);
+ free(conn);
+}
+
+
+HELPER_IMPL(tcp4_blackhole_server) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, &tcp_server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(0 && "Blackhole server dropped out of event loop.");
+
+ return 0;
+}
diff --git a/third-party/libuv/test/dns-server.c b/third-party/libuv/test/dns-server.c
new file mode 100644
index 0000000000..80052c7039
--- /dev/null
+++ b/third-party/libuv/test/dns-server.c
@@ -0,0 +1,340 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+typedef struct {
+ uv_write_t req;
+ uv_buf_t buf;
+} write_req_t;
+
+
+/* used to track multiple DNS requests received */
+typedef struct {
+ char* prevbuf_ptr;
+ int prevbuf_pos;
+ int prevbuf_rem;
+} dnsstate;
+
+
+/* modify handle to append dnsstate */
+typedef struct {
+ uv_tcp_t handle;
+ dnsstate state;
+} dnshandle;
+
+
+static uv_loop_t* loop;
+
+
+static uv_tcp_t server;
+
+
+static void after_write(uv_write_t* req, int status);
+static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf);
+static void on_close(uv_handle_t* peer);
+static void on_connection(uv_stream_t*, int status);
+
+#define WRITE_BUF_LEN (64*1024)
+#define DNSREC_LEN (4)
+
+#define LEN_OFFSET 0
+#define QUERYID_OFFSET 2
+
+static unsigned char DNSRsp[] = {
+ 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0
+};
+
+static unsigned char qrecord[] = {
+ 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1
+};
+
+static unsigned char arecord[] = {
+ 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1
+};
+
+
+static void after_write(uv_write_t* req, int status) {
+ write_req_t* wr;
+
+ if (status) {
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+ ASSERT(0);
+ }
+
+ wr = (write_req_t*) req;
+
+ /* Free the read/write buffer and the request */
+ free(wr->buf.base);
+ free(wr);
+}
+
+
+static void after_shutdown(uv_shutdown_t* req, int status) {
+ uv_close((uv_handle_t*) req->handle, on_close);
+ free(req);
+}
+
+
+static void addrsp(write_req_t* wr, char* hdr) {
+ char * dnsrsp;
+ short int rsplen;
+ short int* reclen;
+
+ rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord);
+
+ ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN);
+
+ dnsrsp = wr->buf.base + wr->buf.len;
+
+ /* copy stock response */
+ memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp));
+ memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord));
+ memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord));
+
+ /* overwrite with network order length and id from request header */
+ reclen = (short int*)dnsrsp;
+ *reclen = htons(rsplen-2);
+ dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET];
+ dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1];
+
+ wr->buf.len += rsplen;
+}
+
+static void process_req(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ write_req_t* wr;
+ dnshandle* dns = (dnshandle*)handle;
+ char hdrbuf[DNSREC_LEN];
+ int hdrbuf_remaining = DNSREC_LEN;
+ int rec_remaining = 0;
+ int readbuf_remaining;
+ char* dnsreq;
+ char* hdrstart;
+ int usingprev = 0;
+
+ wr = (write_req_t*) malloc(sizeof *wr);
+ wr->buf.base = (char*)malloc(WRITE_BUF_LEN);
+ wr->buf.len = 0;
+
+ if (dns->state.prevbuf_ptr != NULL) {
+ dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos;
+ readbuf_remaining = dns->state.prevbuf_rem;
+ usingprev = 1;
+ } else {
+ dnsreq = buf->base;
+ readbuf_remaining = nread;
+ }
+ hdrstart = dnsreq;
+
+ while (dnsreq != NULL) {
+ /* something to process */
+ while (readbuf_remaining > 0) {
+ /* something to process in current buffer */
+ if (hdrbuf_remaining > 0) {
+ /* process len and id */
+ if (readbuf_remaining < hdrbuf_remaining) {
+ /* too little to get request header. save for next buffer */
+ memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining],
+ dnsreq,
+ readbuf_remaining);
+ hdrbuf_remaining = DNSREC_LEN - readbuf_remaining;
+ break;
+ } else {
+ /* save header */
+ memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining],
+ dnsreq,
+ hdrbuf_remaining);
+ dnsreq += hdrbuf_remaining;
+ readbuf_remaining -= hdrbuf_remaining;
+ hdrbuf_remaining = 0;
+
+ /* get record length */
+ rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1];
+ rec_remaining -= (DNSREC_LEN - 2);
+ }
+ }
+
+ if (rec_remaining <= readbuf_remaining) {
+ /* prepare reply */
+ addrsp(wr, hdrbuf);
+
+ /* move to next record */
+ dnsreq += rec_remaining;
+ hdrstart = dnsreq;
+ readbuf_remaining -= rec_remaining;
+ rec_remaining = 0;
+ hdrbuf_remaining = DNSREC_LEN;
+ } else {
+ /* otherwise this buffer is done. */
+ rec_remaining -= readbuf_remaining;
+ break;
+ }
+ }
+
+ /* If we had to use bytes from prev buffer, start processing the current
+ * one.
+ */
+ if (usingprev == 1) {
+ /* free previous buffer */
+ free(dns->state.prevbuf_ptr);
+ dnsreq = buf->base;
+ readbuf_remaining = nread;
+ usingprev = 0;
+ } else {
+ dnsreq = NULL;
+ }
+ }
+
+ /* send write buffer */
+ if (wr->buf.len > 0) {
+ if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) {
+ FATAL("uv_write failed");
+ }
+ }
+
+ if (readbuf_remaining > 0) {
+ /* save start of record position, so we can continue on next read */
+ dns->state.prevbuf_ptr = buf->base;
+ dns->state.prevbuf_pos = hdrstart - buf->base;
+ dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos;
+ } else {
+ /* nothing left in this buffer */
+ dns->state.prevbuf_ptr = NULL;
+ dns->state.prevbuf_pos = 0;
+ dns->state.prevbuf_rem = 0;
+ free(buf->base);
+ }
+}
+
+static void after_read(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ uv_shutdown_t* req;
+
+ if (nread < 0) {
+ /* Error or EOF */
+ ASSERT(nread == UV_EOF);
+
+ if (buf->base) {
+ free(buf->base);
+ }
+
+ req = malloc(sizeof *req);
+ uv_shutdown(req, handle, after_shutdown);
+
+ return;
+ }
+
+ if (nread == 0) {
+ /* Everything OK, but nothing read. */
+ free(buf->base);
+ return;
+ }
+ /* process requests and send responses */
+ process_req(handle, nread, buf);
+}
+
+
+static void on_close(uv_handle_t* peer) {
+ free(peer);
+}
+
+
+static void buf_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+static void on_connection(uv_stream_t* server, int status) {
+ dnshandle* handle;
+ int r;
+
+ ASSERT(status == 0);
+
+ handle = (dnshandle*) malloc(sizeof *handle);
+ ASSERT(handle != NULL);
+
+ /* initialize read buffer state */
+ handle->state.prevbuf_ptr = 0;
+ handle->state.prevbuf_pos = 0;
+ handle->state.prevbuf_rem = 0;
+
+ r = uv_tcp_init(loop, (uv_tcp_t*)handle);
+ ASSERT(r == 0);
+
+ r = uv_accept(server, (uv_stream_t*)handle);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read);
+ ASSERT(r == 0);
+}
+
+
+static int dns_start(int port) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
+
+ r = uv_tcp_init(loop, &server);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Socket creation error\n");
+ return 1;
+ }
+
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Bind error\n");
+ return 1;
+ }
+
+ r = uv_listen((uv_stream_t*)&server, 128, on_connection);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Listen error\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+HELPER_IMPL(dns_server) {
+ loop = uv_default_loop();
+
+ if (dns_start(TEST_PORT_2))
+ return 1;
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ return 0;
+}
diff --git a/third-party/libuv/test/echo-server.c b/third-party/libuv/test/echo-server.c
new file mode 100644
index 0000000000..e5201b9f4c
--- /dev/null
+++ b/third-party/libuv/test/echo-server.c
@@ -0,0 +1,384 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ uv_write_t req;
+ uv_buf_t buf;
+} write_req_t;
+
+static uv_loop_t* loop;
+
+static int server_closed;
+static stream_type serverType;
+static uv_tcp_t tcpServer;
+static uv_udp_t udpServer;
+static uv_pipe_t pipeServer;
+static uv_handle_t* server;
+
+static void after_write(uv_write_t* req, int status);
+static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf);
+static void on_close(uv_handle_t* peer);
+static void on_server_close(uv_handle_t* handle);
+static void on_connection(uv_stream_t*, int status);
+
+
+static void after_write(uv_write_t* req, int status) {
+ write_req_t* wr;
+
+ /* Free the read/write buffer and the request */
+ wr = (write_req_t*) req;
+ free(wr->buf.base);
+ free(wr);
+
+ if (status == 0)
+ return;
+
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+
+ if (status == UV_ECANCELED)
+ return;
+
+ ASSERT(status == UV_EPIPE);
+ uv_close((uv_handle_t*)req->handle, on_close);
+}
+
+
+static void after_shutdown(uv_shutdown_t* req, int status) {
+ uv_close((uv_handle_t*)req->handle, on_close);
+ free(req);
+}
+
+
+static void after_read(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ int i;
+ write_req_t *wr;
+ uv_shutdown_t* req;
+
+ if (nread < 0) {
+ /* Error or EOF */
+ ASSERT(nread == UV_EOF);
+
+ if (buf->base) {
+ free(buf->base);
+ }
+
+ req = (uv_shutdown_t*) malloc(sizeof *req);
+ uv_shutdown(req, handle, after_shutdown);
+
+ return;
+ }
+
+ if (nread == 0) {
+ /* Everything OK, but nothing read. */
+ free(buf->base);
+ return;
+ }
+
+ /*
+ * Scan for the letter Q which signals that we should quit the server.
+ * If we get QS it means close the stream.
+ */
+ if (!server_closed) {
+ for (i = 0; i < nread; i++) {
+ if (buf->base[i] == 'Q') {
+ if (i + 1 < nread && buf->base[i + 1] == 'S') {
+ free(buf->base);
+ uv_close((uv_handle_t*)handle, on_close);
+ return;
+ } else {
+ uv_close(server, on_server_close);
+ server_closed = 1;
+ }
+ }
+ }
+ }
+
+ wr = (write_req_t*) malloc(sizeof *wr);
+
+ wr->buf = uv_buf_init(buf->base, nread);
+ if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
+ FATAL("uv_write failed");
+ }
+}
+
+
+static void on_close(uv_handle_t* peer) {
+ free(peer);
+}
+
+
+static void echo_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+static void on_connection(uv_stream_t* server, int status) {
+ uv_stream_t* stream;
+ int r;
+
+ if (status != 0) {
+ fprintf(stderr, "Connect error %s\n", uv_err_name(status));
+ }
+ ASSERT(status == 0);
+
+ switch (serverType) {
+ case TCP:
+ stream = malloc(sizeof(uv_tcp_t));
+ ASSERT(stream != NULL);
+ r = uv_tcp_init(loop, (uv_tcp_t*)stream);
+ ASSERT(r == 0);
+ break;
+
+ case PIPE:
+ stream = malloc(sizeof(uv_pipe_t));
+ ASSERT(stream != NULL);
+ r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
+ ASSERT(r == 0);
+ break;
+
+ default:
+ ASSERT(0 && "Bad serverType");
+ abort();
+ }
+
+ /* associate server with stream */
+ stream->data = server;
+
+ r = uv_accept(server, stream);
+ ASSERT(r == 0);
+
+ r = uv_read_start(stream, echo_alloc, after_read);
+ ASSERT(r == 0);
+}
+
+
+static void on_server_close(uv_handle_t* handle) {
+ ASSERT(handle == server);
+}
+
+
+static void on_send(uv_udp_send_t* req, int status);
+
+
+static void on_recv(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* rcvbuf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ uv_udp_send_t* req;
+ uv_buf_t sndbuf;
+
+ ASSERT(nread > 0);
+ ASSERT(addr->sa_family == AF_INET);
+
+ req = malloc(sizeof(*req));
+ ASSERT(req != NULL);
+
+ sndbuf = *rcvbuf;
+ ASSERT(0 == uv_udp_send(req, handle, &sndbuf, 1, addr, on_send));
+}
+
+
+static void on_send(uv_udp_send_t* req, int status) {
+ ASSERT(status == 0);
+ free(req);
+}
+
+
+static int tcp4_echo_start(int port) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
+
+ server = (uv_handle_t*)&tcpServer;
+ serverType = TCP;
+
+ r = uv_tcp_init(loop, &tcpServer);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Socket creation error\n");
+ return 1;
+ }
+
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Bind error\n");
+ return 1;
+ }
+
+ r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Listen error %s\n", uv_err_name(r));
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int tcp6_echo_start(int port) {
+ struct sockaddr_in6 addr6;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("::1", port, &addr6));
+
+ server = (uv_handle_t*)&tcpServer;
+ serverType = TCP;
+
+ r = uv_tcp_init(loop, &tcpServer);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Socket creation error\n");
+ return 1;
+ }
+
+ /* IPv6 is optional as not all platforms support it */
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6, 0);
+ if (r) {
+ /* show message but return OK */
+ fprintf(stderr, "IPv6 not supported\n");
+ return 0;
+ }
+
+ r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection);
+ if (r) {
+ /* TODO: Error codes */
+ fprintf(stderr, "Listen error\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int udp4_echo_start(int port) {
+ int r;
+
+ server = (uv_handle_t*)&udpServer;
+ serverType = UDP;
+
+ r = uv_udp_init(loop, &udpServer);
+ if (r) {
+ fprintf(stderr, "uv_udp_init: %s\n", uv_strerror(r));
+ return 1;
+ }
+
+ r = uv_udp_recv_start(&udpServer, echo_alloc, on_recv);
+ if (r) {
+ fprintf(stderr, "uv_udp_recv_start: %s\n", uv_strerror(r));
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static int pipe_echo_start(char* pipeName) {
+ int r;
+
+#ifndef _WIN32
+ {
+ uv_fs_t req;
+ uv_fs_unlink(uv_default_loop(), &req, pipeName, NULL);
+ uv_fs_req_cleanup(&req);
+ }
+#endif
+
+ server = (uv_handle_t*)&pipeServer;
+ serverType = PIPE;
+
+ r = uv_pipe_init(loop, &pipeServer, 0);
+ if (r) {
+ fprintf(stderr, "uv_pipe_init: %s\n", uv_strerror(r));
+ return 1;
+ }
+
+ r = uv_pipe_bind(&pipeServer, pipeName);
+ if (r) {
+ fprintf(stderr, "uv_pipe_bind: %s\n", uv_strerror(r));
+ return 1;
+ }
+
+ r = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, on_connection);
+ if (r) {
+ fprintf(stderr, "uv_pipe_listen: %s\n", uv_strerror(r));
+ return 1;
+ }
+
+ return 0;
+}
+
+
+HELPER_IMPL(tcp4_echo_server) {
+ loop = uv_default_loop();
+
+ if (tcp4_echo_start(TEST_PORT))
+ return 1;
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ return 0;
+}
+
+
+HELPER_IMPL(tcp6_echo_server) {
+ loop = uv_default_loop();
+
+ if (tcp6_echo_start(TEST_PORT))
+ return 1;
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ return 0;
+}
+
+
+HELPER_IMPL(pipe_echo_server) {
+ loop = uv_default_loop();
+
+ if (pipe_echo_start(TEST_PIPENAME))
+ return 1;
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ return 0;
+}
+
+
+HELPER_IMPL(udp4_echo_server) {
+ loop = uv_default_loop();
+
+ if (udp4_echo_start(TEST_PORT))
+ return 1;
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ return 0;
+}
diff --git a/third-party/libuv/test/fixtures/empty_file b/third-party/libuv/test/fixtures/empty_file
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/third-party/libuv/test/fixtures/empty_file
diff --git a/third-party/libuv/test/fixtures/load_error.node b/third-party/libuv/test/fixtures/load_error.node
new file mode 100644
index 0000000000..323fae03f4
--- /dev/null
+++ b/third-party/libuv/test/fixtures/load_error.node
@@ -0,0 +1 @@
+foobar
diff --git a/third-party/libuv/test/run-benchmarks.c b/third-party/libuv/test/run-benchmarks.c
new file mode 100644
index 0000000000..06732b71d3
--- /dev/null
+++ b/third-party/libuv/test/run-benchmarks.c
@@ -0,0 +1,64 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "runner.h"
+#include "task.h"
+
+/* Actual benchmarks and helpers are defined in benchmark-list.h */
+#include "benchmark-list.h"
+
+
+/* The time in milliseconds after which a single benchmark times out. */
+#define BENCHMARK_TIMEOUT 60000
+
+static int maybe_run_test(int argc, char **argv);
+
+
+int main(int argc, char **argv) {
+ platform_init(argc, argv);
+
+ switch (argc) {
+ case 1: return run_tests(BENCHMARK_TIMEOUT, 1);
+ case 2: return maybe_run_test(argc, argv);
+ case 3: return run_test_part(argv[1], argv[2]);
+ default:
+ LOGF("Too many arguments.\n");
+ return 1;
+ }
+}
+
+
+static int maybe_run_test(int argc, char **argv) {
+ if (strcmp(argv[1], "--list") == 0) {
+ print_tests(stdout);
+ return 0;
+ }
+
+ if (strcmp(argv[1], "spawn_helper") == 0) {
+ printf("hello world\n");
+ return 42;
+ }
+
+ return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1);
+}
diff --git a/third-party/libuv/test/run-tests.c b/third-party/libuv/test/run-tests.c
new file mode 100644
index 0000000000..d84be6a1a5
--- /dev/null
+++ b/third-party/libuv/test/run-tests.c
@@ -0,0 +1,159 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+
+#include "uv.h"
+#include "runner.h"
+#include "task.h"
+
+/* Actual tests and helpers are defined in test-list.h */
+#include "test-list.h"
+
+/* The time in milliseconds after which a single test times out. */
+#define TEST_TIMEOUT 5000
+
+int ipc_helper(int listen_after_write);
+int ipc_helper_tcp_connection(void);
+int ipc_send_recv_helper(void);
+int stdio_over_pipes_helper(void);
+
+static int maybe_run_test(int argc, char **argv);
+
+
+int main(int argc, char **argv) {
+ platform_init(argc, argv);
+
+ argv = uv_setup_args(argc, argv);
+
+ switch (argc) {
+ case 1: return run_tests(TEST_TIMEOUT, 0);
+ case 2: return maybe_run_test(argc, argv);
+ case 3: return run_test_part(argv[1], argv[2]);
+ default:
+ LOGF("Too many arguments.\n");
+ return 1;
+ }
+}
+
+
+static int maybe_run_test(int argc, char **argv) {
+ if (strcmp(argv[1], "--list") == 0) {
+ print_tests(stdout);
+ return 0;
+ }
+
+ if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
+ return ipc_helper(0);
+ }
+
+ if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
+ return ipc_helper(1);
+ }
+
+ if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
+ return ipc_send_recv_helper();
+ }
+
+ if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
+ return ipc_helper_tcp_connection();
+ }
+
+ if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
+ return stdio_over_pipes_helper();
+ }
+
+ if (strcmp(argv[1], "spawn_helper1") == 0) {
+ return 1;
+ }
+
+ if (strcmp(argv[1], "spawn_helper2") == 0) {
+ printf("hello world\n");
+ return 1;
+ }
+
+ if (strcmp(argv[1], "spawn_helper3") == 0) {
+ char buffer[256];
+ ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
+ buffer[sizeof(buffer) - 1] = '\0';
+ fputs(buffer, stdout);
+ return 1;
+ }
+
+ if (strcmp(argv[1], "spawn_helper4") == 0) {
+ /* Never surrender, never return! */
+ while (1) uv_sleep(10000);
+ }
+
+ if (strcmp(argv[1], "spawn_helper5") == 0) {
+ const char out[] = "fourth stdio!\n";
+#ifdef _WIN32
+ DWORD bytes;
+ WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
+#else
+ {
+ ssize_t r;
+
+ do
+ r = write(3, out, sizeof(out) - 1);
+ while (r == -1 && errno == EINTR);
+
+ fsync(3);
+ }
+#endif
+ return 1;
+ }
+
+ if (strcmp(argv[1], "spawn_helper6") == 0) {
+ int r;
+
+ r = fprintf(stdout, "hello world\n");
+ ASSERT(r > 0);
+
+ r = fprintf(stderr, "hello errworld\n");
+ ASSERT(r > 0);
+
+ return 1;
+ }
+
+ if (strcmp(argv[1], "spawn_helper7") == 0) {
+ int r;
+ char *test;
+ /* Test if the test value from the parent is still set */
+ test = getenv("ENV_TEST");
+ ASSERT(test != NULL);
+
+ r = fprintf(stdout, "%s", test);
+ ASSERT(r > 0);
+
+ return 1;
+ }
+
+ return run_test(argv[1], TEST_TIMEOUT, 0, 1);
+}
diff --git a/third-party/libuv/test/runner-unix.c b/third-party/libuv/test/runner-unix.c
new file mode 100644
index 0000000000..9afcd1e488
--- /dev/null
+++ b/third-party/libuv/test/runner-unix.c
@@ -0,0 +1,356 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "runner-unix.h"
+#include "runner.h"
+
+#include <stdint.h> /* uintptr_t */
+
+#include <errno.h>
+#include <unistd.h> /* usleep */
+#include <string.h> /* strdup */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#include <sys/select.h>
+#include <pthread.h>
+
+
+/* Do platform-specific initialization. */
+void platform_init(int argc, char **argv) {
+ const char* tap;
+
+ tap = getenv("UV_TAP_OUTPUT");
+ tap_output = (tap != NULL && atoi(tap) > 0);
+
+ /* Disable stdio output buffering. */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+ strncpy(executable_path, argv[0], sizeof(executable_path) - 1);
+ signal(SIGPIPE, SIG_IGN);
+}
+
+
+/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */
+/* Make sure that all stdio output of the processes is buffered up. */
+int process_start(char* name, char* part, process_info_t* p, int is_helper) {
+ FILE* stdout_file;
+ const char* arg;
+ char* args[16];
+ int n;
+
+ stdout_file = tmpfile();
+ if (!stdout_file) {
+ perror("tmpfile");
+ return -1;
+ }
+
+ p->terminated = 0;
+ p->status = 0;
+
+ pid_t pid = fork();
+
+ if (pid < 0) {
+ perror("fork");
+ return -1;
+ }
+
+ if (pid == 0) {
+ /* child */
+ arg = getenv("UV_USE_VALGRIND");
+ n = 0;
+
+ /* Disable valgrind for helpers, it complains about helpers leaking memory.
+ * They're killed after the test and as such never get a chance to clean up.
+ */
+ if (is_helper == 0 && arg != NULL && atoi(arg) != 0) {
+ args[n++] = "valgrind";
+ args[n++] = "--quiet";
+ args[n++] = "--leak-check=full";
+ args[n++] = "--show-reachable=yes";
+ args[n++] = "--error-exitcode=125";
+ }
+
+ args[n++] = executable_path;
+ args[n++] = name;
+ args[n++] = part;
+ args[n++] = NULL;
+
+ dup2(fileno(stdout_file), STDOUT_FILENO);
+ dup2(fileno(stdout_file), STDERR_FILENO);
+ execvp(args[0], args);
+ perror("execvp()");
+ _exit(127);
+ }
+
+ /* parent */
+ p->pid = pid;
+ p->name = strdup(name);
+ p->stdout_file = stdout_file;
+
+ return 0;
+}
+
+
+typedef struct {
+ int pipe[2];
+ process_info_t* vec;
+ int n;
+} dowait_args;
+
+
+/* This function is run inside a pthread. We do this so that we can possibly
+ * timeout.
+ */
+static void* dowait(void* data) {
+ dowait_args* args = data;
+
+ int i, r;
+ process_info_t* p;
+
+ for (i = 0; i < args->n; i++) {
+ p = (process_info_t*)(args->vec + i * sizeof(process_info_t));
+ if (p->terminated) continue;
+ r = waitpid(p->pid, &p->status, 0);
+ if (r < 0) {
+ perror("waitpid");
+ return NULL;
+ }
+ p->terminated = 1;
+ }
+
+ if (args->pipe[1] >= 0) {
+ /* Write a character to the main thread to notify it about this. */
+ ssize_t r;
+
+ do
+ r = write(args->pipe[1], "", 1);
+ while (r == -1 && errno == EINTR);
+ }
+
+ return NULL;
+}
+
+
+/* Wait for all `n` processes in `vec` to terminate. */
+/* Time out after `timeout` msec, or never if timeout == -1 */
+/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
+int process_wait(process_info_t* vec, int n, int timeout) {
+ int i;
+ process_info_t* p;
+ dowait_args args;
+ args.vec = vec;
+ args.n = n;
+ args.pipe[0] = -1;
+ args.pipe[1] = -1;
+
+ /* The simple case is where there is no timeout */
+ if (timeout == -1) {
+ dowait(&args);
+ return 0;
+ }
+
+ /* Hard case. Do the wait with a timeout.
+ *
+ * Assumption: we are the only ones making this call right now. Otherwise
+ * we'd need to lock vec.
+ */
+
+ pthread_t tid;
+ int retval;
+
+ int r = pipe((int*)&(args.pipe));
+ if (r) {
+ perror("pipe()");
+ return -1;
+ }
+
+ r = pthread_create(&tid, NULL, dowait, &args);
+ if (r) {
+ perror("pthread_create()");
+ retval = -1;
+ goto terminate;
+ }
+
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = 0;
+
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(args.pipe[0], &fds);
+
+ r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv);
+
+ if (r == -1) {
+ perror("select()");
+ retval = -1;
+
+ } else if (r) {
+ /* The thread completed successfully. */
+ retval = 0;
+
+ } else {
+ /* Timeout. Kill all the children. */
+ for (i = 0; i < n; i++) {
+ p = (process_info_t*)(vec + i * sizeof(process_info_t));
+ kill(p->pid, SIGTERM);
+ }
+ retval = -2;
+
+ /* Wait for thread to finish. */
+ r = pthread_join(tid, NULL);
+ if (r) {
+ perror("pthread_join");
+ retval = -1;
+ }
+ }
+
+terminate:
+ close(args.pipe[0]);
+ close(args.pipe[1]);
+ return retval;
+}
+
+
+/* Returns the number of bytes in the stdio output buffer for process `p`. */
+long int process_output_size(process_info_t *p) {
+ /* Size of the p->stdout_file */
+ struct stat buf;
+
+ int r = fstat(fileno(p->stdout_file), &buf);
+ if (r < 0) {
+ return -1;
+ }
+
+ return (long)buf.st_size;
+}
+
+
+/* Copy the contents of the stdio output buffer to `fd`. */
+int process_copy_output(process_info_t *p, int fd) {
+ int r = fseek(p->stdout_file, 0, SEEK_SET);
+ if (r < 0) {
+ perror("fseek");
+ return -1;
+ }
+
+ ssize_t nwritten;
+ char buf[1024];
+
+ /* TODO: what if the line is longer than buf */
+ while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) {
+ /* TODO: what if write doesn't write the whole buffer... */
+ nwritten = 0;
+
+ if (tap_output)
+ nwritten += write(fd, "#", 1);
+
+ nwritten += write(fd, buf, strlen(buf));
+
+ if (nwritten < 0) {
+ perror("write");
+ return -1;
+ }
+ }
+
+ if (ferror(p->stdout_file)) {
+ perror("read");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* Copy the last line of the stdio output buffer to `buffer` */
+int process_read_last_line(process_info_t *p,
+ char* buffer,
+ size_t buffer_len) {
+ char* ptr;
+
+ int r = fseek(p->stdout_file, 0, SEEK_SET);
+ if (r < 0) {
+ perror("fseek");
+ return -1;
+ }
+
+ buffer[0] = '\0';
+
+ while (fgets(buffer, buffer_len, p->stdout_file) != NULL) {
+ for (ptr = buffer; *ptr && *ptr != '\r' && *ptr != '\n'; ptr++);
+ *ptr = '\0';
+ }
+
+ if (ferror(p->stdout_file)) {
+ perror("read");
+ buffer[0] = '\0';
+ return -1;
+ }
+ return 0;
+}
+
+
+/* Return the name that was specified when `p` was started by process_start */
+char* process_get_name(process_info_t *p) {
+ return p->name;
+}
+
+
+/* Terminate process `p`. */
+int process_terminate(process_info_t *p) {
+ return kill(p->pid, SIGTERM);
+}
+
+
+/* Return the exit code of process p. */
+/* On error, return -1. */
+int process_reap(process_info_t *p) {
+ if (WIFEXITED(p->status)) {
+ return WEXITSTATUS(p->status);
+ } else {
+ return p->status; /* ? */
+ }
+}
+
+
+/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */
+void process_cleanup(process_info_t *p) {
+ fclose(p->stdout_file);
+ free(p->name);
+}
+
+
+/* Move the console cursor one line up and back to the first column. */
+void rewind_cursor(void) {
+ fprintf(stderr, "\033[2K\r");
+}
+
+
+/* Pause the calling thread for a number of milliseconds. */
+void uv_sleep(int msec) {
+ usleep(msec * 1000);
+}
diff --git a/third-party/libuv/test/runner-unix.h b/third-party/libuv/test/runner-unix.h
new file mode 100644
index 0000000000..e21847f92c
--- /dev/null
+++ b/third-party/libuv/test/runner-unix.h
@@ -0,0 +1,36 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef TEST_RUNNER_UNIX_H
+#define TEST_RUNNER_UNIX_H
+
+#include <sys/types.h>
+#include <stdio.h> /* FILE */
+
+typedef struct {
+ FILE* stdout_file;
+ pid_t pid;
+ char* name;
+ int status;
+ int terminated;
+} process_info_t;
+
+#endif /* TEST_RUNNER_UNIX_H */
diff --git a/third-party/libuv/test/runner-win.c b/third-party/libuv/test/runner-win.c
new file mode 100644
index 0000000000..83d76783f6
--- /dev/null
+++ b/third-party/libuv/test/runner-win.c
@@ -0,0 +1,369 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <io.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <process.h>
+#if !defined(__MINGW32__)
+# include <crtdbg.h>
+#endif
+
+
+#include "task.h"
+#include "runner.h"
+
+
+/*
+ * Define the stuff that MinGW doesn't have
+ */
+#ifndef GetFileSizeEx
+ WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile,
+ PLARGE_INTEGER lpFileSize);
+#endif
+
+
+/* Do platform-specific initialization. */
+void platform_init(int argc, char **argv) {
+ const char* tap;
+
+ tap = getenv("UV_TAP_OUTPUT");
+ tap_output = (tap != NULL && atoi(tap) > 0);
+
+ /* Disable the "application crashed" popup. */
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+#if !defined(__MINGW32__)
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
+#endif
+
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+ _setmode(2, _O_BINARY);
+
+ /* Disable stdio output buffering. */
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ strcpy(executable_path, argv[0]);
+}
+
+
+int process_start(char *name, char *part, process_info_t *p, int is_helper) {
+ HANDLE file = INVALID_HANDLE_VALUE;
+ HANDLE nul = INVALID_HANDLE_VALUE;
+ WCHAR path[MAX_PATH], filename[MAX_PATH];
+ WCHAR image[MAX_PATH + 1];
+ WCHAR args[MAX_PATH * 2];
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ DWORD result;
+
+ if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0)
+ goto error;
+ if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0)
+ goto error;
+
+ file = CreateFileW((WCHAR*)filename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ goto error;
+
+ if (!SetHandleInformation(file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ goto error;
+
+ nul = CreateFileA("nul",
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (nul == INVALID_HANDLE_VALUE)
+ goto error;
+
+ if (!SetHandleInformation(nul, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
+ goto error;
+
+ result = GetModuleFileNameW(NULL,
+ (WCHAR*) &image,
+ sizeof(image) / sizeof(WCHAR));
+ if (result == 0 || result == sizeof(image))
+ goto error;
+
+ if (part) {
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
+ L"\"%s\" %S %S",
+ image,
+ name,
+ part) < 0) {
+ goto error;
+ }
+ } else {
+ if (_snwprintf((WCHAR*)args,
+ sizeof(args) / sizeof(WCHAR),
+ L"\"%s\" %S",
+ image,
+ name) < 0) {
+ goto error;
+ }
+ }
+
+ memset((void*)&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdInput = nul;
+ si.hStdOutput = file;
+ si.hStdError = file;
+
+ if (!CreateProcessW(image, args, NULL, NULL, TRUE,
+ 0, NULL, NULL, &si, &pi))
+ goto error;
+
+ CloseHandle(pi.hThread);
+
+ SetHandleInformation(nul, HANDLE_FLAG_INHERIT, 0);
+ SetHandleInformation(file, HANDLE_FLAG_INHERIT, 0);
+
+ p->stdio_in = nul;
+ p->stdio_out = file;
+ p->process = pi.hProcess;
+ p->name = part;
+
+ return 0;
+
+error:
+ if (file != INVALID_HANDLE_VALUE)
+ CloseHandle(file);
+ if (nul != INVALID_HANDLE_VALUE)
+ CloseHandle(nul);
+
+ return -1;
+}
+
+
+/* Timeout is is msecs. Set timeout < 0 to never time out. */
+/* Returns 0 when all processes are terminated, -2 on timeout. */
+int process_wait(process_info_t *vec, int n, int timeout) {
+ int i;
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ DWORD timeout_api, result;
+
+ /* If there's nothing to wait for, return immediately. */
+ if (n == 0)
+ return 0;
+
+ ASSERT(n <= MAXIMUM_WAIT_OBJECTS);
+
+ for (i = 0; i < n; i++)
+ handles[i] = vec[i].process;
+
+ if (timeout >= 0) {
+ timeout_api = (DWORD)timeout;
+ } else {
+ timeout_api = INFINITE;
+ }
+
+ result = WaitForMultipleObjects(n, handles, TRUE, timeout_api);
+
+ if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n) {
+ /* All processes are terminated. */
+ return 0;
+ }
+ if (result == WAIT_TIMEOUT) {
+ return -2;
+ }
+ return -1;
+}
+
+
+long int process_output_size(process_info_t *p) {
+ LARGE_INTEGER size;
+ if (!GetFileSizeEx(p->stdio_out, &size))
+ return -1;
+ return (long int)size.QuadPart;
+}
+
+
+int process_copy_output(process_info_t *p, int fd) {
+ DWORD read;
+ char buf[1024];
+ char *line, *start;
+
+ if (SetFilePointer(p->stdio_out,
+ 0,
+ 0,
+ FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
+ return -1;
+ }
+
+ if (tap_output)
+ write(fd, "#", 1);
+
+ while (ReadFile(p->stdio_out, (void*)&buf, sizeof(buf), &read, NULL) &&
+ read > 0) {
+ if (tap_output) {
+ start = buf;
+
+ while ((line = strchr(start, '\n')) != NULL) {
+ write(fd, start, line - start + 1);
+ write(fd, "#", 1);
+ start = line + 1;
+ }
+
+ if (start < buf + read)
+ write(fd, start, buf + read - start);
+ } else {
+ write(fd, buf, read);
+ }
+ }
+
+ if (tap_output)
+ write(fd, "\n", 1);
+
+ if (GetLastError() != ERROR_HANDLE_EOF)
+ return -1;
+
+ return 0;
+}
+
+
+int process_read_last_line(process_info_t *p,
+ char * buffer,
+ size_t buffer_len) {
+ DWORD size;
+ DWORD read;
+ DWORD start;
+ OVERLAPPED overlapped;
+
+ ASSERT(buffer_len > 0);
+
+ size = GetFileSize(p->stdio_out, NULL);
+ if (size == INVALID_FILE_SIZE)
+ return -1;
+
+ if (size == 0) {
+ buffer[0] = '\0';
+ return 1;
+ }
+
+ memset(&overlapped, 0, sizeof overlapped);
+ if (size >= buffer_len)
+ overlapped.Offset = size - buffer_len - 1;
+
+ if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped))
+ return -1;
+
+ for (start = read - 1; start >= 0; start--) {
+ if (buffer[start] == '\n' || buffer[start] == '\r')
+ break;
+ }
+
+ if (start > 0)
+ memmove(buffer, buffer + start, read - start);
+
+ buffer[read - start] = '\0';
+
+ return 0;
+}
+
+
+char* process_get_name(process_info_t *p) {
+ return p->name;
+}
+
+
+int process_terminate(process_info_t *p) {
+ if (!TerminateProcess(p->process, 1))
+ return -1;
+ return 0;
+}
+
+
+int process_reap(process_info_t *p) {
+ DWORD exitCode;
+ if (!GetExitCodeProcess(p->process, &exitCode))
+ return -1;
+ return (int)exitCode;
+}
+
+
+void process_cleanup(process_info_t *p) {
+ CloseHandle(p->process);
+ CloseHandle(p->stdio_in);
+ CloseHandle(p->stdio_out);
+}
+
+
+static int clear_line() {
+ HANDLE handle;
+ CONSOLE_SCREEN_BUFFER_INFO info;
+ COORD coord;
+ DWORD written;
+
+ handle = (HANDLE)_get_osfhandle(fileno(stderr));
+ if (handle == INVALID_HANDLE_VALUE)
+ return -1;
+
+ if (!GetConsoleScreenBufferInfo(handle, &info))
+ return -1;
+
+ coord = info.dwCursorPosition;
+ if (coord.Y <= 0)
+ return -1;
+
+ coord.X = 0;
+
+ if (!SetConsoleCursorPosition(handle, coord))
+ return -1;
+
+ if (!FillConsoleOutputCharacterW(handle,
+ 0x20,
+ info.dwSize.X,
+ coord,
+ &written)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void rewind_cursor() {
+ if (clear_line() == -1) {
+ /* If clear_line fails (stdout is not a console), print a newline. */
+ fprintf(stderr, "\n");
+ }
+}
+
+
+/* Pause the calling thread for a number of milliseconds. */
+void uv_sleep(int msec) {
+ Sleep(msec);
+}
diff --git a/third-party/libuv/test/runner-win.h b/third-party/libuv/test/runner-win.h
new file mode 100644
index 0000000000..c94b89bd5e
--- /dev/null
+++ b/third-party/libuv/test/runner-win.h
@@ -0,0 +1,43 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* Don't complain about _snprintf being insecure. */
+#define _CRT_SECURE_NO_WARNINGS
+
+/* Don't complain about write(), fileno() etc. being deprecated. */
+#pragma warning(disable : 4996)
+
+
+#include <winsock2.h>
+#include <windows.h>
+#include <stdio.h>
+
+
+/* Windows has no snprintf, only _snprintf. */
+#define snprintf _snprintf
+
+
+typedef struct {
+ HANDLE process;
+ HANDLE stdio_in;
+ HANDLE stdio_out;
+ char *name;
+} process_info_t;
diff --git a/third-party/libuv/test/runner.c b/third-party/libuv/test/runner.c
new file mode 100644
index 0000000000..f4d982c5b6
--- /dev/null
+++ b/third-party/libuv/test/runner.c
@@ -0,0 +1,455 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "runner.h"
+#include "task.h"
+#include "uv.h"
+
+char executable_path[PATHMAX] = { '\0' };
+
+int tap_output = 0;
+
+
+static void log_progress(int total,
+ int passed,
+ int failed,
+ int todos,
+ int skipped,
+ const char* name) {
+ int progress;
+
+ if (total == 0)
+ total = 1;
+
+ progress = 100 * (passed + failed + skipped + todos) / total;
+ LOGF("[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
+ progress,
+ passed,
+ failed,
+ todos,
+ skipped,
+ name);
+}
+
+
+const char* fmt(double d) {
+ static char buf[1024];
+ static char* p;
+ uint64_t v;
+
+ if (p == NULL)
+ p = buf;
+
+ p += 31;
+
+ if (p >= buf + sizeof(buf))
+ return "<buffer too small>";
+
+ v = (uint64_t) d;
+
+#if 0 /* works but we don't care about fractional precision */
+ if (d - v >= 0.01) {
+ *--p = '0' + (uint64_t) (d * 100) % 10;
+ *--p = '0' + (uint64_t) (d * 10) % 10;
+ *--p = '.';
+ }
+#endif
+
+ if (v == 0)
+ *--p = '0';
+
+ while (v) {
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = '0' + (v % 10), v /= 10;
+ if (v) *--p = ',';
+ }
+
+ return p;
+}
+
+
+int run_tests(int timeout, int benchmark_output) {
+ int total;
+ int passed;
+ int failed;
+ int todos;
+ int skipped;
+ int current;
+ int test_result;
+ task_entry_t* task;
+
+ /* Count the number of tests. */
+ total = 0;
+ for (task = TASKS; task->main; task++) {
+ if (!task->is_helper) {
+ total++;
+ }
+ }
+
+ if (tap_output) {
+ LOGF("1..%d\n", total);
+ }
+
+ /* Run all tests. */
+ passed = 0;
+ failed = 0;
+ todos = 0;
+ skipped = 0;
+ current = 1;
+ for (task = TASKS; task->main; task++) {
+ if (task->is_helper) {
+ continue;
+ }
+
+ if (!tap_output)
+ rewind_cursor();
+
+ if (!benchmark_output && !tap_output) {
+ log_progress(total, passed, failed, todos, skipped, task->task_name);
+ }
+
+ test_result = run_test(task->task_name, timeout, benchmark_output, current);
+ switch (test_result) {
+ case TEST_OK: passed++; break;
+ case TEST_TODO: todos++; break;
+ case TEST_SKIP: skipped++; break;
+ default: failed++;
+ }
+ current++;
+ }
+
+ if (!tap_output)
+ rewind_cursor();
+
+ if (!benchmark_output && !tap_output) {
+ log_progress(total, passed, failed, todos, skipped, "Done.\n");
+ }
+
+ return failed;
+}
+
+
+void log_tap_result(int test_count,
+ const char* test,
+ int status,
+ process_info_t* process) {
+ const char* result;
+ const char* directive;
+ char reason[1024];
+
+ switch (status) {
+ case TEST_OK:
+ result = "ok";
+ directive = "";
+ break;
+ case TEST_TODO:
+ result = "not ok";
+ directive = " # TODO ";
+ break;
+ case TEST_SKIP:
+ result = "ok";
+ directive = " # SKIP ";
+ break;
+ default:
+ result = "not ok";
+ directive = "";
+ }
+
+ if ((status == TEST_SKIP || status == TEST_TODO) &&
+ process_output_size(process) > 0) {
+ process_read_last_line(process, reason, sizeof reason);
+ } else {
+ reason[0] = '\0';
+ }
+
+ LOGF("%s %d - %s%s%s\n", result, test_count, test, directive, reason);
+}
+
+
+int run_test(const char* test,
+ int timeout,
+ int benchmark_output,
+ int test_count) {
+ char errmsg[1024] = "no error";
+ process_info_t processes[1024];
+ process_info_t *main_proc;
+ task_entry_t* task;
+ int process_count;
+ int result;
+ int status;
+ int i;
+
+ status = 255;
+ main_proc = NULL;
+ process_count = 0;
+
+#ifndef _WIN32
+ /* Clean up stale socket from previous run. */
+ remove(TEST_PIPENAME);
+#endif
+
+ /* If it's a helper the user asks for, start it directly. */
+ for (task = TASKS; task->main; task++) {
+ if (task->is_helper && strcmp(test, task->process_name) == 0) {
+ return task->main();
+ }
+ }
+
+ /* Start the helpers first. */
+ for (task = TASKS; task->main; task++) {
+ if (strcmp(test, task->task_name) != 0) {
+ continue;
+ }
+
+ /* Skip the test itself. */
+ if (!task->is_helper) {
+ continue;
+ }
+
+ if (process_start(task->task_name,
+ task->process_name,
+ &processes[process_count],
+ 1 /* is_helper */) == -1) {
+ snprintf(errmsg,
+ sizeof errmsg,
+ "Process `%s` failed to start.",
+ task->process_name);
+ goto out;
+ }
+
+ process_count++;
+ }
+
+ /* Give the helpers time to settle. Race-y, fix this. */
+ uv_sleep(250);
+
+ /* Now start the test itself. */
+ for (task = TASKS; task->main; task++) {
+ if (strcmp(test, task->task_name) != 0) {
+ continue;
+ }
+
+ if (task->is_helper) {
+ continue;
+ }
+
+ if (process_start(task->task_name,
+ task->process_name,
+ &processes[process_count],
+ 0 /* !is_helper */) == -1) {
+ snprintf(errmsg,
+ sizeof errmsg,
+ "Process `%s` failed to start.",
+ task->process_name);
+ goto out;
+ }
+
+ main_proc = &processes[process_count];
+ process_count++;
+ break;
+ }
+
+ if (main_proc == NULL) {
+ snprintf(errmsg,
+ sizeof errmsg,
+ "No test with that name: %s",
+ test);
+ goto out;
+ }
+
+ result = process_wait(main_proc, 1, timeout);
+ if (result == -1) {
+ FATAL("process_wait failed");
+ } else if (result == -2) {
+ /* Don't have to clean up the process, process_wait() has killed it. */
+ snprintf(errmsg,
+ sizeof errmsg,
+ "timeout");
+ goto out;
+ }
+
+ status = process_reap(main_proc);
+ if (status != TEST_OK) {
+ snprintf(errmsg,
+ sizeof errmsg,
+ "exit code %d",
+ status);
+ goto out;
+ }
+
+ if (benchmark_output) {
+ /* Give the helpers time to clean up their act. */
+ uv_sleep(1000);
+ }
+
+out:
+ /* Reap running processes except the main process, it's already dead. */
+ for (i = 0; i < process_count - 1; i++) {
+ process_terminate(&processes[i]);
+ }
+
+ if (process_count > 0 &&
+ process_wait(processes, process_count - 1, -1) < 0) {
+ FATAL("process_wait failed");
+ }
+
+ if (tap_output)
+ log_tap_result(test_count, test, status, &processes[i]);
+
+ /* Show error and output from processes if the test failed. */
+ if (status != 0 || task->show_output) {
+ if (tap_output) {
+ LOGF("#");
+ } else if (status == TEST_TODO) {
+ LOGF("\n`%s` todo\n", test);
+ } else if (status == TEST_SKIP) {
+ LOGF("\n`%s` skipped\n", test);
+ } else if (status != 0) {
+ LOGF("\n`%s` failed: %s\n", test, errmsg);
+ } else {
+ LOGF("\n");
+ }
+
+ for (i = 0; i < process_count; i++) {
+ switch (process_output_size(&processes[i])) {
+ case -1:
+ LOGF("Output from process `%s`: (unavailable)\n",
+ process_get_name(&processes[i]));
+ break;
+
+ case 0:
+ LOGF("Output from process `%s`: (no output)\n",
+ process_get_name(&processes[i]));
+ break;
+
+ default:
+ LOGF("Output from process `%s`:\n", process_get_name(&processes[i]));
+ process_copy_output(&processes[i], fileno(stderr));
+ break;
+ }
+ }
+
+ if (!tap_output) {
+ LOG("=============================================================\n");
+ }
+
+ /* In benchmark mode show concise output from the main process. */
+ } else if (benchmark_output) {
+ switch (process_output_size(main_proc)) {
+ case -1:
+ LOGF("%s: (unavailable)\n", test);
+ break;
+
+ case 0:
+ LOGF("%s: (no output)\n", test);
+ break;
+
+ default:
+ for (i = 0; i < process_count; i++) {
+ process_copy_output(&processes[i], fileno(stderr));
+ }
+ break;
+ }
+ }
+
+ /* Clean up all process handles. */
+ for (i = 0; i < process_count; i++) {
+ process_cleanup(&processes[i]);
+ }
+
+ return status;
+}
+
+
+/* Returns the status code of the task part
+ * or 255 if no matching task was not found.
+ */
+int run_test_part(const char* test, const char* part) {
+ task_entry_t* task;
+ int r;
+
+ for (task = TASKS; task->main; task++) {
+ if (strcmp(test, task->task_name) == 0 &&
+ strcmp(part, task->process_name) == 0) {
+ r = task->main();
+ return r;
+ }
+ }
+
+ LOGF("No test part with that name: %s:%s\n", test, part);
+ return 255;
+}
+
+
+static int compare_task(const void* va, const void* vb) {
+ const task_entry_t* a = va;
+ const task_entry_t* b = vb;
+ return strcmp(a->task_name, b->task_name);
+}
+
+
+static int find_helpers(const task_entry_t* task,
+ const task_entry_t** helpers) {
+ const task_entry_t* helper;
+ int n_helpers;
+
+ for (n_helpers = 0, helper = TASKS; helper->main; helper++) {
+ if (helper->is_helper && strcmp(helper->task_name, task->task_name) == 0) {
+ *helpers++ = helper;
+ n_helpers++;
+ }
+ }
+
+ return n_helpers;
+}
+
+
+void print_tests(FILE* stream) {
+ const task_entry_t* helpers[1024];
+ const task_entry_t* task;
+ int n_helpers;
+ int n_tasks;
+ int i;
+
+ for (n_tasks = 0, task = TASKS; task->main; n_tasks++, task++);
+ qsort(TASKS, n_tasks, sizeof(TASKS[0]), compare_task);
+
+ for (task = TASKS; task->main; task++) {
+ if (task->is_helper) {
+ continue;
+ }
+
+ n_helpers = find_helpers(task, helpers);
+ if (n_helpers) {
+ printf("%-25s (helpers:", task->task_name);
+ for (i = 0; i < n_helpers; i++) {
+ printf(" %s", helpers[i]->process_name);
+ }
+ printf(")\n");
+ } else {
+ printf("%s\n", task->task_name);
+ }
+ }
+}
diff --git a/third-party/libuv/test/runner.h b/third-party/libuv/test/runner.h
new file mode 100644
index 0000000000..aa7f205407
--- /dev/null
+++ b/third-party/libuv/test/runner.h
@@ -0,0 +1,170 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef RUNNER_H_
+#define RUNNER_H_
+
+#include <stdio.h> /* FILE */
+
+
+/*
+ * The maximum number of processes (main + helpers) that a test / benchmark
+ * can have.
+ */
+#define MAX_PROCESSES 8
+
+
+/*
+ * Struct to store both tests and to define helper processes for tasks.
+ */
+typedef struct {
+ char *task_name;
+ char *process_name;
+ int (*main)(void);
+ int is_helper;
+ int show_output;
+} task_entry_t, bench_entry_t;
+
+
+/*
+ * Macros used by test-list.h and benchmark-list.h.
+ */
+#define TASK_LIST_START \
+ task_entry_t TASKS[] = {
+
+#define TASK_LIST_END \
+ { 0, 0, 0, 0, 0 } \
+ };
+
+#define TEST_DECLARE(name) \
+ int run_test_##name(void);
+
+#define TEST_ENTRY(name) \
+ { #name, #name, &run_test_##name, 0, 0 },
+
+#define TEST_OUTPUT_ENTRY(name) \
+ { #name, #name, &run_test_##name, 0, 1 },
+
+#define BENCHMARK_DECLARE(name) \
+ int run_benchmark_##name(void);
+
+#define BENCHMARK_ENTRY(name) \
+ { #name, #name, &run_benchmark_##name, 0, 0 },
+
+#define HELPER_DECLARE(name) \
+ int run_helper_##name(void);
+
+#define HELPER_ENTRY(task_name, name) \
+ { #task_name, #name, &run_helper_##name, 1, 0 },
+
+#define TEST_HELPER HELPER_ENTRY
+#define BENCHMARK_HELPER HELPER_ENTRY
+
+#define PATHMAX 1024
+extern char executable_path[PATHMAX];
+
+/*
+ * Include platform-dependent definitions
+ */
+#ifdef _WIN32
+# include "runner-win.h"
+#else
+# include "runner-unix.h"
+#endif
+
+
+/* The array that is filled by test-list.h or benchmark-list.h */
+extern task_entry_t TASKS[];
+
+/*
+ * Run all tests.
+ */
+int run_tests(int timeout, int benchmark_output);
+
+/*
+ * Run a single test. Starts up any helpers.
+ */
+int run_test(const char* test,
+ int timeout,
+ int benchmark_output,
+ int test_count);
+
+/*
+ * Run a test part, i.e. the test or one of its helpers.
+ */
+int run_test_part(const char* test, const char* part);
+
+
+/*
+ * Print tests in sorted order to `stream`. Used by `./run-tests --list`.
+ */
+void print_tests(FILE* stream);
+
+
+/*
+ * Stuff that should be implemented by test-runner-<platform>.h
+ * All functions return 0 on success, -1 on failure, unless specified
+ * otherwise.
+ */
+
+/* Do platform-specific initialization. */
+void platform_init(int argc, char** argv);
+
+/* Invoke "argv[0] test-name [test-part]". Store process info in *p. */
+/* Make sure that all stdio output of the processes is buffered up. */
+int process_start(char *name, char* part, process_info_t *p, int is_helper);
+
+/* Wait for all `n` processes in `vec` to terminate. */
+/* Time out after `timeout` msec, or never if timeout == -1 */
+/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
+int process_wait(process_info_t *vec, int n, int timeout);
+
+/* Returns the number of bytes in the stdio output buffer for process `p`. */
+long int process_output_size(process_info_t *p);
+
+/* Copy the contents of the stdio output buffer to `fd`. */
+int process_copy_output(process_info_t *p, int fd);
+
+/* Copy the last line of the stdio output buffer to `buffer` */
+int process_read_last_line(process_info_t *p,
+ char * buffer,
+ size_t buffer_len);
+
+/* Return the name that was specified when `p` was started by process_start */
+char* process_get_name(process_info_t *p);
+
+/* Terminate process `p`. */
+int process_terminate(process_info_t *p);
+
+/* Return the exit code of process p. */
+/* On error, return -1. */
+int process_reap(process_info_t *p);
+
+/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */
+void process_cleanup(process_info_t *p);
+
+/* Move the console cursor one line up and back to the first column. */
+void rewind_cursor(void);
+
+/* trigger output as tap */
+extern int tap_output;
+
+#endif /* RUNNER_H_ */
diff --git a/third-party/libuv/test/task.h b/third-party/libuv/test/task.h
new file mode 100644
index 0000000000..b736c375c7
--- /dev/null
+++ b/third-party/libuv/test/task.h
@@ -0,0 +1,207 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef TASK_H_
+#define TASK_H_
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#if !defined(_WIN32)
+# include <sys/time.h>
+# include <sys/resource.h> /* setrlimit() */
+#endif
+
+#define TEST_PORT 9123
+#define TEST_PORT_2 9124
+
+#ifdef _WIN32
+# define TEST_PIPENAME "\\\\.\\pipe\\uv-test"
+# define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2"
+#else
+# define TEST_PIPENAME "/tmp/uv-test-sock"
+# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
+#endif
+
+#ifdef _WIN32
+# include <io.h>
+# ifndef S_IRUSR
+# define S_IRUSR _S_IREAD
+# endif
+# ifndef S_IWUSR
+# define S_IWUSR _S_IWRITE
+# endif
+#endif
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+#define container_of(ptr, type, member) \
+ ((type *) ((char *) (ptr) - offsetof(type, member)))
+
+typedef enum {
+ TCP = 0,
+ UDP,
+ PIPE
+} stream_type;
+
+/* Log to stderr. */
+#define LOG(...) \
+ do { \
+ fprintf(stderr, "%s", __VA_ARGS__); \
+ fflush(stderr); \
+ } while (0)
+
+#define LOGF(...) \
+ do { \
+ fprintf(stderr, __VA_ARGS__); \
+ fflush(stderr); \
+ } while (0)
+
+/* Die with fatal error. */
+#define FATAL(msg) \
+ do { \
+ fprintf(stderr, \
+ "Fatal error in %s on line %d: %s\n", \
+ __FILE__, \
+ __LINE__, \
+ msg); \
+ fflush(stderr); \
+ abort(); \
+ } while (0)
+
+/* Have our own assert, so we are sure it does not get optimized away in
+ * a release build.
+ */
+#define ASSERT(expr) \
+ do { \
+ if (!(expr)) { \
+ fprintf(stderr, \
+ "Assertion failed in %s on line %d: %s\n", \
+ __FILE__, \
+ __LINE__, \
+ #expr); \
+ abort(); \
+ } \
+ } while (0)
+
+/* This macro cleans up the main loop. This is used to avoid valgrind
+ * warnings about memory being "leaked" by the main event loop.
+ */
+#define MAKE_VALGRIND_HAPPY() \
+ uv_loop_delete(uv_default_loop())
+
+/* Just sugar for wrapping the main() for a task or helper. */
+#define TEST_IMPL(name) \
+ int run_test_##name(void); \
+ int run_test_##name(void)
+
+#define BENCHMARK_IMPL(name) \
+ int run_benchmark_##name(void); \
+ int run_benchmark_##name(void)
+
+#define HELPER_IMPL(name) \
+ int run_helper_##name(void); \
+ int run_helper_##name(void)
+
+/* Pause the calling thread for a number of milliseconds. */
+void uv_sleep(int msec);
+
+/* Format big numbers nicely. WARNING: leaks memory. */
+const char* fmt(double d);
+
+/* Reserved test exit codes. */
+enum test_status {
+ TEST_OK = 0,
+ TEST_TODO,
+ TEST_SKIP
+};
+
+#define RETURN_OK() \
+ do { \
+ return TEST_OK; \
+ } while (0)
+
+#define RETURN_TODO(explanation) \
+ do { \
+ LOGF("%s\n", explanation); \
+ return TEST_TODO; \
+ } while (0)
+
+#define RETURN_SKIP(explanation) \
+ do { \
+ LOGF("%s\n", explanation); \
+ return TEST_SKIP; \
+ } while (0)
+
+#if !defined(_WIN32)
+
+# define TEST_FILE_LIMIT(num) \
+ do { \
+ struct rlimit lim; \
+ lim.rlim_cur = (num); \
+ lim.rlim_max = lim.rlim_cur; \
+ if (setrlimit(RLIMIT_NOFILE, &lim)) \
+ RETURN_SKIP("File descriptor limit too low."); \
+ } while (0)
+
+#else /* defined(_WIN32) */
+
+# define TEST_FILE_LIMIT(num) do {} while (0)
+
+#endif
+
+
+#if defined _WIN32 && ! defined __GNUC__
+
+#include <stdarg.h>
+
+/* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer
+ * on overflow...
+ */
+static int snprintf(char* buf, size_t len, const char* fmt, ...) {
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ n = _vsprintf_p(buf, len, fmt, ap);
+ va_end(ap);
+
+ /* It's a sad fact of life that no one ever checks the return value of
+ * snprintf(). Zero-terminating the buffer hopefully reduces the risk
+ * of gaping security holes.
+ */
+ if (n < 0)
+ if (len > 0)
+ buf[0] = '\0';
+
+ return n;
+}
+
+#endif
+
+#endif /* TASK_H_ */
diff --git a/third-party/libuv/test/test-active.c b/third-party/libuv/test/test-active.c
new file mode 100644
index 0000000000..0fae23cdb1
--- /dev/null
+++ b/third-party/libuv/test/test-active.c
@@ -0,0 +1,84 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(0 && "timer_cb should not have been called");
+}
+
+
+TEST_IMPL(active) {
+ int r;
+ uv_timer_t timer;
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ /* uv_is_active() and uv_is_closing() should always return either 0 or 1. */
+ ASSERT(0 == uv_is_active((uv_handle_t*) &timer));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_start(&timer, timer_cb, 1000, 0);
+ ASSERT(r == 0);
+
+ ASSERT(1 == uv_is_active((uv_handle_t*) &timer));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_stop(&timer);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_is_active((uv_handle_t*) &timer));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_timer_start(&timer, timer_cb, 1000, 0);
+ ASSERT(r == 0);
+
+ ASSERT(1 == uv_is_active((uv_handle_t*) &timer));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &timer));
+
+ uv_close((uv_handle_t*) &timer, close_cb);
+
+ ASSERT(0 == uv_is_active((uv_handle_t*) &timer));
+ ASSERT(1 == uv_is_closing((uv_handle_t*) &timer));
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-async-null-cb.c b/third-party/libuv/test/test-async-null-cb.c
new file mode 100644
index 0000000000..d654884268
--- /dev/null
+++ b/third-party/libuv/test/test-async-null-cb.c
@@ -0,0 +1,55 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_async_t async_handle;
+static uv_check_t check_handle;
+static int check_cb_called;
+static uv_thread_t thread;
+
+
+static void thread_cb(void* dummy) {
+ (void) &dummy;
+ uv_async_send(&async_handle);
+}
+
+
+static void check_cb(uv_check_t* handle, int status) {
+ ASSERT(check_cb_called == 0);
+ uv_close((uv_handle_t*) &async_handle, NULL);
+ uv_close((uv_handle_t*) &check_handle, NULL);
+ check_cb_called++;
+}
+
+
+TEST_IMPL(async_null_cb) {
+ ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL));
+ ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
+ ASSERT(0 == uv_check_start(&check_handle, check_cb));
+ ASSERT(0 == uv_thread_create(&thread, thread_cb, NULL));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == uv_thread_join(&thread));
+ ASSERT(1 == check_cb_called);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-async.c b/third-party/libuv/test/test-async.c
new file mode 100644
index 0000000000..d4d94d5fa0
--- /dev/null
+++ b/third-party/libuv/test/test-async.c
@@ -0,0 +1,136 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static uv_thread_t thread;
+static uv_mutex_t mutex;
+
+static uv_prepare_t prepare;
+static uv_async_t async;
+
+static volatile int async_cb_called;
+static int prepare_cb_called;
+static int close_cb_called;
+
+
+static void thread_cb(void *arg) {
+ int n;
+ int r;
+
+ for (;;) {
+ uv_mutex_lock(&mutex);
+ n = async_cb_called;
+ uv_mutex_unlock(&mutex);
+
+ if (n == 3) {
+ break;
+ }
+
+ r = uv_async_send(&async);
+ ASSERT(r == 0);
+
+ /* Work around a bug in Valgrind.
+ *
+ * Valgrind runs threads not in parallel but sequentially, i.e. one after
+ * the other. It also doesn't preempt them, instead it depends on threads
+ * yielding voluntarily by making a syscall.
+ *
+ * That never happens here: the pipe that is associated with the async
+ * handle is written to once but that's too early for Valgrind's scheduler
+ * to kick in. Afterwards, the thread busy-loops, starving the main thread.
+ * Therefore, we yield.
+ *
+ * This behavior has been observed with Valgrind 3.7.0 and 3.9.0.
+ */
+ uv_sleep(0);
+ }
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void async_cb(uv_async_t* handle, int status) {
+ int n;
+
+ ASSERT(handle == &async);
+ ASSERT(status == 0);
+
+ uv_mutex_lock(&mutex);
+ n = ++async_cb_called;
+ uv_mutex_unlock(&mutex);
+
+ if (n == 3) {
+ uv_close((uv_handle_t*)&async, close_cb);
+ uv_close((uv_handle_t*)&prepare, close_cb);
+ }
+}
+
+
+static void prepare_cb(uv_prepare_t* handle, int status) {
+ int r;
+
+ ASSERT(handle == &prepare);
+ ASSERT(status == 0);
+
+ if (prepare_cb_called++)
+ return;
+
+ r = uv_thread_create(&thread, thread_cb, NULL);
+ ASSERT(r == 0);
+ uv_mutex_unlock(&mutex);
+}
+
+
+TEST_IMPL(async) {
+ int r;
+
+ r = uv_mutex_init(&mutex);
+ ASSERT(r == 0);
+ uv_mutex_lock(&mutex);
+
+ r = uv_prepare_init(uv_default_loop(), &prepare);
+ ASSERT(r == 0);
+ r = uv_prepare_start(&prepare, prepare_cb);
+ ASSERT(r == 0);
+
+ r = uv_async_init(uv_default_loop(), &async, async_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(prepare_cb_called > 0);
+ ASSERT(async_cb_called == 3);
+ ASSERT(close_cb_called == 2);
+
+ ASSERT(0 == uv_thread_join(&thread));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-barrier.c b/third-party/libuv/test/test-barrier.c
new file mode 100644
index 0000000000..97df704c0e
--- /dev/null
+++ b/third-party/libuv/test/test-barrier.c
@@ -0,0 +1,98 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+typedef struct {
+ uv_barrier_t barrier;
+ int delay;
+ volatile int posted;
+} worker_config;
+
+
+static void worker(void* arg) {
+ worker_config* c = arg;
+
+ if (c->delay)
+ uv_sleep(c->delay);
+
+ uv_barrier_wait(&c->barrier);
+}
+
+
+TEST_IMPL(barrier_1) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_sleep(100);
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
+
+
+TEST_IMPL(barrier_2) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
+
+
+TEST_IMPL(barrier_3) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_barrier_init(&wc.barrier, 2));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_barrier_wait(&wc.barrier);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_barrier_destroy(&wc.barrier);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-callback-order.c b/third-party/libuv/test/test-callback-order.c
new file mode 100644
index 0000000000..84231e1b6b
--- /dev/null
+++ b/third-party/libuv/test/test-callback-order.c
@@ -0,0 +1,77 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static int idle_cb_called;
+static int timer_cb_called;
+
+static uv_idle_t idle_handle;
+static uv_timer_t timer_handle;
+
+
+/* idle_cb should run before timer_cb */
+static void idle_cb(uv_idle_t* handle, int status) {
+ ASSERT(idle_cb_called == 0);
+ ASSERT(timer_cb_called == 0);
+ uv_idle_stop(handle);
+ idle_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(idle_cb_called == 1);
+ ASSERT(timer_cb_called == 0);
+ uv_timer_stop(handle);
+ timer_cb_called++;
+}
+
+
+static void next_tick(uv_idle_t* handle, int status) {
+ uv_loop_t* loop = handle->loop;
+ uv_idle_stop(handle);
+ uv_idle_init(loop, &idle_handle);
+ uv_idle_start(&idle_handle, idle_cb);
+ uv_timer_init(loop, &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 0, 0);
+}
+
+
+TEST_IMPL(callback_order) {
+ uv_loop_t* loop;
+ uv_idle_t idle;
+
+ loop = uv_default_loop();
+ uv_idle_init(loop, &idle);
+ uv_idle_start(&idle, next_tick);
+
+ ASSERT(idle_cb_called == 0);
+ ASSERT(timer_cb_called == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(idle_cb_called == 1);
+ ASSERT(timer_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-callback-stack.c b/third-party/libuv/test/test-callback-stack.c
new file mode 100644
index 0000000000..accd549697
--- /dev/null
+++ b/third-party/libuv/test/test-callback-stack.c
@@ -0,0 +1,206 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * TODO: Add explanation of why we want on_close to be called from fresh
+ * stack.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone.";
+
+static uv_tcp_t client;
+static uv_timer_t timer;
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+static uv_shutdown_t shutdown_req;
+
+static int nested = 0;
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int timer_cb_called = 0;
+static int bytes_received = 0;
+static int shutdown_cb_called = 0;
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->len = size;
+ buf->base = malloc(size);
+ ASSERT(buf->base != NULL);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(nested == 0 && "close_cb must be called from a fresh stack");
+
+ close_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(status == 0);
+ ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack");
+
+ shutdown_cb_called++;
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(nested == 0 && "read_cb must be called from a fresh stack");
+
+ printf("Read. nread == %d\n", (int)nread);
+ free(buf->base);
+
+ if (nread == 0) {
+ return;
+
+ } else if (nread < 0) {
+ ASSERT(nread == UV_EOF);
+
+ nested++;
+ uv_close((uv_handle_t*)tcp, close_cb);
+ nested--;
+
+ return;
+ }
+
+ bytes_received += nread;
+
+ /* We call shutdown here because when bytes_received == sizeof MESSAGE */
+ /* there will be no more data sent nor received, so here it would be */
+ /* possible for a backend to to call shutdown_cb immediately and *not* */
+ /* from a fresh stack. */
+ if (bytes_received == sizeof MESSAGE) {
+ nested++;
+
+ puts("Shutdown");
+
+ if (uv_shutdown(&shutdown_req, (uv_stream_t*)tcp, shutdown_cb)) {
+ FATAL("uv_shutdown failed");
+ }
+ nested--;
+ }
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer);
+ ASSERT(status == 0);
+ ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");
+
+ puts("Timeout complete. Now read data...");
+
+ nested++;
+ if (uv_read_start((uv_stream_t*)&client, alloc_cb, read_cb)) {
+ FATAL("uv_read_start failed");
+ }
+ nested--;
+
+ timer_cb_called++;
+
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ int r;
+
+ ASSERT(status == 0);
+ ASSERT(nested == 0 && "write_cb must be called from a fresh stack");
+
+ puts("Data written. 500ms timeout...");
+
+ /* After the data has been sent, we're going to wait for a while, then */
+ /* start reading. This makes us certain that the message has been echoed */
+ /* back to our receive buffer when we start reading. This maximizes the */
+ /* temptation for the backend to use dirty stack for calling read_cb. */
+ nested++;
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, timer_cb, 500, 0);
+ ASSERT(r == 0);
+ nested--;
+
+ write_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_buf_t buf;
+
+ puts("Connected. Write some data to echo server...");
+
+ ASSERT(status == 0);
+ ASSERT(nested == 0 && "connect_cb must be called from a fresh stack");
+
+ nested++;
+
+ buf.base = (char*) &MESSAGE;
+ buf.len = sizeof MESSAGE;
+
+ if (uv_write(&write_req, (uv_stream_t*)req->handle, &buf, 1, write_cb)) {
+ FATAL("uv_write failed");
+ }
+
+ nested--;
+
+ connect_cb_called++;
+}
+
+
+TEST_IMPL(callback_stack) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ if (uv_tcp_init(uv_default_loop(), &client)) {
+ FATAL("uv_tcp_init failed");
+ }
+
+ puts("Connecting...");
+
+ nested++;
+
+ if (uv_tcp_connect(&connect_req,
+ &client,
+ (const struct sockaddr*) &addr,
+ connect_cb)) {
+ FATAL("uv_tcp_connect failed");
+ }
+ nested--;
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(nested == 0);
+ ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once");
+ ASSERT(write_cb_called == 1 && "write_cb must be called exactly once");
+ ASSERT(timer_cb_called == 1 && "timer_cb must be called exactly once");
+ ASSERT(bytes_received == sizeof MESSAGE);
+ ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once");
+ ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-close-fd.c b/third-party/libuv/test/test-close-fd.c
new file mode 100644
index 0000000000..0d17f07661
--- /dev/null
+++ b/third-party/libuv/test/test-close-fd.c
@@ -0,0 +1,77 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#if !defined(_WIN32)
+
+#include "uv.h"
+#include "task.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+static unsigned int read_cb_called;
+
+static void alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
+ static char slab[1];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+static void read_cb(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
+ switch (++read_cb_called) {
+ case 1:
+ ASSERT(nread == 1);
+ uv_read_stop(handle);
+ break;
+ case 2:
+ ASSERT(nread == UV_EOF);
+ uv_close((uv_handle_t *) handle, NULL);
+ break;
+ default:
+ ASSERT(!"read_cb_called > 2");
+ }
+}
+
+TEST_IMPL(close_fd) {
+ uv_pipe_t pipe_handle;
+ int fd[2];
+
+ ASSERT(0 == pipe(fd));
+ ASSERT(0 == fcntl(fd[0], F_SETFL, O_NONBLOCK));
+ ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
+ ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
+ fd[0] = -1; /* uv_pipe_open() takes ownership of the file descriptor. */
+ ASSERT(1 == write(fd[1], "", 1));
+ ASSERT(0 == close(fd[1]));
+ fd[1] = -1;
+ ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(1 == read_cb_called);
+ ASSERT(0 == uv_is_active((const uv_handle_t *) &pipe_handle));
+ ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(2 == read_cb_called);
+ ASSERT(0 != uv_is_closing((const uv_handle_t *) &pipe_handle));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !defined(_WIN32) */
diff --git a/third-party/libuv/test/test-close-order.c b/third-party/libuv/test/test-close-order.c
new file mode 100644
index 0000000000..e2f25f987d
--- /dev/null
+++ b/third-party/libuv/test/test-close-order.c
@@ -0,0 +1,80 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static int check_cb_called;
+static int timer_cb_called;
+static int close_cb_called;
+
+static uv_check_t check_handle;
+static uv_timer_t timer_handle1;
+static uv_timer_t timer_handle2;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+/* check_cb should run before any close_cb */
+static void check_cb(uv_check_t* handle, int status) {
+ ASSERT(check_cb_called == 0);
+ ASSERT(timer_cb_called == 1);
+ ASSERT(close_cb_called == 0);
+ uv_close((uv_handle_t*) handle, close_cb);
+ uv_close((uv_handle_t*) &timer_handle2, close_cb);
+ check_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_close((uv_handle_t*) handle, close_cb);
+ timer_cb_called++;
+}
+
+
+TEST_IMPL(close_order) {
+ uv_loop_t* loop;
+ loop = uv_default_loop();
+
+ uv_check_init(loop, &check_handle);
+ uv_check_start(&check_handle, check_cb);
+ uv_timer_init(loop, &timer_handle1);
+ uv_timer_start(&timer_handle1, timer_cb, 0, 0);
+ uv_timer_init(loop, &timer_handle2);
+ uv_timer_start(&timer_handle2, timer_cb, 100000, 0);
+
+ ASSERT(check_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(timer_cb_called == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(check_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+ ASSERT(timer_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-condvar.c b/third-party/libuv/test/test-condvar.c
new file mode 100644
index 0000000000..dbacdba384
--- /dev/null
+++ b/third-party/libuv/test/test-condvar.c
@@ -0,0 +1,173 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+typedef struct {
+ uv_mutex_t mutex;
+ uv_cond_t cond;
+ int delay;
+ int use_broadcast;
+ volatile int posted;
+} worker_config;
+
+
+static void worker(void* arg) {
+ worker_config* c = arg;
+
+ if (c->delay)
+ uv_sleep(c->delay);
+
+ uv_mutex_lock(&c->mutex);
+ ASSERT(c->posted == 0);
+ c->posted = 1;
+ if (c->use_broadcast)
+ uv_cond_broadcast(&c->cond);
+ else
+ uv_cond_signal(&c->cond);
+ uv_mutex_unlock(&c->mutex);
+}
+
+
+TEST_IMPL(condvar_1) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_sleep(100);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ ASSERT(wc.posted == 1);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_2) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_3) {
+ uv_thread_t thread;
+ worker_config wc;
+ int r;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(50 * 1e6));
+ ASSERT(r == UV_ETIMEDOUT);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_4) {
+ uv_thread_t thread;
+ worker_config wc;
+ int r;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(150 * 1e6));
+ ASSERT(r == 0);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
+
+
+TEST_IMPL(condvar_5) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.use_broadcast = 1;
+
+ ASSERT(0 == uv_cond_init(&wc.cond));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_mutex_lock(&wc.mutex);
+ uv_sleep(100);
+ uv_cond_wait(&wc.cond, &wc.mutex);
+ ASSERT(wc.posted == 1);
+ uv_mutex_unlock(&wc.mutex);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_cond_destroy(&wc.cond);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-connection-fail.c b/third-party/libuv/test/test-connection-fail.c
new file mode 100644
index 0000000000..5700140130
--- /dev/null
+++ b/third-party/libuv/test/test-connection-fail.c
@@ -0,0 +1,152 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+static uv_tcp_t tcp;
+static uv_connect_t req;
+static int connect_cb_calls;
+static int close_cb_calls;
+
+static uv_timer_t timer;
+static int timer_close_cb_calls;
+static int timer_cb_calls;
+
+
+static void on_close(uv_handle_t* handle) {
+ close_cb_calls++;
+}
+
+
+static void timer_close_cb(uv_handle_t* handle) {
+ timer_close_cb_calls++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(status == 0);
+ timer_cb_calls++;
+
+ /*
+ * These are the important asserts. The connection callback has been made,
+ * but libuv hasn't automatically closed the socket. The user must
+ * uv_close the handle manually.
+ */
+ ASSERT(close_cb_calls == 0);
+ ASSERT(connect_cb_calls == 1);
+
+ /* Close the tcp handle. */
+ uv_close((uv_handle_t*)&tcp, on_close);
+
+ /* Close the timer. */
+ uv_close((uv_handle_t*)handle, timer_close_cb);
+}
+
+
+static void on_connect_with_close(uv_connect_t *req, int status) {
+ ASSERT((uv_stream_t*) &tcp == req->handle);
+ ASSERT(status == UV_ECONNREFUSED);
+ connect_cb_calls++;
+
+ ASSERT(close_cb_calls == 0);
+ uv_close((uv_handle_t*)req->handle, on_close);
+}
+
+
+static void on_connect_without_close(uv_connect_t *req, int status) {
+ ASSERT(status == UV_ECONNREFUSED);
+ connect_cb_calls++;
+
+ uv_timer_start(&timer, timer_cb, 100, 0);
+
+ ASSERT(close_cb_calls == 0);
+}
+
+
+static void connection_fail(uv_connect_cb connect_cb) {
+ struct sockaddr_in client_addr, server_addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr));
+
+ /* There should be no servers listening on this port. */
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
+
+ /* Try to connect to the server and do NUM_PINGS ping-pongs. */
+ r = uv_tcp_init(uv_default_loop(), &tcp);
+ ASSERT(!r);
+
+ /* We are never doing multiple reads/connects at a time anyway. */
+ /* so these handles can be pre-initialized. */
+ ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr, 0));
+
+ r = uv_tcp_connect(&req,
+ &tcp,
+ (const struct sockaddr*) &server_addr,
+ connect_cb);
+ ASSERT(!r);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connect_cb_calls == 1);
+ ASSERT(close_cb_calls == 1);
+}
+
+
+/*
+ * This test attempts to connect to a port where no server is running. We
+ * expect an error.
+ */
+TEST_IMPL(connection_fail) {
+ connection_fail(on_connect_with_close);
+
+ ASSERT(timer_close_cb_calls == 0);
+ ASSERT(timer_cb_calls == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+/*
+ * This test is the same as the first except it check that the close
+ * callback of the tcp handle hasn't been made after the failed connection
+ * attempt.
+ */
+TEST_IMPL(connection_fail_doesnt_auto_close) {
+ int r;
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ connection_fail(on_connect_without_close);
+
+ ASSERT(timer_close_cb_calls == 1);
+ ASSERT(timer_cb_calls == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-cwd-and-chdir.c b/third-party/libuv/test/test-cwd-and-chdir.c
new file mode 100644
index 0000000000..f1082ac47f
--- /dev/null
+++ b/third-party/libuv/test/test-cwd-and-chdir.c
@@ -0,0 +1,64 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+#define PATHMAX 1024
+extern char executable_path[];
+
+TEST_IMPL(cwd_and_chdir) {
+ char buffer_orig[PATHMAX];
+ char buffer_new[PATHMAX];
+ size_t size;
+ char* last_slash;
+ int err;
+
+ size = sizeof(buffer_orig) / sizeof(buffer_orig[0]);
+ err = uv_cwd(buffer_orig, size);
+ ASSERT(err == 0);
+
+ /* Remove trailing slash unless at a root directory. */
+#ifdef _WIN32
+ last_slash = strrchr(buffer_orig, '\\');
+ ASSERT(last_slash);
+ if (last_slash > buffer_orig && *(last_slash - 1) != ':') {
+ *last_slash = '\0';
+ }
+#else /* Unix */
+ last_slash = strrchr(buffer_orig, '/');
+ ASSERT(last_slash);
+ if (last_slash != buffer_orig) {
+ *last_slash = '\0';
+ }
+#endif
+
+ err = uv_chdir(buffer_orig);
+ ASSERT(err == 0);
+
+ err = uv_cwd(buffer_new, size);
+ ASSERT(err == 0);
+
+ ASSERT(strcmp(buffer_orig, buffer_new) == 0);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-delayed-accept.c b/third-party/libuv/test/test-delayed-accept.c
new file mode 100644
index 0000000000..b45100d625
--- /dev/null
+++ b/third-party/libuv/test/test-delayed-accept.c
@@ -0,0 +1,190 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static int connection_cb_called = 0;
+static int do_accept_called = 0;
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = malloc(size);
+ buf->len = size;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+
+ free(handle);
+
+ close_cb_called++;
+}
+
+
+static void do_accept(uv_timer_t* timer_handle, int status) {
+ uv_tcp_t* server;
+ uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
+ int r;
+
+ ASSERT(timer_handle != NULL);
+ ASSERT(status == 0);
+ ASSERT(accepted_handle != NULL);
+
+ r = uv_tcp_init(uv_default_loop(), accepted_handle);
+ ASSERT(r == 0);
+
+ server = (uv_tcp_t*)timer_handle->data;
+ r = uv_accept((uv_stream_t*)server, (uv_stream_t*)accepted_handle);
+ ASSERT(r == 0);
+
+ do_accept_called++;
+
+ /* Immediately close the accepted handle. */
+ uv_close((uv_handle_t*)accepted_handle, close_cb);
+
+ /* After accepting the two clients close the server handle */
+ if (do_accept_called == 2) {
+ uv_close((uv_handle_t*)server, close_cb);
+ }
+
+ /* Dispose the timer. */
+ uv_close((uv_handle_t*)timer_handle, close_cb);
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ int r;
+ uv_timer_t* timer_handle;
+
+ ASSERT(status == 0);
+
+ timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle);
+ ASSERT(timer_handle != NULL);
+
+ /* Accept the client after 1 second */
+ r = uv_timer_init(uv_default_loop(), timer_handle);
+ ASSERT(r == 0);
+
+ timer_handle->data = tcp;
+
+ r = uv_timer_start(timer_handle, do_accept, 1000, 0);
+ ASSERT(r == 0);
+
+ connection_cb_called++;
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+ uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server);
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+ ASSERT(server != NULL);
+
+ r = uv_tcp_init(uv_default_loop(), server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)server, 128, connection_cb);
+ ASSERT(r == 0);
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ /* The server will not send anything, it should close gracefully. */
+
+ if (buf->base) {
+ free(buf->base);
+ }
+
+ if (nread >= 0) {
+ ASSERT(nread == 0);
+ } else {
+ ASSERT(tcp != NULL);
+ ASSERT(nread == UV_EOF);
+ uv_close((uv_handle_t*)tcp, close_cb);
+ }
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ int r;
+
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+
+ /* Not that the server will send anything, but otherwise we'll never know */
+ /* when the server closes the connection. */
+ r = uv_read_start((uv_stream_t*)(req->handle), alloc_cb, read_cb);
+ ASSERT(r == 0);
+
+ connect_cb_called++;
+
+ free(req);
+}
+
+
+static void client_connect(void) {
+ struct sockaddr_in addr;
+ uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
+ uv_connect_t* connect_req = malloc(sizeof *connect_req);
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(client != NULL);
+ ASSERT(connect_req != NULL);
+
+ r = uv_tcp_init(uv_default_loop(), client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(connect_req,
+ client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+}
+
+
+
+TEST_IMPL(delayed_accept) {
+ start_server();
+
+ client_connect();
+ client_connect();
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connection_cb_called == 2);
+ ASSERT(do_accept_called == 2);
+ ASSERT(connect_cb_called == 2);
+ ASSERT(close_cb_called == 7);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-dlerror.c b/third-party/libuv/test/test-dlerror.c
new file mode 100644
index 0000000000..877ebf3712
--- /dev/null
+++ b/third-party/libuv/test/test-dlerror.c
@@ -0,0 +1,58 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+
+TEST_IMPL(dlerror) {
+ const char* path = "test/fixtures/load_error.node";
+ const char* msg;
+ uv_lib_t lib;
+ int r;
+
+#ifdef __linux__
+ const char* dlerror_desc = "file too short";
+#elif defined (__sun__)
+ const char* dlerror_desc = "unknown file type";
+#elif defined (_WIN32)
+ const char* dlerror_desc = "%1 is not a valid Win32 application";
+#else
+ const char* dlerror_desc = "";
+#endif
+
+ r = uv_dlopen(path, &lib);
+ ASSERT(r == -1);
+
+ msg = uv_dlerror(&lib);
+ ASSERT(msg != NULL);
+ ASSERT(strstr(msg, dlerror_desc) != NULL);
+
+ /* Should return the same error twice in a row. */
+ msg = uv_dlerror(&lib);
+ ASSERT(msg != NULL);
+ ASSERT(strstr(msg, dlerror_desc) != NULL);
+
+ uv_dlclose(&lib);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-embed.c b/third-party/libuv/test/test-embed.c
new file mode 100644
index 0000000000..ac1b3b6750
--- /dev/null
+++ b/third-party/libuv/test/test-embed.c
@@ -0,0 +1,139 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifndef HAVE_KQUEUE
+# if defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# define HAVE_KQUEUE 1
+# endif
+#endif
+
+#ifndef HAVE_EPOLL
+# if defined(__linux__)
+# define HAVE_EPOLL 1
+# endif
+#endif
+
+#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+
+#if defined(HAVE_KQUEUE)
+# include <sys/types.h>
+# include <sys/event.h>
+# include <sys/time.h>
+#endif
+
+#if defined(HAVE_EPOLL)
+# include <sys/epoll.h>
+#endif
+
+static uv_thread_t embed_thread;
+static uv_sem_t embed_sem;
+static uv_timer_t embed_timer;
+static uv_async_t embed_async;
+static volatile int embed_closed;
+
+static int embed_timer_called;
+
+
+static void embed_thread_runner(void* arg) {
+ int r;
+ int fd;
+ int timeout;
+
+ while (!embed_closed) {
+ fd = uv_backend_fd(uv_default_loop());
+ timeout = uv_backend_timeout(uv_default_loop());
+
+ do {
+#if defined(HAVE_KQUEUE)
+ struct timespec ts;
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ r = kevent(fd, NULL, 0, NULL, 0, &ts);
+#elif defined(HAVE_EPOLL)
+ {
+ struct epoll_event ev;
+ r = epoll_wait(fd, &ev, 1, timeout);
+ }
+#endif
+ } while (r == -1 && errno == EINTR);
+ uv_async_send(&embed_async);
+ uv_sem_wait(&embed_sem);
+ }
+}
+
+
+static void embed_cb(uv_async_t* async, int status) {
+ uv_run(uv_default_loop(), UV_RUN_ONCE);
+
+ uv_sem_post(&embed_sem);
+}
+
+
+static void embed_timer_cb(uv_timer_t* timer, int status) {
+ embed_timer_called++;
+ embed_closed = 1;
+
+ uv_close((uv_handle_t*) &embed_async, NULL);
+}
+#endif
+
+
+TEST_IMPL(embed) {
+#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
+ uv_loop_t* external;
+
+ external = uv_loop_new();
+ ASSERT(external != NULL);
+
+ embed_timer_called = 0;
+ embed_closed = 0;
+
+ uv_async_init(external, &embed_async, embed_cb);
+
+ /* Start timer in default loop */
+ uv_timer_init(uv_default_loop(), &embed_timer);
+ uv_timer_start(&embed_timer, embed_timer_cb, 250, 0);
+
+ /* Start worker that will interrupt external loop */
+ uv_sem_init(&embed_sem, 0);
+ uv_thread_create(&embed_thread, embed_thread_runner, NULL);
+
+ /* But run external loop */
+ uv_run(external, UV_RUN_DEFAULT);
+
+ uv_thread_join(&embed_thread);
+ uv_loop_delete(external);
+
+ ASSERT(embed_timer_called == 1);
+#endif
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-emfile.c b/third-party/libuv/test/test-emfile.c
new file mode 100644
index 0000000000..453bfe4cf5
--- /dev/null
+++ b/third-party/libuv/test/test-emfile.c
@@ -0,0 +1,111 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#if !defined(_WIN32)
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+static void connection_cb(uv_stream_t* server_handle, int status);
+static void connect_cb(uv_connect_t* req, int status);
+
+static const int maxfd = 31;
+static unsigned connect_cb_called;
+static uv_tcp_t server_handle;
+static uv_tcp_t client_handle;
+
+
+TEST_IMPL(emfile) {
+ struct sockaddr_in addr;
+ struct rlimit limits;
+ uv_connect_t connect_req;
+ uv_loop_t* loop;
+ int first_fd;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_tcp_init(loop, &server_handle));
+ ASSERT(0 == uv_tcp_init(loop, &client_handle));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
+
+ /* Lower the file descriptor limit and use up all fds save one. */
+ limits.rlim_cur = limits.rlim_max = maxfd + 1;
+ if (setrlimit(RLIMIT_NOFILE, &limits)) {
+ perror("setrlimit(RLIMIT_NOFILE)");
+ ASSERT(0);
+ }
+
+ /* Remember the first one so we can clean up afterwards. */
+ do
+ first_fd = dup(0);
+ while (first_fd == -1 && errno == EINTR);
+ ASSERT(first_fd > 0);
+
+ while (dup(0) != -1 || errno == EINTR);
+ ASSERT(errno == EMFILE);
+ close(maxfd);
+
+ /* Now connect and use up the last available file descriptor. The EMFILE
+ * handling logic in src/unix/stream.c should ensure that connect_cb() runs
+ * whereas connection_cb() should *not* run.
+ */
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == connect_cb_called);
+
+ /* Close the dups again. Ignore errors in the unlikely event that the
+ * file descriptors were not contiguous.
+ */
+ while (first_fd < maxfd) {
+ close(first_fd);
+ first_fd += 1;
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void connection_cb(uv_stream_t* server_handle, int status) {
+ ASSERT(0 && "connection_cb should not be called.");
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ /* |status| should equal 0 because the connection should have been accepted,
+ * it's just that the server immediately closes it again.
+ */
+ ASSERT(0 == status);
+ connect_cb_called += 1;
+ uv_close((uv_handle_t*) &server_handle, NULL);
+ uv_close((uv_handle_t*) &client_handle, NULL);
+}
+
+#endif /* !defined(_WIN32) */
diff --git a/third-party/libuv/test/test-error.c b/third-party/libuv/test/test-error.c
new file mode 100644
index 0000000000..eb337e66f3
--- /dev/null
+++ b/third-party/libuv/test/test-error.c
@@ -0,0 +1,50 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+ * Synthetic errors (errors that originate from within libuv, not the system)
+ * should produce sensible error messages when run through uv_strerror().
+ *
+ * See https://github.com/joyent/libuv/issues/210
+ */
+TEST_IMPL(error_message) {
+ /* Cop out. Can't do proper checks on systems with
+ * i18n-ized error messages...
+ */
+ if (strcmp(uv_strerror(0), "Success") != 0) {
+ printf("i18n error messages detected, skipping test.\n");
+ return 0;
+ }
+
+ ASSERT(strstr(uv_strerror(UV_EINVAL), "Success") == NULL);
+ ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0);
+ ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-fail-always.c b/third-party/libuv/test/test-fail-always.c
new file mode 100644
index 0000000000..0008459eac
--- /dev/null
+++ b/third-party/libuv/test/test-fail-always.c
@@ -0,0 +1,29 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+
+
+TEST_IMPL(fail_always) {
+ /* This test always fails. It is used to test the test runner. */
+ FATAL("Yes, it always fails");
+ return 2;
+}
diff --git a/third-party/libuv/test/test-fs-event.c b/third-party/libuv/test/test-fs-event.c
new file mode 100644
index 0000000000..3286de51f9
--- /dev/null
+++ b/third-party/libuv/test/test-fs-event.c
@@ -0,0 +1,730 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <fcntl.h>
+
+#ifndef HAVE_KQUEUE
+# if defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# define HAVE_KQUEUE 1
+# endif
+#endif
+
+static uv_fs_event_t fs_event;
+static const char file_prefix[] = "fsevent-";
+static uv_timer_t timer;
+static int timer_cb_called;
+static int close_cb_called;
+static const int fs_event_file_count = 128;
+static int fs_event_created;
+static int fs_event_cb_called;
+#if defined(PATH_MAX)
+static char fs_event_filename[PATH_MAX];
+#else
+static char fs_event_filename[1024];
+#endif /* defined(PATH_MAX) */
+static int timer_cb_touch_called;
+
+static void fs_event_unlink_files(uv_timer_t* handle, int status);
+
+static void create_dir(uv_loop_t* loop, const char* name) {
+ int r;
+ uv_fs_t req;
+ r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
+ ASSERT(r == 0 || r == UV_EEXIST);
+ uv_fs_req_cleanup(&req);
+}
+
+static void create_file(uv_loop_t* loop, const char* name) {
+ int r;
+ uv_file file;
+ uv_fs_t req;
+
+ r = uv_fs_open(loop, &req, name, O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ file = r;
+ uv_fs_req_cleanup(&req);
+ r = uv_fs_close(loop, &req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+}
+
+static void touch_file(uv_loop_t* loop, const char* name) {
+ int r;
+ uv_file file;
+ uv_fs_t req;
+
+ r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ file = r;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_write(loop, &req, file, "foo", 4, -1, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_close(loop, &req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+}
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+static void fail_cb(uv_fs_event_t* handle,
+ const char* path,
+ int events,
+ int status) {
+ ASSERT(0 && "fail_cb called");
+}
+
+static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
+ int events, int status) {
+ ++fs_event_cb_called;
+ ASSERT(handle == &fs_event);
+ ASSERT(status == 0);
+ ASSERT(events == UV_RENAME);
+ ASSERT(filename == NULL || strcmp(filename, "file1") == 0);
+ ASSERT(0 == uv_fs_event_stop(handle));
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
+ const char* filename,
+ int events,
+ int status) {
+ fs_event_cb_called++;
+ ASSERT(handle == &fs_event);
+ ASSERT(status == 0);
+ ASSERT(events == UV_RENAME);
+ ASSERT(filename == NULL ||
+ strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0);
+
+ /* Stop watching dir when received events about all files:
+ * both create and close events */
+ if (fs_event_cb_called == 2 * fs_event_file_count) {
+ ASSERT(0 == uv_fs_event_stop(handle));
+ uv_close((uv_handle_t*) handle, close_cb);
+ }
+}
+
+static const char* fs_event_get_filename(int i) {
+ snprintf(fs_event_filename,
+ sizeof(fs_event_filename),
+ "watch_dir/%s%d",
+ file_prefix,
+ i);
+ return fs_event_filename;
+}
+
+static void fs_event_create_files(uv_timer_t* handle, int status) {
+ int i;
+
+ /* Already created all files */
+ if (fs_event_created == fs_event_file_count) {
+ uv_close((uv_handle_t*) &timer, close_cb);
+ return;
+ }
+
+ /* Create all files */
+ for (i = 0; i < 16; i++, fs_event_created++)
+ create_file(handle->loop, fs_event_get_filename(i));
+
+ /* And unlink them */
+ ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 50, 0));
+}
+
+void fs_event_unlink_files(uv_timer_t* handle, int status) {
+ int r;
+ int i;
+
+ /* NOTE: handle might be NULL if invoked not as timer callback */
+
+ /* Unlink all files */
+ for (i = 0; i < 16; i++) {
+ r = remove(fs_event_get_filename(i));
+ if (handle != NULL)
+ ASSERT(r == 0);
+ }
+
+ /* And create them again */
+ if (handle != NULL)
+ ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 50, 0));
+}
+
+static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
+ int events, int status) {
+ ++fs_event_cb_called;
+ ASSERT(handle == &fs_event);
+ ASSERT(status == 0);
+ ASSERT(events == UV_CHANGE);
+ ASSERT(filename == NULL || strcmp(filename, "file2") == 0);
+ ASSERT(0 == uv_fs_event_stop(handle));
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+static void timer_cb_close_handle(uv_timer_t* timer, int status) {
+ uv_handle_t* handle;
+
+ ASSERT(timer != NULL);
+ ASSERT(status == 0);
+ handle = timer->data;
+
+ uv_close((uv_handle_t*)timer, NULL);
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
+ const char* filename, int events, int status) {
+ ASSERT(fs_event_cb_called == 0);
+ ++fs_event_cb_called;
+
+ ASSERT(handle == &fs_event);
+ ASSERT(status == 0);
+ ASSERT(events == UV_CHANGE);
+ ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0);
+
+ /* Regression test for SunOS: touch should generate just one event. */
+ {
+ static uv_timer_t timer;
+ uv_timer_init(handle->loop, &timer);
+ timer.data = handle;
+ uv_timer_start(&timer, timer_cb_close_handle, 250, 0);
+ }
+}
+
+static void timer_cb_file(uv_timer_t* handle, int status) {
+ ++timer_cb_called;
+
+ if (timer_cb_called == 1) {
+ touch_file(handle->loop, "watch_dir/file1");
+ } else {
+ touch_file(handle->loop, "watch_dir/file2");
+ uv_close((uv_handle_t*)handle, close_cb);
+ }
+}
+
+static void timer_cb_touch(uv_timer_t* timer, int status) {
+ ASSERT(status == 0);
+ uv_close((uv_handle_t*)timer, NULL);
+ touch_file(timer->loop, "watch_file");
+ timer_cb_touch_called++;
+}
+
+static void timer_cb_watch_twice(uv_timer_t* handle, int status) {
+ uv_fs_event_t* handles = handle->data;
+ uv_close((uv_handle_t*) (handles + 0), NULL);
+ uv_close((uv_handle_t*) (handles + 1), NULL);
+ uv_close((uv_handle_t*) handle, NULL);
+}
+
+TEST_IMPL(fs_event_watch_dir) {
+ uv_loop_t* loop = uv_default_loop();
+ int r;
+
+ /* Setup */
+ fs_event_unlink_files(NULL, 0);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ create_dir(loop, "watch_dir");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file, "watch_dir", 0);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, fs_event_create_files, 100, 0);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(fs_event_cb_called == 2 * fs_event_file_count);
+ ASSERT(fs_event_created == fs_event_file_count);
+ ASSERT(close_cb_called == 2);
+
+ /* Cleanup */
+ fs_event_unlink_files(NULL, 0);
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_event_watch_file) {
+ uv_loop_t* loop = uv_default_loop();
+ int r;
+
+ /* Setup */
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ create_dir(loop, "watch_dir");
+ create_file(loop, "watch_dir/file1");
+ create_file(loop, "watch_dir/file2");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_file, "watch_dir/file2", 0);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, timer_cb_file, 100, 100);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(fs_event_cb_called == 1);
+ ASSERT(timer_cb_called == 2);
+ ASSERT(close_cb_called == 2);
+
+ /* Cleanup */
+ remove("watch_dir/file2");
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_event_watch_file_twice) {
+ const char path[] = "test/fixtures/empty_file";
+ uv_fs_event_t watchers[2];
+ uv_timer_t timer;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ timer.data = watchers;
+
+ ASSERT(0 == uv_fs_event_init(loop, watchers + 0));
+ ASSERT(0 == uv_fs_event_start(watchers + 0, fail_cb, path, 0));
+ ASSERT(0 == uv_fs_event_init(loop, watchers + 1));
+ ASSERT(0 == uv_fs_event_start(watchers + 1, fail_cb, path, 0));
+ ASSERT(0 == uv_timer_init(loop, &timer));
+ ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_event_watch_file_current_dir) {
+ uv_timer_t timer;
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ /* Setup */
+ remove("watch_file");
+ create_file(loop, "watch_file");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event,
+ fs_event_cb_file_current_dir,
+ "watch_file",
+ 0);
+ ASSERT(r == 0);
+
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb_touch, 1, 0);
+ ASSERT(r == 0);
+
+ ASSERT(timer_cb_touch_called == 0);
+ ASSERT(fs_event_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(timer_cb_touch_called == 1);
+ ASSERT(fs_event_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ /* Cleanup */
+ remove("watch_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_event_no_callback_after_close) {
+ uv_loop_t* loop = uv_default_loop();
+ int r;
+
+ /* Setup */
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ create_dir(loop, "watch_dir");
+ create_file(loop, "watch_dir/file1");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event,
+ fs_event_cb_file,
+ "watch_dir/file1",
+ 0);
+ ASSERT(r == 0);
+
+
+ uv_close((uv_handle_t*)&fs_event, close_cb);
+ touch_file(loop, "watch_dir/file1");
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(fs_event_cb_called == 0);
+ ASSERT(close_cb_called == 1);
+
+ /* Cleanup */
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_event_no_callback_on_close) {
+ uv_loop_t* loop = uv_default_loop();
+ int r;
+
+ /* Setup */
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+ create_dir(loop, "watch_dir");
+ create_file(loop, "watch_dir/file1");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event,
+ fs_event_cb_file,
+ "watch_dir/file1",
+ 0);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)&fs_event, close_cb);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(fs_event_cb_called == 0);
+ ASSERT(close_cb_called == 1);
+
+ /* Cleanup */
+ remove("watch_dir/file1");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void fs_event_fail(uv_fs_event_t* handle, const char* filename,
+ int events, int status) {
+ ASSERT(0 && "should never be called");
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ int r;
+
+ ASSERT(status == 0);
+
+ r = uv_fs_event_init(handle->loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_fail, ".", 0);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)&fs_event, close_cb);
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+
+TEST_IMPL(fs_event_immediate_close) {
+ uv_timer_t timer;
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 1, 0);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_event_close_with_pending_event) {
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ create_dir(loop, "watch_dir");
+ create_file(loop, "watch_dir/file");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_fail, "watch_dir", 0);
+ ASSERT(r == 0);
+
+ /* Generate an fs event. */
+ touch_file(loop, "watch_dir/file");
+
+ uv_close((uv_handle_t*)&fs_event, close_cb);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ /* Clean up */
+ remove("watch_dir/file");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#if defined(HAVE_KQUEUE)
+
+/* kqueue doesn't register fs events if you don't have an active watcher.
+ * The file descriptor needs to be part of the kqueue set of interest and
+ * that's not the case until we actually enter the event loop.
+ */
+TEST_IMPL(fs_event_close_in_callback) {
+ fprintf(stderr, "Skipping test, doesn't work with kqueue.\n");
+ return 0;
+}
+
+#else /* !HAVE_KQUEUE */
+
+static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
+ int events, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(fs_event_cb_called < 3);
+ ++fs_event_cb_called;
+
+ if (fs_event_cb_called == 3) {
+ uv_close((uv_handle_t*) handle, close_cb);
+ }
+}
+
+
+TEST_IMPL(fs_event_close_in_callback) {
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ create_dir(loop, "watch_dir");
+ create_file(loop, "watch_dir/file1");
+ create_file(loop, "watch_dir/file2");
+ create_file(loop, "watch_dir/file3");
+ create_file(loop, "watch_dir/file4");
+ create_file(loop, "watch_dir/file5");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_close, "watch_dir", 0);
+ ASSERT(r == 0);
+
+ /* Generate a couple of fs events. */
+ touch_file(loop, "watch_dir/file1");
+ touch_file(loop, "watch_dir/file2");
+ touch_file(loop, "watch_dir/file3");
+ touch_file(loop, "watch_dir/file4");
+ touch_file(loop, "watch_dir/file5");
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+ ASSERT(fs_event_cb_called == 3);
+
+ /* Clean up */
+ remove("watch_dir/file1");
+ remove("watch_dir/file2");
+ remove("watch_dir/file3");
+ remove("watch_dir/file4");
+ remove("watch_dir/file5");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* HAVE_KQUEUE */
+
+TEST_IMPL(fs_event_start_and_close) {
+ uv_loop_t* loop;
+ uv_fs_event_t fs_event1;
+ uv_fs_event_t fs_event2;
+ int r;
+
+ loop = uv_default_loop();
+
+ create_dir(loop, "watch_dir");
+
+ r = uv_fs_event_init(loop, &fs_event1);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event1, fs_event_cb_dir, "watch_dir", 0);
+ ASSERT(r == 0);
+
+ r = uv_fs_event_init(loop, &fs_event2);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event2, fs_event_cb_dir, "watch_dir", 0);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) &fs_event2, close_cb);
+ uv_close((uv_handle_t*) &fs_event1, close_cb);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 2);
+
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#if defined(__APPLE__)
+
+static int fs_event_error_reported;
+
+static void fs_event_error_report_cb(uv_fs_event_t* handle,
+ const char* filename,
+ int events,
+ int status) {
+ if (status != 0)
+ fs_event_error_reported = status;
+}
+
+static void timer_cb_nop(uv_timer_t* handle, int status) {
+ ++timer_cb_called;
+ uv_close((uv_handle_t*) handle, close_cb);
+}
+
+static void fs_event_error_report_close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+
+ /* handle is allocated on-stack, no need to free it */
+}
+
+
+TEST_IMPL(fs_event_error_reporting) {
+ unsigned int i;
+ uv_loop_t* loops[1024];
+ uv_fs_event_t events[ARRAY_SIZE(loops)];
+ uv_loop_t* loop;
+ uv_fs_event_t* event;
+
+ TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3);
+
+ remove("watch_dir/");
+ create_dir(uv_default_loop(), "watch_dir");
+
+ /* Create a lot of loops, and start FSEventStream in each of them.
+ * Eventually, this should create enough streams to make FSEventStreamStart()
+ * fail.
+ */
+ for (i = 0; i < ARRAY_SIZE(loops); i++) {
+ loop = uv_loop_new();
+ event = &events[i];
+ ASSERT(loop != NULL);
+
+ loops[i] = loop;
+ timer_cb_called = 0;
+ close_cb_called = 0;
+ ASSERT(0 == uv_fs_event_init(loop, event));
+ ASSERT(0 == uv_fs_event_start(event,
+ fs_event_error_report_cb,
+ "watch_dir",
+ 0));
+ uv_unref((uv_handle_t*) event);
+
+ /* Let loop run for some time */
+ ASSERT(0 == uv_timer_init(loop, &timer));
+ ASSERT(0 == uv_timer_start(&timer, timer_cb_nop, 2, 0));
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(1 == timer_cb_called);
+ ASSERT(1 == close_cb_called);
+ if (fs_event_error_reported != 0)
+ break;
+ }
+
+ /* At least one loop should fail */
+ ASSERT(fs_event_error_reported == UV_EMFILE);
+
+ /* Stop and close all events, and destroy loops */
+ do {
+ loop = loops[i];
+ event = &events[i];
+
+ ASSERT(0 == uv_fs_event_stop(event));
+ uv_ref((uv_handle_t*) event);
+ uv_close((uv_handle_t*) event, fs_event_error_report_close_cb);
+
+ close_cb_called = 0;
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(close_cb_called == 1);
+
+ uv_loop_delete(loop);
+
+ loops[i] = NULL;
+ } while (i-- != 0);
+
+ remove("watch_dir/");
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#else /* !defined(__APPLE__) */
+
+TEST_IMPL(fs_event_error_reporting) {
+ /* No-op, needed only for FSEvents backend */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* defined(__APPLE__) */
diff --git a/third-party/libuv/test/test-fs-poll.c b/third-party/libuv/test/test-fs-poll.c
new file mode 100644
index 0000000000..9213f04b34
--- /dev/null
+++ b/third-party/libuv/test/test-fs-poll.c
@@ -0,0 +1,146 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+
+#define FIXTURE "testfile"
+
+static void timer_cb(uv_timer_t* handle, int status);
+static void close_cb(uv_handle_t* handle);
+static void poll_cb(uv_fs_poll_t* handle,
+ int status,
+ const uv_stat_t* prev,
+ const uv_stat_t* curr);
+
+static uv_fs_poll_t poll_handle;
+static uv_timer_t timer_handle;
+static uv_loop_t* loop;
+
+static int poll_cb_called;
+static int timer_cb_called;
+static int close_cb_called;
+
+
+static void touch_file(const char* path) {
+ static int count;
+ FILE* fp;
+ int i;
+
+ ASSERT((fp = fopen(FIXTURE, "w+")));
+
+ /* Need to change the file size because the poller may not pick up
+ * sub-second mtime changes.
+ */
+ i = ++count;
+
+ while (i--)
+ fputc('*', fp);
+
+ fclose(fp);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ touch_file(FIXTURE);
+ timer_cb_called++;
+}
+
+
+static void poll_cb(uv_fs_poll_t* handle,
+ int status,
+ const uv_stat_t* prev,
+ const uv_stat_t* curr) {
+ uv_stat_t zero_statbuf;
+
+ memset(&zero_statbuf, 0, sizeof(zero_statbuf));
+
+ ASSERT(handle == &poll_handle);
+ ASSERT(1 == uv_is_active((uv_handle_t*) handle));
+ ASSERT(prev != NULL);
+ ASSERT(curr != NULL);
+
+ switch (poll_cb_called++) {
+ case 0:
+ ASSERT(status == UV_ENOENT);
+ ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
+ touch_file(FIXTURE);
+ break;
+
+ case 1:
+ ASSERT(status == 0);
+ ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 20, 0));
+ break;
+
+ case 2:
+ ASSERT(status == 0);
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 200, 0));
+ break;
+
+ case 3:
+ ASSERT(status == 0);
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
+ remove(FIXTURE);
+ break;
+
+ case 4:
+ ASSERT(status == UV_ENOENT);
+ ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf)));
+ ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf)));
+ uv_close((uv_handle_t*)handle, close_cb);
+ break;
+
+ default:
+ ASSERT(0);
+ }
+}
+
+
+TEST_IMPL(fs_poll) {
+ loop = uv_default_loop();
+
+ remove(FIXTURE);
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
+ ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ ASSERT(poll_cb_called == 5);
+ ASSERT(timer_cb_called == 2);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-fs.c b/third-party/libuv/test/test-fs.c
new file mode 100644
index 0000000000..f0ff824f40
--- /dev/null
+++ b/third-party/libuv/test/test-fs.c
@@ -0,0 +1,1955 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <string.h> /* memset */
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* FIXME we shouldn't need to branch in this file */
+#if defined(__unix__) || defined(__POSIX__) || \
+ defined(__APPLE__) || defined(_AIX)
+#include <unistd.h> /* unlink, rmdir, etc. */
+#else
+# include <direct.h>
+# include <io.h>
+# define unlink _unlink
+# define rmdir _rmdir
+# define stat _stati64
+# define open _open
+# define write _write
+# define lseek _lseek
+# define close _close
+#endif
+
+#define TOO_LONG_NAME_LENGTH 65536
+#define PATHMAX 1024
+
+typedef struct {
+ const char* path;
+ double atime;
+ double mtime;
+} utime_check_t;
+
+
+static int dummy_cb_count;
+static int close_cb_count;
+static int create_cb_count;
+static int open_cb_count;
+static int read_cb_count;
+static int write_cb_count;
+static int unlink_cb_count;
+static int mkdir_cb_count;
+static int rmdir_cb_count;
+static int readdir_cb_count;
+static int stat_cb_count;
+static int rename_cb_count;
+static int fsync_cb_count;
+static int fdatasync_cb_count;
+static int ftruncate_cb_count;
+static int sendfile_cb_count;
+static int fstat_cb_count;
+static int chmod_cb_count;
+static int fchmod_cb_count;
+static int chown_cb_count;
+static int fchown_cb_count;
+static int link_cb_count;
+static int symlink_cb_count;
+static int readlink_cb_count;
+static int utime_cb_count;
+static int futime_cb_count;
+
+static uv_loop_t* loop;
+
+static uv_fs_t open_req1;
+static uv_fs_t open_req2;
+static uv_fs_t read_req;
+static uv_fs_t write_req;
+static uv_fs_t unlink_req;
+static uv_fs_t close_req;
+static uv_fs_t mkdir_req;
+static uv_fs_t rmdir_req;
+static uv_fs_t readdir_req;
+static uv_fs_t stat_req;
+static uv_fs_t rename_req;
+static uv_fs_t fsync_req;
+static uv_fs_t fdatasync_req;
+static uv_fs_t ftruncate_req;
+static uv_fs_t sendfile_req;
+static uv_fs_t utime_req;
+static uv_fs_t futime_req;
+
+static char buf[32];
+static char test_buf[] = "test-buffer\n";
+
+
+static void check_permission(const char* filename, unsigned int mode) {
+ int r;
+ uv_fs_t req;
+ uv_stat_t* s;
+
+ r = uv_fs_stat(uv_default_loop(), &req, filename, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+
+ s = &req.statbuf;
+#ifdef _WIN32
+ /*
+ * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit,
+ * so only testing for the specified flags.
+ */
+ ASSERT((s->st_mode & 0777) & mode);
+#else
+ ASSERT((s->st_mode & 0777) == mode);
+#endif
+
+ uv_fs_req_cleanup(&req);
+}
+
+
+static void dummy_cb(uv_fs_t* req) {
+ (void) req;
+ dummy_cb_count++;
+}
+
+
+static void link_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_LINK);
+ ASSERT(req->result == 0);
+ link_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+
+static void symlink_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_SYMLINK);
+ ASSERT(req->result == 0);
+ symlink_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void readlink_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_READLINK);
+ ASSERT(req->result == 0);
+ ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0);
+ readlink_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void fchmod_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_FCHMOD);
+ ASSERT(req->result == 0);
+ fchmod_cb_count++;
+ uv_fs_req_cleanup(req);
+ check_permission("test_file", *(int*)req->data);
+}
+
+
+static void chmod_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_CHMOD);
+ ASSERT(req->result == 0);
+ chmod_cb_count++;
+ uv_fs_req_cleanup(req);
+ check_permission("test_file", *(int*)req->data);
+}
+
+
+static void fchown_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_FCHOWN);
+ ASSERT(req->result == 0);
+ fchown_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+
+static void chown_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_CHOWN);
+ ASSERT(req->result == 0);
+ chown_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void chown_root_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_CHOWN);
+#ifdef _WIN32
+ /* On windows, chown is a no-op and always succeeds. */
+ ASSERT(req->result == 0);
+#else
+ /* On unix, chown'ing the root directory is not allowed -
+ * unless you're root, of course.
+ */
+ if (geteuid() == 0)
+ ASSERT(req->result == 0);
+ else
+ ASSERT(req->result == UV_EPERM);
+#endif
+ chown_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void unlink_cb(uv_fs_t* req) {
+ ASSERT(req == &unlink_req);
+ ASSERT(req->fs_type == UV_FS_UNLINK);
+ ASSERT(req->result == 0);
+ unlink_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void fstat_cb(uv_fs_t* req) {
+ uv_stat_t* s = req->ptr;
+ ASSERT(req->fs_type == UV_FS_FSTAT);
+ ASSERT(req->result == 0);
+ ASSERT(s->st_size == sizeof(test_buf));
+ uv_fs_req_cleanup(req);
+ fstat_cb_count++;
+}
+
+
+static void close_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &close_req);
+ ASSERT(req->fs_type == UV_FS_CLOSE);
+ ASSERT(req->result == 0);
+ close_cb_count++;
+ uv_fs_req_cleanup(req);
+ if (close_cb_count == 3) {
+ r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb);
+ ASSERT(r == 0);
+ }
+}
+
+
+static void ftruncate_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &ftruncate_req);
+ ASSERT(req->fs_type == UV_FS_FTRUNCATE);
+ ASSERT(req->result == 0);
+ ftruncate_cb_count++;
+ uv_fs_req_cleanup(req);
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
+ ASSERT(r == 0);
+}
+
+
+static void read_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &read_req);
+ ASSERT(req->fs_type == UV_FS_READ);
+ ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */
+ read_cb_count++;
+ uv_fs_req_cleanup(req);
+ if (read_cb_count == 1) {
+ ASSERT(strcmp(buf, test_buf) == 0);
+ r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7,
+ ftruncate_cb);
+ } else {
+ ASSERT(strcmp(buf, "test-bu") == 0);
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
+ }
+ ASSERT(r == 0);
+}
+
+
+static void open_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &open_req1);
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ if (req->result < 0) {
+ fprintf(stderr, "async open error: %d\n", (int) req->result);
+ ASSERT(0);
+ }
+ open_cb_count++;
+ ASSERT(req->path);
+ ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
+ uv_fs_req_cleanup(req);
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ read_cb);
+ ASSERT(r == 0);
+}
+
+
+static void open_cb_simple(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ if (req->result < 0) {
+ fprintf(stderr, "async open error: %d\n", (int) req->result);
+ ASSERT(0);
+ }
+ open_cb_count++;
+ ASSERT(req->path);
+ uv_fs_req_cleanup(req);
+}
+
+
+static void fsync_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &fsync_req);
+ ASSERT(req->fs_type == UV_FS_FSYNC);
+ ASSERT(req->result == 0);
+ fsync_cb_count++;
+ uv_fs_req_cleanup(req);
+ r = uv_fs_close(loop, &close_req, open_req1.result, close_cb);
+ ASSERT(r == 0);
+}
+
+
+static void fdatasync_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &fdatasync_req);
+ ASSERT(req->fs_type == UV_FS_FDATASYNC);
+ ASSERT(req->result == 0);
+ fdatasync_cb_count++;
+ uv_fs_req_cleanup(req);
+ r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb);
+ ASSERT(r == 0);
+}
+
+
+static void write_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &write_req);
+ ASSERT(req->fs_type == UV_FS_WRITE);
+ ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */
+ write_cb_count++;
+ uv_fs_req_cleanup(req);
+ r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb);
+ ASSERT(r == 0);
+}
+
+
+static void create_cb(uv_fs_t* req) {
+ int r;
+ ASSERT(req == &open_req1);
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ ASSERT(req->result >= 0);
+ create_cb_count++;
+ uv_fs_req_cleanup(req);
+ r = uv_fs_write(loop, &write_req, req->result, test_buf, sizeof(test_buf),
+ -1, write_cb);
+ ASSERT(r == 0);
+}
+
+
+static void rename_cb(uv_fs_t* req) {
+ ASSERT(req == &rename_req);
+ ASSERT(req->fs_type == UV_FS_RENAME);
+ ASSERT(req->result == 0);
+ rename_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+
+static void mkdir_cb(uv_fs_t* req) {
+ ASSERT(req == &mkdir_req);
+ ASSERT(req->fs_type == UV_FS_MKDIR);
+ ASSERT(req->result == 0);
+ mkdir_cb_count++;
+ ASSERT(req->path);
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
+ uv_fs_req_cleanup(req);
+}
+
+
+static void rmdir_cb(uv_fs_t* req) {
+ ASSERT(req == &rmdir_req);
+ ASSERT(req->fs_type == UV_FS_RMDIR);
+ ASSERT(req->result == 0);
+ rmdir_cb_count++;
+ ASSERT(req->path);
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
+ uv_fs_req_cleanup(req);
+}
+
+
+static void readdir_cb(uv_fs_t* req) {
+ ASSERT(req == &readdir_req);
+ ASSERT(req->fs_type == UV_FS_READDIR);
+ ASSERT(req->result == 2);
+ ASSERT(req->ptr);
+ ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
+ || memcmp(req->ptr, "file2\0file1\0", 12) == 0);
+ readdir_cb_count++;
+ ASSERT(req->path);
+ ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
+ uv_fs_req_cleanup(req);
+ ASSERT(!req->ptr);
+}
+
+
+static void empty_readdir_cb(uv_fs_t* req) {
+ ASSERT(req == &readdir_req);
+ ASSERT(req->fs_type == UV_FS_READDIR);
+ ASSERT(req->result == 0);
+ ASSERT(req->ptr == NULL);
+ uv_fs_req_cleanup(req);
+ readdir_cb_count++;
+}
+
+
+static void file_readdir_cb(uv_fs_t* req) {
+ ASSERT(req == &readdir_req);
+ ASSERT(req->fs_type == UV_FS_READDIR);
+ ASSERT(req->result == UV_ENOTDIR);
+ ASSERT(req->ptr == NULL);
+ uv_fs_req_cleanup(req);
+ readdir_cb_count++;
+}
+
+
+static void stat_cb(uv_fs_t* req) {
+ ASSERT(req == &stat_req);
+ ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT);
+ ASSERT(req->result == 0);
+ ASSERT(req->ptr);
+ stat_cb_count++;
+ uv_fs_req_cleanup(req);
+ ASSERT(!req->ptr);
+}
+
+
+static void sendfile_cb(uv_fs_t* req) {
+ ASSERT(req == &sendfile_req);
+ ASSERT(req->fs_type == UV_FS_SENDFILE);
+ ASSERT(req->result == 65546);
+ sendfile_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+
+static void open_noent_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ ASSERT(req->result == UV_ENOENT);
+ open_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void open_nametoolong_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ ASSERT(req->result == UV_ENAMETOOLONG);
+ open_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+static void open_loop_cb(uv_fs_t* req) {
+ ASSERT(req->fs_type == UV_FS_OPEN);
+ ASSERT(req->result == UV_ELOOP);
+ open_cb_count++;
+ uv_fs_req_cleanup(req);
+}
+
+
+TEST_IMPL(fs_file_noent) {
+ uv_fs_t req;
+ int r;
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, NULL);
+ ASSERT(r == UV_ENOENT);
+ ASSERT(req.result == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, open_noent_cb);
+ ASSERT(r == 0);
+
+ ASSERT(open_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 1);
+
+ /* TODO add EACCES test */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_file_nametoolong) {
+ uv_fs_t req;
+ int r;
+ char name[TOO_LONG_NAME_LENGTH + 1];
+
+ loop = uv_default_loop();
+
+ memset(name, 'a', TOO_LONG_NAME_LENGTH);
+ name[TOO_LONG_NAME_LENGTH] = 0;
+
+ r = uv_fs_open(loop, &req, name, O_RDONLY, 0, NULL);
+ ASSERT(r == UV_ENAMETOOLONG);
+ ASSERT(req.result == UV_ENAMETOOLONG);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb);
+ ASSERT(r == 0);
+
+ ASSERT(open_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(fs_file_loop) {
+ uv_fs_t req;
+ int r;
+
+ loop = uv_default_loop();
+
+ unlink("test_symlink");
+ uv_fs_symlink(loop, &req, "test_symlink", "test_symlink", 0, NULL);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, NULL);
+ ASSERT(r == UV_ELOOP);
+ ASSERT(req.result == UV_ELOOP);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb);
+ ASSERT(r == 0);
+
+ ASSERT(open_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 1);
+
+ unlink("test_symlink");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+static void check_utime(const char* path, double atime, double mtime) {
+ uv_stat_t* s;
+ uv_fs_t req;
+ int r;
+
+ r = uv_fs_stat(loop, &req, path, NULL);
+ ASSERT(r == 0);
+
+ ASSERT(req.result == 0);
+ s = &req.statbuf;
+
+ ASSERT(s->st_atim.tv_sec == atime);
+ ASSERT(s->st_mtim.tv_sec == mtime);
+
+ uv_fs_req_cleanup(&req);
+}
+
+
+static void utime_cb(uv_fs_t* req) {
+ utime_check_t* c;
+
+ ASSERT(req == &utime_req);
+ ASSERT(req->result == 0);
+ ASSERT(req->fs_type == UV_FS_UTIME);
+
+ c = req->data;
+ check_utime(c->path, c->atime, c->mtime);
+
+ uv_fs_req_cleanup(req);
+ utime_cb_count++;
+}
+
+
+static void futime_cb(uv_fs_t* req) {
+ utime_check_t* c;
+
+ ASSERT(req == &futime_req);
+ ASSERT(req->result == 0);
+ ASSERT(req->fs_type == UV_FS_FUTIME);
+
+ c = req->data;
+ check_utime(c->path, c->atime, c->mtime);
+
+ uv_fs_req_cleanup(req);
+ futime_cb_count++;
+}
+
+
+TEST_IMPL(fs_file_async) {
+ int r;
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+ S_IRUSR | S_IWUSR, create_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(create_cb_count == 1);
+ ASSERT(write_cb_count == 1);
+ ASSERT(fsync_cb_count == 1);
+ ASSERT(fdatasync_cb_count == 1);
+ ASSERT(close_cb_count == 1);
+
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(create_cb_count == 1);
+ ASSERT(write_cb_count == 1);
+ ASSERT(close_cb_count == 1);
+ ASSERT(rename_cb_count == 1);
+
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 1);
+ ASSERT(read_cb_count == 1);
+ ASSERT(close_cb_count == 2);
+ ASSERT(rename_cb_count == 1);
+ ASSERT(create_cb_count == 1);
+ ASSERT(write_cb_count == 1);
+ ASSERT(ftruncate_cb_count == 1);
+
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 2);
+ ASSERT(read_cb_count == 2);
+ ASSERT(close_cb_count == 3);
+ ASSERT(rename_cb_count == 1);
+ ASSERT(unlink_cb_count == 1);
+ ASSERT(create_cb_count == 1);
+ ASSERT(write_cb_count == 1);
+ ASSERT(ftruncate_cb_count == 1);
+
+ /* Cleanup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_file_sync) {
+ int r;
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+ sizeof(test_buf), -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(write_req.result >= 0);
+ uv_fs_req_cleanup(&write_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(read_req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, NULL);
+ ASSERT(r == 0);
+ ASSERT(ftruncate_req.result == 0);
+ uv_fs_req_cleanup(&ftruncate_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", NULL);
+ ASSERT(r == 0);
+ ASSERT(rename_req.result == 0);
+ uv_fs_req_cleanup(&rename_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(read_req.result >= 0);
+ ASSERT(strcmp(buf, "test-bu") == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_unlink(loop, &unlink_req, "test_file2", NULL);
+ ASSERT(r == 0);
+ ASSERT(unlink_req.result == 0);
+ uv_fs_req_cleanup(&unlink_req);
+
+ /* Cleanup */
+ unlink("test_file");
+ unlink("test_file2");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_async_dir) {
+ int r;
+
+ /* Setup */
+ unlink("test_dir/file1");
+ unlink("test_dir/file2");
+ rmdir("test_dir");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(mkdir_cb_count == 1);
+
+ /* Create 2 files synchronously. */
+ r = uv_fs_open(loop, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&open_req1);
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&open_req1);
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, readdir_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(readdir_cb_count == 1);
+
+ /* sync uv_fs_readdir */
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
+ ASSERT(r == 2);
+ ASSERT(readdir_req.result == 2);
+ ASSERT(readdir_req.ptr);
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ uv_fs_req_cleanup(&readdir_req);
+ ASSERT(!readdir_req.ptr);
+
+ r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(stat_cb_count == 4);
+
+ r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(unlink_cb_count == 1);
+
+ r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(unlink_cb_count == 2);
+
+ r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(rmdir_cb_count == 1);
+
+ /* Cleanup */
+ unlink("test_dir/file1");
+ unlink("test_dir/file2");
+ rmdir("test_dir");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_async_sendfile) {
+ int f, r;
+ struct stat s1, s2;
+
+ loop = uv_default_loop();
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ f = open("test_file", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
+ ASSERT(f != -1);
+
+ r = write(f, "begin\n", 6);
+ ASSERT(r == 6);
+
+ r = lseek(f, 65536, SEEK_CUR);
+ ASSERT(r == 65542);
+
+ r = write(f, "end\n", 4);
+ ASSERT(r != -1);
+
+ r = close(f);
+ ASSERT(r == 0);
+
+ /* Test starts here. */
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_open(loop, &open_req2, "test_file2", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req2.result >= 0);
+ uv_fs_req_cleanup(&open_req2);
+
+ r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
+ 0, 131072, sendfile_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(sendfile_cb_count == 1);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+ r = uv_fs_close(loop, &close_req, open_req2.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ stat("test_file", &s1);
+ stat("test_file2", &s2);
+ ASSERT(65546 == s2.st_size && s1.st_size == s2.st_size);
+
+ /* Cleanup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_fstat) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+ uv_stat_t* s;
+#ifndef _WIN32
+ struct stat t;
+#endif
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_fstat(loop, &req, file, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ s = req.ptr;
+ ASSERT(s->st_size == sizeof(test_buf));
+
+#ifndef _WIN32
+ r = fstat(file, &t);
+ ASSERT(r == 0);
+
+ ASSERT(s->st_dev == (uint64_t) t.st_dev);
+ ASSERT(s->st_mode == (uint64_t) t.st_mode);
+ ASSERT(s->st_nlink == (uint64_t) t.st_nlink);
+ ASSERT(s->st_uid == (uint64_t) t.st_uid);
+ ASSERT(s->st_gid == (uint64_t) t.st_gid);
+ ASSERT(s->st_rdev == (uint64_t) t.st_rdev);
+ ASSERT(s->st_ino == (uint64_t) t.st_ino);
+ ASSERT(s->st_size == (uint64_t) t.st_size);
+ ASSERT(s->st_blksize == (uint64_t) t.st_blksize);
+ ASSERT(s->st_blocks == (uint64_t) t.st_blocks);
+#if defined(__APPLE__)
+ ASSERT(s->st_atim.tv_sec == t.st_atimespec.tv_sec);
+ ASSERT(s->st_atim.tv_nsec == t.st_atimespec.tv_nsec);
+ ASSERT(s->st_mtim.tv_sec == t.st_mtimespec.tv_sec);
+ ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec);
+ ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec);
+ ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec);
+ ASSERT(s->st_birthtim.tv_sec == t.st_birthtimespec.tv_sec);
+ ASSERT(s->st_birthtim.tv_nsec == t.st_birthtimespec.tv_nsec);
+ ASSERT(s->st_flags == t.st_flags);
+ ASSERT(s->st_gen == t.st_gen);
+#elif defined(__sun) || \
+ defined(_BSD_SOURCE) || \
+ defined(_SVID_SOURCE) || \
+ defined(_XOPEN_SOURCE)
+ ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec);
+ ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec);
+ ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec);
+ ASSERT(s->st_mtim.tv_nsec == t.st_mtim.tv_nsec);
+ ASSERT(s->st_ctim.tv_sec == t.st_ctim.tv_sec);
+ ASSERT(s->st_ctim.tv_nsec == t.st_ctim.tv_nsec);
+# if defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+ ASSERT(s->st_birthtim.tv_sec == t.st_birthtim.tv_sec);
+ ASSERT(s->st_birthtim.tv_nsec == t.st_birthtim.tv_nsec);
+ ASSERT(s->st_flags == t.st_flags);
+ ASSERT(s->st_gen == t.st_gen);
+# endif
+#else
+ ASSERT(s->st_atim.tv_sec == t.st_atime);
+ ASSERT(s->st_atim.tv_nsec == 0);
+ ASSERT(s->st_mtim.tv_sec == t.st_mtime);
+ ASSERT(s->st_mtim.tv_nsec == 0);
+ ASSERT(s->st_ctim.tv_sec == t.st_ctime);
+ ASSERT(s->st_ctim.tv_nsec == 0);
+#endif
+#endif
+
+ uv_fs_req_cleanup(&req);
+
+ /* Now do the uv_fs_fstat call asynchronously */
+ r = uv_fs_fstat(loop, &req, file, fstat_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(fstat_cb_count == 1);
+
+
+ r = uv_fs_close(loop, &req, file, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_chmod) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+#ifndef _WIN32
+ /* Make the file write-only */
+ r = uv_fs_chmod(loop, &req, "test_file", 0200, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ check_permission("test_file", 0200);
+#endif
+
+ /* Make the file read-only */
+ r = uv_fs_chmod(loop, &req, "test_file", 0400, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ check_permission("test_file", 0400);
+
+ /* Make the file read+write with sync uv_fs_fchmod */
+ r = uv_fs_fchmod(loop, &req, file, 0600, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ check_permission("test_file", 0600);
+
+#ifndef _WIN32
+ /* async chmod */
+ {
+ static int mode = 0200;
+ req.data = &mode;
+ }
+ r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(chmod_cb_count == 1);
+ chmod_cb_count = 0; /* reset for the next test */
+#endif
+
+ /* async chmod */
+ {
+ static int mode = 0400;
+ req.data = &mode;
+ }
+ r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(chmod_cb_count == 1);
+
+ /* async fchmod */
+ {
+ static int mode = 0600;
+ req.data = &mode;
+ }
+ r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(fchmod_cb_count == 1);
+
+ close(file);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_chown) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ /* sync chown */
+ r = uv_fs_chown(loop, &req, "test_file", -1, -1, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ /* sync fchown */
+ r = uv_fs_fchown(loop, &req, file, -1, -1, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ /* async chown */
+ r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(chown_cb_count == 1);
+
+ /* chown to root (fail) */
+ chown_cb_count = 0;
+ r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(chown_cb_count == 1);
+
+ /* async fchown */
+ r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(fchown_cb_count == 1);
+
+ close(file);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_link) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+ uv_file link;
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file_link");
+ unlink("test_file_link2");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ close(file);
+
+ /* sync link */
+ r = uv_fs_link(loop, &req, "test_file", "test_file_link", NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, "test_file_link", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ link = req.result;
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+
+ close(link);
+
+ /* async link */
+ r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(link_cb_count == 1);
+
+ r = uv_fs_open(loop, &req, "test_file_link2", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ link = req.result;
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+
+ close(link);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ unlink("test_file");
+ unlink("test_file_link");
+ unlink("test_file_link2");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_readlink) {
+ uv_fs_t req;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(dummy_cb_count == 1);
+ ASSERT(req.ptr == NULL);
+ ASSERT(req.result == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ ASSERT(UV_ENOENT == uv_fs_readlink(loop, &req, "no_such_file", NULL));
+ ASSERT(req.ptr == NULL);
+ ASSERT(req.result == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_symlink) {
+ int r;
+ uv_fs_t req;
+ uv_file file;
+ uv_file link;
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file_symlink");
+ unlink("test_file_symlink2");
+ unlink("test_file_symlink_symlink");
+ unlink("test_file_symlink2_symlink");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ close(file);
+
+ /* sync symlink */
+ r = uv_fs_symlink(loop, &req, "test_file", "test_file_symlink", 0, NULL);
+#ifdef _WIN32
+ if (r < 0) {
+ if (r == UV_ENOTSUP) {
+ /*
+ * Windows doesn't support symlinks on older versions.
+ * We just pass the test and bail out early if we get ENOTSUP.
+ */
+ return 0;
+ } else if (r == UV_EPERM) {
+ /*
+ * Creating a symlink is only allowed when running elevated.
+ * We pass the test and bail out early if we get UV_EPERM.
+ */
+ return 0;
+ }
+ }
+#endif
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &req, "test_file_symlink", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ link = req.result;
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+
+ close(link);
+
+ r = uv_fs_symlink(loop,
+ &req,
+ "test_file_symlink",
+ "test_file_symlink_symlink",
+ 0,
+ NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readlink(loop, &req, "test_file_symlink_symlink", NULL);
+ ASSERT(r == 0);
+ ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
+ uv_fs_req_cleanup(&req);
+
+ /* async link */
+ r = uv_fs_symlink(loop,
+ &req,
+ "test_file",
+ "test_file_symlink2",
+ 0,
+ symlink_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(symlink_cb_count == 1);
+
+ r = uv_fs_open(loop, &req, "test_file_symlink2", O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ link = req.result;
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+
+ close(link);
+
+ r = uv_fs_symlink(loop,
+ &req,
+ "test_file_symlink2",
+ "test_file_symlink2_symlink",
+ 0,
+ NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(readlink_cb_count == 1);
+
+ /*
+ * Run the loop just to check we don't have make any extraneous uv_ref()
+ * calls. This should drop out immediately.
+ */
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ /* Cleanup. */
+ unlink("test_file");
+ unlink("test_file_symlink");
+ unlink("test_file_symlink_symlink");
+ unlink("test_file_symlink2");
+ unlink("test_file_symlink2_symlink");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_symlink_dir) {
+ uv_fs_t req;
+ int r;
+ char* test_dir;
+
+ /* set-up */
+ unlink("test_dir/file1");
+ unlink("test_dir/file2");
+ rmdir("test_dir");
+ rmdir("test_dir_symlink");
+
+ loop = uv_default_loop();
+
+ uv_fs_mkdir(loop, &req, "test_dir", 0777, NULL);
+ uv_fs_req_cleanup(&req);
+
+#ifdef _WIN32
+ {
+ static char src_path_buf[PATHMAX];
+ strcpy(src_path_buf, "\\\\?\\");
+ uv_cwd(src_path_buf + 4, sizeof(src_path_buf));
+ strcat(src_path_buf, "\\test_dir\\");
+ test_dir = src_path_buf;
+ }
+#else
+ test_dir = "test_dir";
+#endif
+
+ r = uv_fs_symlink(loop, &req, test_dir, "test_dir_symlink",
+ UV_FS_SYMLINK_JUNCTION, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_stat(loop, &req, "test_dir_symlink", NULL);
+ ASSERT(r == 0);
+ ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_lstat(loop, &req, "test_dir_symlink", NULL);
+ ASSERT(r == 0);
+ ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK);
+#ifdef _WIN32
+ ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4));
+#else
+ ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir));
+#endif
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readlink(loop, &req, "test_dir_symlink", NULL);
+ ASSERT(r == 0);
+#ifdef _WIN32
+ ASSERT(strcmp(req.ptr, test_dir + 4) == 0);
+#else
+ ASSERT(strcmp(req.ptr, test_dir) == 0);
+#endif
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_open(loop, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&open_req1);
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ uv_fs_req_cleanup(&open_req1);
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
+ ASSERT(r == 2);
+ ASSERT(readdir_req.result == 2);
+ ASSERT(readdir_req.ptr);
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ uv_fs_req_cleanup(&readdir_req);
+ ASSERT(!readdir_req.ptr);
+
+ /* unlink will remove the directory symlink */
+ r = uv_fs_unlink(loop, &req, "test_dir_symlink", NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir_symlink", 0, NULL);
+ ASSERT(r == UV_ENOENT);
+ uv_fs_req_cleanup(&readdir_req);
+
+ r = uv_fs_readdir(loop, &readdir_req, "test_dir", 0, NULL);
+ ASSERT(r == 2);
+ ASSERT(readdir_req.result == 2);
+ ASSERT(readdir_req.ptr);
+ ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
+ || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ uv_fs_req_cleanup(&readdir_req);
+ ASSERT(!readdir_req.ptr);
+
+ /* clean-up */
+ unlink("test_dir/file1");
+ unlink("test_dir/file2");
+ rmdir("test_dir");
+ rmdir("test_dir_symlink");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_utime) {
+ utime_check_t checkme;
+ const char* path = "test_file";
+ double atime;
+ double mtime;
+ uv_fs_t req;
+ int r;
+
+ /* Setup. */
+ loop = uv_default_loop();
+ unlink(path);
+ r = uv_fs_open(loop, &req, path, O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ uv_fs_req_cleanup(&req);
+ close(r);
+
+ atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
+
+ r = uv_fs_utime(loop, &req, path, atime, mtime, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_stat(loop, &req, path, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ check_utime(path, atime, mtime);
+ uv_fs_req_cleanup(&req);
+
+ atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
+ checkme.path = path;
+ checkme.atime = atime;
+ checkme.mtime = mtime;
+
+ /* async utime */
+ utime_req.data = &checkme;
+ r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(utime_cb_count == 1);
+
+ /* Cleanup. */
+ unlink(path);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(fs_stat_root) {
+ int r;
+ uv_loop_t* loop = uv_default_loop();
+
+ r = uv_fs_stat(loop, &stat_req, "\\", NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_stat(loop, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_stat(loop, &stat_req, "..", NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_stat(loop, &stat_req, "..\\", NULL);
+ ASSERT(r == 0);
+
+ /* stats the current directory on c: */
+ r = uv_fs_stat(loop, &stat_req, "c:", NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_stat(loop, &stat_req, "c:\\", NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_stat(loop, &stat_req, "\\\\?\\C:\\", NULL);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
+TEST_IMPL(fs_futime) {
+ utime_check_t checkme;
+ const char* path = "test_file";
+ double atime;
+ double mtime;
+ uv_file file;
+ uv_fs_t req;
+ int r;
+
+ /* Setup. */
+ loop = uv_default_loop();
+ unlink(path);
+ r = uv_fs_open(loop, &req, path, O_RDWR | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ uv_fs_req_cleanup(&req);
+ close(r);
+
+ atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
+
+ r = uv_fs_open(loop, &req, path, O_RDWR, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ file = req.result; /* FIXME probably not how it's supposed to be used */
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_futime(loop, &req, file, atime, mtime, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_stat(loop, &req, path, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ check_utime(path, atime, mtime);
+ uv_fs_req_cleanup(&req);
+
+ atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */
+
+ checkme.atime = atime;
+ checkme.mtime = mtime;
+ checkme.path = path;
+
+ /* async futime */
+ futime_req.data = &checkme;
+ r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb);
+ ASSERT(r == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(futime_cb_count == 1);
+
+ /* Cleanup. */
+ unlink(path);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_stat_missing_path) {
+ uv_fs_t req;
+ int r;
+
+ loop = uv_default_loop();
+
+ r = uv_fs_stat(loop, &req, "non_existent_file", NULL);
+ ASSERT(r == UV_ENOENT);
+ ASSERT(req.result == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_readdir_empty_dir) {
+ const char* path;
+ uv_fs_t req;
+ int r;
+
+ path = "./empty_dir/";
+ loop = uv_default_loop();
+
+ uv_fs_mkdir(loop, &req, path, 0777, NULL);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readdir(loop, &req, path, 0, NULL);
+ ASSERT(r == 0);
+ ASSERT(req.result == 0);
+ ASSERT(req.ptr == NULL);
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, empty_readdir_cb);
+ ASSERT(r == 0);
+
+ ASSERT(readdir_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(readdir_cb_count == 1);
+
+ uv_fs_rmdir(loop, &req, path, NULL);
+ uv_fs_req_cleanup(&req);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_readdir_file) {
+ const char* path;
+ int r;
+
+ path = "test/fixtures/empty_file";
+ loop = uv_default_loop();
+
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, NULL);
+ ASSERT(r == UV_ENOTDIR);
+ uv_fs_req_cleanup(&readdir_req);
+
+ r = uv_fs_readdir(loop, &readdir_req, path, 0, file_readdir_cb);
+ ASSERT(r == 0);
+
+ ASSERT(readdir_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(readdir_cb_count == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_open_dir) {
+ const char* path;
+ uv_fs_t req;
+ int r, file;
+
+ path = ".";
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &req, path, O_RDONLY, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(req.ptr == NULL);
+ file = r;
+ uv_fs_req_cleanup(&req);
+
+ r = uv_fs_close(loop, &req, file, NULL);
+ ASSERT(r == 0);
+
+ r = uv_fs_open(loop, &req, path, O_RDONLY, 0, open_cb_simple);
+ ASSERT(r == 0);
+
+ ASSERT(open_cb_count == 0);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(open_cb_count == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_file_open_append) {
+ int r;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+ sizeof(test_buf), -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(write_req.result >= 0);
+ uv_fs_req_cleanup(&write_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+ sizeof(test_buf), -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(write_req.result >= 0);
+ uv_fs_req_cleanup(&write_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ NULL);
+ printf("read = %d\n", r);
+ ASSERT(r == 26);
+ ASSERT(read_req.result == 26);
+ ASSERT(memcmp(buf,
+ "test-buffer\n\0test-buffer\n\0",
+ sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ /* Cleanup */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_rename_to_existing_file) {
+ int r;
+
+ /* Setup. */
+ unlink("test_file");
+ unlink("test_file2");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+ sizeof(test_buf), -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(write_req.result >= 0);
+ uv_fs_req_cleanup(&write_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", NULL);
+ ASSERT(r == 0);
+ ASSERT(rename_req.result == 0);
+ uv_fs_req_cleanup(&rename_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(read_req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ /* Cleanup */
+ unlink("test_file");
+ unlink("test_file2");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_read_file_eof) {
+ int r;
+
+ /* Setup. */
+ unlink("test_file");
+
+ loop = uv_default_loop();
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+ S_IWUSR | S_IRUSR, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+ sizeof(test_buf), -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(write_req.result >= 0);
+ uv_fs_req_cleanup(&write_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, 0, NULL);
+ ASSERT(r >= 0);
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ memset(buf, 0, sizeof(buf));
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+ NULL);
+ ASSERT(r >= 0);
+ ASSERT(read_req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf),
+ read_req.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(read_req.result == 0);
+ uv_fs_req_cleanup(&read_req);
+
+ r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+ ASSERT(r == 0);
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ /* Cleanup */
+ unlink("test_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-get-currentexe.c b/third-party/libuv/test/test-get-currentexe.c
new file mode 100644
index 0000000000..be578db75d
--- /dev/null
+++ b/third-party/libuv/test/test-get-currentexe.c
@@ -0,0 +1,65 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+#define PATHMAX 1024
+extern char executable_path[];
+
+TEST_IMPL(get_currentexe) {
+ char buffer[PATHMAX];
+ size_t size;
+ char* match;
+ char* path;
+ int r;
+
+ size = sizeof(buffer) / sizeof(buffer[0]);
+ r = uv_exepath(buffer, &size);
+ ASSERT(!r);
+
+ /* uv_exepath can return an absolute path on darwin, so if the test runner
+ * was run with a relative prefix of "./", we need to strip that prefix off
+ * executable_path or we'll fail. */
+ if (executable_path[0] == '.' && executable_path[1] == '/') {
+ path = executable_path + 2;
+ } else {
+ path = executable_path;
+ }
+
+ match = strstr(buffer, path);
+ /* Verify that the path returned from uv_exepath is a subdirectory of
+ * executable_path.
+ */
+ ASSERT(match && !strcmp(match, path));
+ ASSERT(size == strlen(buffer));
+
+ /* Negative tests */
+ size = sizeof(buffer) / sizeof(buffer[0]);
+ r = uv_exepath(NULL, &size);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_exepath(buffer, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-get-loadavg.c b/third-party/libuv/test/test-get-loadavg.c
new file mode 100644
index 0000000000..7465e18b91
--- /dev/null
+++ b/third-party/libuv/test/test-get-loadavg.c
@@ -0,0 +1,36 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+TEST_IMPL(get_loadavg) {
+
+ double avg[3];
+ uv_loadavg(avg);
+
+ ASSERT(avg != NULL);
+ ASSERT(avg[0] >= 0);
+ ASSERT(avg[1] >= 0);
+ ASSERT(avg[2] >= 0);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-get-memory.c b/third-party/libuv/test/test-get-memory.c
new file mode 100644
index 0000000000..2396939bcb
--- /dev/null
+++ b/third-party/libuv/test/test-get-memory.c
@@ -0,0 +1,38 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+TEST_IMPL(get_memory) {
+ uint64_t free_mem = uv_get_free_memory();
+ uint64_t total_mem = uv_get_total_memory();
+
+ printf("free_mem=%llu, total_mem=%llu\n",
+ (unsigned long long) free_mem,
+ (unsigned long long) total_mem);
+
+ ASSERT(free_mem > 0);
+ ASSERT(total_mem > 0);
+ ASSERT(total_mem > free_mem);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-getaddrinfo.c b/third-party/libuv/test/test-getaddrinfo.c
new file mode 100644
index 0000000000..bca2a6bd70
--- /dev/null
+++ b/third-party/libuv/test/test-getaddrinfo.c
@@ -0,0 +1,149 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdlib.h>
+
+#define CONCURRENT_COUNT 10
+
+static const char* name = "localhost";
+
+static int getaddrinfo_cbs = 0;
+
+/* data used for running multiple calls concurrently */
+static uv_getaddrinfo_t* getaddrinfo_handle;
+static uv_getaddrinfo_t getaddrinfo_handles[CONCURRENT_COUNT];
+static int callback_counts[CONCURRENT_COUNT];
+static int fail_cb_called;
+
+
+static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req,
+ int status,
+ struct addrinfo* res) {
+ ASSERT(fail_cb_called == 0);
+ ASSERT(status < 0);
+ ASSERT(res == NULL);
+ uv_freeaddrinfo(res); /* Should not crash. */
+ fail_cb_called++;
+}
+
+
+static void getaddrinfo_basic_cb(uv_getaddrinfo_t* handle,
+ int status,
+ struct addrinfo* res) {
+ ASSERT(handle == getaddrinfo_handle);
+ getaddrinfo_cbs++;
+ free(handle);
+ uv_freeaddrinfo(res);
+}
+
+
+static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle,
+ int status,
+ struct addrinfo* res) {
+ int i;
+ int* data = (int*)handle->data;
+
+ for (i = 0; i < CONCURRENT_COUNT; i++) {
+ if (&getaddrinfo_handles[i] == handle) {
+ ASSERT(i == *data);
+
+ callback_counts[i]++;
+ break;
+ }
+ }
+ ASSERT (i < CONCURRENT_COUNT);
+
+ free(data);
+ uv_freeaddrinfo(res);
+
+ getaddrinfo_cbs++;
+}
+
+
+TEST_IMPL(getaddrinfo_fail) {
+ uv_getaddrinfo_t req;
+
+ ASSERT(0 == uv_getaddrinfo(uv_default_loop(),
+ &req,
+ getaddrinfo_fail_cb,
+ "xyzzy.xyzzy.xyzzy",
+ NULL,
+ NULL));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(fail_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(getaddrinfo_basic) {
+ int r;
+ getaddrinfo_handle = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t));
+
+ r = uv_getaddrinfo(uv_default_loop(),
+ getaddrinfo_handle,
+ &getaddrinfo_basic_cb,
+ name,
+ NULL,
+ NULL);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(getaddrinfo_cbs == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(getaddrinfo_concurrent) {
+ int i, r;
+ int* data;
+
+ for (i = 0; i < CONCURRENT_COUNT; i++) {
+ callback_counts[i] = 0;
+
+ data = (int*)malloc(sizeof(int));
+ *data = i;
+ getaddrinfo_handles[i].data = data;
+
+ r = uv_getaddrinfo(uv_default_loop(),
+ &getaddrinfo_handles[i],
+ &getaddrinfo_cuncurrent_cb,
+ name,
+ NULL,
+ NULL);
+ ASSERT(r == 0);
+ }
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ for (i = 0; i < CONCURRENT_COUNT; i++) {
+ ASSERT(callback_counts[i] == 1);
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-getsockname.c b/third-party/libuv/test/test-getsockname.c
new file mode 100644
index 0000000000..a67d967f0b
--- /dev/null
+++ b/third-party/libuv/test/test-getsockname.c
@@ -0,0 +1,358 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const int server_port = TEST_PORT;
+/* Will be updated right after making the uv_connect_call */
+static int connect_port = -1;
+
+static int getsocknamecount = 0;
+static int getpeernamecount = 0;
+
+static uv_loop_t* loop;
+static uv_tcp_t tcp;
+static uv_udp_t udp;
+static uv_connect_t connect_req;
+static uv_tcp_t tcpServer;
+static uv_udp_t udpServer;
+static uv_udp_send_t send_req;
+
+
+static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+static void on_close(uv_handle_t* peer) {
+ free(peer);
+ uv_close((uv_handle_t*)&tcpServer, NULL);
+}
+
+
+static void after_shutdown(uv_shutdown_t* req, int status) {
+ uv_close((uv_handle_t*) req->handle, on_close);
+ free(req);
+}
+
+
+static void after_read(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ uv_shutdown_t* req;
+ int r;
+
+ if (buf->base) {
+ free(buf->base);
+ }
+
+ req = (uv_shutdown_t*) malloc(sizeof *req);
+ r = uv_shutdown(req, handle, after_shutdown);
+ ASSERT(r == 0);
+}
+
+
+static void check_sockname(struct sockaddr* addr, const char* compare_ip,
+ int compare_port, const char* context) {
+ struct sockaddr_in check_addr = *(struct sockaddr_in*) addr;
+ struct sockaddr_in compare_addr;
+ char check_ip[17];
+ int r;
+
+ ASSERT(0 == uv_ip4_addr(compare_ip, compare_port, &compare_addr));
+
+ /* Both addresses should be ipv4 */
+ ASSERT(check_addr.sin_family == AF_INET);
+ ASSERT(compare_addr.sin_family == AF_INET);
+
+ /* Check if the ip matches */
+ ASSERT(memcmp(&check_addr.sin_addr,
+ &compare_addr.sin_addr,
+ sizeof compare_addr.sin_addr) == 0);
+
+ /* Check if the port matches. If port == 0 anything goes. */
+ ASSERT(compare_port == 0 || check_addr.sin_port == compare_addr.sin_port);
+
+ r = uv_ip4_name(&check_addr, (char*) check_ip, sizeof check_ip);
+ ASSERT(r == 0);
+
+ printf("%s: %s:%d\n", context, check_ip, ntohs(check_addr.sin_port));
+}
+
+
+static void on_connection(uv_stream_t* server, int status) {
+ struct sockaddr sockname, peername;
+ int namelen;
+ uv_tcp_t* handle;
+ int r;
+
+ if (status != 0) {
+ fprintf(stderr, "Connect error %s\n", uv_err_name(status));
+ }
+ ASSERT(status == 0);
+
+ handle = malloc(sizeof(*handle));
+ ASSERT(handle != NULL);
+
+ r = uv_tcp_init(loop, handle);
+ ASSERT(r == 0);
+
+ /* associate server with stream */
+ handle->data = server;
+
+ r = uv_accept(server, (uv_stream_t*)handle);
+ ASSERT(r == 0);
+
+ namelen = sizeof sockname;
+ r = uv_tcp_getsockname(handle, &sockname, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket");
+ getsocknamecount++;
+
+ namelen = sizeof peername;
+ r = uv_tcp_getpeername(handle, &peername, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer");
+ getpeernamecount++;
+
+ r = uv_read_start((uv_stream_t*)handle, alloc, after_read);
+ ASSERT(r == 0);
+}
+
+
+static void on_connect(uv_connect_t* req, int status) {
+ struct sockaddr sockname, peername;
+ int r, namelen;
+
+ ASSERT(status == 0);
+
+ namelen = sizeof sockname;
+ r = uv_tcp_getsockname((uv_tcp_t*) req->handle, &sockname, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&sockname, "127.0.0.1", 0, "connected socket");
+ getsocknamecount++;
+
+ namelen = sizeof peername;
+ r = uv_tcp_getpeername((uv_tcp_t*) req->handle, &peername, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&peername, "127.0.0.1", server_port, "connected socket peer");
+ getpeernamecount++;
+
+ uv_close((uv_handle_t*)&tcp, NULL);
+}
+
+
+static int tcp_listener(void) {
+ struct sockaddr_in addr;
+ struct sockaddr sockname, peername;
+ int namelen;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr));
+
+ r = uv_tcp_init(loop, &tcpServer);
+ if (r) {
+ fprintf(stderr, "Socket creation error\n");
+ return 1;
+ }
+
+ r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
+ if (r) {
+ fprintf(stderr, "Bind error\n");
+ return 1;
+ }
+
+ r = uv_listen((uv_stream_t*)&tcpServer, 128, on_connection);
+ if (r) {
+ fprintf(stderr, "Listen error\n");
+ return 1;
+ }
+
+ memset(&sockname, -1, sizeof sockname);
+ namelen = sizeof sockname;
+ r = uv_tcp_getsockname(&tcpServer, &sockname, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&sockname, "0.0.0.0", server_port, "server socket");
+ getsocknamecount++;
+
+ namelen = sizeof sockname;
+ r = uv_tcp_getpeername(&tcpServer, &peername, &namelen);
+ ASSERT(r == UV_ENOTCONN);
+ getpeernamecount++;
+
+ return 0;
+}
+
+
+static void tcp_connector(void) {
+ struct sockaddr_in server_addr;
+ struct sockaddr sockname;
+ int r, namelen;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr));
+
+ r = uv_tcp_init(loop, &tcp);
+ tcp.data = &connect_req;
+ ASSERT(!r);
+
+ r = uv_tcp_connect(&connect_req,
+ &tcp,
+ (const struct sockaddr*) &server_addr,
+ on_connect);
+ ASSERT(!r);
+
+ /* Fetch the actual port used by the connecting socket. */
+ namelen = sizeof sockname;
+ r = uv_tcp_getsockname(&tcp, &sockname, &namelen);
+ ASSERT(!r);
+ ASSERT(sockname.sa_family == AF_INET);
+ connect_port = ntohs(((struct sockaddr_in*) &sockname)->sin_port);
+ ASSERT(connect_port > 0);
+}
+
+
+static void udp_recv(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ struct sockaddr sockname;
+ int namelen;
+ int r;
+
+ ASSERT(nread >= 0);
+ free(buf->base);
+
+ if (nread == 0) {
+ return;
+ }
+
+ memset(&sockname, -1, sizeof sockname);
+ namelen = sizeof(sockname);
+ r = uv_udp_getsockname(&udp, &sockname, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&sockname, "0.0.0.0", 0, "udp receiving socket");
+ getsocknamecount++;
+
+ uv_close((uv_handle_t*) &udp, NULL);
+ uv_close((uv_handle_t*) handle, NULL);
+}
+
+
+static void udp_send(uv_udp_send_t* req, int status) {
+
+}
+
+
+static int udp_listener(void) {
+ struct sockaddr_in addr;
+ struct sockaddr sockname;
+ int namelen;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr));
+
+ r = uv_udp_init(loop, &udpServer);
+ if (r) {
+ fprintf(stderr, "Socket creation error\n");
+ return 1;
+ }
+
+ r = uv_udp_bind(&udpServer, (const struct sockaddr*) &addr, 0);
+ if (r) {
+ fprintf(stderr, "Bind error\n");
+ return 1;
+ }
+
+ memset(&sockname, -1, sizeof sockname);
+ namelen = sizeof sockname;
+ r = uv_udp_getsockname(&udpServer, &sockname, &namelen);
+ ASSERT(r == 0);
+ check_sockname(&sockname, "0.0.0.0", server_port, "udp listener socket");
+ getsocknamecount++;
+
+ r = uv_udp_recv_start(&udpServer, alloc, udp_recv);
+ ASSERT(r == 0);
+
+ return 0;
+}
+
+
+static void udp_sender(void) {
+ struct sockaddr_in server_addr;
+ uv_buf_t buf;
+ int r;
+
+ r = uv_udp_init(loop, &udp);
+ ASSERT(!r);
+
+ buf = uv_buf_init("PING", 4);
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr));
+
+ r = uv_udp_send(&send_req,
+ &udp,
+ &buf,
+ 1,
+ (const struct sockaddr*) &server_addr,
+ udp_send);
+ ASSERT(!r);
+}
+
+
+TEST_IMPL(getsockname_tcp) {
+ loop = uv_default_loop();
+
+ if (tcp_listener())
+ return 1;
+
+ tcp_connector();
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(getsocknamecount == 3);
+ ASSERT(getpeernamecount == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(getsockname_udp) {
+ loop = uv_default_loop();
+
+ if (udp_listener())
+ return 1;
+
+ udp_sender();
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(getsocknamecount == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-hrtime.c b/third-party/libuv/test/test-hrtime.c
new file mode 100644
index 0000000000..72a4d4b181
--- /dev/null
+++ b/third-party/libuv/test/test-hrtime.c
@@ -0,0 +1,54 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#ifndef MILLISEC
+# define MILLISEC 1000
+#endif
+
+#ifndef NANOSEC
+# define NANOSEC ((uint64_t) 1e9)
+#endif
+
+
+TEST_IMPL(hrtime) {
+ uint64_t a, b, diff;
+ int i = 75;
+ while (i > 0) {
+ a = uv_hrtime();
+ uv_sleep(45);
+ b = uv_hrtime();
+
+ diff = b - a;
+
+ /* printf("i= %d diff = %llu\n", i, (unsigned long long int) diff); */
+
+ /* The windows Sleep() function has only a resolution of 10-20 ms. */
+ /* Check that the difference between the two hrtime values is somewhat in */
+ /* the range we expect it to be. */
+ ASSERT(diff > (uint64_t) 25 * NANOSEC / MILLISEC);
+ ASSERT(diff < (uint64_t) 80 * NANOSEC / MILLISEC);
+ --i;
+ }
+ return 0;
+}
diff --git a/third-party/libuv/test/test-idle.c b/third-party/libuv/test/test-idle.c
new file mode 100644
index 0000000000..7eea1b83b1
--- /dev/null
+++ b/third-party/libuv/test/test-idle.c
@@ -0,0 +1,99 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+static uv_idle_t idle_handle;
+static uv_check_t check_handle;
+static uv_timer_t timer_handle;
+
+static int idle_cb_called = 0;
+static int check_cb_called = 0;
+static int timer_cb_called = 0;
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+
+ uv_close((uv_handle_t*) &idle_handle, close_cb);
+ uv_close((uv_handle_t*) &check_handle, close_cb);
+ uv_close((uv_handle_t*) &timer_handle, close_cb);
+
+ timer_cb_called++;
+ LOGF("timer_cb %d\n", timer_cb_called);
+}
+
+
+static void idle_cb(uv_idle_t* handle, int status) {
+ ASSERT(handle == &idle_handle);
+ ASSERT(status == 0);
+
+ idle_cb_called++;
+ LOGF("idle_cb %d\n", idle_cb_called);
+}
+
+
+static void check_cb(uv_check_t* handle, int status) {
+ ASSERT(handle == &check_handle);
+ ASSERT(status == 0);
+
+ check_cb_called++;
+ LOGF("check_cb %d\n", check_cb_called);
+}
+
+
+TEST_IMPL(idle_starvation) {
+ int r;
+
+ r = uv_idle_init(uv_default_loop(), &idle_handle);
+ ASSERT(r == 0);
+ r = uv_idle_start(&idle_handle, idle_cb);
+ ASSERT(r == 0);
+
+ r = uv_check_init(uv_default_loop(), &check_handle);
+ ASSERT(r == 0);
+ r = uv_check_start(&check_handle, check_cb);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(uv_default_loop(), &timer_handle);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer_handle, timer_cb, 50, 0);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(idle_cb_called > 0);
+ ASSERT(timer_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-ip4-addr.c b/third-party/libuv/test/test-ip4-addr.c
new file mode 100644
index 0000000000..3d6e0cf286
--- /dev/null
+++ b/third-party/libuv/test/test-ip4-addr.c
@@ -0,0 +1,46 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+
+TEST_IMPL(ip4_addr) {
+
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255*000", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255.256", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr));
+
+ /* for broken address family */
+ ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1",
+ &addr.sin_addr.s_addr));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-ip6-addr.c b/third-party/libuv/test/test-ip6-addr.c
new file mode 100644
index 0000000000..ddd0812285
--- /dev/null
+++ b/third-party/libuv/test/test-ip6-addr.c
@@ -0,0 +1,99 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __linux__
+# include <sys/socket.h>
+# include <net/if.h>
+#endif
+
+
+TEST_IMPL(ip6_addr_link_local) {
+#ifdef UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+ char string_address[INET6_ADDRSTRLEN];
+ uv_interface_address_t* addresses;
+ uv_interface_address_t* address;
+ struct sockaddr_in6 addr;
+ unsigned int iface_index;
+ const char* device_name;
+ /* 40 bytes address, 16 bytes device name, plus reserve. */
+ char scoped_addr[128];
+ int count;
+ int ix;
+
+ ASSERT(0 == uv_interface_addresses(&addresses, &count));
+
+ for (ix = 0; ix < count; ix++) {
+ address = addresses + ix;
+
+ if (address->address.address6.sin6_family != AF_INET6)
+ continue;
+
+ ASSERT(0 == uv_inet_ntop(AF_INET6,
+ &address->address.address6.sin6_addr,
+ string_address,
+ sizeof(string_address)));
+
+ /* Skip addresses that are not link-local. */
+ if (strncmp(string_address, "fe80::", 6) != 0)
+ continue;
+
+ iface_index = address->address.address6.sin6_scope_id;
+ device_name = address->name;
+
+#ifdef _WIN32
+ snprintf(scoped_addr,
+ sizeof(scoped_addr),
+ "%s%%%d",
+ string_address,
+ iface_index);
+#else
+ snprintf(scoped_addr,
+ sizeof(scoped_addr),
+ "%s%%%s",
+ string_address,
+ device_name);
+#endif
+
+ LOGF("Testing link-local address %s "
+ "(iface_index: 0x%02x, device_name: %s)\n",
+ scoped_addr,
+ iface_index,
+ device_name);
+
+ ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr));
+ LOGF("Got scope_id 0x%02x\n", addr.sin6_scope_id);
+ ASSERT(iface_index == addr.sin6_scope_id);
+ }
+
+ uv_free_interface_addresses(addresses, count);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#else
+ RETURN_SKIP("Qualified link-local addresses are not supported.");
+#endif
+}
diff --git a/third-party/libuv/test/test-ipc-send-recv.c b/third-party/libuv/test/test-ipc-send-recv.c
new file mode 100644
index 0000000000..b2b5aa0e92
--- /dev/null
+++ b/third-party/libuv/test/test-ipc-send-recv.c
@@ -0,0 +1,226 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/* See test-ipc.ctx */
+void spawn_helper(uv_pipe_t* channel,
+ uv_process_t* process,
+ const char* helper);
+
+union handles {
+ uv_handle_t handle;
+ uv_stream_t stream;
+ uv_pipe_t pipe;
+ uv_tcp_t tcp;
+ uv_tty_t tty;
+};
+
+struct echo_ctx {
+ uv_pipe_t channel;
+ uv_write_t write_req;
+ uv_handle_type expected_type;
+ union handles send;
+ union handles recv;
+};
+
+static struct echo_ctx ctx;
+static int num_recv_handles;
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ /* we're not actually reading anything so a small buffer is okay */
+ static char slab[8];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void recv_cb(uv_pipe_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type pending) {
+ int r;
+
+ ASSERT(pending == ctx.expected_type);
+ ASSERT(handle == &ctx.channel);
+ ASSERT(nread >= 0);
+
+ if (pending == UV_NAMED_PIPE)
+ r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
+ else if (pending == UV_TCP)
+ r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
+ else
+ abort();
+ ASSERT(r == 0);
+
+ r = uv_accept((uv_stream_t*)&ctx.channel, &ctx.recv.stream);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)&ctx.channel, NULL);
+ uv_close(&ctx.send.handle, NULL);
+ uv_close(&ctx.recv.handle, NULL);
+ num_recv_handles++;
+}
+
+
+static int run_test(void) {
+ uv_process_t process;
+ uv_buf_t buf;
+ int r;
+
+ spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper");
+
+ buf = uv_buf_init(".", 1);
+ r = uv_write2(&ctx.write_req,
+ (uv_stream_t*)&ctx.channel,
+ &buf, 1,
+ &ctx.send.stream,
+ NULL);
+ ASSERT(r == 0);
+
+ r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(num_recv_handles == 1);
+
+ return 0;
+}
+
+
+TEST_IMPL(ipc_send_recv_pipe) {
+ int r;
+
+ ctx.expected_type = UV_NAMED_PIPE;
+
+ r = uv_pipe_init(uv_default_loop(), &ctx.send.pipe, 1);
+ ASSERT(r == 0);
+
+ r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME);
+ ASSERT(r == 0);
+
+ r = run_test();
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(ipc_send_recv_tcp) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ctx.expected_type = UV_TCP;
+
+ r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = run_test();
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+/* Everything here runs in a child process. */
+
+static void write2_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ uv_close(&ctx.recv.handle, NULL);
+ uv_close((uv_handle_t*)&ctx.channel, NULL);
+}
+
+
+static void read2_cb(uv_pipe_t* handle,
+ ssize_t nread,
+ const uv_buf_t* rdbuf,
+ uv_handle_type pending) {
+ uv_buf_t wrbuf;
+ int r;
+
+ ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
+ ASSERT(handle == &ctx.channel);
+ ASSERT(nread >= 0);
+
+ wrbuf = uv_buf_init(".", 1);
+
+ if (pending == UV_NAMED_PIPE)
+ r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
+ else if (pending == UV_TCP)
+ r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
+ else
+ abort();
+ ASSERT(r == 0);
+
+ r = uv_accept((uv_stream_t*)handle, &ctx.recv.stream);
+ ASSERT(r == 0);
+
+ r = uv_write2(&ctx.write_req,
+ (uv_stream_t*)&ctx.channel,
+ &wrbuf,
+ 1,
+ &ctx.recv.stream,
+ write2_cb);
+ ASSERT(r == 0);
+}
+
+
+/* stdin is a duplex channel over which a handle is sent.
+ * We receive it and send it back where it came from.
+ */
+int ipc_send_recv_helper(void) {
+ int r;
+
+ memset(&ctx, 0, sizeof(ctx));
+
+ r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&ctx.channel, 0);
+ ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx.channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx.channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*)&ctx.channel));
+
+ r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, read2_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-ipc.c b/third-party/libuv/test/test-ipc.c
new file mode 100644
index 0000000000..cc44d32e28
--- /dev/null
+++ b/third-party/libuv/test/test-ipc.c
@@ -0,0 +1,648 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static uv_pipe_t channel;
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_connection;
+
+static int exit_cb_called;
+static int read2_cb_called;
+static int tcp_write_cb_called;
+static int tcp_read_cb_called;
+static int on_pipe_read_called;
+static int local_conn_accepted;
+static int remote_conn_accepted;
+static int tcp_server_listening;
+static uv_write_t write_req;
+static uv_pipe_t channel;
+static uv_tcp_t tcp_server;
+static uv_write_t conn_notify_req;
+static int close_cb_called;
+static int connection_accepted;
+static int tcp_conn_read_cb_called;
+static int tcp_conn_write_cb_called;
+
+typedef struct {
+ uv_connect_t conn_req;
+ uv_write_t tcp_write_req;
+ uv_tcp_t conn;
+} tcp_conn;
+
+#define CONN_COUNT 100
+
+
+static void close_server_conn_cb(uv_handle_t* handle) {
+ free(handle);
+}
+
+
+static void on_connection(uv_stream_t* server, int status) {
+ uv_tcp_t* conn;
+ int r;
+
+ if (!local_conn_accepted) {
+ /* Accept the connection and close it. Also and close the server. */
+ ASSERT(status == 0);
+ ASSERT((uv_stream_t*)&tcp_server == server);
+
+ conn = malloc(sizeof(*conn));
+ ASSERT(conn);
+ r = uv_tcp_init(server->loop, conn);
+ ASSERT(r == 0);
+
+ r = uv_accept(server, (uv_stream_t*)conn);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)conn, close_server_conn_cb);
+ uv_close((uv_handle_t*)server, NULL);
+ local_conn_accepted = 1;
+ }
+}
+
+
+static void exit_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ printf("exit_cb\n");
+ exit_cb_called++;
+ ASSERT(exit_status == 0);
+ uv_close((uv_handle_t*)process, NULL);
+}
+
+
+static void on_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+static void close_client_conn_cb(uv_handle_t* handle) {
+ tcp_conn* p = (tcp_conn*)handle->data;
+ free(p);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_close((uv_handle_t*)req->handle, close_client_conn_cb);
+}
+
+
+static void make_many_connections(void) {
+ tcp_conn* conn;
+ struct sockaddr_in addr;
+ int r, i;
+
+ for (i = 0; i < CONN_COUNT; i++) {
+ conn = malloc(sizeof(*conn));
+ ASSERT(conn);
+
+ r = uv_tcp_init(uv_default_loop(), &conn->conn);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_connect(&conn->conn_req,
+ (uv_tcp_t*) &conn->conn,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ conn->conn.data = conn;
+ }
+}
+
+
+static void on_read(uv_pipe_t* pipe,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type pending) {
+ int r;
+ uv_buf_t outbuf;
+
+ if (nread == 0) {
+ /* Everything OK, but nothing read. */
+ free(buf->base);
+ return;
+ }
+
+ if (nread < 0) {
+ if (nread == UV_EOF) {
+ free(buf->base);
+ return;
+ }
+
+ printf("error recving on channel: %s\n", uv_strerror(nread));
+ abort();
+ }
+
+ fprintf(stderr, "got %d bytes\n", (int)nread);
+
+ if (!tcp_server_listening) {
+ ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE);
+ read2_cb_called++;
+
+ /* Accept the pending TCP server, and start listening on it. */
+ ASSERT(pending == UV_TCP);
+ r = uv_tcp_init(uv_default_loop(), &tcp_server);
+ ASSERT(r == 0);
+
+ r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&tcp_server, 12, on_connection);
+ ASSERT(r == 0);
+
+ tcp_server_listening = 1;
+
+ /* Make sure that the expected data is correctly multiplexed. */
+ ASSERT(memcmp("hello\n", buf->base, nread) == 0);
+
+ outbuf = uv_buf_init("world\n", 6);
+ r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL);
+ ASSERT(r == 0);
+
+ /* Create a bunch of connections to get both servers to accept. */
+ make_many_connections();
+ } else if (memcmp("accepted_connection\n", buf->base, nread) == 0) {
+ /* Remote server has accepted a connection. Close the channel. */
+ ASSERT(pending == UV_UNKNOWN_HANDLE);
+ remote_conn_accepted = 1;
+ uv_close((uv_handle_t*)&channel, NULL);
+ }
+
+ free(buf->base);
+}
+
+
+void spawn_helper(uv_pipe_t* channel,
+ uv_process_t* process,
+ const char* helper) {
+ uv_process_options_t options;
+ size_t exepath_size;
+ char exepath[1024];
+ char* args[3];
+ int r;
+ uv_stdio_container_t stdio[1];
+
+ r = uv_pipe_init(uv_default_loop(), channel, 1);
+ ASSERT(r == 0);
+ ASSERT(channel->ipc);
+
+ exepath_size = sizeof(exepath);
+ r = uv_exepath(exepath, &exepath_size);
+ ASSERT(r == 0);
+
+ exepath[exepath_size] = '\0';
+ args[0] = exepath;
+ args[1] = (char*)helper;
+ args[2] = NULL;
+
+ memset(&options, 0, sizeof(options));
+ options.file = exepath;
+ options.args = args;
+ options.exit_cb = exit_cb;
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE |
+ UV_READABLE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)channel;
+ options.stdio_count = 1;
+
+ r = uv_spawn(uv_default_loop(), process, &options);
+ ASSERT(r == 0);
+}
+
+
+static void on_tcp_write(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ ASSERT(req->handle == (uv_stream_t*)&tcp_connection);
+ tcp_write_cb_called++;
+}
+
+
+static void on_read_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+static void on_tcp_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(nread > 0);
+ ASSERT(memcmp("hello again\n", buf->base, nread) == 0);
+ ASSERT(tcp == (uv_stream_t*)&tcp_connection);
+ free(buf->base);
+
+ tcp_read_cb_called++;
+
+ uv_close((uv_handle_t*)tcp, NULL);
+ uv_close((uv_handle_t*)&channel, NULL);
+}
+
+
+static void on_read_connection(uv_pipe_t* pipe,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ uv_handle_type pending) {
+ int r;
+ uv_buf_t outbuf;
+
+ if (nread == 0) {
+ /* Everything OK, but nothing read. */
+ free(buf->base);
+ return;
+ }
+
+ if (nread < 0) {
+ if (nread == UV_EOF) {
+ free(buf->base);
+ return;
+ }
+
+ printf("error recving on channel: %s\n", uv_strerror(nread));
+ abort();
+ }
+
+ fprintf(stderr, "got %d bytes\n", (int)nread);
+
+ ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE);
+ read2_cb_called++;
+
+ /* Accept the pending TCP connection */
+ ASSERT(pending == UV_TCP);
+ r = uv_tcp_init(uv_default_loop(), &tcp_connection);
+ ASSERT(r == 0);
+
+ r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_connection);
+ ASSERT(r == 0);
+
+ /* Make sure that the expected data is correctly multiplexed. */
+ ASSERT(memcmp("hello\n", buf->base, nread) == 0);
+
+ /* Write/read to/from the connection */
+ outbuf = uv_buf_init("world\n", 6);
+ r = uv_write(&write_req, (uv_stream_t*)&tcp_connection, &outbuf, 1,
+ on_tcp_write);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&tcp_connection, on_read_alloc, on_tcp_read);
+ ASSERT(r == 0);
+
+ free(buf->base);
+}
+
+
+static int run_ipc_test(const char* helper, uv_read2_cb read_cb) {
+ uv_process_t process;
+ int r;
+
+ spawn_helper(&channel, &process, helper);
+ uv_read2_start((uv_stream_t*)&channel, on_alloc, read_cb);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(ipc_listen_before_write) {
+ int r = run_ipc_test("ipc_helper_listen_before_write", on_read);
+ ASSERT(local_conn_accepted == 1);
+ ASSERT(remote_conn_accepted == 1);
+ ASSERT(read2_cb_called == 1);
+ ASSERT(exit_cb_called == 1);
+ return r;
+}
+
+
+TEST_IMPL(ipc_listen_after_write) {
+ int r = run_ipc_test("ipc_helper_listen_after_write", on_read);
+ ASSERT(local_conn_accepted == 1);
+ ASSERT(remote_conn_accepted == 1);
+ ASSERT(read2_cb_called == 1);
+ ASSERT(exit_cb_called == 1);
+ return r;
+}
+
+
+TEST_IMPL(ipc_tcp_connection) {
+ int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection);
+ ASSERT(read2_cb_called == 1);
+ ASSERT(tcp_write_cb_called == 1);
+ ASSERT(tcp_read_cb_called == 1);
+ ASSERT(exit_cb_called == 1);
+ return r;
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(listen_with_simultaneous_accepts) {
+ uv_tcp_t server;
+ int r;
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_simultaneous_accepts(&server, 1);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+ ASSERT(r == 0);
+ ASSERT(server.reqs_pending == 32);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(listen_no_simultaneous_accepts) {
+ uv_tcp_t server;
+ int r;
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_simultaneous_accepts(&server, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+ ASSERT(r == 0);
+ ASSERT(server.reqs_pending == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
+/* Everything here runs in a child process. */
+
+static tcp_conn conn;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void conn_notify_write_cb(uv_write_t* req, int status) {
+ uv_close((uv_handle_t*)&tcp_server, close_cb);
+ uv_close((uv_handle_t*)&channel, close_cb);
+}
+
+
+static void tcp_connection_write_cb(uv_write_t* req, int status) {
+ ASSERT((uv_handle_t*)&conn.conn == (uv_handle_t*)req->handle);
+ uv_close((uv_handle_t*)req->handle, close_cb);
+ uv_close((uv_handle_t*)&channel, close_cb);
+ uv_close((uv_handle_t*)&tcp_server, close_cb);
+ tcp_conn_write_cb_called++;
+}
+
+
+static void on_tcp_child_process_read(uv_stream_t* tcp,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ uv_buf_t outbuf;
+ int r;
+
+ if (nread < 0) {
+ if (nread == UV_EOF) {
+ free(buf->base);
+ return;
+ }
+
+ printf("error recving on tcp connection: %s\n", uv_strerror(nread));
+ abort();
+ }
+
+ ASSERT(nread > 0);
+ ASSERT(memcmp("world\n", buf->base, nread) == 0);
+ on_pipe_read_called++;
+ free(buf->base);
+
+ /* Write to the socket */
+ outbuf = uv_buf_init("hello again\n", 12);
+ r = uv_write(&conn.tcp_write_req, tcp, &outbuf, 1, tcp_connection_write_cb);
+ ASSERT(r == 0);
+
+ tcp_conn_read_cb_called++;
+}
+
+
+static void connect_child_process_cb(uv_connect_t* req, int status) {
+ int r;
+
+ ASSERT(status == 0);
+ r = uv_read_start(req->handle, on_read_alloc, on_tcp_child_process_read);
+ ASSERT(r == 0);
+}
+
+
+static void ipc_on_connection(uv_stream_t* server, int status) {
+ int r;
+ uv_buf_t buf;
+
+ if (!connection_accepted) {
+ /*
+ * Accept the connection and close it. Also let the other
+ * side know.
+ */
+ ASSERT(status == 0);
+ ASSERT((uv_stream_t*)&tcp_server == server);
+
+ r = uv_tcp_init(server->loop, &conn.conn);
+ ASSERT(r == 0);
+
+ r = uv_accept(server, (uv_stream_t*)&conn.conn);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)&conn.conn, close_cb);
+
+ buf = uv_buf_init("accepted_connection\n", 20);
+ r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1,
+ NULL, conn_notify_write_cb);
+ ASSERT(r == 0);
+
+ connection_accepted = 1;
+ }
+}
+
+
+static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) {
+ int r;
+ uv_buf_t buf;
+ uv_tcp_t* conn;
+
+ ASSERT(status == 0);
+ ASSERT((uv_stream_t*)&tcp_server == server);
+
+ conn = malloc(sizeof(*conn));
+ ASSERT(conn);
+
+ r = uv_tcp_init(server->loop, conn);
+ ASSERT(r == 0);
+
+ r = uv_accept(server, (uv_stream_t*)conn);
+ ASSERT(r == 0);
+
+ /* Send the accepted connection to the other process */
+ buf = uv_buf_init("hello\n", 6);
+ r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1,
+ (uv_stream_t*)conn, NULL);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) conn,
+ on_read_alloc,
+ on_tcp_child_process_read);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)conn, close_cb);
+}
+
+
+int ipc_helper(int listen_after_write) {
+ /*
+ * This is launched from test-ipc.c. stdin is a duplex channel that we
+ * over which a handle will be transmitted.
+ */
+ struct sockaddr_in addr;
+ uv_write_t write_req;
+ int r;
+ uv_buf_t buf;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 1);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ r = uv_tcp_init(uv_default_loop(), &tcp_server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ if (!listen_after_write) {
+ r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection);
+ ASSERT(r == 0);
+ }
+
+ buf = uv_buf_init("hello\n", 6);
+ r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1,
+ (uv_stream_t*)&tcp_server, NULL);
+ ASSERT(r == 0);
+
+ if (listen_after_write) {
+ r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection);
+ ASSERT(r == 0);
+ }
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(connection_accepted == 1);
+ ASSERT(close_cb_called == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+int ipc_helper_tcp_connection(void) {
+ /*
+ * This is launched from test-ipc.c. stdin is a duplex channel that we
+ * over which a handle will be transmitted.
+ */
+
+ int r;
+ struct sockaddr_in addr;
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 1);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ r = uv_tcp_init(uv_default_loop(), &tcp_server);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection_tcp_conn);
+ ASSERT(r == 0);
+
+ /* Make a connection to the server */
+ r = uv_tcp_init(uv_default_loop(), &conn.conn);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_connect(&conn.conn_req,
+ (uv_tcp_t*) &conn.conn,
+ (const struct sockaddr*) &addr,
+ connect_child_process_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(tcp_conn_read_cb_called == 1);
+ ASSERT(tcp_conn_write_cb_called == 1);
+ ASSERT(close_cb_called == 4);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-list.h b/third-party/libuv/test/test-list.h
new file mode 100644
index 0000000000..c3e15783b5
--- /dev/null
+++ b/third-party/libuv/test/test-list.h
@@ -0,0 +1,537 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+TEST_DECLARE (platform_output)
+TEST_DECLARE (callback_order)
+TEST_DECLARE (close_order)
+TEST_DECLARE (run_once)
+TEST_DECLARE (run_nowait)
+TEST_DECLARE (loop_alive)
+TEST_DECLARE (loop_stop)
+TEST_DECLARE (loop_update_time)
+TEST_DECLARE (barrier_1)
+TEST_DECLARE (barrier_2)
+TEST_DECLARE (barrier_3)
+TEST_DECLARE (condvar_1)
+TEST_DECLARE (condvar_2)
+TEST_DECLARE (condvar_3)
+TEST_DECLARE (condvar_4)
+TEST_DECLARE (condvar_5)
+TEST_DECLARE (semaphore_1)
+TEST_DECLARE (semaphore_2)
+TEST_DECLARE (semaphore_3)
+TEST_DECLARE (tty)
+TEST_DECLARE (stdio_over_pipes)
+TEST_DECLARE (ipc_listen_before_write)
+TEST_DECLARE (ipc_listen_after_write)
+#ifndef _WIN32
+TEST_DECLARE (ipc_send_recv_pipe)
+#endif
+TEST_DECLARE (ipc_send_recv_tcp)
+TEST_DECLARE (ipc_tcp_connection)
+TEST_DECLARE (tcp_ping_pong)
+TEST_DECLARE (tcp_ping_pong_v6)
+TEST_DECLARE (pipe_ping_pong)
+TEST_DECLARE (delayed_accept)
+TEST_DECLARE (multiple_listen)
+TEST_DECLARE (tcp_writealot)
+TEST_DECLARE (tcp_try_write)
+TEST_DECLARE (tcp_open)
+TEST_DECLARE (tcp_connect_error_after_write)
+TEST_DECLARE (tcp_shutdown_after_write)
+TEST_DECLARE (tcp_bind_error_addrinuse)
+TEST_DECLARE (tcp_bind_error_addrnotavail_1)
+TEST_DECLARE (tcp_bind_error_addrnotavail_2)
+TEST_DECLARE (tcp_bind_error_fault)
+TEST_DECLARE (tcp_bind_error_inval)
+TEST_DECLARE (tcp_bind_localhost_ok)
+TEST_DECLARE (tcp_listen_without_bind)
+TEST_DECLARE (tcp_connect_error_fault)
+TEST_DECLARE (tcp_connect_timeout)
+TEST_DECLARE (tcp_close_while_connecting)
+TEST_DECLARE (tcp_close)
+TEST_DECLARE (tcp_close_accept)
+TEST_DECLARE (tcp_flags)
+TEST_DECLARE (tcp_write_to_half_open_connection)
+TEST_DECLARE (tcp_unexpected_read)
+TEST_DECLARE (tcp_read_stop)
+TEST_DECLARE (tcp_bind6_error_addrinuse)
+TEST_DECLARE (tcp_bind6_error_addrnotavail)
+TEST_DECLARE (tcp_bind6_error_fault)
+TEST_DECLARE (tcp_bind6_error_inval)
+TEST_DECLARE (tcp_bind6_localhost_ok)
+TEST_DECLARE (udp_send_and_recv)
+TEST_DECLARE (udp_multicast_join)
+TEST_DECLARE (udp_multicast_ttl)
+TEST_DECLARE (udp_dgram_too_big)
+TEST_DECLARE (udp_dual_stack)
+TEST_DECLARE (udp_ipv6_only)
+TEST_DECLARE (udp_options)
+TEST_DECLARE (udp_open)
+TEST_DECLARE (pipe_bind_error_addrinuse)
+TEST_DECLARE (pipe_bind_error_addrnotavail)
+TEST_DECLARE (pipe_bind_error_inval)
+TEST_DECLARE (pipe_listen_without_bind)
+TEST_DECLARE (pipe_connect_bad_name)
+TEST_DECLARE (pipe_connect_to_file)
+TEST_DECLARE (pipe_server_close)
+TEST_DECLARE (connection_fail)
+TEST_DECLARE (connection_fail_doesnt_auto_close)
+TEST_DECLARE (shutdown_close_tcp)
+TEST_DECLARE (shutdown_close_pipe)
+TEST_DECLARE (shutdown_eof)
+TEST_DECLARE (callback_stack)
+TEST_DECLARE (error_message)
+TEST_DECLARE (timer)
+TEST_DECLARE (timer_init)
+TEST_DECLARE (timer_again)
+TEST_DECLARE (timer_start_twice)
+TEST_DECLARE (timer_order)
+TEST_DECLARE (timer_huge_timeout)
+TEST_DECLARE (timer_huge_repeat)
+TEST_DECLARE (timer_run_once)
+TEST_DECLARE (timer_from_check)
+TEST_DECLARE (idle_starvation)
+TEST_DECLARE (loop_handles)
+TEST_DECLARE (get_loadavg)
+TEST_DECLARE (walk_handles)
+TEST_DECLARE (watcher_cross_stop)
+TEST_DECLARE (ref)
+TEST_DECLARE (idle_ref)
+TEST_DECLARE (async_ref)
+TEST_DECLARE (prepare_ref)
+TEST_DECLARE (check_ref)
+TEST_DECLARE (unref_in_prepare_cb)
+TEST_DECLARE (timer_ref)
+TEST_DECLARE (timer_ref2)
+TEST_DECLARE (fs_event_ref)
+TEST_DECLARE (fs_poll_ref)
+TEST_DECLARE (tcp_ref)
+TEST_DECLARE (tcp_ref2)
+TEST_DECLARE (tcp_ref2b)
+TEST_DECLARE (tcp_ref3)
+TEST_DECLARE (tcp_ref4)
+TEST_DECLARE (udp_ref)
+TEST_DECLARE (udp_ref2)
+TEST_DECLARE (udp_ref3)
+TEST_DECLARE (pipe_ref)
+TEST_DECLARE (pipe_ref2)
+TEST_DECLARE (pipe_ref3)
+TEST_DECLARE (pipe_ref4)
+TEST_DECLARE (process_ref)
+TEST_DECLARE (has_ref)
+TEST_DECLARE (active)
+TEST_DECLARE (embed)
+TEST_DECLARE (async)
+TEST_DECLARE (async_null_cb)
+TEST_DECLARE (get_currentexe)
+TEST_DECLARE (process_title)
+TEST_DECLARE (cwd_and_chdir)
+TEST_DECLARE (get_memory)
+TEST_DECLARE (hrtime)
+TEST_DECLARE (getaddrinfo_fail)
+TEST_DECLARE (getaddrinfo_basic)
+TEST_DECLARE (getaddrinfo_concurrent)
+TEST_DECLARE (getsockname_tcp)
+TEST_DECLARE (getsockname_udp)
+TEST_DECLARE (fail_always)
+TEST_DECLARE (pass_always)
+TEST_DECLARE (spawn_fails)
+TEST_DECLARE (spawn_exit_code)
+TEST_DECLARE (spawn_stdout)
+TEST_DECLARE (spawn_stdin)
+TEST_DECLARE (spawn_stdio_greater_than_3)
+TEST_DECLARE (spawn_ignored_stdio)
+TEST_DECLARE (spawn_and_kill)
+TEST_DECLARE (spawn_detached)
+TEST_DECLARE (spawn_and_kill_with_std)
+TEST_DECLARE (spawn_and_ping)
+TEST_DECLARE (spawn_preserve_env)
+TEST_DECLARE (spawn_setuid_fails)
+TEST_DECLARE (spawn_setgid_fails)
+TEST_DECLARE (spawn_stdout_to_file)
+TEST_DECLARE (spawn_stdout_and_stderr_to_file)
+TEST_DECLARE (spawn_auto_unref)
+TEST_DECLARE (fs_poll)
+TEST_DECLARE (kill)
+TEST_DECLARE (fs_file_noent)
+TEST_DECLARE (fs_file_nametoolong)
+TEST_DECLARE (fs_file_loop)
+TEST_DECLARE (fs_file_async)
+TEST_DECLARE (fs_file_sync)
+TEST_DECLARE (fs_async_dir)
+TEST_DECLARE (fs_async_sendfile)
+TEST_DECLARE (fs_fstat)
+TEST_DECLARE (fs_chmod)
+TEST_DECLARE (fs_chown)
+TEST_DECLARE (fs_link)
+TEST_DECLARE (fs_readlink)
+TEST_DECLARE (fs_symlink)
+TEST_DECLARE (fs_symlink_dir)
+TEST_DECLARE (fs_utime)
+TEST_DECLARE (fs_futime)
+TEST_DECLARE (fs_file_open_append)
+TEST_DECLARE (fs_stat_missing_path)
+TEST_DECLARE (fs_read_file_eof)
+TEST_DECLARE (fs_event_watch_dir)
+TEST_DECLARE (fs_event_watch_file)
+TEST_DECLARE (fs_event_watch_file_twice)
+TEST_DECLARE (fs_event_watch_file_current_dir)
+TEST_DECLARE (fs_event_no_callback_after_close)
+TEST_DECLARE (fs_event_no_callback_on_close)
+TEST_DECLARE (fs_event_immediate_close)
+TEST_DECLARE (fs_event_close_with_pending_event)
+TEST_DECLARE (fs_event_close_in_callback)
+TEST_DECLARE (fs_event_start_and_close)
+TEST_DECLARE (fs_event_error_reporting)
+TEST_DECLARE (fs_readdir_empty_dir)
+TEST_DECLARE (fs_readdir_file)
+TEST_DECLARE (fs_open_dir)
+TEST_DECLARE (fs_rename_to_existing_file)
+TEST_DECLARE (threadpool_queue_work_simple)
+TEST_DECLARE (threadpool_queue_work_einval)
+TEST_DECLARE (threadpool_multiple_event_loops)
+TEST_DECLARE (threadpool_cancel_getaddrinfo)
+TEST_DECLARE (threadpool_cancel_work)
+TEST_DECLARE (threadpool_cancel_fs)
+TEST_DECLARE (threadpool_cancel_single)
+TEST_DECLARE (thread_local_storage)
+TEST_DECLARE (thread_mutex)
+TEST_DECLARE (thread_rwlock)
+TEST_DECLARE (thread_create)
+TEST_DECLARE (dlerror)
+TEST_DECLARE (poll_duplex)
+TEST_DECLARE (poll_unidirectional)
+TEST_DECLARE (poll_close)
+TEST_DECLARE (ip4_addr)
+TEST_DECLARE (ip6_addr_link_local)
+#ifdef _WIN32
+TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
+TEST_DECLARE (argument_escaping)
+TEST_DECLARE (environment_creation)
+TEST_DECLARE (listen_with_simultaneous_accepts)
+TEST_DECLARE (listen_no_simultaneous_accepts)
+TEST_DECLARE (fs_stat_root)
+#else
+TEST_DECLARE (emfile)
+TEST_DECLARE (close_fd)
+TEST_DECLARE (spawn_setuid_setgid)
+TEST_DECLARE (we_get_signal)
+TEST_DECLARE (we_get_signals)
+TEST_DECLARE (signal_multiple_loops)
+#endif
+#ifdef __APPLE__
+TEST_DECLARE (osx_select)
+#endif
+HELPER_DECLARE (tcp4_echo_server)
+HELPER_DECLARE (tcp6_echo_server)
+HELPER_DECLARE (udp4_echo_server)
+HELPER_DECLARE (pipe_echo_server)
+
+
+TASK_LIST_START
+ TEST_OUTPUT_ENTRY (platform_output)
+
+#if 0
+ TEST_ENTRY (callback_order)
+#endif
+ TEST_ENTRY (close_order)
+ TEST_ENTRY (run_once)
+ TEST_ENTRY (run_nowait)
+ TEST_ENTRY (loop_alive)
+ TEST_ENTRY (loop_stop)
+ TEST_ENTRY (loop_update_time)
+ TEST_ENTRY (barrier_1)
+ TEST_ENTRY (barrier_2)
+ TEST_ENTRY (barrier_3)
+ TEST_ENTRY (condvar_1)
+ TEST_ENTRY (condvar_2)
+ TEST_ENTRY (condvar_3)
+ TEST_ENTRY (condvar_4)
+ TEST_ENTRY (condvar_5)
+ TEST_ENTRY (semaphore_1)
+ TEST_ENTRY (semaphore_2)
+ TEST_ENTRY (semaphore_3)
+
+ TEST_ENTRY (pipe_connect_bad_name)
+ TEST_ENTRY (pipe_connect_to_file)
+
+ TEST_ENTRY (pipe_server_close)
+ TEST_ENTRY (tty)
+ TEST_ENTRY (stdio_over_pipes)
+ TEST_ENTRY (ipc_listen_before_write)
+ TEST_ENTRY (ipc_listen_after_write)
+#ifndef _WIN32
+ TEST_ENTRY (ipc_send_recv_pipe)
+#endif
+ TEST_ENTRY (ipc_send_recv_tcp)
+ TEST_ENTRY (ipc_tcp_connection)
+
+ TEST_ENTRY (tcp_ping_pong)
+ TEST_HELPER (tcp_ping_pong, tcp4_echo_server)
+
+ TEST_ENTRY (tcp_ping_pong_v6)
+ TEST_HELPER (tcp_ping_pong_v6, tcp6_echo_server)
+
+ TEST_ENTRY (pipe_ping_pong)
+ TEST_HELPER (pipe_ping_pong, pipe_echo_server)
+
+ TEST_ENTRY (delayed_accept)
+ TEST_ENTRY (multiple_listen)
+
+ TEST_ENTRY (tcp_writealot)
+ TEST_HELPER (tcp_writealot, tcp4_echo_server)
+
+ TEST_ENTRY (tcp_try_write)
+
+ TEST_ENTRY (tcp_open)
+ TEST_HELPER (tcp_open, tcp4_echo_server)
+
+ TEST_ENTRY (tcp_shutdown_after_write)
+ TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
+
+ TEST_ENTRY (tcp_connect_error_after_write)
+ TEST_ENTRY (tcp_bind_error_addrinuse)
+ TEST_ENTRY (tcp_bind_error_addrnotavail_1)
+ TEST_ENTRY (tcp_bind_error_addrnotavail_2)
+ TEST_ENTRY (tcp_bind_error_fault)
+ TEST_ENTRY (tcp_bind_error_inval)
+ TEST_ENTRY (tcp_bind_localhost_ok)
+ TEST_ENTRY (tcp_listen_without_bind)
+ TEST_ENTRY (tcp_connect_error_fault)
+ TEST_ENTRY (tcp_connect_timeout)
+ TEST_ENTRY (tcp_close_while_connecting)
+ TEST_ENTRY (tcp_close)
+ TEST_ENTRY (tcp_close_accept)
+ TEST_ENTRY (tcp_flags)
+ TEST_ENTRY (tcp_write_to_half_open_connection)
+ TEST_ENTRY (tcp_unexpected_read)
+
+ TEST_ENTRY (tcp_read_stop)
+ TEST_HELPER (tcp_read_stop, tcp4_echo_server)
+
+ TEST_ENTRY (tcp_bind6_error_addrinuse)
+ TEST_ENTRY (tcp_bind6_error_addrnotavail)
+ TEST_ENTRY (tcp_bind6_error_fault)
+ TEST_ENTRY (tcp_bind6_error_inval)
+ TEST_ENTRY (tcp_bind6_localhost_ok)
+
+ TEST_ENTRY (udp_send_and_recv)
+ TEST_ENTRY (udp_dgram_too_big)
+ TEST_ENTRY (udp_dual_stack)
+ TEST_ENTRY (udp_ipv6_only)
+ TEST_ENTRY (udp_options)
+ TEST_ENTRY (udp_multicast_join)
+ TEST_ENTRY (udp_multicast_ttl)
+
+ TEST_ENTRY (udp_open)
+ TEST_HELPER (udp_open, udp4_echo_server)
+
+ TEST_ENTRY (pipe_bind_error_addrinuse)
+ TEST_ENTRY (pipe_bind_error_addrnotavail)
+ TEST_ENTRY (pipe_bind_error_inval)
+ TEST_ENTRY (pipe_listen_without_bind)
+
+ TEST_ENTRY (connection_fail)
+ TEST_ENTRY (connection_fail_doesnt_auto_close)
+
+ TEST_ENTRY (shutdown_close_tcp)
+ TEST_HELPER (shutdown_close_tcp, tcp4_echo_server)
+ TEST_ENTRY (shutdown_close_pipe)
+ TEST_HELPER (shutdown_close_pipe, pipe_echo_server)
+
+ TEST_ENTRY (shutdown_eof)
+ TEST_HELPER (shutdown_eof, tcp4_echo_server)
+
+ TEST_ENTRY (callback_stack)
+ TEST_HELPER (callback_stack, tcp4_echo_server)
+
+ TEST_ENTRY (error_message)
+
+ TEST_ENTRY (timer)
+ TEST_ENTRY (timer_init)
+ TEST_ENTRY (timer_again)
+ TEST_ENTRY (timer_start_twice)
+ TEST_ENTRY (timer_order)
+ TEST_ENTRY (timer_huge_timeout)
+ TEST_ENTRY (timer_huge_repeat)
+ TEST_ENTRY (timer_run_once)
+ TEST_ENTRY (timer_from_check)
+
+ TEST_ENTRY (idle_starvation)
+
+ TEST_ENTRY (ref)
+ TEST_ENTRY (idle_ref)
+ TEST_ENTRY (fs_poll_ref)
+ TEST_ENTRY (async_ref)
+ TEST_ENTRY (prepare_ref)
+ TEST_ENTRY (check_ref)
+ TEST_ENTRY (unref_in_prepare_cb)
+ TEST_ENTRY (timer_ref)
+ TEST_ENTRY (timer_ref2)
+ TEST_ENTRY (fs_event_ref)
+ TEST_ENTRY (tcp_ref)
+ TEST_ENTRY (tcp_ref2)
+ TEST_ENTRY (tcp_ref2b)
+ TEST_ENTRY (tcp_ref3)
+ TEST_HELPER (tcp_ref3, tcp4_echo_server)
+ TEST_ENTRY (tcp_ref4)
+ TEST_HELPER (tcp_ref4, tcp4_echo_server)
+ TEST_ENTRY (udp_ref)
+ TEST_ENTRY (udp_ref2)
+ TEST_ENTRY (udp_ref3)
+ TEST_HELPER (udp_ref3, udp4_echo_server)
+ TEST_ENTRY (pipe_ref)
+ TEST_ENTRY (pipe_ref2)
+ TEST_ENTRY (pipe_ref3)
+ TEST_HELPER (pipe_ref3, pipe_echo_server)
+ TEST_ENTRY (pipe_ref4)
+ TEST_HELPER (pipe_ref4, pipe_echo_server)
+ TEST_ENTRY (process_ref)
+ TEST_ENTRY (has_ref)
+
+ TEST_ENTRY (loop_handles)
+ TEST_ENTRY (walk_handles)
+
+ TEST_ENTRY (watcher_cross_stop)
+
+ TEST_ENTRY (active)
+
+ TEST_ENTRY (embed)
+
+ TEST_ENTRY (async)
+ TEST_ENTRY (async_null_cb)
+
+ TEST_ENTRY (get_currentexe)
+
+ TEST_ENTRY (process_title)
+
+ TEST_ENTRY (cwd_and_chdir)
+
+ TEST_ENTRY (get_memory)
+
+ TEST_ENTRY (get_loadavg)
+
+ TEST_ENTRY (hrtime)
+
+ TEST_ENTRY (getaddrinfo_fail)
+ TEST_ENTRY (getaddrinfo_basic)
+ TEST_ENTRY (getaddrinfo_concurrent)
+
+ TEST_ENTRY (getsockname_tcp)
+ TEST_ENTRY (getsockname_udp)
+
+ TEST_ENTRY (poll_duplex)
+ TEST_ENTRY (poll_unidirectional)
+ TEST_ENTRY (poll_close)
+
+ TEST_ENTRY (spawn_fails)
+ TEST_ENTRY (spawn_exit_code)
+ TEST_ENTRY (spawn_stdout)
+ TEST_ENTRY (spawn_stdin)
+ TEST_ENTRY (spawn_stdio_greater_than_3)
+ TEST_ENTRY (spawn_ignored_stdio)
+ TEST_ENTRY (spawn_and_kill)
+ TEST_ENTRY (spawn_detached)
+ TEST_ENTRY (spawn_and_kill_with_std)
+ TEST_ENTRY (spawn_and_ping)
+ TEST_ENTRY (spawn_preserve_env)
+ TEST_ENTRY (spawn_setuid_fails)
+ TEST_ENTRY (spawn_setgid_fails)
+ TEST_ENTRY (spawn_stdout_to_file)
+ TEST_ENTRY (spawn_stdout_and_stderr_to_file)
+ TEST_ENTRY (spawn_auto_unref)
+ TEST_ENTRY (fs_poll)
+ TEST_ENTRY (kill)
+
+#ifdef _WIN32
+ TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
+ TEST_ENTRY (argument_escaping)
+ TEST_ENTRY (environment_creation)
+ TEST_ENTRY (listen_with_simultaneous_accepts)
+ TEST_ENTRY (listen_no_simultaneous_accepts)
+ TEST_ENTRY (fs_stat_root)
+#else
+ TEST_ENTRY (emfile)
+ TEST_ENTRY (close_fd)
+ TEST_ENTRY (spawn_setuid_setgid)
+ TEST_ENTRY (we_get_signal)
+ TEST_ENTRY (we_get_signals)
+ TEST_ENTRY (signal_multiple_loops)
+#endif
+
+#ifdef __APPLE__
+ TEST_ENTRY (osx_select)
+#endif
+
+ TEST_ENTRY (fs_file_noent)
+ TEST_ENTRY (fs_file_nametoolong)
+ TEST_ENTRY (fs_file_loop)
+ TEST_ENTRY (fs_file_async)
+ TEST_ENTRY (fs_file_sync)
+ TEST_ENTRY (fs_async_dir)
+ TEST_ENTRY (fs_async_sendfile)
+ TEST_ENTRY (fs_fstat)
+ TEST_ENTRY (fs_chmod)
+ TEST_ENTRY (fs_chown)
+ TEST_ENTRY (fs_utime)
+ TEST_ENTRY (fs_futime)
+ TEST_ENTRY (fs_readlink)
+ TEST_ENTRY (fs_symlink)
+ TEST_ENTRY (fs_symlink_dir)
+ TEST_ENTRY (fs_stat_missing_path)
+ TEST_ENTRY (fs_read_file_eof)
+ TEST_ENTRY (fs_file_open_append)
+ TEST_ENTRY (fs_event_watch_dir)
+ TEST_ENTRY (fs_event_watch_file)
+ TEST_ENTRY (fs_event_watch_file_twice)
+ TEST_ENTRY (fs_event_watch_file_current_dir)
+ TEST_ENTRY (fs_event_no_callback_after_close)
+ TEST_ENTRY (fs_event_no_callback_on_close)
+ TEST_ENTRY (fs_event_immediate_close)
+ TEST_ENTRY (fs_event_close_with_pending_event)
+ TEST_ENTRY (fs_event_close_in_callback)
+ TEST_ENTRY (fs_event_start_and_close)
+ TEST_ENTRY (fs_event_error_reporting)
+ TEST_ENTRY (fs_readdir_empty_dir)
+ TEST_ENTRY (fs_readdir_file)
+ TEST_ENTRY (fs_open_dir)
+ TEST_ENTRY (fs_rename_to_existing_file)
+ TEST_ENTRY (threadpool_queue_work_simple)
+ TEST_ENTRY (threadpool_queue_work_einval)
+ TEST_ENTRY (threadpool_multiple_event_loops)
+ TEST_ENTRY (threadpool_cancel_getaddrinfo)
+ TEST_ENTRY (threadpool_cancel_work)
+ TEST_ENTRY (threadpool_cancel_fs)
+ TEST_ENTRY (threadpool_cancel_single)
+ TEST_ENTRY (thread_local_storage)
+ TEST_ENTRY (thread_mutex)
+ TEST_ENTRY (thread_rwlock)
+ TEST_ENTRY (thread_create)
+ TEST_ENTRY (dlerror)
+ TEST_ENTRY (ip4_addr)
+ TEST_ENTRY (ip6_addr_link_local)
+#if 0
+ /* These are for testing the test runner. */
+ TEST_ENTRY (fail_always)
+ TEST_ENTRY (pass_always)
+#endif
+TASK_LIST_END
diff --git a/third-party/libuv/test/test-loop-alive.c b/third-party/libuv/test/test-loop-alive.c
new file mode 100644
index 0000000000..89243357c3
--- /dev/null
+++ b/third-party/libuv/test/test-loop-alive.c
@@ -0,0 +1,68 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle);
+ ASSERT(status == 0);
+}
+
+
+static uv_work_t work_req;
+
+static void work_cb(uv_work_t* req) {
+ ASSERT(req);
+}
+
+static void after_work_cb(uv_work_t* req, int status) {
+ ASSERT(req);
+ ASSERT(status == 0);
+}
+
+
+TEST_IMPL(loop_alive) {
+ int r;
+ ASSERT(!uv_loop_alive(uv_default_loop()));
+
+ /* loops with handles are alive */
+ uv_timer_init(uv_default_loop(), &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 100, 0);
+ ASSERT(uv_loop_alive(uv_default_loop()));
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(!uv_loop_alive(uv_default_loop()));
+
+ /* loops with requests are alive */
+ r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
+ ASSERT(r == 0);
+ ASSERT(uv_loop_alive(uv_default_loop()));
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(!uv_loop_alive(uv_default_loop()));
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-loop-handles.c b/third-party/libuv/test/test-loop-handles.c
new file mode 100644
index 0000000000..fdf9281478
--- /dev/null
+++ b/third-party/libuv/test/test-loop-handles.c
@@ -0,0 +1,337 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/* Tests commented out with XXX are ones that are failing on Linux */
+
+/*
+ * Purpose of this test is to check semantics of starting and stopping
+ * prepare, check and idle watchers.
+ *
+ * - A watcher must be able to safely stop or close itself;
+ * - Once a watcher is stopped or closed its callback should never be called.
+ * - If a watcher is closed, it is implicitly stopped and its close_cb should
+ * be called exactly once.
+ * - A watcher can safely start and stop other watchers of the same type.
+ * - Prepare and check watchers are called once per event loop iterations.
+ * - All active idle watchers are queued when the event loop has no more work
+ * to do. This is done repeatedly until all idle watchers are inactive.
+ * - If a watcher starts another watcher of the same type its callback is not
+ * immediately queued. For check and prepare watchers, that means that if
+ * a watcher makes another of the same type active, it'll not be called until
+ * the next event loop iteration. For idle. watchers this means that the
+ * newly activated idle watcher might not be queued immediately.
+ * - Prepare, check, idle watchers keep the event loop alive even when they're
+ * not active.
+ *
+ * This is what the test globally does:
+ *
+ * - prepare_1 is always active and counts event loop iterations. It also
+ * creates and starts prepare_2 every other iteration. Finally it verifies
+ * that no idle watchers are active before polling.
+ * - prepare_2 is started by prepare_1 every other iteration. It immediately
+ * stops itself. It verifies that a watcher is not queued immediately
+ * if created by another watcher of the same type.
+ * - There's a check watcher that stops the event loop after a certain number
+ * of iterations. It starts a varying number of idle_1 watchers.
+ * - Idle_1 watchers stop themselves after being called a few times. All idle_1
+ * watchers try to start the idle_2 watcher if it is not already started or
+ * awaiting its close callback.
+ * - The idle_2 watcher always exists but immediately closes itself after
+ * being started by a check_1 watcher. It verifies that a watcher is
+ * implicitly stopped when closed, and that a watcher can close itself
+ * safely.
+ * - There is a repeating timer. It does not keep the event loop alive
+ * (ev_unref) but makes sure that the loop keeps polling the system for
+ * events.
+ */
+
+
+#include "uv.h"
+#include "task.h"
+
+#include <math.h>
+
+
+#define IDLE_COUNT 7
+#define ITERATIONS 21
+#define TIMEOUT 100
+
+
+static uv_prepare_t prepare_1_handle;
+static uv_prepare_t prepare_2_handle;
+
+static uv_check_t check_handle;
+
+static uv_idle_t idle_1_handles[IDLE_COUNT];
+static uv_idle_t idle_2_handle;
+
+static uv_timer_t timer_handle;
+
+
+static int loop_iteration = 0;
+
+static int prepare_1_cb_called = 0;
+static int prepare_1_close_cb_called = 0;
+
+static int prepare_2_cb_called = 0;
+static int prepare_2_close_cb_called = 0;
+
+static int check_cb_called = 0;
+static int check_close_cb_called = 0;
+
+static int idle_1_cb_called = 0;
+static int idle_1_close_cb_called = 0;
+static int idles_1_active = 0;
+
+static int idle_2_cb_called = 0;
+static int idle_2_close_cb_called = 0;
+static int idle_2_cb_started = 0;
+static int idle_2_is_active = 0;
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+}
+
+
+static void idle_2_close_cb(uv_handle_t* handle) {
+ LOG("IDLE_2_CLOSE_CB\n");
+
+ ASSERT(handle == (uv_handle_t*)&idle_2_handle);
+
+ ASSERT(idle_2_is_active);
+
+ idle_2_close_cb_called++;
+ idle_2_is_active = 0;
+}
+
+
+static void idle_2_cb(uv_idle_t* handle, int status) {
+ LOG("IDLE_2_CB\n");
+
+ ASSERT(handle == &idle_2_handle);
+ ASSERT(status == 0);
+
+ idle_2_cb_called++;
+
+ uv_close((uv_handle_t*)handle, idle_2_close_cb);
+}
+
+
+static void idle_1_cb(uv_idle_t* handle, int status) {
+ int r;
+
+ LOG("IDLE_1_CB\n");
+
+ ASSERT(handle != NULL);
+ ASSERT(status == 0);
+
+ ASSERT(idles_1_active > 0);
+
+ /* Init idle_2 and make it active */
+ if (!idle_2_is_active && !uv_is_closing((uv_handle_t*)&idle_2_handle)) {
+ r = uv_idle_init(uv_default_loop(), &idle_2_handle);
+ ASSERT(r == 0);
+ r = uv_idle_start(&idle_2_handle, idle_2_cb);
+ ASSERT(r == 0);
+ idle_2_is_active = 1;
+ idle_2_cb_started++;
+ }
+
+ idle_1_cb_called++;
+
+ if (idle_1_cb_called % 5 == 0) {
+ r = uv_idle_stop((uv_idle_t*)handle);
+ ASSERT(r == 0);
+ idles_1_active--;
+ }
+}
+
+
+static void idle_1_close_cb(uv_handle_t* handle) {
+ LOG("IDLE_1_CLOSE_CB\n");
+
+ ASSERT(handle != NULL);
+
+ idle_1_close_cb_called++;
+}
+
+
+static void prepare_1_close_cb(uv_handle_t* handle) {
+ LOG("PREPARE_1_CLOSE_CB");
+ ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
+
+ prepare_1_close_cb_called++;
+}
+
+
+static void check_close_cb(uv_handle_t* handle) {
+ LOG("CHECK_CLOSE_CB\n");
+ ASSERT(handle == (uv_handle_t*)&check_handle);
+
+ check_close_cb_called++;
+}
+
+
+static void prepare_2_close_cb(uv_handle_t* handle) {
+ LOG("PREPARE_2_CLOSE_CB\n");
+ ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
+
+ prepare_2_close_cb_called++;
+}
+
+
+static void check_cb(uv_check_t* handle, int status) {
+ int i, r;
+
+ LOG("CHECK_CB\n");
+
+ ASSERT(handle == &check_handle);
+ ASSERT(status == 0);
+
+ if (loop_iteration < ITERATIONS) {
+ /* Make some idle watchers active */
+ for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) {
+ r = uv_idle_start(&idle_1_handles[i], idle_1_cb);
+ ASSERT(r == 0);
+ idles_1_active++;
+ }
+
+ } else {
+ /* End of the test - close all handles */
+ uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb);
+ uv_close((uv_handle_t*)&check_handle, check_close_cb);
+ uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb);
+
+ for (i = 0; i < IDLE_COUNT; i++) {
+ uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb);
+ }
+
+ /* This handle is closed/recreated every time, close it only if it is */
+ /* active.*/
+ if (idle_2_is_active) {
+ uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb);
+ }
+ }
+
+ check_cb_called++;
+}
+
+
+static void prepare_2_cb(uv_prepare_t* handle, int status) {
+ int r;
+
+ LOG("PREPARE_2_CB\n");
+
+ ASSERT(handle == &prepare_2_handle);
+ ASSERT(status == 0);
+
+ /* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */
+ /* and it stops itself immediately. A started watcher is not queued */
+ /* until the next round, so when this callback is made */
+ /* (loop_iteration % 2 == 0) cannot be true. */
+ ASSERT(loop_iteration % 2 != 0);
+
+ r = uv_prepare_stop((uv_prepare_t*)handle);
+ ASSERT(r == 0);
+
+ prepare_2_cb_called++;
+}
+
+
+static void prepare_1_cb(uv_prepare_t* handle, int status) {
+ int r;
+
+ LOG("PREPARE_1_CB\n");
+
+ ASSERT(handle == &prepare_1_handle);
+ ASSERT(status == 0);
+
+ if (loop_iteration % 2 == 0) {
+ r = uv_prepare_start(&prepare_2_handle, prepare_2_cb);
+ ASSERT(r == 0);
+ }
+
+ prepare_1_cb_called++;
+ loop_iteration++;
+
+ printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS);
+}
+
+
+TEST_IMPL(loop_handles) {
+ int i;
+ int r;
+
+ r = uv_prepare_init(uv_default_loop(), &prepare_1_handle);
+ ASSERT(r == 0);
+ r = uv_prepare_start(&prepare_1_handle, prepare_1_cb);
+ ASSERT(r == 0);
+
+ r = uv_check_init(uv_default_loop(), &check_handle);
+ ASSERT(r == 0);
+ r = uv_check_start(&check_handle, check_cb);
+ ASSERT(r == 0);
+
+ /* initialize only, prepare_2 is started by prepare_1_cb */
+ r = uv_prepare_init(uv_default_loop(), &prepare_2_handle);
+ ASSERT(r == 0);
+
+ for (i = 0; i < IDLE_COUNT; i++) {
+ /* initialize only, idle_1 handles are started by check_cb */
+ r = uv_idle_init(uv_default_loop(), &idle_1_handles[i]);
+ ASSERT(r == 0);
+ }
+
+ /* don't init or start idle_2, both is done by idle_1_cb */
+
+ /* the timer callback is there to keep the event loop polling */
+ /* unref it as it is not supposed to keep the loop alive */
+ r = uv_timer_init(uv_default_loop(), &timer_handle);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT);
+ ASSERT(r == 0);
+ uv_unref((uv_handle_t*)&timer_handle);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(loop_iteration == ITERATIONS);
+
+ ASSERT(prepare_1_cb_called == ITERATIONS);
+ ASSERT(prepare_1_close_cb_called == 1);
+
+ ASSERT(prepare_2_cb_called == floor(ITERATIONS / 2.0));
+ ASSERT(prepare_2_close_cb_called == 1);
+
+ ASSERT(check_cb_called == ITERATIONS);
+ ASSERT(check_close_cb_called == 1);
+
+ /* idle_1_cb should be called a lot */
+ ASSERT(idle_1_close_cb_called == IDLE_COUNT);
+
+ ASSERT(idle_2_close_cb_called == idle_2_cb_started);
+ ASSERT(idle_2_is_active == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-loop-stop.c b/third-party/libuv/test/test-loop-stop.c
new file mode 100644
index 0000000000..c519644ed2
--- /dev/null
+++ b/third-party/libuv/test/test-loop-stop.c
@@ -0,0 +1,73 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_prepare_t prepare_handle;
+static uv_timer_t timer_handle;
+static int prepare_called = 0;
+static int timer_called = 0;
+static int num_ticks = 10;
+
+
+static void prepare_cb(uv_prepare_t* handle, int status) {
+ ASSERT(handle == &prepare_handle);
+ ASSERT(status == 0);
+ prepare_called++;
+ if (prepare_called == num_ticks)
+ uv_prepare_stop(handle);
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+ timer_called++;
+ if (timer_called == 1)
+ uv_stop(uv_default_loop());
+ else if (timer_called == num_ticks)
+ uv_timer_stop(handle);
+}
+
+
+TEST_IMPL(loop_stop) {
+ int r;
+ uv_prepare_init(uv_default_loop(), &prepare_handle);
+ uv_prepare_start(&prepare_handle, prepare_cb);
+ uv_timer_init(uv_default_loop(), &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 100, 100);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r != 0);
+ ASSERT(timer_called == 1);
+
+ r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
+ ASSERT(r != 0);
+ ASSERT(prepare_called > 1);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(timer_called == 10);
+ ASSERT(prepare_called == 10);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-loop-time.c b/third-party/libuv/test/test-loop-time.c
new file mode 100644
index 0000000000..49dc79b2c3
--- /dev/null
+++ b/third-party/libuv/test/test-loop-time.c
@@ -0,0 +1,34 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+TEST_IMPL(loop_update_time) {
+ uint64_t start;
+
+ start = uv_now(uv_default_loop());
+ while (uv_now(uv_default_loop()) - start < 1000)
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-multiple-listen.c b/third-party/libuv/test/test-multiple-listen.c
new file mode 100644
index 0000000000..4ae5fa67b3
--- /dev/null
+++ b/third-party/libuv/test/test-multiple-listen.c
@@ -0,0 +1,109 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static int connection_cb_called = 0;
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+static uv_tcp_t server;
+static uv_tcp_t client;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ ASSERT(status == 0);
+ uv_close((uv_handle_t*)&server, close_cb);
+ connection_cb_called++;
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
+ ASSERT(r == 0);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ free(req);
+ uv_close((uv_handle_t*)&client, close_cb);
+ connect_cb_called++;
+}
+
+
+static void client_connect(void) {
+ struct sockaddr_in addr;
+ uv_connect_t* connect_req = malloc(sizeof *connect_req);
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(connect_req != NULL);
+
+ r = uv_tcp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(connect_req,
+ &client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+}
+
+
+
+TEST_IMPL(multiple_listen) {
+ start_server();
+
+ client_connect();
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connection_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-mutexes.c b/third-party/libuv/test/test-mutexes.c
new file mode 100644
index 0000000000..896f46bbed
--- /dev/null
+++ b/third-party/libuv/test/test-mutexes.c
@@ -0,0 +1,63 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* The mutex and rwlock tests are really poor.
+ * They're very basic sanity checks and nothing more.
+ * Apologies if that rhymes.
+ */
+
+TEST_IMPL(thread_mutex) {
+ uv_mutex_t mutex;
+ int r;
+
+ r = uv_mutex_init(&mutex);
+ ASSERT(r == 0);
+
+ uv_mutex_lock(&mutex);
+ uv_mutex_unlock(&mutex);
+ uv_mutex_destroy(&mutex);
+
+ return 0;
+}
+
+
+TEST_IMPL(thread_rwlock) {
+ uv_rwlock_t rwlock;
+ int r;
+
+ r = uv_rwlock_init(&rwlock);
+ ASSERT(r == 0);
+
+ uv_rwlock_rdlock(&rwlock);
+ uv_rwlock_rdunlock(&rwlock);
+ uv_rwlock_wrlock(&rwlock);
+ uv_rwlock_wrunlock(&rwlock);
+ uv_rwlock_destroy(&rwlock);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-osx-select.c b/third-party/libuv/test/test-osx-select.c
new file mode 100644
index 0000000000..e5e1bf8b46
--- /dev/null
+++ b/third-party/libuv/test/test-osx-select.c
@@ -0,0 +1,82 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#ifdef __APPLE__
+
+#include <sys/ioctl.h>
+#include <string.h>
+
+static int read_count;
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char slab[1024];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ fprintf(stdout, "got data %d\n", ++read_count);
+
+ if (read_count == 3)
+ uv_close((uv_handle_t*) stream, NULL);
+}
+
+
+TEST_IMPL(osx_select) {
+ int r;
+ int fd;
+ size_t i;
+ size_t len;
+ const char* str;
+ uv_tty_t tty;
+
+ fd = open("/dev/tty", O_RDONLY);
+
+ ASSERT(fd >= 0);
+
+ r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
+ ASSERT(r == 0);
+
+ uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
+
+ /* Emulate user-input */
+ str = "got some input\n"
+ "with a couple of lines\n"
+ "feel pretty happy\n";
+ for (i = 0, len = strlen(str); i < len; i++) {
+ r = ioctl(fd, TIOCSTI, str + i);
+ ASSERT(r == 0);
+ }
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(read_count == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* __APPLE__ */
diff --git a/third-party/libuv/test/test-pass-always.c b/third-party/libuv/test/test-pass-always.c
new file mode 100644
index 0000000000..4fb58ff94b
--- /dev/null
+++ b/third-party/libuv/test/test-pass-always.c
@@ -0,0 +1,28 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "task.h"
+
+
+TEST_IMPL(pass_always) {
+ /* This test always passes. It is used to test the test runner. */
+ return 0;
+}
diff --git a/third-party/libuv/test/test-ping-pong.c b/third-party/libuv/test/test-ping-pong.c
new file mode 100644
index 0000000000..c579fdd668
--- /dev/null
+++ b/third-party/libuv/test/test-ping-pong.c
@@ -0,0 +1,263 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static int completed_pingers = 0;
+
+#define NUM_PINGS 1000
+
+/* 64 bytes is enough for a pinger */
+#define BUFSIZE 10240
+
+static char PING[] = "PING\n";
+static int pinger_on_connect_count;
+
+
+typedef struct {
+ int pongs;
+ int state;
+ union {
+ uv_tcp_t tcp;
+ uv_pipe_t pipe;
+ } stream;
+ uv_connect_t connect_req;
+ char read_buffer[BUFSIZE];
+} pinger_t;
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = malloc(size);
+ buf->len = size;
+}
+
+
+static void pinger_on_close(uv_handle_t* handle) {
+ pinger_t* pinger = (pinger_t*)handle->data;
+
+ ASSERT(NUM_PINGS == pinger->pongs);
+
+ free(pinger);
+
+ completed_pingers++;
+}
+
+
+static void pinger_after_write(uv_write_t *req, int status) {
+ ASSERT(status == 0);
+ free(req);
+}
+
+
+static void pinger_write_ping(pinger_t* pinger) {
+ uv_write_t *req;
+ uv_buf_t buf;
+
+ buf = uv_buf_init(PING, sizeof(PING) - 1);
+
+ req = malloc(sizeof(*req));
+ if (uv_write(req,
+ (uv_stream_t*) &pinger->stream.tcp,
+ &buf,
+ 1,
+ pinger_after_write)) {
+ FATAL("uv_write failed");
+ }
+
+ puts("PING");
+}
+
+
+static void pinger_read_cb(uv_stream_t* stream,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ssize_t i;
+ pinger_t* pinger;
+
+ pinger = (pinger_t*)stream->data;
+
+ if (nread < 0) {
+ ASSERT(nread == UV_EOF);
+
+ puts("got EOF");
+ free(buf->base);
+
+ uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
+
+ return;
+ }
+
+ /* Now we count the pings */
+ for (i = 0; i < nread; i++) {
+ ASSERT(buf->base[i] == PING[pinger->state]);
+ pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
+
+ if (pinger->state != 0)
+ continue;
+
+ printf("PONG %d\n", pinger->pongs);
+ pinger->pongs++;
+
+ if (pinger->pongs < NUM_PINGS) {
+ pinger_write_ping(pinger);
+ } else {
+ uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
+ break;
+ }
+ }
+
+ free(buf->base);
+}
+
+
+static void pinger_on_connect(uv_connect_t *req, int status) {
+ pinger_t *pinger = (pinger_t*)req->handle->data;
+
+ pinger_on_connect_count++;
+
+ ASSERT(status == 0);
+
+ ASSERT(1 == uv_is_readable(req->handle));
+ ASSERT(1 == uv_is_writable(req->handle));
+ ASSERT(0 == uv_is_closing((uv_handle_t *) req->handle));
+
+ pinger_write_ping(pinger);
+
+ uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb);
+}
+
+
+/* same ping-pong test, but using IPv6 connection */
+static void tcp_pinger_v6_new(void) {
+ int r;
+ struct sockaddr_in6 server_addr;
+ pinger_t *pinger;
+
+ ASSERT(0 ==uv_ip6_addr("::1", TEST_PORT, &server_addr));
+ pinger = malloc(sizeof(*pinger));
+ pinger->state = 0;
+ pinger->pongs = 0;
+
+ /* Try to connect to the server and do NUM_PINGS ping-pongs. */
+ r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
+ pinger->stream.tcp.data = pinger;
+ ASSERT(!r);
+
+ /* We are never doing multiple reads/connects at a time anyway. */
+ /* so these handles can be pre-initialized. */
+ r = uv_tcp_connect(&pinger->connect_req,
+ &pinger->stream.tcp,
+ (const struct sockaddr*) &server_addr,
+ pinger_on_connect);
+ ASSERT(!r);
+
+ /* Synchronous connect callbacks are not allowed. */
+ ASSERT(pinger_on_connect_count == 0);
+}
+
+
+static void tcp_pinger_new(void) {
+ int r;
+ struct sockaddr_in server_addr;
+ pinger_t *pinger;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
+ pinger = malloc(sizeof(*pinger));
+ pinger->state = 0;
+ pinger->pongs = 0;
+
+ /* Try to connect to the server and do NUM_PINGS ping-pongs. */
+ r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
+ pinger->stream.tcp.data = pinger;
+ ASSERT(!r);
+
+ /* We are never doing multiple reads/connects at a time anyway. */
+ /* so these handles can be pre-initialized. */
+ r = uv_tcp_connect(&pinger->connect_req,
+ &pinger->stream.tcp,
+ (const struct sockaddr*) &server_addr,
+ pinger_on_connect);
+ ASSERT(!r);
+
+ /* Synchronous connect callbacks are not allowed. */
+ ASSERT(pinger_on_connect_count == 0);
+}
+
+
+static void pipe_pinger_new(void) {
+ int r;
+ pinger_t *pinger;
+
+ pinger = (pinger_t*)malloc(sizeof(*pinger));
+ pinger->state = 0;
+ pinger->pongs = 0;
+
+ /* Try to connect to the server and do NUM_PINGS ping-pongs. */
+ r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0);
+ pinger->stream.pipe.data = pinger;
+ ASSERT(!r);
+
+ /* We are never doing multiple reads/connects at a time anyway. */
+ /* so these handles can be pre-initialized. */
+
+ uv_pipe_connect(&pinger->connect_req, &pinger->stream.pipe, TEST_PIPENAME,
+ pinger_on_connect);
+
+ /* Synchronous connect callbacks are not allowed. */
+ ASSERT(pinger_on_connect_count == 0);
+}
+
+
+TEST_IMPL(tcp_ping_pong) {
+ tcp_pinger_new();
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(completed_pingers == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ping_pong_v6) {
+ tcp_pinger_v6_new();
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(completed_pingers == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_ping_pong) {
+ pipe_pinger_new();
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(completed_pingers == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-pipe-bind-error.c b/third-party/libuv/test/test-pipe-bind-error.c
new file mode 100644
index 0000000000..38b57db699
--- /dev/null
+++ b/third-party/libuv/test/test-pipe-bind-error.c
@@ -0,0 +1,136 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+TEST_IMPL(pipe_bind_error_addrinuse) {
+ uv_pipe_t server1, server2;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &server1, 0);
+ ASSERT(r == 0);
+ r = uv_pipe_bind(&server1, TEST_PIPENAME);
+ ASSERT(r == 0);
+
+ r = uv_pipe_init(uv_default_loop(), &server2, 0);
+ ASSERT(r == 0);
+ r = uv_pipe_bind(&server2, TEST_PIPENAME);
+ ASSERT(r == UV_EADDRINUSE);
+
+ r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server1, close_cb);
+ uv_close((uv_handle_t*)&server2, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_bind_error_addrnotavail) {
+ uv_pipe_t server;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &server, 0);
+ ASSERT(r == 0);
+
+ r = uv_pipe_bind(&server, BAD_PIPENAME);
+ ASSERT(r == UV_EACCES);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_bind_error_inval) {
+ uv_pipe_t server;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &server, 0);
+ ASSERT(r == 0);
+ r = uv_pipe_bind(&server, TEST_PIPENAME);
+ ASSERT(r == 0);
+ r = uv_pipe_bind(&server, TEST_PIPENAME_2);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_listen_without_bind) {
+ uv_pipe_t server;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &server, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-pipe-connect-error.c b/third-party/libuv/test/test-pipe-connect-error.c
new file mode 100644
index 0000000000..ebb2a6ca82
--- /dev/null
+++ b/third-party/libuv/test/test-pipe-connect-error.c
@@ -0,0 +1,95 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+ ASSERT(status == UV_ENOENT);
+ uv_close((uv_handle_t*)connect_req->handle, close_cb);
+ connect_cb_called++;
+}
+
+
+static void connect_cb_file(uv_connect_t* connect_req, int status) {
+ ASSERT(status == UV_ENOTSOCK || status == UV_ECONNREFUSED);
+ uv_close((uv_handle_t*)connect_req->handle, close_cb);
+ connect_cb_called++;
+}
+
+
+TEST_IMPL(pipe_connect_bad_name) {
+ uv_pipe_t client;
+ uv_connect_t req;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &client, 0);
+ ASSERT(r == 0);
+ uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_connect_to_file) {
+ const char* path = "test/fixtures/empty_file";
+ uv_pipe_t client;
+ uv_connect_t req;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &client, 0);
+ ASSERT(r == 0);
+ uv_pipe_connect(&req, &client, path, connect_cb_file);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-pipe-server-close.c b/third-party/libuv/test/test-pipe-server-close.c
new file mode 100644
index 0000000000..1dcdfffaf7
--- /dev/null
+++ b/third-party/libuv/test/test-pipe-server-close.c
@@ -0,0 +1,91 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+
+static uv_pipe_t pipe_client;
+static uv_pipe_t pipe_server;
+static uv_connect_t connect_req;
+
+static int pipe_close_cb_called = 0;
+static int pipe_client_connect_cb_called = 0;
+
+
+static void pipe_close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*) &pipe_client ||
+ handle == (uv_handle_t*) &pipe_server);
+ pipe_close_cb_called++;
+}
+
+
+static void pipe_client_connect_cb(uv_connect_t* req, int status) {
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ pipe_client_connect_cb_called++;
+
+ uv_close((uv_handle_t*) &pipe_client, pipe_close_cb);
+ uv_close((uv_handle_t*) &pipe_server, pipe_close_cb);
+}
+
+
+static void pipe_server_connection_cb(uv_stream_t* handle, int status) {
+ /* This function *may* be called, depending on whether accept or the
+ * connection callback is called first.
+ */
+ ASSERT(status == 0);
+}
+
+
+TEST_IMPL(pipe_server_close) {
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+ ASSERT(loop != NULL);
+
+ r = uv_pipe_init(loop, &pipe_server, 0);
+ ASSERT(r == 0);
+
+ r = uv_pipe_bind(&pipe_server, TEST_PIPENAME);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb);
+ ASSERT(r == 0);
+
+ r = uv_pipe_init(loop, &pipe_client, 0);
+ ASSERT(r == 0);
+
+ uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(pipe_client_connect_cb_called == 1);
+ ASSERT(pipe_close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-platform-output.c b/third-party/libuv/test/test-platform-output.c
new file mode 100644
index 0000000000..d2104f40a1
--- /dev/null
+++ b/third-party/libuv/test/test-platform-output.c
@@ -0,0 +1,103 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+
+TEST_IMPL(platform_output) {
+ char buffer[512];
+ size_t rss;
+ double uptime;
+ uv_cpu_info_t* cpus;
+ uv_interface_address_t* interfaces;
+ int count;
+ int i;
+ int err;
+
+ err = uv_get_process_title(buffer, sizeof(buffer));
+ ASSERT(err == 0);
+ printf("uv_get_process_title: %s\n", buffer);
+
+ err = uv_resident_set_memory(&rss);
+ ASSERT(err == 0);
+ printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss);
+
+ err = uv_uptime(&uptime);
+ ASSERT(err == 0);
+ ASSERT(uptime > 0);
+ printf("uv_uptime: %f\n", uptime);
+
+ err = uv_cpu_info(&cpus, &count);
+ ASSERT(err == 0);
+
+ printf("uv_cpu_info:\n");
+ for (i = 0; i < count; i++) {
+ printf(" model: %s\n", cpus[i].model);
+ printf(" speed: %d\n", cpus[i].speed);
+ printf(" times.sys: %llu\n", (unsigned long long) cpus[i].cpu_times.sys);
+ printf(" times.user: %llu\n",
+ (unsigned long long) cpus[i].cpu_times.user);
+ printf(" times.idle: %llu\n",
+ (unsigned long long) cpus[i].cpu_times.idle);
+ printf(" times.irq: %llu\n", (unsigned long long) cpus[i].cpu_times.irq);
+ printf(" times.nice: %llu\n",
+ (unsigned long long) cpus[i].cpu_times.nice);
+ }
+ uv_free_cpu_info(cpus, count);
+
+ err = uv_interface_addresses(&interfaces, &count);
+ ASSERT(err == 0);
+
+ printf("uv_interface_addresses:\n");
+ for (i = 0; i < count; i++) {
+ printf(" name: %s\n", interfaces[i].name);
+ printf(" internal: %d\n", interfaces[i].is_internal);
+ printf(" physical address: ");
+ printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
+ (unsigned char)interfaces[i].phys_addr[0],
+ (unsigned char)interfaces[i].phys_addr[1],
+ (unsigned char)interfaces[i].phys_addr[2],
+ (unsigned char)interfaces[i].phys_addr[3],
+ (unsigned char)interfaces[i].phys_addr[4],
+ (unsigned char)interfaces[i].phys_addr[5]);
+
+ if (interfaces[i].address.address4.sin_family == AF_INET) {
+ uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer));
+ } else if (interfaces[i].address.address4.sin_family == AF_INET6) {
+ uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer));
+ }
+
+ printf(" address: %s\n", buffer);
+
+ if (interfaces[i].netmask.netmask4.sin_family == AF_INET) {
+ uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer));
+ } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) {
+ uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer));
+ }
+
+ printf(" netmask: %s\n", buffer);
+ }
+ uv_free_interface_addresses(interfaces, count);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-poll-close.c b/third-party/libuv/test/test-poll-close.c
new file mode 100644
index 0000000000..2eccddf5b0
--- /dev/null
+++ b/third-party/libuv/test/test-poll-close.c
@@ -0,0 +1,73 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <errno.h>
+
+#ifndef _WIN32
+# include <fcntl.h>
+# include <sys/socket.h>
+# include <unistd.h>
+#endif
+
+#include "uv.h"
+#include "task.h"
+
+#define NUM_SOCKETS 64
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+TEST_IMPL(poll_close) {
+ uv_os_sock_t sockets[NUM_SOCKETS];
+ uv_poll_t poll_handles[NUM_SOCKETS];
+ int i;
+
+#ifdef _WIN32
+ {
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+ }
+#endif
+
+ for (i = 0; i < NUM_SOCKETS; i++) {
+ sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
+ uv_poll_init_socket(uv_default_loop(), &poll_handles[i], sockets[i]);
+ uv_poll_start(&poll_handles[i], UV_READABLE | UV_WRITABLE, NULL);
+ }
+
+ for (i = 0; i < NUM_SOCKETS; i++) {
+ uv_close((uv_handle_t*) &poll_handles[i], close_cb);
+ }
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == NUM_SOCKETS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-poll.c b/third-party/libuv/test/test-poll.c
new file mode 100644
index 0000000000..0736b9b0bf
--- /dev/null
+++ b/third-party/libuv/test/test-poll.c
@@ -0,0 +1,581 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <errno.h>
+
+#ifndef _WIN32
+# include <fcntl.h>
+# include <sys/socket.h>
+# include <unistd.h>
+#endif
+
+#include "uv.h"
+#include "task.h"
+
+
+#define NUM_CLIENTS 5
+#define TRANSFER_BYTES (1 << 16)
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b));
+
+
+typedef enum {
+ UNIDIRECTIONAL,
+ DUPLEX
+} test_mode_t;
+
+typedef struct connection_context_s {
+ uv_poll_t poll_handle;
+ uv_timer_t timer_handle;
+ uv_os_sock_t sock;
+ size_t read, sent;
+ int is_server_connection;
+ int open_handles;
+ int got_fin, sent_fin;
+ unsigned int events, delayed_events;
+} connection_context_t;
+
+typedef struct server_context_s {
+ uv_poll_t poll_handle;
+ uv_os_sock_t sock;
+ int connections;
+} server_context_t;
+
+
+static void delay_timer_cb(uv_timer_t* timer, int status);
+
+
+static test_mode_t test_mode = DUPLEX;
+
+static int closed_connections = 0;
+
+static int valid_writable_wakeups = 0;
+static int spurious_writable_wakeups = 0;
+
+
+static int got_eagain(void) {
+#ifdef _WIN32
+ return WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+ return errno == EAGAIN
+ || errno == EINPROGRESS
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK;
+#endif
+ ;
+#endif
+}
+
+
+static void set_nonblocking(uv_os_sock_t sock) {
+ int r;
+#ifdef _WIN32
+ unsigned long on = 1;
+ r = ioctlsocket(sock, FIONBIO, &on);
+ ASSERT(r == 0);
+#else
+ int flags = fcntl(sock, F_GETFL, 0);
+ ASSERT(flags >= 0);
+ r = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ ASSERT(r >= 0);
+#endif
+}
+
+
+static uv_os_sock_t create_nonblocking_bound_socket(
+ struct sockaddr_in bind_addr) {
+ uv_os_sock_t sock;
+ int r;
+
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+ set_nonblocking(sock);
+
+#ifndef _WIN32
+ {
+ /* Allow reuse of the port. */
+ int yes = 1;
+ r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
+ ASSERT(r == 0);
+ }
+#endif
+
+ r = bind(sock, (const struct sockaddr*) &bind_addr, sizeof bind_addr);
+ ASSERT(r == 0);
+
+ return sock;
+}
+
+
+static void close_socket(uv_os_sock_t sock) {
+ int r;
+#ifdef _WIN32
+ r = closesocket(sock);
+#else
+ r = close(sock);
+#endif
+ ASSERT(r == 0);
+}
+
+
+static connection_context_t* create_connection_context(
+ uv_os_sock_t sock, int is_server_connection) {
+ int r;
+ connection_context_t* context;
+
+ context = (connection_context_t*) malloc(sizeof *context);
+ ASSERT(context != NULL);
+
+ context->sock = sock;
+ context->is_server_connection = is_server_connection;
+ context->read = 0;
+ context->sent = 0;
+ context->open_handles = 0;
+ context->events = 0;
+ context->delayed_events = 0;
+ context->got_fin = 0;
+ context->sent_fin = 0;
+
+ r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock);
+ context->open_handles++;
+ context->poll_handle.data = context;
+ ASSERT(r == 0);
+
+ r = uv_timer_init(uv_default_loop(), &context->timer_handle);
+ context->open_handles++;
+ context->timer_handle.data = context;
+ ASSERT(r == 0);
+
+ return context;
+}
+
+
+static void connection_close_cb(uv_handle_t* handle) {
+ connection_context_t* context = (connection_context_t*) handle->data;
+
+ if (--context->open_handles == 0) {
+ if (test_mode == DUPLEX || context->is_server_connection) {
+ ASSERT(context->read == TRANSFER_BYTES);
+ } else {
+ ASSERT(context->read == 0);
+ }
+
+ if (test_mode == DUPLEX || !context->is_server_connection) {
+ ASSERT(context->sent == TRANSFER_BYTES);
+ } else {
+ ASSERT(context->sent == 0);
+ }
+
+ closed_connections++;
+
+ free(context);
+ }
+}
+
+
+static void destroy_connection_context(connection_context_t* context) {
+ uv_close((uv_handle_t*) &context->poll_handle, connection_close_cb);
+ uv_close((uv_handle_t*) &context->timer_handle, connection_close_cb);
+}
+
+
+static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
+ connection_context_t* context = (connection_context_t*) handle->data;
+ unsigned int new_events;
+ int r;
+
+ ASSERT(status == 0);
+ ASSERT(events & context->events);
+ ASSERT(!(events & ~context->events));
+
+ new_events = context->events;
+
+ if (events & UV_READABLE) {
+ int action = rand() % 7;
+
+ switch (action) {
+ case 0:
+ case 1: {
+ /* Read a couple of bytes. */
+ static char buffer[74];
+ r = recv(context->sock, buffer, sizeof buffer, 0);
+ ASSERT(r >= 0);
+
+ if (r > 0) {
+ context->read += r;
+ } else {
+ /* Got FIN. */
+ context->got_fin = 1;
+ new_events &= ~UV_READABLE;
+ }
+
+ break;
+ }
+
+ case 2:
+ case 3: {
+ /* Read until EAGAIN. */
+ static char buffer[931];
+ r = recv(context->sock, buffer, sizeof buffer, 0);
+ ASSERT(r >= 0);
+
+ while (r > 0) {
+ context->read += r;
+ r = recv(context->sock, buffer, sizeof buffer, 0);
+ }
+
+ if (r == 0) {
+ /* Got FIN. */
+ context->got_fin = 1;
+ new_events &= ~UV_READABLE;
+ } else {
+ ASSERT(got_eagain());
+ }
+
+ break;
+ }
+
+ case 4:
+ /* Ignore. */
+ break;
+
+ case 5:
+ /* Stop reading for a while. Restart in timer callback. */
+ new_events &= ~UV_READABLE;
+ if (!uv_is_active((uv_handle_t*) &context->timer_handle)) {
+ context->delayed_events = UV_READABLE;
+ uv_timer_start(&context->timer_handle, delay_timer_cb, 10, 0);
+ } else {
+ context->delayed_events |= UV_READABLE;
+ }
+ break;
+
+ case 6:
+ /* Fudge with the event mask. */
+ uv_poll_start(&context->poll_handle, UV_WRITABLE, connection_poll_cb);
+ uv_poll_start(&context->poll_handle, UV_READABLE, connection_poll_cb);
+ context->events = UV_READABLE;
+ break;
+
+ default:
+ ASSERT(0);
+ }
+ }
+
+ if (events & UV_WRITABLE) {
+ if (context->sent < TRANSFER_BYTES &&
+ !(test_mode == UNIDIRECTIONAL && context->is_server_connection)) {
+ /* We have to send more bytes. */
+ int action = rand() % 7;
+
+ switch (action) {
+ case 0:
+ case 1: {
+ /* Send a couple of bytes. */
+ static char buffer[103];
+
+ int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
+ ASSERT(send_bytes > 0);
+
+ r = send(context->sock, buffer, send_bytes, 0);
+
+ if (r < 0) {
+ ASSERT(got_eagain());
+ spurious_writable_wakeups++;
+ break;
+ }
+
+ ASSERT(r > 0);
+ context->sent += r;
+ valid_writable_wakeups++;
+ break;
+ }
+
+ case 2:
+ case 3: {
+ /* Send until EAGAIN. */
+ static char buffer[1234];
+
+ int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
+ ASSERT(send_bytes > 0);
+
+ r = send(context->sock, buffer, send_bytes, 0);
+
+ if (r < 0) {
+ ASSERT(got_eagain());
+ spurious_writable_wakeups++;
+ break;
+ }
+
+ ASSERT(r > 0);
+ valid_writable_wakeups++;
+ context->sent += r;
+
+ while (context->sent < TRANSFER_BYTES) {
+ send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
+ ASSERT(send_bytes > 0);
+
+ r = send(context->sock, buffer, send_bytes, 0);
+
+ if (r <= 0) break;
+ context->sent += r;
+ }
+ ASSERT(r > 0 || got_eagain());
+ break;
+ }
+
+ case 4:
+ /* Ignore. */
+ break;
+
+ case 5:
+ /* Stop sending for a while. Restart in timer callback. */
+ new_events &= ~UV_WRITABLE;
+ if (!uv_is_active((uv_handle_t*) &context->timer_handle)) {
+ context->delayed_events = UV_WRITABLE;
+ uv_timer_start(&context->timer_handle, delay_timer_cb, 100, 0);
+ } else {
+ context->delayed_events |= UV_WRITABLE;
+ }
+ break;
+
+ case 6:
+ /* Fudge with the event mask. */
+ uv_poll_start(&context->poll_handle,
+ UV_READABLE,
+ connection_poll_cb);
+ uv_poll_start(&context->poll_handle,
+ UV_WRITABLE,
+ connection_poll_cb);
+ context->events = UV_WRITABLE;
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ } else {
+ /* Nothing more to write. Send FIN. */
+ int r;
+#ifdef _WIN32
+ r = shutdown(context->sock, SD_SEND);
+#else
+ r = shutdown(context->sock, SHUT_WR);
+#endif
+ ASSERT(r == 0);
+ context->sent_fin = 1;
+ new_events &= ~UV_WRITABLE;
+ }
+ }
+
+ if (context->got_fin && context->sent_fin) {
+ /* Sent and received FIN. Close and destroy context. */
+ close_socket(context->sock);
+ destroy_connection_context(context);
+ context->events = 0;
+
+ } else if (new_events != context->events) {
+ /* Poll mask changed. Call uv_poll_start again. */
+ context->events = new_events;
+ uv_poll_start(handle, new_events, connection_poll_cb);
+ }
+
+ /* Assert that uv_is_active works correctly for poll handles. */
+ if (context->events != 0) {
+ ASSERT(1 == uv_is_active((uv_handle_t*) handle));
+ } else {
+ ASSERT(0 == uv_is_active((uv_handle_t*) handle));
+ }
+}
+
+
+static void delay_timer_cb(uv_timer_t* timer, int status) {
+ connection_context_t* context = (connection_context_t*) timer->data;
+ int r;
+
+ /* Timer should auto stop. */
+ ASSERT(0 == uv_is_active((uv_handle_t*) timer));
+
+ /* Add the requested events to the poll mask. */
+ ASSERT(context->delayed_events != 0);
+ context->events |= context->delayed_events;
+ context->delayed_events = 0;
+
+ r = uv_poll_start(&context->poll_handle,
+ context->events,
+ connection_poll_cb);
+ ASSERT(r == 0);
+}
+
+
+static server_context_t* create_server_context(
+ uv_os_sock_t sock) {
+ int r;
+ server_context_t* context;
+
+ context = (server_context_t*) malloc(sizeof *context);
+ ASSERT(context != NULL);
+
+ context->sock = sock;
+ context->connections = 0;
+
+ r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock);
+ context->poll_handle.data = context;
+ ASSERT(r == 0);
+
+ return context;
+}
+
+
+static void server_close_cb(uv_handle_t* handle) {
+ server_context_t* context = (server_context_t*) handle->data;
+ free(context);
+}
+
+
+static void destroy_server_context(server_context_t* context) {
+ uv_close((uv_handle_t*) &context->poll_handle, server_close_cb);
+}
+
+
+static void server_poll_cb(uv_poll_t* handle, int status, int events) {
+ server_context_t* server_context = (server_context_t*)
+ handle->data;
+ connection_context_t* connection_context;
+ struct sockaddr_in addr;
+ socklen_t addr_len;
+ uv_os_sock_t sock;
+ int r;
+
+ addr_len = sizeof addr;
+ sock = accept(server_context->sock, (struct sockaddr*) &addr, &addr_len);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+ set_nonblocking(sock);
+
+ connection_context = create_connection_context(sock, 1);
+ connection_context->events = UV_READABLE | UV_WRITABLE;
+ r = uv_poll_start(&connection_context->poll_handle,
+ UV_READABLE | UV_WRITABLE,
+ connection_poll_cb);
+ ASSERT(r == 0);
+
+ if (++server_context->connections == NUM_CLIENTS) {
+ close_socket(server_context->sock);
+ destroy_server_context(server_context);
+ }
+}
+
+
+static void start_server(void) {
+ server_context_t* context;
+ struct sockaddr_in addr;
+ uv_os_sock_t sock;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ sock = create_nonblocking_bound_socket(addr);
+ context = create_server_context(sock);
+
+ r = listen(sock, 100);
+ ASSERT(r == 0);
+
+ r = uv_poll_start(&context->poll_handle, UV_READABLE, server_poll_cb);
+ ASSERT(r == 0);
+}
+
+
+static void start_client(void) {
+ uv_os_sock_t sock;
+ connection_context_t* context;
+ struct sockaddr_in server_addr;
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr));
+
+ sock = create_nonblocking_bound_socket(addr);
+ context = create_connection_context(sock, 0);
+
+ context->events = UV_READABLE | UV_WRITABLE;
+ r = uv_poll_start(&context->poll_handle,
+ UV_READABLE | UV_WRITABLE,
+ connection_poll_cb);
+ ASSERT(r == 0);
+
+ r = connect(sock, (struct sockaddr*) &server_addr, sizeof server_addr);
+ ASSERT(r == 0 || got_eagain());
+}
+
+
+static void start_poll_test(void) {
+ int i, r;
+
+#ifdef _WIN32
+ {
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+ }
+#endif
+
+ start_server();
+
+ for (i = 0; i < NUM_CLIENTS; i++)
+ start_client();
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ /* Assert that at most five percent of the writable wakeups was spurious. */
+ ASSERT(spurious_writable_wakeups == 0 ||
+ (valid_writable_wakeups + spurious_writable_wakeups) /
+ spurious_writable_wakeups > 20);
+
+ ASSERT(closed_connections == NUM_CLIENTS * 2);
+
+ MAKE_VALGRIND_HAPPY();
+}
+
+
+TEST_IMPL(poll_duplex) {
+ test_mode = DUPLEX;
+ start_poll_test();
+ return 0;
+}
+
+
+TEST_IMPL(poll_unidirectional) {
+ test_mode = UNIDIRECTIONAL;
+ start_poll_test();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-process-title.c b/third-party/libuv/test/test-process-title.c
new file mode 100644
index 0000000000..29be20749b
--- /dev/null
+++ b/third-party/libuv/test/test-process-title.c
@@ -0,0 +1,53 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+
+static void set_title(const char* title) {
+ char buffer[512];
+ int err;
+
+ err = uv_get_process_title(buffer, sizeof(buffer));
+ ASSERT(err == 0);
+
+ err = uv_set_process_title(title);
+ ASSERT(err == 0);
+
+ err = uv_get_process_title(buffer, sizeof(buffer));
+ ASSERT(err == 0);
+
+ ASSERT(strcmp(buffer, title) == 0);
+}
+
+
+TEST_IMPL(process_title) {
+#if defined(__sun)
+ RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
+#else
+ /* Check for format string vulnerabilities. */
+ set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s");
+ set_title("new title");
+ return 0;
+#endif
+}
diff --git a/third-party/libuv/test/test-ref.c b/third-party/libuv/test/test-ref.c
new file mode 100644
index 0000000000..7ff2e84e38
--- /dev/null
+++ b/third-party/libuv/test/test-ref.c
@@ -0,0 +1,443 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+static uv_write_t write_req;
+static uv_shutdown_t shutdown_req;
+static uv_connect_t connect_req;
+
+static char buffer[32767];
+
+static int req_cb_called;
+static int connect_cb_called;
+static int write_cb_called;
+static int shutdown_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void do_close(void* handle) {
+ close_cb_called = 0;
+ uv_close((uv_handle_t*)handle, close_cb);
+ ASSERT(close_cb_called == 0);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(close_cb_called == 1);
+}
+
+
+static void fail_cb(void) {
+ FATAL("fail_cb should not have been called");
+}
+
+
+static void fail_cb2(void) {
+ ASSERT(0 && "fail_cb2 should not have been called");
+}
+
+
+static void req_cb(uv_handle_t* req, int status) {
+ req_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(req == &shutdown_req);
+ shutdown_cb_called++;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req == &write_req);
+ uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
+ write_cb_called++;
+}
+
+
+static void connect_and_write(uv_connect_t* req, int status) {
+ uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+ uv_write(&write_req, req->handle, &buf, 1, write_cb);
+ connect_cb_called++;
+}
+
+
+
+static void connect_and_shutdown(uv_connect_t* req, int status) {
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+ uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
+ connect_cb_called++;
+}
+
+
+TEST_IMPL(ref) {
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(idle_ref) {
+ uv_idle_t h;
+ uv_idle_init(uv_default_loop(), &h);
+ uv_idle_start(&h, (uv_idle_cb) fail_cb2);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(async_ref) {
+ uv_async_t h;
+ uv_async_init(uv_default_loop(), &h, NULL);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(prepare_ref) {
+ uv_prepare_t h;
+ uv_prepare_init(uv_default_loop(), &h);
+ uv_prepare_start(&h, (uv_prepare_cb) fail_cb2);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(check_ref) {
+ uv_check_t h;
+ uv_check_init(uv_default_loop(), &h);
+ uv_check_start(&h, (uv_check_cb) fail_cb2);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void prepare_cb(uv_prepare_t* h, int status) {
+ ASSERT(h != NULL);
+ ASSERT(status == 0);
+ uv_unref((uv_handle_t*)h);
+}
+
+
+TEST_IMPL(unref_in_prepare_cb) {
+ uv_prepare_t h;
+ uv_prepare_init(uv_default_loop(), &h);
+ uv_prepare_start(&h, prepare_cb);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(timer_ref) {
+ uv_timer_t h;
+ uv_timer_init(uv_default_loop(), &h);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(timer_ref2) {
+ uv_timer_t h;
+ uv_timer_init(uv_default_loop(), &h);
+ uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_event_ref) {
+ uv_fs_event_t h;
+ uv_fs_event_init(uv_default_loop(), &h);
+ uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(fs_poll_ref) {
+ uv_fs_poll_t h;
+ uv_fs_poll_init(uv_default_loop(), &h);
+ uv_fs_poll_start(&h, NULL, ".", 999);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref) {
+ uv_tcp_t h;
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref2) {
+ uv_tcp_t h;
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref2b) {
+ uv_tcp_t h;
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_close((uv_handle_t*)&h, close_cb);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(close_cb_called == 1);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref3) {
+ struct sockaddr_in addr;
+ uv_tcp_t h;
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_tcp_connect(&connect_req,
+ &h,
+ (const struct sockaddr*) &addr,
+ connect_and_shutdown);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_ref4) {
+ struct sockaddr_in addr;
+ uv_tcp_t h;
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ uv_tcp_init(uv_default_loop(), &h);
+ uv_tcp_connect(&connect_req,
+ &h,
+ (const struct sockaddr*) &addr,
+ connect_and_write);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(udp_ref) {
+ uv_udp_t h;
+ uv_udp_init(uv_default_loop(), &h);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(udp_ref2) {
+ struct sockaddr_in addr;
+ uv_udp_t h;
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ uv_udp_init(uv_default_loop(), &h);
+ uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
+ uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(udp_ref3) {
+ struct sockaddr_in addr;
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ uv_udp_send_t req;
+ uv_udp_t h;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ uv_udp_init(uv_default_loop(), &h);
+ uv_udp_send(&req,
+ &h,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ (uv_udp_send_cb) req_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(req_cb_called == 1);
+ do_close(&h);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_ref) {
+ uv_pipe_t h;
+ uv_pipe_init(uv_default_loop(), &h, 0);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_ref2) {
+ uv_pipe_t h;
+ uv_pipe_init(uv_default_loop(), &h, 0);
+ uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_ref3) {
+ uv_pipe_t h;
+ uv_pipe_init(uv_default_loop(), &h, 0);
+ uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(pipe_ref4) {
+ uv_pipe_t h;
+ uv_pipe_init(uv_default_loop(), &h, 0);
+ uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write);
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ do_close(&h);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(process_ref) {
+ /* spawn_helper4 blocks indefinitely. */
+ char *argv[] = { NULL, "spawn_helper4", NULL };
+ uv_process_options_t options;
+ size_t exepath_size;
+ char exepath[256];
+ uv_process_t h;
+ int r;
+
+ memset(&options, 0, sizeof(options));
+ exepath_size = sizeof(exepath);
+
+ r = uv_exepath(exepath, &exepath_size);
+ ASSERT(r == 0);
+
+ argv[0] = exepath;
+ options.file = exepath;
+ options.args = argv;
+ options.exit_cb = NULL;
+
+ r = uv_spawn(uv_default_loop(), &h, &options);
+ ASSERT(r == 0);
+
+ uv_unref((uv_handle_t*)&h);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ r = uv_process_kill(&h, /* SIGTERM */ 15);
+ ASSERT(r == 0);
+
+ do_close(&h);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(has_ref) {
+ uv_idle_t h;
+ uv_idle_init(uv_default_loop(), &h);
+ uv_ref((uv_handle_t*)&h);
+ ASSERT(uv_has_ref((uv_handle_t*)&h) == 1);
+ uv_unref((uv_handle_t*)&h);
+ ASSERT(uv_has_ref((uv_handle_t*)&h) == 0);
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-run-nowait.c b/third-party/libuv/test/test-run-nowait.c
new file mode 100644
index 0000000000..ee4b36ff3b
--- /dev/null
+++ b/third-party/libuv/test/test-run-nowait.c
@@ -0,0 +1,46 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+static int timer_called = 0;
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer_handle);
+ ASSERT(status == 0);
+ timer_called = 1;
+}
+
+
+TEST_IMPL(run_nowait) {
+ int r;
+ uv_timer_init(uv_default_loop(), &timer_handle);
+ uv_timer_start(&timer_handle, timer_cb, 100, 100);
+
+ r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
+ ASSERT(r != 0);
+ ASSERT(timer_called == 0);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-run-once.c b/third-party/libuv/test/test-run-once.c
new file mode 100644
index 0000000000..e243de0ade
--- /dev/null
+++ b/third-party/libuv/test/test-run-once.c
@@ -0,0 +1,49 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#define NUM_TICKS 64
+
+static uv_idle_t idle_handle;
+static int idle_counter;
+
+
+static void idle_cb(uv_idle_t* handle, int status) {
+ ASSERT(handle == &idle_handle);
+ ASSERT(status == 0);
+
+ if (++idle_counter == NUM_TICKS)
+ uv_idle_stop(handle);
+}
+
+
+TEST_IMPL(run_once) {
+ uv_idle_init(uv_default_loop(), &idle_handle);
+ uv_idle_start(&idle_handle, idle_cb);
+
+ while (uv_run(uv_default_loop(), UV_RUN_ONCE));
+ ASSERT(idle_counter == NUM_TICKS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-semaphore.c b/third-party/libuv/test/test-semaphore.c
new file mode 100644
index 0000000000..ac03bb08f1
--- /dev/null
+++ b/third-party/libuv/test/test-semaphore.c
@@ -0,0 +1,111 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ uv_mutex_t mutex;
+ uv_sem_t sem;
+ int delay;
+ volatile int posted;
+} worker_config;
+
+
+static void worker(void* arg) {
+ worker_config* c = arg;
+
+ if (c->delay)
+ uv_sleep(c->delay);
+
+ uv_mutex_lock(&c->mutex);
+ ASSERT(c->posted == 0);
+ uv_sem_post(&c->sem);
+ c->posted = 1;
+ uv_mutex_unlock(&c->mutex);
+}
+
+
+TEST_IMPL(semaphore_1) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+
+ ASSERT(0 == uv_sem_init(&wc.sem, 0));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_sleep(100);
+ uv_mutex_lock(&wc.mutex);
+ ASSERT(wc.posted == 1);
+ uv_sem_wait(&wc.sem); /* should not block */
+ uv_mutex_unlock(&wc.mutex); /* ergo, it should be ok to unlock after wait */
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_sem_destroy(&wc.sem);
+
+ return 0;
+}
+
+
+TEST_IMPL(semaphore_2) {
+ uv_thread_t thread;
+ worker_config wc;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.delay = 100;
+
+ ASSERT(0 == uv_sem_init(&wc.sem, 0));
+ ASSERT(0 == uv_mutex_init(&wc.mutex));
+ ASSERT(0 == uv_thread_create(&thread, worker, &wc));
+
+ uv_sem_wait(&wc.sem);
+
+ ASSERT(0 == uv_thread_join(&thread));
+ uv_mutex_destroy(&wc.mutex);
+ uv_sem_destroy(&wc.sem);
+
+ return 0;
+}
+
+
+TEST_IMPL(semaphore_3) {
+ uv_sem_t sem;
+
+ ASSERT(0 == uv_sem_init(&sem, 3));
+ uv_sem_wait(&sem); /* should not block */
+ uv_sem_wait(&sem); /* should not block */
+ ASSERT(0 == uv_sem_trywait(&sem));
+ ASSERT(UV_EAGAIN == uv_sem_trywait(&sem));
+
+ uv_sem_post(&sem);
+ ASSERT(0 == uv_sem_trywait(&sem));
+ ASSERT(UV_EAGAIN == uv_sem_trywait(&sem));
+
+ uv_sem_destroy(&sem);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-shutdown-close.c b/third-party/libuv/test/test-shutdown-close.c
new file mode 100644
index 0000000000..78c369be2d
--- /dev/null
+++ b/third-party/libuv/test/test-shutdown-close.c
@@ -0,0 +1,108 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+/*
+ * These tests verify that the uv_shutdown callback is always made, even when
+ * it is immediately followed by an uv_close call.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+static uv_shutdown_t shutdown_req;
+static uv_connect_t connect_req;
+
+static int connect_cb_called = 0;
+static int shutdown_cb_called = 0;
+static int close_cb_called = 0;
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(req == &shutdown_req);
+ ASSERT(status == 0 || status == UV_ECANCELED);
+ shutdown_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ int r;
+
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
+ ASSERT(r == 0);
+ ASSERT(0 == uv_is_closing((uv_handle_t*) req->handle));
+ uv_close((uv_handle_t*) req->handle, close_cb);
+ ASSERT(1 == uv_is_closing((uv_handle_t*) req->handle));
+
+ connect_cb_called++;
+}
+
+
+TEST_IMPL(shutdown_close_tcp) {
+ struct sockaddr_in addr;
+ uv_tcp_t h;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ r = uv_tcp_init(uv_default_loop(), &h);
+ ASSERT(r == 0);
+ r = uv_tcp_connect(&connect_req,
+ &h,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(shutdown_close_pipe) {
+ uv_pipe_t h;
+ int r;
+
+ r = uv_pipe_init(uv_default_loop(), &h, 0);
+ ASSERT(r == 0);
+ uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_cb);
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-shutdown-eof.c b/third-party/libuv/test/test-shutdown-eof.c
new file mode 100644
index 0000000000..58346361c7
--- /dev/null
+++ b/third-party/libuv/test/test-shutdown-eof.c
@@ -0,0 +1,182 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static uv_timer_t timer;
+static uv_tcp_t tcp;
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+static uv_shutdown_t shutdown_req;
+static uv_buf_t qbuf;
+static int got_q;
+static int got_eof;
+static int called_connect_cb;
+static int called_shutdown_cb;
+static int called_tcp_close_cb;
+static int called_timer_close_cb;
+static int called_timer_cb;
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = malloc(size);
+ buf->len = size;
+}
+
+
+static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT((uv_tcp_t*)t == &tcp);
+
+ if (nread == 0) {
+ free(buf->base);
+ return;
+ }
+
+ if (!got_q) {
+ ASSERT(nread == 1);
+ ASSERT(!got_eof);
+ ASSERT(buf->base[0] == 'Q');
+ free(buf->base);
+ got_q = 1;
+ puts("got Q");
+ } else {
+ ASSERT(nread == UV_EOF);
+ if (buf->base) {
+ free(buf->base);
+ }
+ got_eof = 1;
+ puts("got EOF");
+ }
+}
+
+
+static void shutdown_cb(uv_shutdown_t *req, int status) {
+ ASSERT(req == &shutdown_req);
+
+ ASSERT(called_connect_cb == 1);
+ ASSERT(!got_eof);
+ ASSERT(called_tcp_close_cb == 0);
+ ASSERT(called_timer_close_cb == 0);
+ ASSERT(called_timer_cb == 0);
+
+ called_shutdown_cb++;
+}
+
+
+static void connect_cb(uv_connect_t *req, int status) {
+ ASSERT(status == 0);
+ ASSERT(req == &connect_req);
+
+ /* Start reading from our connection so we can receive the EOF. */
+ uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb);
+
+ /*
+ * Write the letter 'Q' to gracefully kill the echo-server. This will not
+ * effect our connection.
+ */
+ uv_write(&write_req, (uv_stream_t*) &tcp, &qbuf, 1, NULL);
+
+ /* Shutdown our end of the connection. */
+ uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb);
+
+ called_connect_cb++;
+ ASSERT(called_shutdown_cb == 0);
+}
+
+
+static void tcp_close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*) &tcp);
+
+ ASSERT(called_connect_cb == 1);
+ ASSERT(got_q);
+ ASSERT(got_eof);
+ ASSERT(called_timer_cb == 1);
+
+ called_tcp_close_cb++;
+}
+
+
+static void timer_close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*) &timer);
+ called_timer_close_cb++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer);
+ uv_close((uv_handle_t*) handle, timer_close_cb);
+
+ /*
+ * The most important assert of the test: we have not received
+ * tcp_close_cb yet.
+ */
+ ASSERT(called_tcp_close_cb == 0);
+ uv_close((uv_handle_t*) &tcp, tcp_close_cb);
+
+ called_timer_cb++;
+}
+
+
+/*
+ * This test has a client which connects to the echo_server and immediately
+ * issues a shutdown. The echo-server, in response, will also shutdown their
+ * connection. We check, with a timer, that libuv is not automatically
+ * calling uv_close when the client receives the EOF from echo-server.
+ */
+TEST_IMPL(shutdown_eof) {
+ struct sockaddr_in server_addr;
+ int r;
+
+ qbuf.base = "Q";
+ qbuf.len = 1;
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ uv_timer_start(&timer, timer_cb, 100, 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
+ r = uv_tcp_init(uv_default_loop(), &tcp);
+ ASSERT(!r);
+
+ r = uv_tcp_connect(&connect_req,
+ &tcp,
+ (const struct sockaddr*) &server_addr,
+ connect_cb);
+ ASSERT(!r);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(called_connect_cb == 1);
+ ASSERT(called_shutdown_cb == 1);
+ ASSERT(got_eof);
+ ASSERT(got_q);
+ ASSERT(called_tcp_close_cb == 1);
+ ASSERT(called_timer_close_cb == 1);
+ ASSERT(called_timer_cb == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
diff --git a/third-party/libuv/test/test-signal-multiple-loops.c b/third-party/libuv/test/test-signal-multiple-loops.c
new file mode 100644
index 0000000000..e80154e3e8
--- /dev/null
+++ b/third-party/libuv/test/test-signal-multiple-loops.c
@@ -0,0 +1,289 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+
+/* This test does not pretend to be cross-platform. */
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* The value of NUM_SIGNAL_HANDLING_THREADS is not arbitrary; it needs to be a
+ * multiple of three for reasons that will become clear when you scroll down.
+ * We're basically creating three different thread groups. The total needs
+ * to be divisible by three in order for the numbers in the final check to
+ * match up.
+ */
+#define NUM_SIGNAL_HANDLING_THREADS 24
+#define NUM_LOOP_CREATING_THREADS 10
+
+enum signal_action {
+ ONLY_SIGUSR1,
+ ONLY_SIGUSR2,
+ SIGUSR1_AND_SIGUSR2
+};
+
+static uv_sem_t sem;
+static uv_mutex_t counter_lock;
+static volatile int stop = 0;
+
+static volatile int signal1_cb_counter = 0;
+static volatile int signal2_cb_counter = 0;
+static volatile int loop_creation_counter = 0;
+
+
+static void increment_counter(volatile int* counter) {
+ uv_mutex_lock(&counter_lock);
+ ++(*counter);
+ uv_mutex_unlock(&counter_lock);
+}
+
+
+static void signal1_cb(uv_signal_t* handle, int signum) {
+ ASSERT(signum == SIGUSR1);
+ increment_counter(&signal1_cb_counter);
+ uv_signal_stop(handle);
+}
+
+
+static void signal2_cb(uv_signal_t* handle, int signum) {
+ ASSERT(signum == SIGUSR2);
+ increment_counter(&signal2_cb_counter);
+ uv_signal_stop(handle);
+}
+
+
+static void signal_handling_worker(void* context) {
+ enum signal_action action;
+ uv_signal_t signal1a;
+ uv_signal_t signal1b;
+ uv_signal_t signal2;
+ uv_loop_t* loop;
+ int r;
+
+ action = (enum signal_action) (uintptr_t) context;
+
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ /* Setup the signal watchers and start them. */
+ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) {
+ r = uv_signal_init(loop, &signal1a);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ r = uv_signal_init(loop, &signal1b);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ }
+
+ if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) {
+ r = uv_signal_init(loop, &signal2);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
+ ASSERT(r == 0);
+ }
+
+ /* Signal watchers are now set up. */
+ uv_sem_post(&sem);
+
+ /* Wait for all signals. The signal callbacks stop the watcher, so uv_run
+ * will return when all signal watchers caught a signal.
+ */
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ /* Restart the signal watchers. */
+ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) {
+ r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
+ ASSERT(r == 0);
+ }
+
+ if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) {
+ r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
+ ASSERT(r == 0);
+ }
+
+ /* Wait for signals once more. */
+ uv_sem_post(&sem);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ /* Close the watchers. */
+ if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) {
+ uv_close((uv_handle_t*) &signal1a, NULL);
+ uv_close((uv_handle_t*) &signal1b, NULL);
+ }
+
+ if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) {
+ uv_close((uv_handle_t*) &signal2, NULL);
+ }
+
+ /* Wait for the signal watchers to close. */
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_loop_delete(loop);
+}
+
+
+static void signal_unexpected_cb(uv_signal_t* handle, int signum) {
+ ASSERT(0 && "signal_unexpected_cb should never be called");
+}
+
+
+static void loop_creating_worker(void* context) {
+ (void) context;
+
+ do {
+ uv_loop_t* loop;
+ uv_signal_t signal;
+ int r;
+
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ r = uv_signal_init(loop, &signal);
+ ASSERT(r == 0);
+
+ r = uv_signal_start(&signal, signal_unexpected_cb, SIGTERM);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) &signal, NULL);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_loop_delete(loop);
+
+ increment_counter(&loop_creation_counter);
+ } while (!stop);
+}
+
+
+TEST_IMPL(signal_multiple_loops) {
+ uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS];
+ uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS];
+ enum signal_action action;
+ sigset_t sigset;
+ int i;
+ int r;
+
+ r = uv_sem_init(&sem, 0);
+ ASSERT(r == 0);
+
+ r = uv_mutex_init(&counter_lock);
+ ASSERT(r == 0);
+
+ /* Create a couple of threads that create a destroy loops continuously. */
+ for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) {
+ r = uv_thread_create(&loop_creating_threads[i],
+ loop_creating_worker,
+ NULL);
+ ASSERT(r == 0);
+ }
+
+ /* Create a couple of threads that actually handle signals. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) {
+ switch (i % 3) {
+ case 0: action = ONLY_SIGUSR1; break;
+ case 1: action = ONLY_SIGUSR2; break;
+ case 2: action = SIGUSR1_AND_SIGUSR2; break;
+ }
+
+ r = uv_thread_create(&signal_handling_threads[i],
+ signal_handling_worker,
+ (void*) (uintptr_t) action);
+ ASSERT(r == 0);
+ }
+
+ /* Wait until all threads have started and set up their signal watchers. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++)
+ uv_sem_wait(&sem);
+
+ r = kill(getpid(), SIGUSR1);
+ ASSERT(r == 0);
+ r = kill(getpid(), SIGUSR2);
+ ASSERT(r == 0);
+
+ /* Wait for all threads to handle these signals. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++)
+ uv_sem_wait(&sem);
+
+ /* Block all signals to this thread, so we are sure that from here the signal
+ * handler runs in another thread. This is is more likely to catch thread and
+ * signal safety issues if there are any.
+ */
+ sigfillset(&sigset);
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL);
+
+ r = kill(getpid(), SIGUSR1);
+ ASSERT(r == 0);
+ r = kill(getpid(), SIGUSR2);
+ ASSERT(r == 0);
+
+ /* Wait for all signal handling threads to exit. */
+ for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) {
+ r = uv_thread_join(&signal_handling_threads[i]);
+ ASSERT(r == 0);
+ }
+
+ /* Tell all loop creating threads to stop. */
+ stop = 1;
+
+ /* Wait for all loop creating threads to exit. */
+ for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) {
+ r = uv_thread_join(&loop_creating_threads[i]);
+ ASSERT(r == 0);
+ }
+
+ printf("signal1_cb calls: %d\n", signal1_cb_counter);
+ printf("signal2_cb calls: %d\n", signal2_cb_counter);
+ printf("loops created and destroyed: %d\n", loop_creation_counter);
+
+ /* The division by three reflects the fact that we spawn three different
+ * thread groups of (NUM_SIGNAL_HANDLING_THREADS / 3) threads each.
+ */
+ ASSERT(signal1_cb_counter == 8 * (NUM_SIGNAL_HANDLING_THREADS / 3));
+ ASSERT(signal2_cb_counter == 4 * (NUM_SIGNAL_HANDLING_THREADS / 3));
+
+ /* We don't know exactly how much loops will be created and destroyed, but at
+ * least there should be 1 for every loop creating thread.
+ */
+ ASSERT(loop_creation_counter >= NUM_LOOP_CREATING_THREADS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !_WIN32 */
diff --git a/third-party/libuv/test/test-signal.c b/third-party/libuv/test/test-signal.c
new file mode 100644
index 0000000000..9fb1c7f916
--- /dev/null
+++ b/third-party/libuv/test/test-signal.c
@@ -0,0 +1,152 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+
+/* This test does not pretend to be cross-platform. */
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NSIGNALS 10
+
+struct timer_ctx {
+ unsigned int ncalls;
+ uv_timer_t handle;
+ int signum;
+};
+
+struct signal_ctx {
+ enum { CLOSE, STOP } stop_or_close;
+ unsigned int ncalls;
+ uv_signal_t handle;
+ int signum;
+};
+
+
+static void signal_cb(uv_signal_t* handle, int signum) {
+ struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
+ ASSERT(signum == ctx->signum);
+
+ if (++ctx->ncalls == NSIGNALS) {
+ if (ctx->stop_or_close == STOP)
+ uv_signal_stop(handle);
+ else if (ctx->stop_or_close == CLOSE)
+ uv_close((uv_handle_t*)handle, NULL);
+ else
+ ASSERT(0);
+ }
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
+
+ raise(ctx->signum);
+
+ if (++ctx->ncalls == NSIGNALS)
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) {
+ ctx->ncalls = 0;
+ ctx->signum = signum;
+ ctx->stop_or_close = CLOSE;
+ ASSERT(0 == uv_signal_init(loop, &ctx->handle));
+ ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
+}
+
+
+static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
+ ctx->ncalls = 0;
+ ctx->signum = signum;
+ ASSERT(0 == uv_timer_init(loop, &ctx->handle));
+ ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
+}
+
+
+TEST_IMPL(we_get_signal) {
+ struct signal_ctx sc;
+ struct timer_ctx tc;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ start_timer(loop, SIGCHLD, &tc);
+ start_watcher(loop, SIGCHLD, &sc);
+ sc.stop_or_close = STOP; /* stop, don't close the signal handle */
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ sc.ncalls = 0;
+ sc.stop_or_close = CLOSE; /* now close it when it's done */
+ uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
+
+ start_timer(loop, SIGCHLD, &tc);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(tc.ncalls == NSIGNALS);
+ ASSERT(sc.ncalls == NSIGNALS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(we_get_signals) {
+ struct signal_ctx sc[4];
+ struct timer_ctx tc[2];
+ uv_loop_t* loop;
+ unsigned int i;
+
+ loop = uv_default_loop();
+ start_watcher(loop, SIGUSR1, sc + 0);
+ start_watcher(loop, SIGUSR1, sc + 1);
+ start_watcher(loop, SIGUSR2, sc + 2);
+ start_watcher(loop, SIGUSR2, sc + 3);
+ start_timer(loop, SIGUSR1, tc + 0);
+ start_timer(loop, SIGUSR2, tc + 1);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ for (i = 0; i < ARRAY_SIZE(sc); i++)
+ ASSERT(sc[i].ncalls == NSIGNALS);
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ ASSERT(tc[i].ncalls == NSIGNALS);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* _WIN32 */
diff --git a/third-party/libuv/test/test-spawn.c b/third-party/libuv/test/test-spawn.c
new file mode 100644
index 0000000000..5f71fce2c0
--- /dev/null
+++ b/third-party/libuv/test/test-spawn.c
@@ -0,0 +1,1051 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+
+static int close_cb_called;
+static int exit_cb_called;
+static uv_process_t process;
+static uv_timer_t timer;
+static uv_process_options_t options;
+static char exepath[1024];
+static size_t exepath_size = 1024;
+static char* args[3];
+static int no_term_signal;
+
+#define OUTPUT_SIZE 1024
+static char output[OUTPUT_SIZE];
+static int output_used;
+
+
+static void close_cb(uv_handle_t* handle) {
+ printf("close_cb\n");
+ close_cb_called++;
+}
+
+static void exit_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ printf("exit_cb\n");
+ exit_cb_called++;
+ ASSERT(exit_status == 1);
+ ASSERT(term_signal == 0);
+ uv_close((uv_handle_t*)process, close_cb);
+}
+
+
+static void fail_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ ASSERT(0 && "fail_cb called");
+}
+
+
+static void kill_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ int err;
+
+ printf("exit_cb\n");
+ exit_cb_called++;
+#ifdef _WIN32
+ ASSERT(exit_status == 1);
+#else
+ ASSERT(exit_status == 0);
+#endif
+ ASSERT(no_term_signal || term_signal == 15);
+ uv_close((uv_handle_t*)process, close_cb);
+
+ /*
+ * Sending signum == 0 should check if the
+ * child process is still alive, not kill it.
+ * This process should be dead.
+ */
+ err = uv_kill(process->pid, 0);
+ ASSERT(err == UV_ESRCH);
+}
+
+static void detach_failure_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ printf("detach_cb\n");
+ exit_cb_called++;
+}
+
+static void on_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = output + output_used;
+ buf->len = OUTPUT_SIZE - output_used;
+}
+
+
+static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ if (nread > 0) {
+ output_used += nread;
+ } else if (nread < 0) {
+ ASSERT(nread == UV_EOF);
+ uv_close((uv_handle_t*)tcp, close_cb);
+ }
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ uv_close((uv_handle_t*)req->handle, close_cb);
+}
+
+
+static void init_process_options(char* test, uv_exit_cb exit_cb) {
+ /* Note spawn_helper1 defined in test/run-tests.c */
+ int r = uv_exepath(exepath, &exepath_size);
+ ASSERT(r == 0);
+ exepath[exepath_size] = '\0';
+ args[0] = exepath;
+ args[1] = test;
+ args[2] = NULL;
+ options.file = exepath;
+ options.args = args;
+ options.exit_cb = exit_cb;
+ options.flags = 0;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_process_kill(&process, /* SIGTERM */ 15);
+ uv_close((uv_handle_t*)handle, close_cb);
+}
+
+
+TEST_IMPL(spawn_fails) {
+ int r;
+
+ init_process_options("", fail_cb);
+ options.file = options.args[0] = "program-that-had-better-not-exist";
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_ENOENT || r == UV_EACCES);
+ ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_exit_code) {
+ int r;
+
+ init_process_options("spawn_helper1", exit_cb);
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_stdout) {
+ int r;
+ uv_pipe_t out;
+ uv_stdio_container_t stdio[2];
+
+ init_process_options("spawn_helper2", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\n", output) == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_stdout_to_file) {
+ int r;
+ uv_file file;
+ uv_fs_t fs_req;
+ uv_stdio_container_t stdio[2];
+
+ /* Setup. */
+ unlink("stdout_file");
+
+ init_process_options("spawn_helper2", exit_cb);
+
+ r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
+ S_IRUSR | S_IWUSR, NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+
+ file = r;
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_INHERIT_FD;
+ options.stdio[1].data.fd = file;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
+ 0, NULL);
+ ASSERT(r == 12);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\n", output) == 0);
+
+ /* Cleanup. */
+ unlink("stdout_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_stdout_and_stderr_to_file) {
+ int r;
+ uv_file file;
+ uv_fs_t fs_req;
+ uv_stdio_container_t stdio[3];
+
+ /* Setup. */
+ unlink("stdout_file");
+
+ init_process_options("spawn_helper6", exit_cb);
+
+ r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
+ S_IREAD | S_IWRITE, NULL);
+ ASSERT(r != -1);
+ uv_fs_req_cleanup(&fs_req);
+
+ file = r;
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_INHERIT_FD;
+ options.stdio[1].data.fd = file;
+ options.stdio[2].flags = UV_INHERIT_FD;
+ options.stdio[2].data.fd = file;
+ options.stdio_count = 3;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
+ 0, NULL);
+ ASSERT(r == 27);
+ uv_fs_req_cleanup(&fs_req);
+
+ r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&fs_req);
+
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+ /* Cleanup. */
+ unlink("stdout_file");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_stdin) {
+ int r;
+ uv_pipe_t out;
+ uv_pipe_t in;
+ uv_write_t write_req;
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[2];
+ char buffer[] = "hello-from-spawn_stdin";
+
+ init_process_options("spawn_helper3", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ uv_pipe_init(uv_default_loop(), &in, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ buf.base = buffer;
+ buf.len = sizeof(buffer);
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */
+ ASSERT(strcmp(buffer, output) == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_stdio_greater_than_3) {
+ int r;
+ uv_pipe_t pipe;
+ uv_stdio_container_t stdio[4];
+
+ init_process_options("spawn_helper5", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &pipe, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_IGNORE;
+ options.stdio[2].flags = UV_IGNORE;
+ options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[3].data.stream = (uv_stream_t*)&pipe;
+ options.stdio_count = 4;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+ printf("output from stdio[3] is: %s", output);
+ ASSERT(strcmp("fourth stdio!\n", output) == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_ignored_stdio) {
+ int r;
+
+ init_process_options("spawn_helper6", exit_cb);
+
+ options.stdio = NULL;
+ options.stdio_count = 0;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_and_kill) {
+ int r;
+
+ init_process_options("spawn_helper4", kill_cb);
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 500, 0);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2); /* Once for process and once for timer. */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_preserve_env) {
+ int r;
+ uv_pipe_t out;
+ uv_stdio_container_t stdio[2];
+
+ init_process_options("spawn_helper7", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*) &out;
+ options.stdio_count = 2;
+
+ r = putenv("ENV_TEST=testval");
+ ASSERT(r == 0);
+
+ /* Explicitly set options.env to NULL to test for env clobbering. */
+ options.env = NULL;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ printf("output is: %s", output);
+ ASSERT(strcmp("testval", output) == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_detached) {
+ int r;
+
+ init_process_options("spawn_helper4", detach_failure_cb);
+
+ options.flags |= UV_PROCESS_DETACHED;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ uv_unref((uv_handle_t*)&process);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 0);
+
+ r = uv_kill(process.pid, 0);
+ ASSERT(r == 0);
+
+ r = uv_kill(process.pid, 15);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(spawn_and_kill_with_std) {
+ int r;
+ uv_pipe_t in, out, err;
+ uv_write_t write;
+ char message[] = "Nancy's joining me because the message this evening is "
+ "not my message but ours.";
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[3];
+
+ init_process_options("spawn_helper4", kill_cb);
+
+ r = uv_pipe_init(uv_default_loop(), &in, 0);
+ ASSERT(r == 0);
+
+ r = uv_pipe_init(uv_default_loop(), &out, 0);
+ ASSERT(r == 0);
+
+ r = uv_pipe_init(uv_default_loop(), &err, 0);
+ ASSERT(r == 0);
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[2].data.stream = (uv_stream_t*)&err;
+ options.stdio_count = 3;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init(message, sizeof message);
+ r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 500, 0);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_and_ping) {
+ uv_write_t write_req;
+ uv_pipe_t in, out;
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[2];
+ int r;
+
+ init_process_options("spawn_helper3", exit_cb);
+ buf = uv_buf_init("TEST", 4);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ uv_pipe_init(uv_default_loop(), &in, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ /* Sending signum == 0 should check if the
+ * child process is still alive, not kill it.
+ */
+ r = uv_process_kill(&process, 0);
+ ASSERT(r == 0);
+
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(strcmp(output, "TEST") == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_same_stdout_stderr) {
+ uv_write_t write_req;
+ uv_pipe_t in, out;
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[3];
+ int r;
+
+ init_process_options("spawn_helper3", exit_cb);
+ buf = uv_buf_init("TEST", 4);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ uv_pipe_init(uv_default_loop(), &in, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ /* Sending signum == 0 should check if the
+ * child process is still alive, not kill it.
+ */
+ r = uv_process_kill(&process, 0);
+ ASSERT(r == 0);
+
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(strcmp(output, "TEST") == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(kill) {
+ int r;
+
+#ifdef _WIN32
+ no_term_signal = 1;
+#endif
+
+ init_process_options("spawn_helper4", kill_cb);
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ /* Sending signum == 0 should check if the
+ * child process is still alive, not kill it.
+ */
+ r = uv_kill(process.pid, 0);
+ ASSERT(r == 0);
+
+ /* Kill the process. */
+ r = uv_kill(process.pid, /* SIGTERM */ 15);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
+ int r;
+ uv_pipe_t out;
+ char name[64];
+ HANDLE pipe_handle;
+ uv_stdio_container_t stdio[2];
+
+ init_process_options("spawn_helper2", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &out, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_IGNORE;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ /* Create a pipe that'll cause a collision. */
+ _snprintf(name,
+ sizeof(name),
+ "\\\\.\\pipe\\uv\\%p-%d",
+ &out,
+ GetCurrentProcessId());
+ pipe_handle = CreateNamedPipeA(name,
+ PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ 10,
+ 65536,
+ 65536,
+ 0,
+ NULL);
+ ASSERT(pipe_handle != INVALID_HANDLE_VALUE);
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+ printf("output is: %s", output);
+ ASSERT(strcmp("hello world\n", output) == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
+
+TEST_IMPL(argument_escaping) {
+ const WCHAR* test_str[] = {
+ L"HelloWorld",
+ L"Hello World",
+ L"Hello\"World",
+ L"Hello World\\",
+ L"Hello\\\"World",
+ L"Hello\\World",
+ L"Hello\\\\World",
+ L"Hello World\\",
+ L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
+ };
+ const int count = sizeof(test_str) / sizeof(*test_str);
+ WCHAR** test_output;
+ WCHAR* command_line;
+ WCHAR** cracked;
+ size_t total_size = 0;
+ int i;
+ int num_args;
+ int result;
+
+ char* verbatim[] = {
+ "cmd.exe",
+ "/c",
+ "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
+ NULL
+ };
+ WCHAR* verbatim_output;
+ WCHAR* non_verbatim_output;
+
+ test_output = calloc(count, sizeof(WCHAR*));
+ for (i = 0; i < count; ++i) {
+ test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
+ quote_cmd_arg(test_str[i], test_output[i]);
+ wprintf(L"input : %s\n", test_str[i]);
+ wprintf(L"output: %s\n", test_output[i]);
+ total_size += wcslen(test_output[i]) + 1;
+ }
+ command_line = calloc(total_size + 1, sizeof(WCHAR));
+ for (i = 0; i < count; ++i) {
+ wcscat(command_line, test_output[i]);
+ wcscat(command_line, L" ");
+ }
+ command_line[total_size - 1] = L'\0';
+
+ wprintf(L"command_line: %s\n", command_line);
+
+ cracked = CommandLineToArgvW(command_line, &num_args);
+ for (i = 0; i < num_args; ++i) {
+ wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]);
+ ASSERT(wcscmp(test_str[i], cracked[i]) == 0);
+ }
+
+ LocalFree(cracked);
+ for (i = 0; i < count; ++i) {
+ free(test_output[i]);
+ }
+
+ result = make_program_args(verbatim, 1, &verbatim_output);
+ ASSERT(result == 0);
+ result = make_program_args(verbatim, 0, &non_verbatim_output);
+ ASSERT(result == 0);
+
+ wprintf(L" verbatim_output: %s\n", verbatim_output);
+ wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
+
+ ASSERT(wcscmp(verbatim_output,
+ L"cmd.exe /c c:\\path\\to\\node.exe --eval "
+ L"\"require('c:\\\\path\\\\to\\\\test.js')\"") == 0);
+ ASSERT(wcscmp(non_verbatim_output,
+ L"cmd.exe /c \"c:\\path\\to\\node.exe --eval "
+ L"\\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0);
+
+ free(verbatim_output);
+ free(non_verbatim_output);
+
+ return 0;
+}
+
+int make_program_env(char** env_block, WCHAR** dst_ptr);
+
+TEST_IMPL(environment_creation) {
+ int i;
+ char* environment[] = {
+ "FOO=BAR",
+ "SYSTEM=ROOT", /* substring of a supplied var name */
+ "SYSTEMROOTED=OMG", /* supplied var name is a substring */
+ "TEMP=C:\\Temp",
+ "BAZ=QUX",
+ NULL
+ };
+
+ WCHAR expected[512];
+ WCHAR* ptr = expected;
+ int result;
+ WCHAR* str;
+ WCHAR* env;
+
+ for (i = 0; i < sizeof(environment) / sizeof(environment[0]) - 1; i++) {
+ ptr += uv_utf8_to_utf16(environment[i],
+ ptr,
+ expected + sizeof(expected) - ptr);
+ }
+
+ memcpy(ptr, L"SYSTEMROOT=", sizeof(L"SYSTEMROOT="));
+ ptr += sizeof(L"SYSTEMROOT=")/sizeof(WCHAR) - 1;
+ ptr += GetEnvironmentVariableW(L"SYSTEMROOT",
+ ptr,
+ expected + sizeof(expected) - ptr);
+ ++ptr;
+
+ memcpy(ptr, L"SYSTEMDRIVE=", sizeof(L"SYSTEMDRIVE="));
+ ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(WCHAR) - 1;
+ ptr += GetEnvironmentVariableW(L"SYSTEMDRIVE",
+ ptr,
+ expected + sizeof(expected) - ptr);
+ ++ptr;
+ *ptr = '\0';
+
+ result = make_program_env(environment, &env);
+ ASSERT(result == 0);
+
+ for (str = env; *str; str += wcslen(str) + 1) {
+ wprintf(L"%s\n", str);
+ }
+
+ ASSERT(wcscmp(expected, env) == 0);
+
+ return 0;
+}
+#endif
+
+#ifndef _WIN32
+TEST_IMPL(spawn_setuid_setgid) {
+ int r;
+
+ /* if not root, then this will fail. */
+ uv_uid_t uid = getuid();
+ if (uid != 0) {
+ fprintf(stderr, "spawn_setuid_setgid skipped: not root\n");
+ return 0;
+ }
+
+ init_process_options("spawn_helper1", exit_cb);
+
+ /* become the "nobody" user. */
+ struct passwd* pw;
+ pw = getpwnam("nobody");
+ ASSERT(pw != NULL);
+ options.uid = pw->pw_uid;
+ options.gid = pw->pw_gid;
+ options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
+#ifndef _WIN32
+TEST_IMPL(spawn_setuid_fails) {
+ int r;
+
+ /* if root, become nobody. */
+ uv_uid_t uid = getuid();
+ if (uid == 0) {
+ struct passwd* pw;
+ pw = getpwnam("nobody");
+ ASSERT(pw != NULL);
+ ASSERT(0 == setgid(pw->pw_gid));
+ ASSERT(0 == setuid(pw->pw_uid));
+ }
+
+ init_process_options("spawn_helper1", fail_cb);
+
+ options.flags |= UV_PROCESS_SETUID;
+ options.uid = 0;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_EPERM);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_setgid_fails) {
+ int r;
+
+ /* if root, become nobody. */
+ uv_uid_t uid = getuid();
+ if (uid == 0) {
+ struct passwd* pw;
+ pw = getpwnam("nobody");
+ ASSERT(pw != NULL);
+ ASSERT(0 == setgid(pw->pw_gid));
+ ASSERT(0 == setuid(pw->pw_uid));
+ }
+
+ init_process_options("spawn_helper1", fail_cb);
+
+ options.flags |= UV_PROCESS_SETGID;
+ options.gid = 0;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_EPERM);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
+#ifdef _WIN32
+
+static void exit_cb_unexpected(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ ASSERT(0 && "should not have been called");
+}
+
+
+TEST_IMPL(spawn_setuid_fails) {
+ int r;
+
+ init_process_options("spawn_helper1", exit_cb_unexpected);
+
+ options.flags |= UV_PROCESS_SETUID;
+ options.uid = (uv_uid_t) -42424242;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_ENOTSUP);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(spawn_setgid_fails) {
+ int r;
+
+ init_process_options("spawn_helper1", exit_cb_unexpected);
+
+ options.flags |= UV_PROCESS_SETGID;
+ options.gid = (uv_gid_t) -42424242;
+
+ r = uv_spawn(uv_default_loop(), &process, &options);
+ ASSERT(r == UV_ENOTSUP);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
+
+TEST_IMPL(spawn_auto_unref) {
+ init_process_options("spawn_helper1", NULL);
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &process));
+ uv_close((uv_handle_t*) &process, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(1 == uv_is_closing((uv_handle_t*) &process));
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-stdio-over-pipes.c b/third-party/libuv/test/test-stdio-over-pipes.c
new file mode 100644
index 0000000000..1574476104
--- /dev/null
+++ b/third-party/libuv/test/test-stdio-over-pipes.c
@@ -0,0 +1,255 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+static char exepath[1024];
+static size_t exepath_size = 1024;
+static char* args[3];
+static uv_process_options_t options;
+static int close_cb_called;
+static int exit_cb_called;
+static int on_read_cb_called;
+static int after_write_cb_called;
+static uv_pipe_t in;
+static uv_pipe_t out;
+static uv_loop_t* loop;
+#define OUTPUT_SIZE 1024
+static char output[OUTPUT_SIZE];
+static int output_used;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void exit_cb(uv_process_t* process,
+ int64_t exit_status,
+ int term_signal) {
+ printf("exit_cb\n");
+ exit_cb_called++;
+ ASSERT(exit_status == 0);
+ ASSERT(term_signal == 0);
+ uv_close((uv_handle_t*)process, close_cb);
+ uv_close((uv_handle_t*)&in, close_cb);
+ uv_close((uv_handle_t*)&out, close_cb);
+}
+
+
+static void init_process_options(char* test, uv_exit_cb exit_cb) {
+ int r = uv_exepath(exepath, &exepath_size);
+ ASSERT(r == 0);
+ exepath[exepath_size] = '\0';
+ args[0] = exepath;
+ args[1] = test;
+ args[2] = NULL;
+ options.file = exepath;
+ options.args = args;
+ options.exit_cb = exit_cb;
+}
+
+
+static void on_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = output + output_used;
+ buf->len = OUTPUT_SIZE - output_used;
+}
+
+
+static void after_write(uv_write_t* req, int status) {
+ if (status) {
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+ ASSERT(0);
+ }
+
+ /* Free the read/write buffer and the request */
+ free(req);
+
+ after_write_cb_called++;
+}
+
+
+static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* rdbuf) {
+ uv_write_t* req;
+ uv_buf_t wrbuf;
+ int r;
+
+ ASSERT(nread > 0 || nread == UV_EOF);
+
+ if (nread > 0) {
+ output_used += nread;
+ if (output_used == 12) {
+ ASSERT(memcmp("hello world\n", output, 12) == 0);
+ wrbuf = uv_buf_init(output, output_used);
+ req = malloc(sizeof(*req));
+ r = uv_write(req, (uv_stream_t*)&in, &wrbuf, 1, after_write);
+ ASSERT(r == 0);
+ }
+ }
+
+ on_read_cb_called++;
+}
+
+
+TEST_IMPL(stdio_over_pipes) {
+ int r;
+ uv_process_t process;
+ uv_stdio_container_t stdio[2];
+
+ loop = uv_default_loop();
+
+ init_process_options("stdio_over_pipes_helper", exit_cb);
+
+ uv_pipe_init(loop, &out, 0);
+ uv_pipe_init(loop, &in, 0);
+
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
+ options.stdio_count = 2;
+
+ r = uv_spawn(loop, &process, &options);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(on_read_cb_called > 1);
+ ASSERT(after_write_cb_called == 1);
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+ ASSERT(memcmp("hello world\n", output, 12) == 0);
+ ASSERT(output_used == 12);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+/* Everything here runs in a child process. */
+
+static int on_pipe_read_called;
+static int after_write_called;
+static uv_pipe_t stdin_pipe;
+static uv_pipe_t stdout_pipe;
+
+static void on_pipe_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(nread > 0);
+ ASSERT(memcmp("hello world\n", buf->base, nread) == 0);
+ on_pipe_read_called++;
+
+ free(buf->base);
+
+ uv_close((uv_handle_t*)&stdin_pipe, close_cb);
+ uv_close((uv_handle_t*)&stdout_pipe, close_cb);
+}
+
+
+static void after_pipe_write(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ after_write_called++;
+}
+
+
+static void on_read_alloc(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+}
+
+
+int stdio_over_pipes_helper(void) {
+ /* Write several buffers to test that the write order is preserved. */
+ char* buffers[] = {
+ "he",
+ "ll",
+ "o ",
+ "wo",
+ "rl",
+ "d",
+ "\n"
+ };
+
+ uv_write_t write_req[ARRAY_SIZE(buffers)];
+ uv_buf_t buf[ARRAY_SIZE(buffers)];
+ unsigned int i;
+ int r;
+ uv_loop_t* loop = uv_default_loop();
+
+ ASSERT(UV_NAMED_PIPE == uv_guess_handle(0));
+ ASSERT(UV_NAMED_PIPE == uv_guess_handle(1));
+
+ r = uv_pipe_init(loop, &stdin_pipe, 0);
+ ASSERT(r == 0);
+ r = uv_pipe_init(loop, &stdout_pipe, 0);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&stdin_pipe, 0);
+ uv_pipe_open(&stdout_pipe, 1);
+
+ /* Unref both stdio handles to make sure that all writes complete. */
+ uv_unref((uv_handle_t*)&stdin_pipe);
+ uv_unref((uv_handle_t*)&stdout_pipe);
+
+ for (i = 0; i < ARRAY_SIZE(buffers); i++) {
+ buf[i] = uv_buf_init((char*)buffers[i], strlen(buffers[i]));
+ }
+
+ for (i = 0; i < ARRAY_SIZE(buffers); i++) {
+ r = uv_write(&write_req[i], (uv_stream_t*)&stdout_pipe, &buf[i], 1,
+ after_pipe_write);
+ ASSERT(r == 0);
+ }
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(after_write_called == 7);
+ ASSERT(on_pipe_read_called == 0);
+ ASSERT(close_cb_called == 0);
+
+ uv_ref((uv_handle_t*)&stdout_pipe);
+ uv_ref((uv_handle_t*)&stdin_pipe);
+
+ r = uv_read_start((uv_stream_t*)&stdin_pipe, on_read_alloc, on_pipe_read);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(after_write_called == 7);
+ ASSERT(on_pipe_read_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-bind-error.c b/third-party/libuv/test/test-tcp-bind-error.c
new file mode 100644
index 0000000000..96bfe11601
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-bind-error.c
@@ -0,0 +1,199 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+TEST_IMPL(tcp_bind_error_addrinuse) {
+ struct sockaddr_in addr;
+ uv_tcp_t server1, server2;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+ r = uv_tcp_init(uv_default_loop(), &server1);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_init(uv_default_loop(), &server2);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server1, 128, NULL);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&server2, 128, NULL);
+ ASSERT(r == UV_EADDRINUSE);
+
+ uv_close((uv_handle_t*)&server1, close_cb);
+ uv_close((uv_handle_t*)&server2, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind_error_addrnotavail_1) {
+ struct sockaddr_in addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ /* It seems that Linux is broken here - bind succeeds. */
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind_error_addrnotavail_2) {
+ struct sockaddr_in addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == UV_EADDRNOTAVAIL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind_error_fault) {
+ char garbage[] =
+ "blah blah blah blah blah blah blah blah blah blah blah blah";
+ struct sockaddr_in* garbage_addr;
+ uv_tcp_t server;
+ int r;
+
+ garbage_addr = (struct sockaddr_in*) &garbage;
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+/* Notes: On Linux uv_bind(server, NULL) will segfault the program. */
+
+TEST_IMPL(tcp_bind_error_inval) {
+ struct sockaddr_in addr1;
+ struct sockaddr_in addr2;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1));
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind_localhost_ok) {
+ struct sockaddr_in addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_listen_without_bind) {
+ int r;
+ uv_tcp_t server;
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&server, 128, NULL);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-bind6-error.c b/third-party/libuv/test/test-tcp-bind6-error.c
new file mode 100644
index 0000000000..1d65f3de3e
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-bind6-error.c
@@ -0,0 +1,161 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+TEST_IMPL(tcp_bind6_error_addrinuse) {
+ struct sockaddr_in6 addr;
+ uv_tcp_t server1, server2;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server1);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_init(uv_default_loop(), &server2);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&server1, 128, NULL);
+ ASSERT(r == 0);
+ r = uv_listen((uv_stream_t*)&server2, 128, NULL);
+ ASSERT(r == UV_EADDRINUSE);
+
+ uv_close((uv_handle_t*)&server1, close_cb);
+ uv_close((uv_handle_t*)&server2, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind6_error_addrnotavail) {
+ struct sockaddr_in6 addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == UV_EADDRNOTAVAIL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind6_error_fault) {
+ char garbage[] =
+ "blah blah blah blah blah blah blah blah blah blah blah blah";
+ struct sockaddr_in6* garbage_addr;
+ uv_tcp_t server;
+ int r;
+
+ garbage_addr = (struct sockaddr_in6*) &garbage;
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+/* Notes: On Linux uv_bind6(server, NULL) will segfault the program. */
+
+TEST_IMPL(tcp_bind6_error_inval) {
+ struct sockaddr_in6 addr1;
+ struct sockaddr_in6 addr2;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr1));
+ ASSERT(0 == uv_ip6_addr("::", TEST_PORT_2, &addr2));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_bind6_localhost_ok) {
+ struct sockaddr_in6 addr;
+ uv_tcp_t server;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-close-accept.c b/third-party/libuv/test/test-tcp-close-accept.c
new file mode 100644
index 0000000000..10f9d91964
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-close-accept.c
@@ -0,0 +1,183 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static struct sockaddr_in addr;
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_outgoing[2];
+static uv_tcp_t tcp_incoming[ARRAY_SIZE(tcp_outgoing)];
+static uv_connect_t connect_reqs[ARRAY_SIZE(tcp_outgoing)];
+static uv_tcp_t tcp_check;
+static uv_connect_t tcp_check_req;
+static uv_write_t write_reqs[ARRAY_SIZE(tcp_outgoing)];
+static unsigned int got_connections;
+static unsigned int close_cb_called;
+static unsigned int write_cb_called;
+static unsigned int read_cb_called;
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ write_cb_called++;
+}
+
+static void connect_cb(uv_connect_t* req, int status) {
+ unsigned int i;
+ uv_buf_t buf;
+ uv_stream_t* outgoing;
+
+ if (req == &tcp_check_req) {
+ ASSERT(status != 0);
+
+ /* Close check and incoming[0], time to finish test */
+ uv_close((uv_handle_t*) &tcp_incoming[0], close_cb);
+ uv_close((uv_handle_t*) &tcp_check, close_cb);
+ return;
+ }
+
+ ASSERT(status == 0);
+ ASSERT(connect_reqs <= req);
+ ASSERT(req <= connect_reqs + ARRAY_SIZE(connect_reqs));
+ i = req - connect_reqs;
+
+ buf = uv_buf_init("x", 1);
+ outgoing = (uv_stream_t*) &tcp_outgoing[i];
+ ASSERT(0 == uv_write(&write_reqs[i], outgoing, &buf, 1, write_cb));
+}
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char slab[1];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ uv_loop_t* loop;
+ unsigned int i;
+
+ /* Only first stream should receive read events */
+ ASSERT(stream == (uv_stream_t*) &tcp_incoming[0]);
+ ASSERT(0 == uv_read_stop(stream));
+ ASSERT(1 == nread);
+
+ loop = stream->loop;
+ read_cb_called++;
+
+ /* Close all active incomings, except current one */
+ for (i = 1; i < got_connections; i++)
+ uv_close((uv_handle_t*) &tcp_incoming[i], close_cb);
+
+ /* Create new fd that should be one of the closed incomings */
+ ASSERT(0 == uv_tcp_init(loop, &tcp_check));
+ ASSERT(0 == uv_tcp_connect(&tcp_check_req,
+ &tcp_check,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_check, alloc_cb, read_cb));
+
+ /* Close server, so no one will connect to it */
+ uv_close((uv_handle_t*) &tcp_server, close_cb);
+}
+
+static void connection_cb(uv_stream_t* server, int status) {
+ unsigned int i;
+ uv_tcp_t* incoming;
+
+ ASSERT(server == (uv_stream_t*) &tcp_server);
+
+ /* Ignore tcp_check connection */
+ if (got_connections == ARRAY_SIZE(tcp_incoming))
+ return;
+
+ /* Accept everyone */
+ incoming = &tcp_incoming[got_connections++];
+ ASSERT(0 == uv_tcp_init(server->loop, incoming));
+ ASSERT(0 == uv_accept(server, (uv_stream_t*) incoming));
+
+ if (got_connections != ARRAY_SIZE(tcp_incoming))
+ return;
+
+ /* Once all clients are accepted - start reading */
+ for (i = 0; i < ARRAY_SIZE(tcp_incoming); i++) {
+ incoming = &tcp_incoming[i];
+ ASSERT(0 == uv_read_start((uv_stream_t*) incoming, alloc_cb, read_cb));
+ }
+}
+
+TEST_IMPL(tcp_close_accept) {
+ unsigned int i;
+ uv_loop_t* loop;
+ uv_tcp_t* client;
+
+ /*
+ * A little explanation of what goes on below:
+ *
+ * We'll create server and connect to it using two clients, each writing one
+ * byte once connected.
+ *
+ * When all clients will be accepted by server - we'll start reading from them
+ * and, on first client's first byte, will close second client and server.
+ * After that, we'll immediately initiate new connection to server using
+ * tcp_check handle (thus, reusing fd from second client).
+ *
+ * In this situation uv__io_poll()'s event list should still contain read
+ * event for second client, and, if not cleaned up properly, `tcp_check` will
+ * receive stale event of second incoming and invoke `connect_cb` with zero
+ * status.
+ */
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(loop, &tcp_server));
+ ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &tcp_server,
+ ARRAY_SIZE(tcp_outgoing),
+ connection_cb));
+
+ for (i = 0; i < ARRAY_SIZE(tcp_outgoing); i++) {
+ client = tcp_outgoing + i;
+
+ ASSERT(0 == uv_tcp_init(loop, client));
+ ASSERT(0 == uv_tcp_connect(&connect_reqs[i],
+ client,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ }
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(ARRAY_SIZE(tcp_outgoing) == got_connections);
+ ASSERT((ARRAY_SIZE(tcp_outgoing) + 2) == close_cb_called);
+ ASSERT(ARRAY_SIZE(tcp_outgoing) == write_cb_called);
+ ASSERT(1 == read_cb_called);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-close-while-connecting.c b/third-party/libuv/test/test-tcp-close-while-connecting.c
new file mode 100644
index 0000000000..b9f7f9661c
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-close-while-connecting.c
@@ -0,0 +1,82 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer1_handle;
+static uv_timer_t timer2_handle;
+static uv_tcp_t tcp_handle;
+
+static int connect_cb_called;
+static int timer1_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(status == UV_ECANCELED);
+ uv_timer_stop(&timer2_handle);
+ connect_cb_called++;
+}
+
+
+static void timer1_cb(uv_timer_t* handle, int status) {
+ uv_close((uv_handle_t*)handle, close_cb);
+ uv_close((uv_handle_t*)&tcp_handle, close_cb);
+ timer1_cb_called++;
+}
+
+
+static void timer2_cb(uv_timer_t* handle, int status) {
+ ASSERT(0 && "should not be called");
+}
+
+
+TEST_IMPL(tcp_close_while_connecting) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("1.2.3.4", TEST_PORT, &addr));
+ ASSERT(0 == uv_tcp_init(loop, &tcp_handle));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &tcp_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_timer_init(loop, &timer1_handle));
+ ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 50, 0));
+ ASSERT(0 == uv_timer_init(loop, &timer2_handle));
+ ASSERT(0 == uv_timer_start(&timer2_handle, timer2_cb, 86400 * 1000, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(timer1_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-close.c b/third-party/libuv/test/test-tcp-close.c
new file mode 100644
index 0000000000..e65885aa55
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-close.c
@@ -0,0 +1,136 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <string.h> /* memset */
+
+#define NUM_WRITE_REQS 32
+
+static uv_tcp_t tcp_handle;
+static uv_connect_t connect_req;
+
+static int write_cb_called;
+static int close_cb_called;
+
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void close_cb(uv_handle_t* handle);
+
+
+static void connect_cb(uv_connect_t* conn_req, int status) {
+ uv_write_t* req;
+ uv_buf_t buf;
+ int i, r;
+
+ buf = uv_buf_init("PING", 4);
+ for (i = 0; i < NUM_WRITE_REQS; i++) {
+ req = malloc(sizeof *req);
+ ASSERT(req != NULL);
+
+ r = uv_write(req, (uv_stream_t*)&tcp_handle, &buf, 1, write_cb);
+ ASSERT(r == 0);
+ }
+
+ uv_close((uv_handle_t*)&tcp_handle, close_cb);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ /* write callbacks should run before the close callback */
+ ASSERT(close_cb_called == 0);
+ ASSERT(req->handle == (uv_stream_t*)&tcp_handle);
+ write_cb_called++;
+ free(req);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*)&tcp_handle);
+ close_cb_called++;
+}
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+ ASSERT(status == 0);
+}
+
+
+static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, handle);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
+ ASSERT(r == 0);
+
+ uv_unref((uv_handle_t*)handle);
+}
+
+
+/* Check that pending write requests have their callbacks
+ * invoked when the handle is closed.
+ */
+TEST_IMPL(tcp_close) {
+ struct sockaddr_in addr;
+ uv_tcp_t tcp_server;
+ uv_loop_t* loop;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ loop = uv_default_loop();
+
+ /* We can't use the echo server, it doesn't handle ECONNRESET. */
+ start_server(loop, &tcp_server);
+
+ r = uv_tcp_init(loop, &tcp_handle);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &tcp_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ printf("%d of %d write reqs seen\n", write_cb_called, NUM_WRITE_REQS);
+
+ ASSERT(write_cb_called == NUM_WRITE_REQS);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-connect-error-after-write.c b/third-party/libuv/test/test-tcp-connect-error-after-write.c
new file mode 100644
index 0000000000..3f2e3572da
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-connect-error-after-write.c
@@ -0,0 +1,98 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int connect_cb_called;
+static int write_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(status < 0);
+ connect_cb_called++;
+ uv_close((uv_handle_t*)req->handle, close_cb);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status < 0);
+ write_cb_called++;
+}
+
+
+/*
+ * Try to connect to an address on which nothing listens, get ECONNREFUSED
+ * (uv errno 12) and get connect_cb() called once with status != 0.
+ * Related issue: https://github.com/joyent/libuv/issues/443
+ */
+TEST_IMPL(tcp_connect_error_after_write) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+ uv_write_t write_req;
+ uv_tcp_t conn;
+ uv_buf_t buf;
+ int r;
+
+#ifdef _WIN32
+ fprintf(stderr, "This test is disabled on Windows for now.\n");
+ fprintf(stderr, "See https://github.com/joyent/libuv/issues/444\n");
+ return 0; /* windows slackers... */
+#endif
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ buf = uv_buf_init("TEST", 4);
+
+ r = uv_tcp_init(uv_default_loop(), &conn);
+ ASSERT(r == 0);
+
+ r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
+ ASSERT(r == UV_EBADF);
+
+ r = uv_tcp_connect(&connect_req,
+ &conn,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-connect-error.c b/third-party/libuv/test/test-tcp-connect-error.c
new file mode 100644
index 0000000000..eab1eeb254
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-connect-error.c
@@ -0,0 +1,73 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int connect_cb_called = 0;
+static int close_cb_called = 0;
+
+
+
+static void connect_cb(uv_connect_t* handle, int status) {
+ ASSERT(handle != NULL);
+ connect_cb_called++;
+}
+
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+TEST_IMPL(tcp_connect_error_fault) {
+ const char garbage[] =
+ "blah blah blah blah blah blah blah blah blah blah blah blah";
+ const struct sockaddr_in* garbage_addr;
+ uv_tcp_t server;
+ int r;
+ uv_connect_t req;
+
+ garbage_addr = (const struct sockaddr_in*) &garbage;
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_connect(&req,
+ &server,
+ (const struct sockaddr*) garbage_addr,
+ connect_cb);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connect_cb_called == 0);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-connect-timeout.c b/third-party/libuv/test/test-tcp-connect-timeout.c
new file mode 100644
index 0000000000..cc583cafb2
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-connect-timeout.c
@@ -0,0 +1,89 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int connect_cb_called;
+static int close_cb_called;
+
+static uv_connect_t connect_req;
+static uv_timer_t timer;
+static uv_tcp_t conn;
+
+static void connect_cb(uv_connect_t* req, int status);
+static void timer_cb(uv_timer_t* handle, int status);
+static void close_cb(uv_handle_t* handle);
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(req == &connect_req);
+ ASSERT(status == UV_ECANCELED);
+ connect_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer);
+ uv_close((uv_handle_t*)&conn, close_cb);
+ uv_close((uv_handle_t*)&timer, close_cb);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle == (uv_handle_t*)&conn || handle == (uv_handle_t*)&timer);
+ close_cb_called++;
+}
+
+
+/* Verify that connecting to an unreachable address or port doesn't hang
+ * the event loop.
+ */
+TEST_IMPL(tcp_connect_timeout) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("8.8.8.8", 9999, &addr));
+
+ r = uv_timer_init(uv_default_loop(), &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 50, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_init(uv_default_loop(), &conn);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &conn,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-connect6-error.c b/third-party/libuv/test/test-tcp-connect6-error.c
new file mode 100644
index 0000000000..91ac0a3a10
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-connect6-error.c
@@ -0,0 +1,71 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static int connect_cb_called = 0;
+static int close_cb_called = 0;
+
+
+static void connect_cb(uv_connect_t* handle, int status) {
+ ASSERT(handle != NULL);
+ connect_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+TEST_IMPL(tcp_connect6_error_fault) {
+ const char garbage[] =
+ "blah blah blah blah blah blah blah blah blah blah blah blah";
+ const struct sockaddr_in6* garbage_addr;
+ uv_tcp_t server;
+ int r;
+ uv_connect_t req;
+
+ garbage_addr = (const struct sockaddr_in6*) &garbage;
+
+ r = uv_tcp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+ r = uv_tcp_connect(&req,
+ &server,
+ (const struct sockaddr*) garbage_addr,
+ connect_cb);
+ ASSERT(r == UV_EINVAL);
+
+ uv_close((uv_handle_t*)&server, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(connect_cb_called == 0);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-flags.c b/third-party/libuv/test/test-tcp-flags.c
new file mode 100644
index 0000000000..68afb39f45
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-flags.c
@@ -0,0 +1,52 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+TEST_IMPL(tcp_flags) {
+ uv_loop_t* loop;
+ uv_tcp_t handle;
+ int r;
+
+ loop = uv_default_loop();
+
+ r = uv_tcp_init(loop, &handle);
+ ASSERT(r == 0);
+
+ r = uv_tcp_nodelay(&handle, 1);
+ ASSERT(r == 0);
+
+ r = uv_tcp_keepalive(&handle, 1, 60);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*)&handle, NULL);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-open.c b/third-party/libuv/test/test-tcp-open.c
new file mode 100644
index 0000000000..edeacc70e4
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-open.c
@@ -0,0 +1,182 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+static int shutdown_cb_called = 0;
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int close_cb_called = 0;
+
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+static uv_write_t write_req;
+
+
+static void startup(void) {
+#ifdef _WIN32
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+#endif
+}
+
+
+static uv_os_sock_t create_tcp_socket(void) {
+ uv_os_sock_t sock;
+
+ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+#ifndef _WIN32
+ {
+ /* Allow reuse of the port. */
+ int yes = 1;
+ int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
+ ASSERT(r == 0);
+ }
+#endif
+
+ return sock;
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(req == &shutdown_req);
+ ASSERT(status == 0);
+
+ /* Now we wait for the EOF */
+ shutdown_cb_called++;
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(tcp != NULL);
+
+ if (nread >= 0) {
+ ASSERT(nread == 4);
+ ASSERT(memcmp("PING", buf->base, nread) == 0);
+ }
+ else {
+ ASSERT(nread == UV_EOF);
+ printf("GOT EOF\n");
+ uv_close((uv_handle_t*)tcp, close_cb);
+ }
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+
+ if (status) {
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+ ASSERT(0);
+ }
+
+ write_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ uv_stream_t* stream;
+ int r;
+
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ stream = req->handle;
+ connect_cb_called++;
+
+ r = uv_write(&write_req, stream, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ /* Shutdown on drain. */
+ r = uv_shutdown(&shutdown_req, stream, shutdown_cb);
+ ASSERT(r == 0);
+
+ /* Start reading */
+ r = uv_read_start(stream, alloc_cb, read_cb);
+ ASSERT(r == 0);
+}
+
+
+TEST_IMPL(tcp_open) {
+ struct sockaddr_in addr;
+ uv_tcp_t client;
+ uv_os_sock_t sock;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ startup();
+ sock = create_tcp_socket();
+
+ r = uv_tcp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_open(&client, sock);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-read-stop.c b/third-party/libuv/test/test-tcp-read-stop.c
new file mode 100644
index 0000000000..c8d9c0407e
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-read-stop.c
@@ -0,0 +1,76 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_timer_t timer_handle;
+static uv_tcp_t tcp_handle;
+static uv_write_t write_req;
+
+
+static void fail_cb(void) {
+ ASSERT(0 && "fail_cb called");
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ uv_close((uv_handle_t*) &tcp_handle, NULL);
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ ASSERT(0 == uv_write(&write_req,
+ (uv_stream_t*) &tcp_handle,
+ &buf,
+ 1,
+ write_cb));
+ ASSERT(0 == uv_read_stop((uv_stream_t*) &tcp_handle));
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(0 == status);
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
+ ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_handle,
+ (uv_alloc_cb) fail_cb,
+ (uv_read_cb) fail_cb));
+}
+
+
+TEST_IMPL(tcp_read_stop) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp_handle));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &tcp_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ MAKE_VALGRIND_HAPPY();
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-shutdown-after-write.c b/third-party/libuv/test/test-tcp-shutdown-after-write.c
new file mode 100644
index 0000000000..c59acc4020
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-shutdown-after-write.c
@@ -0,0 +1,138 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static void write_cb(uv_write_t* req, int status);
+static void shutdown_cb(uv_shutdown_t* req, int status);
+
+static uv_tcp_t conn;
+static uv_timer_t timer;
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+static uv_shutdown_t shutdown_req;
+
+static int connect_cb_called;
+static int write_cb_called;
+static int shutdown_cb_called;
+
+static int conn_close_cb_called;
+static int timer_close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ if (handle == (uv_handle_t*)&conn)
+ conn_close_cb_called++;
+ else if (handle == (uv_handle_t*)&timer)
+ timer_close_cb_called++;
+ else
+ ASSERT(0 && "bad handle in close_cb");
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[64];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_buf_t buf;
+ int r;
+
+ uv_close((uv_handle_t*)handle, close_cb);
+
+ buf = uv_buf_init("TEST", 4);
+ r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
+ ASSERT(r == 0);
+
+ r = uv_shutdown(&shutdown_req, (uv_stream_t*)&conn, shutdown_cb);
+ ASSERT(r == 0);
+}
+
+
+static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ int r;
+
+ ASSERT(status == 0);
+ connect_cb_called++;
+
+ r = uv_read_start((uv_stream_t*)&conn, alloc_cb, read_cb);
+ ASSERT(r == 0);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ write_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ ASSERT(status == 0);
+ shutdown_cb_called++;
+ uv_close((uv_handle_t*)&conn, close_cb);
+}
+
+
+TEST_IMPL(tcp_shutdown_after_write) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ loop = uv_default_loop();
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 125, 0);
+ ASSERT(r == 0);
+
+ r = uv_tcp_init(loop, &conn);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &conn,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(conn_close_cb_called == 1);
+ ASSERT(timer_close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-try-write.c b/third-party/libuv/test/test-tcp-try-write.c
new file mode 100644
index 0000000000..00341e4169
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-try-write.c
@@ -0,0 +1,144 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_BYTES 1024 * 1024
+
+#ifdef _WIN32
+
+TEST_IMPL(tcp_try_write) {
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#else /* !_WIN32 */
+
+static uv_tcp_t server;
+static uv_tcp_t client;
+static uv_tcp_t incoming;
+static int connect_cb_called;
+static int close_cb_called;
+static int connection_cb_called;
+static int bytes_read;
+static int bytes_written;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ static char zeroes[1024];
+ int r;
+ uv_buf_t buf;
+ ASSERT(status == 0);
+ connect_cb_called++;
+
+ do {
+ buf = uv_buf_init(zeroes, sizeof(zeroes));
+ r = uv_try_write((uv_stream_t*) &client, &buf, 1);
+ ASSERT(r >= 0);
+ bytes_written += r;
+
+ /* Partial write */
+ if (r != (int) sizeof(zeroes))
+ break;
+ } while (1);
+ uv_close((uv_handle_t*) &client, close_cb);
+}
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char base[1024];
+
+ buf->base = base;
+ buf->len = sizeof(base);
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ if (nread < 0) {
+ uv_close((uv_handle_t*) tcp, close_cb);
+ uv_close((uv_handle_t*) &server, close_cb);
+ return;
+ }
+
+ bytes_read += nread;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
+ ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+
+ connection_cb_called++;
+ ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb));
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+ ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
+}
+
+
+TEST_IMPL(tcp_try_write) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ start_server();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client,
+ (struct sockaddr*) &addr,
+ connect_cb));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+ ASSERT(connection_cb_called == 1);
+ ASSERT(bytes_read == bytes_written);
+ ASSERT(bytes_written > 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !_WIN32 */
diff --git a/third-party/libuv/test/test-tcp-unexpected-read.c b/third-party/libuv/test/test-tcp-unexpected-read.c
new file mode 100644
index 0000000000..11fee8ba8e
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-unexpected-read.c
@@ -0,0 +1,117 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_check_t check_handle;
+static uv_timer_t timer_handle;
+static uv_tcp_t server_handle;
+static uv_tcp_t client_handle;
+static uv_tcp_t peer_handle;
+static uv_write_t write_req;
+static uv_connect_t connect_req;
+
+static unsigned long ticks; /* event loop ticks */
+
+
+static void check_cb(uv_check_t* handle, int status) {
+ ticks++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ uv_close((uv_handle_t*) &check_handle, NULL);
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ uv_close((uv_handle_t*) &server_handle, NULL);
+ uv_close((uv_handle_t*) &client_handle, NULL);
+ uv_close((uv_handle_t*) &peer_handle, NULL);
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ ASSERT(0 && "alloc_cb should not have been called");
+}
+
+
+static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(0 && "read_cb should not have been called");
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(req->handle == (uv_stream_t*) &client_handle);
+ ASSERT(0 == status);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req->handle == (uv_stream_t*) &peer_handle);
+ ASSERT(0 == status);
+}
+
+
+static void connection_cb(uv_stream_t* handle, int status) {
+ uv_buf_t buf;
+
+ buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == status);
+ ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle));
+ ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb));
+ ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &peer_handle,
+ &buf, 1, write_cb));
+}
+
+
+TEST_IMPL(tcp_unexpected_read) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ loop = uv_default_loop();
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1000, 0));
+ ASSERT(0 == uv_check_init(loop, &check_handle));
+ ASSERT(0 == uv_check_start(&check_handle, check_cb));
+ ASSERT(0 == uv_tcp_init(loop, &server_handle));
+ ASSERT(0 == uv_tcp_init(loop, &client_handle));
+ ASSERT(0 == uv_tcp_init(loop, &peer_handle));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ /* This is somewhat inexact but the idea is that the event loop should not
+ * start busy looping when the server sends a message and the client isn't
+ * reading.
+ */
+ ASSERT(ticks <= 20);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-write-to-half-open-connection.c b/third-party/libuv/test/test-tcp-write-to-half-open-connection.c
new file mode 100644
index 0000000000..2fa2ae7225
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-write-to-half-open-connection.c
@@ -0,0 +1,141 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void connection_cb(uv_stream_t* server, int status);
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
+static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
+
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_client;
+static uv_tcp_t tcp_peer; /* client socket as accept()-ed by server */
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+
+static int write_cb_called;
+static int read_cb_called;
+
+static void connection_cb(uv_stream_t* server, int status) {
+ int r;
+ uv_buf_t buf;
+
+ ASSERT(server == (uv_stream_t*)&tcp_server);
+ ASSERT(status == 0);
+
+ r = uv_tcp_init(server->loop, &tcp_peer);
+ ASSERT(r == 0);
+
+ r = uv_accept(server, (uv_stream_t*)&tcp_peer);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&tcp_peer, alloc_cb, read_cb);
+ ASSERT(r == 0);
+
+ buf.base = "hello\n";
+ buf.len = 6;
+
+ r = uv_write(&write_req, (uv_stream_t*)&tcp_peer, &buf, 1, write_cb);
+ ASSERT(r == 0);
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[1024];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ if (nread < 0) {
+ fprintf(stderr, "read_cb error: %s\n", uv_err_name(nread));
+ ASSERT(nread == UV_ECONNRESET || nread == UV_EOF);
+
+ uv_close((uv_handle_t*)&tcp_server, NULL);
+ uv_close((uv_handle_t*)&tcp_peer, NULL);
+ }
+
+ read_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ /* Close the client. */
+ uv_close((uv_handle_t*)&tcp_client, NULL);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ write_cb_called++;
+}
+
+
+TEST_IMPL(tcp_write_to_half_open_connection) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ loop = uv_default_loop();
+ ASSERT(loop != NULL);
+
+ r = uv_tcp_init(loop, &tcp_server);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb);
+ ASSERT(r == 0);
+
+ r = uv_tcp_init(loop, &tcp_client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &tcp_client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called > 0);
+ ASSERT(read_cb_called > 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tcp-writealot.c b/third-party/libuv/test/test-tcp-writealot.c
new file mode 100644
index 0000000000..6cfe2ebb18
--- /dev/null
+++ b/third-party/libuv/test/test-tcp-writealot.c
@@ -0,0 +1,176 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#define WRITES 3
+#define CHUNKS_PER_WRITE 4096
+#define CHUNK_SIZE 10024 /* 10 kb */
+
+#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE)
+
+static char* send_buffer;
+
+static int shutdown_cb_called = 0;
+static int connect_cb_called = 0;
+static int write_cb_called = 0;
+static int close_cb_called = 0;
+static size_t bytes_sent = 0;
+static size_t bytes_sent_done = 0;
+static size_t bytes_received_done = 0;
+
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+static uv_write_t write_reqs[WRITES];
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = malloc(size);
+ buf->len = size;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ uv_tcp_t* tcp;
+
+ ASSERT(req == &shutdown_req);
+ ASSERT(status == 0);
+
+ tcp = (uv_tcp_t*)(req->handle);
+
+ /* The write buffer should be empty by now. */
+ ASSERT(tcp->write_queue_size == 0);
+
+ /* Now we wait for the EOF */
+ shutdown_cb_called++;
+
+ /* We should have had all the writes called already. */
+ ASSERT(write_cb_called == WRITES);
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT(tcp != NULL);
+
+ if (nread >= 0) {
+ bytes_received_done += nread;
+ }
+ else {
+ ASSERT(nread == UV_EOF);
+ printf("GOT EOF\n");
+ uv_close((uv_handle_t*)tcp, close_cb);
+ }
+
+ free(buf->base);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+
+ if (status) {
+ fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
+ ASSERT(0);
+ }
+
+ bytes_sent_done += CHUNKS_PER_WRITE * CHUNK_SIZE;
+ write_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ uv_buf_t send_bufs[CHUNKS_PER_WRITE];
+ uv_stream_t* stream;
+ int i, j, r;
+
+ ASSERT(req == &connect_req);
+ ASSERT(status == 0);
+
+ stream = req->handle;
+ connect_cb_called++;
+
+ /* Write a lot of data */
+ for (i = 0; i < WRITES; i++) {
+ uv_write_t* write_req = write_reqs + i;
+
+ for (j = 0; j < CHUNKS_PER_WRITE; j++) {
+ send_bufs[j] = uv_buf_init(send_buffer + bytes_sent, CHUNK_SIZE);
+ bytes_sent += CHUNK_SIZE;
+ }
+
+ r = uv_write(write_req, stream, send_bufs, CHUNKS_PER_WRITE, write_cb);
+ ASSERT(r == 0);
+ }
+
+ /* Shutdown on drain. */
+ r = uv_shutdown(&shutdown_req, stream, shutdown_cb);
+ ASSERT(r == 0);
+
+ /* Start reading */
+ r = uv_read_start(stream, alloc_cb, read_cb);
+ ASSERT(r == 0);
+}
+
+
+TEST_IMPL(tcp_writealot) {
+ struct sockaddr_in addr;
+ uv_tcp_t client;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ send_buffer = calloc(1, TOTAL_BYTES);
+ ASSERT(send_buffer != NULL);
+
+ r = uv_tcp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ &client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(connect_cb_called == 1);
+ ASSERT(write_cb_called == WRITES);
+ ASSERT(close_cb_called == 1);
+ ASSERT(bytes_sent == TOTAL_BYTES);
+ ASSERT(bytes_sent_done == TOTAL_BYTES);
+ ASSERT(bytes_received_done == TOTAL_BYTES);
+
+ free(send_buffer);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-thread.c b/third-party/libuv/test/test-thread.c
new file mode 100644
index 0000000000..c396baa100
--- /dev/null
+++ b/third-party/libuv/test/test-thread.c
@@ -0,0 +1,209 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* memset */
+
+struct getaddrinfo_req {
+ uv_thread_t thread_id;
+ unsigned int counter;
+ uv_loop_t* loop;
+ uv_getaddrinfo_t handle;
+};
+
+
+struct fs_req {
+ uv_thread_t thread_id;
+ unsigned int counter;
+ uv_loop_t* loop;
+ uv_fs_t handle;
+};
+
+
+struct test_thread {
+ uv_thread_t thread_id;
+ volatile int thread_called;
+};
+
+static void getaddrinfo_do(struct getaddrinfo_req* req);
+static void getaddrinfo_cb(uv_getaddrinfo_t* handle,
+ int status,
+ struct addrinfo* res);
+static void fs_do(struct fs_req* req);
+static void fs_cb(uv_fs_t* handle);
+
+static volatile int thread_called;
+static uv_key_t tls_key;
+
+
+static void getaddrinfo_do(struct getaddrinfo_req* req) {
+ int r;
+
+ r = uv_getaddrinfo(req->loop,
+ &req->handle,
+ getaddrinfo_cb,
+ "localhost",
+ NULL,
+ NULL);
+ ASSERT(r == 0);
+}
+
+
+static void getaddrinfo_cb(uv_getaddrinfo_t* handle,
+ int status,
+ struct addrinfo* res) {
+ struct getaddrinfo_req* req;
+
+ ASSERT(status == 0);
+
+ req = container_of(handle, struct getaddrinfo_req, handle);
+ uv_freeaddrinfo(res);
+
+ if (--req->counter)
+ getaddrinfo_do(req);
+}
+
+
+static void fs_do(struct fs_req* req) {
+ int r;
+
+ r = uv_fs_stat(req->loop, &req->handle, ".", fs_cb);
+ ASSERT(r == 0);
+}
+
+
+static void fs_cb(uv_fs_t* handle) {
+ struct fs_req* req = container_of(handle, struct fs_req, handle);
+
+ uv_fs_req_cleanup(handle);
+
+ if (--req->counter)
+ fs_do(req);
+}
+
+
+static void do_work(void* arg) {
+ struct getaddrinfo_req getaddrinfo_reqs[16];
+ struct fs_req fs_reqs[16];
+ uv_loop_t* loop;
+ size_t i;
+ int r;
+ struct test_thread* thread = arg;
+
+ loop = uv_loop_new();
+ ASSERT(loop != NULL);
+
+ for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) {
+ struct getaddrinfo_req* req = getaddrinfo_reqs + i;
+ req->counter = 16;
+ req->loop = loop;
+ getaddrinfo_do(req);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(fs_reqs); i++) {
+ struct fs_req* req = fs_reqs + i;
+ req->counter = 16;
+ req->loop = loop;
+ fs_do(req);
+ }
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ uv_loop_delete(loop);
+ thread->thread_called = 1;
+}
+
+
+static void thread_entry(void* arg) {
+ ASSERT(arg == (void *) 42);
+ thread_called++;
+}
+
+
+TEST_IMPL(thread_create) {
+ uv_thread_t tid;
+ int r;
+
+ r = uv_thread_create(&tid, thread_entry, (void *) 42);
+ ASSERT(r == 0);
+
+ r = uv_thread_join(&tid);
+ ASSERT(r == 0);
+
+ ASSERT(thread_called == 1);
+
+ return 0;
+}
+
+
+/* Hilariously bad test name. Run a lot of tasks in the thread pool and verify
+ * that each "finished" callback is run in its originating thread.
+ */
+TEST_IMPL(threadpool_multiple_event_loops) {
+ struct test_thread threads[8];
+ size_t i;
+ int r;
+
+ memset(threads, 0, sizeof(threads));
+
+ for (i = 0; i < ARRAY_SIZE(threads); i++) {
+ r = uv_thread_create(&threads[i].thread_id, do_work, &threads[i]);
+ ASSERT(r == 0);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(threads); i++) {
+ r = uv_thread_join(&threads[i].thread_id);
+ ASSERT(r == 0);
+ ASSERT(threads[i].thread_called);
+ }
+
+ return 0;
+}
+
+
+static void tls_thread(void* arg) {
+ ASSERT(NULL == uv_key_get(&tls_key));
+ uv_key_set(&tls_key, arg);
+ ASSERT(arg == uv_key_get(&tls_key));
+ uv_key_set(&tls_key, NULL);
+ ASSERT(NULL == uv_key_get(&tls_key));
+}
+
+
+TEST_IMPL(thread_local_storage) {
+ char name[] = "main";
+ uv_thread_t threads[2];
+ ASSERT(0 == uv_key_create(&tls_key));
+ ASSERT(NULL == uv_key_get(&tls_key));
+ uv_key_set(&tls_key, name);
+ ASSERT(name == uv_key_get(&tls_key));
+ ASSERT(0 == uv_thread_create(threads + 0, tls_thread, threads + 0));
+ ASSERT(0 == uv_thread_create(threads + 1, tls_thread, threads + 1));
+ ASSERT(0 == uv_thread_join(threads + 0));
+ ASSERT(0 == uv_thread_join(threads + 1));
+ uv_key_delete(&tls_key);
+ return 0;
+}
diff --git a/third-party/libuv/test/test-threadpool-cancel.c b/third-party/libuv/test/test-threadpool-cancel.c
new file mode 100644
index 0000000000..1443773cc2
--- /dev/null
+++ b/third-party/libuv/test/test-threadpool-cancel.c
@@ -0,0 +1,311 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#define INIT_CANCEL_INFO(ci, what) \
+ do { \
+ (ci)->reqs = (what); \
+ (ci)->nreqs = ARRAY_SIZE(what); \
+ (ci)->stride = sizeof((what)[0]); \
+ } \
+ while (0)
+
+struct cancel_info {
+ void* reqs;
+ unsigned nreqs;
+ unsigned stride;
+ uv_timer_t timer_handle;
+};
+
+static uv_cond_t signal_cond;
+static uv_mutex_t signal_mutex;
+static uv_mutex_t wait_mutex;
+static unsigned num_threads;
+static unsigned fs_cb_called;
+static unsigned work_cb_called;
+static unsigned done_cb_called;
+static unsigned done2_cb_called;
+static unsigned timer_cb_called;
+static unsigned getaddrinfo_cb_called;
+
+
+static void work_cb(uv_work_t* req) {
+ uv_mutex_lock(&signal_mutex);
+ uv_cond_signal(&signal_cond);
+ uv_mutex_unlock(&signal_mutex);
+
+ uv_mutex_lock(&wait_mutex);
+ uv_mutex_unlock(&wait_mutex);
+
+ work_cb_called++;
+}
+
+
+static void done_cb(uv_work_t* req, int status) {
+ done_cb_called++;
+ free(req);
+}
+
+
+static void saturate_threadpool(void) {
+ uv_work_t* req;
+
+ ASSERT(0 == uv_cond_init(&signal_cond));
+ ASSERT(0 == uv_mutex_init(&signal_mutex));
+ ASSERT(0 == uv_mutex_init(&wait_mutex));
+
+ uv_mutex_lock(&signal_mutex);
+ uv_mutex_lock(&wait_mutex);
+
+ for (num_threads = 0; /* empty */; num_threads++) {
+ req = malloc(sizeof(*req));
+ ASSERT(req != NULL);
+ ASSERT(0 == uv_queue_work(uv_default_loop(), req, work_cb, done_cb));
+
+ /* Expect to get signalled within 350 ms, otherwise assume that
+ * the thread pool is saturated. As with any timing dependent test,
+ * this is obviously not ideal.
+ */
+ if (uv_cond_timedwait(&signal_cond, &signal_mutex, 350 * 1e6)) {
+ ASSERT(0 == uv_cancel((uv_req_t*) req));
+ break;
+ }
+ }
+}
+
+
+static void unblock_threadpool(void) {
+ uv_mutex_unlock(&signal_mutex);
+ uv_mutex_unlock(&wait_mutex);
+}
+
+
+static void cleanup_threadpool(void) {
+ ASSERT(done_cb_called == num_threads + 1); /* +1 == cancelled work req. */
+ ASSERT(work_cb_called == num_threads);
+
+ uv_cond_destroy(&signal_cond);
+ uv_mutex_destroy(&signal_mutex);
+ uv_mutex_destroy(&wait_mutex);
+}
+
+
+static void fs_cb(uv_fs_t* req) {
+ ASSERT(req->result == UV_ECANCELED);
+ uv_fs_req_cleanup(req);
+ fs_cb_called++;
+}
+
+
+static void getaddrinfo_cb(uv_getaddrinfo_t* req,
+ int status,
+ struct addrinfo* res) {
+ ASSERT(status == UV_EAI_CANCELED);
+ ASSERT(res == NULL);
+ uv_freeaddrinfo(res); /* Should not crash. */
+ getaddrinfo_cb_called++;
+}
+
+
+static void work2_cb(uv_work_t* req) {
+ ASSERT(0 && "work2_cb called");
+}
+
+
+static void done2_cb(uv_work_t* req, int status) {
+ ASSERT(status == UV_ECANCELED);
+ done2_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ struct cancel_info* ci;
+ uv_req_t* req;
+ unsigned i;
+
+ ci = container_of(handle, struct cancel_info, timer_handle);
+
+ for (i = 0; i < ci->nreqs; i++) {
+ req = (uv_req_t*) ((char*) ci->reqs + i * ci->stride);
+ ASSERT(0 == uv_cancel(req));
+ }
+
+ uv_close((uv_handle_t*) &ci->timer_handle, NULL);
+ unblock_threadpool();
+ timer_cb_called++;
+}
+
+
+static void nop_work_cb(uv_work_t* req) {
+}
+
+
+static void nop_done_cb(uv_work_t* req, int status) {
+ req->data = "OK";
+}
+
+
+TEST_IMPL(threadpool_cancel_getaddrinfo) {
+ uv_getaddrinfo_t reqs[4];
+ struct cancel_info ci;
+ struct addrinfo hints;
+ uv_loop_t* loop;
+ int r;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ r = uv_getaddrinfo(loop, reqs + 0, getaddrinfo_cb, "fail", NULL, NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 1, getaddrinfo_cb, NULL, "fail", NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 2, getaddrinfo_cb, "fail", "fail", NULL);
+ ASSERT(r == 0);
+
+ r = uv_getaddrinfo(loop, reqs + 3, getaddrinfo_cb, "fail", NULL, &hints);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_work) {
+ struct cancel_info ci;
+ uv_work_t reqs[16];
+ uv_loop_t* loop;
+ unsigned i;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ for (i = 0; i < ARRAY_SIZE(reqs); i++)
+ ASSERT(0 == uv_queue_work(loop, reqs + i, work2_cb, done2_cb));
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+ ASSERT(ARRAY_SIZE(reqs) == done2_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_fs) {
+ struct cancel_info ci;
+ uv_fs_t reqs[25];
+ uv_loop_t* loop;
+ unsigned n;
+
+ INIT_CANCEL_INFO(&ci, reqs);
+ loop = uv_default_loop();
+ saturate_threadpool();
+
+ /* Needs to match ARRAY_SIZE(fs_reqs). */
+ n = 0;
+ ASSERT(0 == uv_fs_chmod(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_chown(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_close(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fchmod(loop, reqs + n++, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_fchown(loop, reqs + n++, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_fdatasync(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fstat(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_fsync(loop, reqs + n++, 0, fs_cb));
+ ASSERT(0 == uv_fs_ftruncate(loop, reqs + n++, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_futime(loop, reqs + n++, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_link(loop, reqs + n++, "/", "/", fs_cb));
+ ASSERT(0 == uv_fs_lstat(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_readdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb));
+ ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_stat(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb));
+ ASSERT(0 == uv_fs_unlink(loop, reqs + n++, "/", fs_cb));
+ ASSERT(0 == uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb));
+ ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
+ ASSERT(n == ARRAY_SIZE(reqs));
+
+ ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));
+ ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(n == fs_cb_called);
+ ASSERT(1 == timer_cb_called);
+
+ cleanup_threadpool();
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_cancel_single) {
+ uv_loop_t* loop;
+ uv_work_t req;
+ int cancelled;
+ int i;
+
+ loop = uv_default_loop();
+ for (i = 0; i < 5000; i++) {
+ req.data = NULL;
+ ASSERT(0 == uv_queue_work(loop, &req, nop_work_cb, nop_done_cb));
+
+ cancelled = uv_cancel((uv_req_t*) &req);
+ if (cancelled == 0)
+ break;
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ }
+
+ if (cancelled != 0) {
+ fputs("Failed to cancel a work req in 5,000 iterations, giving up.\n",
+ stderr);
+ return 1;
+ }
+
+ ASSERT(req.data == NULL);
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(req.data != NULL); /* Should have been updated by nop_done_cb(). */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-threadpool.c b/third-party/libuv/test/test-threadpool.c
new file mode 100644
index 0000000000..e3d17d7546
--- /dev/null
+++ b/third-party/libuv/test/test-threadpool.c
@@ -0,0 +1,76 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static int work_cb_count;
+static int after_work_cb_count;
+static uv_work_t work_req;
+static char data;
+
+
+static void work_cb(uv_work_t* req) {
+ ASSERT(req == &work_req);
+ ASSERT(req->data == &data);
+ work_cb_count++;
+}
+
+
+static void after_work_cb(uv_work_t* req, int status) {
+ ASSERT(status == 0);
+ ASSERT(req == &work_req);
+ ASSERT(req->data == &data);
+ after_work_cb_count++;
+}
+
+
+TEST_IMPL(threadpool_queue_work_simple) {
+ int r;
+
+ work_req.data = &data;
+ r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
+ ASSERT(r == 0);
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(work_cb_count == 1);
+ ASSERT(after_work_cb_count == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(threadpool_queue_work_einval) {
+ int r;
+
+ work_req.data = &data;
+ r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb);
+ ASSERT(r == UV_EINVAL);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(work_cb_count == 0);
+ ASSERT(after_work_cb_count == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-timer-again.c b/third-party/libuv/test/test-timer-again.c
new file mode 100644
index 0000000000..1638da2dfc
--- /dev/null
+++ b/third-party/libuv/test/test-timer-again.c
@@ -0,0 +1,140 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+static int close_cb_called = 0;
+static int repeat_1_cb_called = 0;
+static int repeat_2_cb_called = 0;
+
+static int repeat_2_cb_allowed = 0;
+
+static uv_timer_t dummy, repeat_1, repeat_2;
+
+static uint64_t start_time;
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+
+ close_cb_called++;
+}
+
+
+static void repeat_1_cb(uv_timer_t* handle, int status) {
+ int r;
+
+ ASSERT(handle == &repeat_1);
+ ASSERT(status == 0);
+
+ ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
+
+ LOGF("repeat_1_cb called after %ld ms\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+
+ repeat_1_cb_called++;
+
+ r = uv_timer_again(&repeat_2);
+ ASSERT(r == 0);
+
+ if (repeat_1_cb_called == 10) {
+ uv_close((uv_handle_t*)handle, close_cb);
+ /* We're not calling uv_timer_again on repeat_2 any more, so after this */
+ /* timer_2_cb is expected. */
+ repeat_2_cb_allowed = 1;
+ return;
+ }
+}
+
+
+static void repeat_2_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &repeat_2);
+ ASSERT(status == 0);
+ ASSERT(repeat_2_cb_allowed);
+
+ LOGF("repeat_2_cb called after %ld ms\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+
+ repeat_2_cb_called++;
+
+ if (uv_timer_get_repeat(&repeat_2) == 0) {
+ ASSERT(0 == uv_is_active((uv_handle_t*) handle));
+ uv_close((uv_handle_t*)handle, close_cb);
+ return;
+ }
+
+ LOGF("uv_timer_get_repeat %ld ms\n",
+ (long int)uv_timer_get_repeat(&repeat_2));
+ ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
+
+ /* This shouldn't take effect immediately. */
+ uv_timer_set_repeat(&repeat_2, 0);
+}
+
+
+TEST_IMPL(timer_again) {
+ int r;
+
+ start_time = uv_now(uv_default_loop());
+ ASSERT(0 < start_time);
+
+ /* Verify that it is not possible to uv_timer_again a never-started timer. */
+ r = uv_timer_init(uv_default_loop(), &dummy);
+ ASSERT(r == 0);
+ r = uv_timer_again(&dummy);
+ ASSERT(r == UV_EINVAL);
+ uv_unref((uv_handle_t*)&dummy);
+
+ /* Start timer repeat_1. */
+ r = uv_timer_init(uv_default_loop(), &repeat_1);
+ ASSERT(r == 0);
+ r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0);
+ ASSERT(r == 0);
+ ASSERT(uv_timer_get_repeat(&repeat_1) == 0);
+
+ /* Actually make repeat_1 repeating. */
+ uv_timer_set_repeat(&repeat_1, 50);
+ ASSERT(uv_timer_get_repeat(&repeat_1) == 50);
+
+ /*
+ * Start another repeating timer. It'll be again()ed by the repeat_1 so
+ * it should not time out until repeat_1 stops.
+ */
+ r = uv_timer_init(uv_default_loop(), &repeat_2);
+ ASSERT(r == 0);
+ r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100);
+ ASSERT(r == 0);
+ ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(repeat_1_cb_called == 10);
+ ASSERT(repeat_2_cb_called == 2);
+ ASSERT(close_cb_called == 2);
+
+ LOGF("Test took %ld ms (expected ~700 ms)\n",
+ (long int)(uv_now(uv_default_loop()) - start_time));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-timer-from-check.c b/third-party/libuv/test/test-timer-from-check.c
new file mode 100644
index 0000000000..2aa3fe4119
--- /dev/null
+++ b/third-party/libuv/test/test-timer-from-check.c
@@ -0,0 +1,80 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+static uv_prepare_t prepare_handle;
+static uv_check_t check_handle;
+static uv_timer_t timer_handle;
+
+static int prepare_cb_called;
+static int check_cb_called;
+static int timer_cb_called;
+
+
+static void prepare_cb(uv_prepare_t* handle, int status) {
+ ASSERT(0 == uv_prepare_stop(&prepare_handle));
+ ASSERT(0 == prepare_cb_called);
+ ASSERT(1 == check_cb_called);
+ ASSERT(0 == timer_cb_called);
+ prepare_cb_called++;
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(0 == uv_timer_stop(&timer_handle));
+ ASSERT(1 == prepare_cb_called);
+ ASSERT(1 == check_cb_called);
+ ASSERT(0 == timer_cb_called);
+ timer_cb_called++;
+}
+
+
+static void check_cb(uv_check_t* handle, int status) {
+ ASSERT(0 == uv_check_stop(&check_handle));
+ ASSERT(0 == uv_timer_stop(&timer_handle)); /* Runs before timer_cb. */
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
+ ASSERT(0 == uv_prepare_start(&prepare_handle, prepare_cb));
+ ASSERT(0 == prepare_cb_called);
+ ASSERT(0 == check_cb_called);
+ ASSERT(0 == timer_cb_called);
+ check_cb_called++;
+}
+
+
+TEST_IMPL(timer_from_check) {
+ ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle));
+ ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
+ ASSERT(0 == uv_check_start(&check_handle, check_cb));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(1 == prepare_cb_called);
+ ASSERT(1 == check_cb_called);
+ ASSERT(1 == timer_cb_called);
+ uv_close((uv_handle_t*) &prepare_handle, NULL);
+ uv_close((uv_handle_t*) &check_handle, NULL);
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-timer.c b/third-party/libuv/test/test-timer.c
new file mode 100644
index 0000000000..bbe69f68be
--- /dev/null
+++ b/third-party/libuv/test/test-timer.c
@@ -0,0 +1,294 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+
+static int once_cb_called = 0;
+static int once_close_cb_called = 0;
+static int repeat_cb_called = 0;
+static int repeat_close_cb_called = 0;
+static int order_cb_called = 0;
+static uint64_t start_time;
+static uv_timer_t tiny_timer;
+static uv_timer_t huge_timer1;
+static uv_timer_t huge_timer2;
+
+
+static void once_close_cb(uv_handle_t* handle) {
+ printf("ONCE_CLOSE_CB\n");
+
+ ASSERT(handle != NULL);
+ ASSERT(0 == uv_is_active(handle));
+
+ once_close_cb_called++;
+}
+
+
+static void once_cb(uv_timer_t* handle, int status) {
+ printf("ONCE_CB %d\n", once_cb_called);
+
+ ASSERT(handle != NULL);
+ ASSERT(status == 0);
+ ASSERT(0 == uv_is_active((uv_handle_t*) handle));
+
+ once_cb_called++;
+
+ uv_close((uv_handle_t*)handle, once_close_cb);
+
+ /* Just call this randomly for the code coverage. */
+ uv_update_time(uv_default_loop());
+}
+
+
+static void repeat_close_cb(uv_handle_t* handle) {
+ printf("REPEAT_CLOSE_CB\n");
+
+ ASSERT(handle != NULL);
+
+ repeat_close_cb_called++;
+}
+
+
+static void repeat_cb(uv_timer_t* handle, int status) {
+ printf("REPEAT_CB\n");
+
+ ASSERT(handle != NULL);
+ ASSERT(status == 0);
+ ASSERT(1 == uv_is_active((uv_handle_t*) handle));
+
+ repeat_cb_called++;
+
+ if (repeat_cb_called == 5) {
+ uv_close((uv_handle_t*)handle, repeat_close_cb);
+ }
+}
+
+
+static void never_cb(uv_timer_t* handle, int status) {
+ FATAL("never_cb should never be called");
+}
+
+
+TEST_IMPL(timer) {
+ uv_timer_t once_timers[10];
+ uv_timer_t *once;
+ uv_timer_t repeat, never;
+ unsigned int i;
+ int r;
+
+ start_time = uv_now(uv_default_loop());
+ ASSERT(0 < start_time);
+
+ /* Let 10 timers time out in 500 ms total. */
+ for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
+ once = once_timers + i;
+ r = uv_timer_init(uv_default_loop(), once);
+ ASSERT(r == 0);
+ r = uv_timer_start(once, once_cb, i * 50, 0);
+ ASSERT(r == 0);
+ }
+
+ /* The 11th timer is a repeating timer that runs 4 times */
+ r = uv_timer_init(uv_default_loop(), &repeat);
+ ASSERT(r == 0);
+ r = uv_timer_start(&repeat, repeat_cb, 100, 100);
+ ASSERT(r == 0);
+
+ /* The 12th timer should not do anything. */
+ r = uv_timer_init(uv_default_loop(), &never);
+ ASSERT(r == 0);
+ r = uv_timer_start(&never, never_cb, 100, 100);
+ ASSERT(r == 0);
+ r = uv_timer_stop(&never);
+ ASSERT(r == 0);
+ uv_unref((uv_handle_t*)&never);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(once_cb_called == 10);
+ ASSERT(once_close_cb_called == 10);
+ printf("repeat_cb_called %d\n", repeat_cb_called);
+ ASSERT(repeat_cb_called == 5);
+ ASSERT(repeat_close_cb_called == 1);
+
+ ASSERT(500 <= uv_now(uv_default_loop()) - start_time);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(timer_start_twice) {
+ uv_timer_t once;
+ int r;
+
+ r = uv_timer_init(uv_default_loop(), &once);
+ ASSERT(r == 0);
+ r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
+ ASSERT(r == 0);
+ r = uv_timer_start(&once, once_cb, 10, 0);
+ ASSERT(r == 0);
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(once_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(timer_init) {
+ uv_timer_t handle;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
+ ASSERT(0 == uv_timer_get_repeat(&handle));
+ ASSERT(0 == uv_is_active((uv_handle_t*) &handle));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void order_cb_a(uv_timer_t *handle, int status) {
+ ASSERT(order_cb_called++ == *(int*)handle->data);
+}
+
+
+static void order_cb_b(uv_timer_t *handle, int status) {
+ ASSERT(order_cb_called++ == *(int*)handle->data);
+}
+
+
+TEST_IMPL(timer_order) {
+ int first;
+ int second;
+ uv_timer_t handle_a;
+ uv_timer_t handle_b;
+
+ first = 0;
+ second = 1;
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b));
+
+ /* Test for starting handle_a then handle_b */
+ handle_a.data = &first;
+ ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
+ handle_b.data = &second;
+ ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(order_cb_called == 2);
+
+ ASSERT(0 == uv_timer_stop(&handle_a));
+ ASSERT(0 == uv_timer_stop(&handle_b));
+
+ /* Test for starting handle_b then handle_a */
+ order_cb_called = 0;
+ handle_b.data = &first;
+ ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
+
+ handle_a.data = &second;
+ ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(order_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void tiny_timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &tiny_timer);
+ uv_close((uv_handle_t*) &tiny_timer, NULL);
+ uv_close((uv_handle_t*) &huge_timer1, NULL);
+ uv_close((uv_handle_t*) &huge_timer2, NULL);
+}
+
+
+TEST_IMPL(timer_huge_timeout) {
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2));
+ ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
+ ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0));
+ ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void huge_repeat_cb(uv_timer_t* handle, int status) {
+ static int ncalls;
+
+ if (ncalls == 0)
+ ASSERT(handle == &huge_timer1);
+ else
+ ASSERT(handle == &tiny_timer);
+
+ if (++ncalls == 10) {
+ uv_close((uv_handle_t*) &tiny_timer, NULL);
+ uv_close((uv_handle_t*) &huge_timer1, NULL);
+ }
+}
+
+
+TEST_IMPL(timer_huge_repeat) {
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
+ ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
+ ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static unsigned int timer_run_once_timer_cb_called;
+
+
+static void timer_run_once_timer_cb(uv_timer_t* handle, int status) {
+ timer_run_once_timer_cb_called++;
+}
+
+
+TEST_IMPL(timer_run_once) {
+ uv_timer_t timer_handle;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+ ASSERT(1 == timer_run_once_timer_cb_called);
+
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+ ASSERT(2 == timer_run_once_timer_cb_called);
+
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-tty.c b/third-party/libuv/test/test-tty.c
new file mode 100644
index 0000000000..fb69910732
--- /dev/null
+++ b/third-party/libuv/test/test-tty.c
@@ -0,0 +1,123 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#ifdef _WIN32
+# include <io.h>
+# include <windows.h>
+#else /* Unix */
+# include <fcntl.h>
+# include <unistd.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+
+
+TEST_IMPL(tty) {
+ int r, width, height;
+ int ttyin_fd, ttyout_fd;
+ uv_tty_t tty_in, tty_out;
+ uv_loop_t* loop = uv_default_loop();
+
+ /* Make sure we have an FD that refers to a tty */
+#ifdef _WIN32
+ HANDLE handle;
+ handle = CreateFileA("conin$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ ASSERT(handle != INVALID_HANDLE_VALUE);
+ ttyin_fd = _open_osfhandle((intptr_t) handle, 0);
+
+ handle = CreateFileA("conout$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ ASSERT(handle != INVALID_HANDLE_VALUE);
+ ttyout_fd = _open_osfhandle((intptr_t) handle, 0);
+
+#else /* unix */
+ ttyin_fd = open("/dev/tty", O_RDONLY, 0);
+ if (ttyin_fd < 0) {
+ LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno));
+ return TEST_SKIP;
+ }
+
+ ttyout_fd = open("/dev/tty", O_WRONLY, 0);
+ if (ttyout_fd < 0) {
+ LOGF("Cannot open /dev/tty as write-only: %s\n", strerror(errno));
+ return TEST_SKIP;
+ }
+#endif
+
+ ASSERT(ttyin_fd >= 0);
+ ASSERT(ttyout_fd >= 0);
+
+ ASSERT(UV_UNKNOWN_HANDLE == uv_guess_handle(-1));
+
+ ASSERT(UV_TTY == uv_guess_handle(ttyin_fd));
+ ASSERT(UV_TTY == uv_guess_handle(ttyout_fd));
+
+ r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */
+ ASSERT(r == 0);
+
+ r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */
+ ASSERT(r == 0);
+
+ r = uv_tty_get_winsize(&tty_out, &width, &height);
+ ASSERT(r == 0);
+
+ printf("width=%d height=%d\n", width, height);
+
+ /*
+ * Is it a safe assumption that most people have terminals larger than
+ * 10x10?
+ */
+ ASSERT(width > 10);
+ ASSERT(height > 10);
+
+ /* Turn on raw mode. */
+ r = uv_tty_set_mode(&tty_in, 1);
+ ASSERT(r == 0);
+
+ /* Turn off raw mode. */
+ r = uv_tty_set_mode(&tty_in, 0);
+ ASSERT(r == 0);
+
+ /* TODO check the actual mode! */
+
+ uv_close((uv_handle_t*) &tty_in, NULL);
+ uv_close((uv_handle_t*) &tty_out, NULL);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-dgram-too-big.c b/third-party/libuv/test/test-udp-dgram-too-big.c
new file mode 100644
index 0000000000..bd44c42528
--- /dev/null
+++ b/third-party/libuv/test/test-udp-dgram-too-big.c
@@ -0,0 +1,91 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &handle_)
+
+#define CHECK_REQ(req) \
+ ASSERT((req) == &req_);
+
+static uv_udp_t handle_;
+static uv_udp_send_t req_;
+
+static int send_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ CHECK_REQ(req);
+ CHECK_HANDLE(req->handle);
+
+ ASSERT(status == UV_EMSGSIZE);
+
+ uv_close((uv_handle_t*)req->handle, close_cb);
+ send_cb_called++;
+}
+
+
+TEST_IMPL(udp_dgram_too_big) {
+ char dgram[65536]; /* 64K MTU is unlikely, even on localhost */
+ struct sockaddr_in addr;
+ uv_buf_t buf;
+ int r;
+
+ memset(dgram, 42, sizeof dgram); /* silence valgrind */
+
+ r = uv_udp_init(uv_default_loop(), &handle_);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init(dgram, sizeof dgram);
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_udp_send(&req_,
+ &handle_,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(send_cb_called == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(send_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-ipv6.c b/third-party/libuv/test/test-udp-ipv6.c
new file mode 100644
index 0000000000..32cabf097c
--- /dev/null
+++ b/third-party/libuv/test/test-udp-ipv6.c
@@ -0,0 +1,166 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server \
+ || (uv_udp_t*)(handle) == &client \
+ || (uv_timer_t*)(handle) == &timeout)
+
+#define CHECK_REQ(req) \
+ ASSERT((req) == &req_);
+
+static uv_udp_t client;
+static uv_udp_t server;
+static uv_udp_send_t req_;
+static uv_timer_t timeout;
+
+static int send_cb_called;
+static int recv_cb_called;
+static int close_cb_called;
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ CHECK_REQ(req);
+ CHECK_HANDLE(req->handle);
+ ASSERT(status == 0);
+ send_cb_called++;
+}
+
+
+static void ipv6_recv_fail(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ ASSERT(0 && "this function should not have been called");
+}
+
+
+static void ipv6_recv_ok(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ ASSERT(nread >= 0);
+
+ if (nread)
+ recv_cb_called++;
+}
+
+
+static void timeout_cb(uv_timer_t* timer, int status) {
+ uv_close((uv_handle_t*)&server, close_cb);
+ uv_close((uv_handle_t*)&client, close_cb);
+ uv_close((uv_handle_t*)&timeout, close_cb);
+}
+
+
+static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
+ struct sockaddr_in6 addr6;
+ struct sockaddr_in addr;
+ uv_buf_t buf;
+ int r;
+
+ ASSERT(0 == uv_ip6_addr("::0", TEST_PORT, &addr6));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr6, bind_flags);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&server, alloc_cb, recv_cb);
+ ASSERT(r == 0);
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init("PING", 4);
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_udp_send(&req_,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+
+ r = uv_timer_init(uv_default_loop(), &timeout);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timeout, timeout_cb, 500, 0);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(send_cb_called == 0);
+ ASSERT(recv_cb_called == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 3);
+
+ MAKE_VALGRIND_HAPPY();
+}
+
+
+TEST_IMPL(udp_dual_stack) {
+ do_test(ipv6_recv_ok, 0);
+
+ ASSERT(recv_cb_called == 1);
+ ASSERT(send_cb_called == 1);
+
+ return 0;
+}
+
+
+TEST_IMPL(udp_ipv6_only) {
+ do_test(ipv6_recv_fail, UV_UDP_IPV6ONLY);
+
+ ASSERT(recv_cb_called == 0);
+ ASSERT(send_cb_called == 1);
+
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-multicast-join.c b/third-party/libuv/test/test-udp-multicast-join.c
new file mode 100644
index 0000000000..686edf3d22
--- /dev/null
+++ b/third-party/libuv/test/test-udp-multicast-join.c
@@ -0,0 +1,148 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int cl_recv_cb_called;
+
+static int sv_send_cb_called;
+
+static int close_cb_called;
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ sv_send_cb_called++;
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static void cl_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+
+ cl_recv_cb_called++;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards cl_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(!memcmp("PING", buf->base, nread));
+
+ /* we are done with the client handle, we can close it */
+ uv_close((uv_handle_t*) &client, close_cb);
+}
+
+
+TEST_IMPL(udp_multicast_join) {
+ int r;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ /* bind to the desired port */
+ r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ /* join the multicast channel */
+ r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init("PING", 4);
+
+ /* server sends "PING" */
+ r = uv_udp_send(&req,
+ &server,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(cl_recv_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+
+ /* run the loop till all events are processed */
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(cl_recv_cb_called == 1);
+ ASSERT(sv_send_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-multicast-ttl.c b/third-party/libuv/test/test-udp-multicast-ttl.c
new file mode 100644
index 0000000000..bed0ea1342
--- /dev/null
+++ b/third-party/libuv/test/test-udp-multicast-ttl.c
@@ -0,0 +1,94 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int sv_send_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ sv_send_cb_called++;
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+TEST_IMPL(udp_multicast_ttl) {
+ int r;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ struct sockaddr_in addr;
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr));
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_multicast_ttl(&server, 32);
+ ASSERT(r == 0);
+
+ /* server sends "PING" */
+ buf = uv_buf_init("PING", 4);
+ ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr));
+ r = uv_udp_send(&req,
+ &server,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+
+ /* run the loop till all events are processed */
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(sv_send_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-open.c b/third-party/libuv/test/test-udp-open.c
new file mode 100644
index 0000000000..9a97303f12
--- /dev/null
+++ b/third-party/libuv/test/test-udp-open.c
@@ -0,0 +1,164 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+#endif
+
+static int send_cb_called = 0;
+static int close_cb_called = 0;
+
+static uv_udp_send_t send_req;
+
+
+static void startup(void) {
+#ifdef _WIN32
+ struct WSAData wsa_data;
+ int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+ ASSERT(r == 0);
+#endif
+}
+
+
+static uv_os_sock_t create_udp_socket(void) {
+ uv_os_sock_t sock;
+
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+#ifdef _WIN32
+ ASSERT(sock != INVALID_SOCKET);
+#else
+ ASSERT(sock >= 0);
+#endif
+
+#ifndef _WIN32
+ {
+ /* Allow reuse of the port. */
+ int yes = 1;
+ int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
+ ASSERT(r == 0);
+ }
+#endif
+
+ return sock;
+}
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(handle != NULL);
+ close_cb_called++;
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ int r;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards sv_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ ASSERT(flags == 0);
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(memcmp("PING", buf->base, nread) == 0);
+
+ r = uv_udp_recv_stop(handle);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) handle, close_cb);
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+
+ send_cb_called++;
+}
+
+
+TEST_IMPL(udp_open) {
+ struct sockaddr_in addr;
+ uv_buf_t buf = uv_buf_init("PING", 4);
+ uv_udp_t client;
+ uv_os_sock_t sock;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ startup();
+ sock = create_udp_socket();
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_udp_open(&client, sock);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
+ ASSERT(r == 0);
+
+ r = uv_udp_send(&send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(send_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-options.c b/third-party/libuv/test/test-udp-options.c
new file mode 100644
index 0000000000..5cc369878a
--- /dev/null
+++ b/third-party/libuv/test/test-udp-options.c
@@ -0,0 +1,88 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+TEST_IMPL(udp_options) {
+ static int invalid_ttls[] = { -1, 0, 256 };
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ uv_udp_t h;
+ int i, r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ loop = uv_default_loop();
+
+ r = uv_udp_init(loop, &h);
+ ASSERT(r == 0);
+
+ uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */
+
+ r = uv_udp_bind(&h, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_broadcast(&h, 1);
+ r |= uv_udp_set_broadcast(&h, 1);
+ r |= uv_udp_set_broadcast(&h, 0);
+ r |= uv_udp_set_broadcast(&h, 0);
+ ASSERT(r == 0);
+
+ /* values 1-255 should work */
+ for (i = 1; i <= 255; i++) {
+ r = uv_udp_set_ttl(&h, i);
+ ASSERT(r == 0);
+ }
+
+ for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) {
+ r = uv_udp_set_ttl(&h, invalid_ttls[i]);
+ ASSERT(r == UV_EINVAL);
+ }
+
+ r = uv_udp_set_multicast_loop(&h, 1);
+ r |= uv_udp_set_multicast_loop(&h, 1);
+ r |= uv_udp_set_multicast_loop(&h, 0);
+ r |= uv_udp_set_multicast_loop(&h, 0);
+ ASSERT(r == 0);
+
+ /* values 0-255 should work */
+ for (i = 0; i <= 255; i++) {
+ r = uv_udp_set_multicast_ttl(&h, i);
+ ASSERT(r == 0);
+ }
+
+ /* anything >255 should fail */
+ r = uv_udp_set_multicast_ttl(&h, 256);
+ ASSERT(r == UV_EINVAL);
+ /* don't test ttl=-1, it's a valid value on some platforms */
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-udp-send-and-recv.c b/third-party/libuv/test/test-udp-send-and-recv.c
new file mode 100644
index 0000000000..3020ded7bf
--- /dev/null
+++ b/third-party/libuv/test/test-udp-send-and-recv.c
@@ -0,0 +1,211 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int cl_send_cb_called;
+static int cl_recv_cb_called;
+
+static int sv_send_cb_called;
+static int sv_recv_cb_called;
+
+static int close_cb_called;
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ ASSERT(1 == uv_is_closing(handle));
+ close_cb_called++;
+}
+
+
+static void cl_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards cl_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(!memcmp("PONG", buf->base, nread));
+
+ cl_recv_cb_called++;
+
+ uv_close((uv_handle_t*) handle, close_cb);
+}
+
+
+static void cl_send_cb(uv_udp_send_t* req, int status) {
+ int r;
+
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ r = uv_udp_recv_start(req->handle, alloc_cb, cl_recv_cb);
+ ASSERT(r == 0);
+
+ cl_send_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+ free(req);
+
+ sv_send_cb_called++;
+}
+
+
+static void sv_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* rcvbuf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ uv_udp_send_t* req;
+ uv_buf_t sndbuf;
+ int r;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards sv_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(!memcmp("PING", rcvbuf->base, nread));
+
+ /* FIXME? `uv_udp_recv_stop` does what it says: recv_cb is not called
+ * anymore. That's problematic because the read buffer won't be returned
+ * either... Not sure I like that but it's consistent with `uv_read_stop`.
+ */
+ r = uv_udp_recv_stop(handle);
+ ASSERT(r == 0);
+
+ req = malloc(sizeof *req);
+ ASSERT(req != NULL);
+
+ sndbuf = uv_buf_init("PONG", 4);
+ r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb);
+ ASSERT(r == 0);
+
+ sv_recv_cb_called++;
+}
+
+
+TEST_IMPL(udp_send_and_recv) {
+ struct sockaddr_in addr;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ /* client sends "PING", expects "PONG" */
+ buf = uv_buf_init("PING", 4);
+
+ r = uv_udp_send(&req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ cl_send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(cl_send_cb_called == 0);
+ ASSERT(cl_recv_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+ ASSERT(sv_recv_cb_called == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(cl_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 1);
+ ASSERT(sv_send_cb_called == 1);
+ ASSERT(sv_recv_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-walk-handles.c b/third-party/libuv/test/test-walk-handles.c
new file mode 100644
index 0000000000..f2ae41564f
--- /dev/null
+++ b/third-party/libuv/test/test-walk-handles.c
@@ -0,0 +1,78 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static char magic_cookie[] = "magic cookie";
+static int seen_timer_handle;
+static uv_timer_t timer;
+
+
+static void walk_cb(uv_handle_t* handle, void* arg) {
+ ASSERT(arg == (void*)magic_cookie);
+
+ if (handle == (uv_handle_t*)&timer) {
+ seen_timer_handle++;
+ } else {
+ ASSERT(0 && "unexpected handle");
+ }
+}
+
+
+static void timer_cb(uv_timer_t* handle, int status) {
+ ASSERT(handle == &timer);
+ ASSERT(status == 0);
+
+ uv_walk(handle->loop, walk_cb, magic_cookie);
+ uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+TEST_IMPL(walk_handles) {
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+
+ r = uv_timer_start(&timer, timer_cb, 1, 0);
+ ASSERT(r == 0);
+
+ /* Start event loop, expect to see the timer handle in walk_cb. */
+ ASSERT(seen_timer_handle == 0);
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(seen_timer_handle == 1);
+
+ /* Loop is finished, walk_cb should not see our timer handle. */
+ seen_timer_handle = 0;
+ uv_walk(loop, walk_cb, magic_cookie);
+ ASSERT(seen_timer_handle == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/test/test-watcher-cross-stop.c b/third-party/libuv/test/test-watcher-cross-stop.c
new file mode 100644
index 0000000000..c701dd2f91
--- /dev/null
+++ b/third-party/libuv/test/test-watcher-cross-stop.c
@@ -0,0 +1,101 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <errno.h>
+
+/* NOTE: Number should be big enough to trigger this problem */
+static uv_udp_t sockets[2500];
+static uv_udp_send_t reqs[ARRAY_SIZE(sockets)];
+static char slab[1];
+static unsigned int recv_cb_called;
+static unsigned int send_cb_called;
+static unsigned int close_cb_called;
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ recv_cb_called++;
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ send_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+TEST_IMPL(watcher_cross_stop) {
+ uv_loop_t* loop = uv_default_loop();
+ unsigned int i;
+ struct sockaddr_in addr;
+ uv_buf_t buf;
+ char big_string[1024];
+
+ TEST_FILE_LIMIT(ARRAY_SIZE(sockets) + 32);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ memset(big_string, 'A', sizeof(big_string));
+ buf = uv_buf_init(big_string, sizeof(big_string));
+
+ for (i = 0; i < ARRAY_SIZE(sockets); i++) {
+ ASSERT(0 == uv_udp_init(loop, &sockets[i]));
+ ASSERT(0 == uv_udp_bind(&sockets[i], (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_udp_recv_start(&sockets[i], alloc_cb, recv_cb));
+ ASSERT(0 == uv_udp_send(&reqs[i],
+ &sockets[i],
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb));
+ }
+
+ while (recv_cb_called == 0)
+ uv_run(loop, UV_RUN_ONCE);
+
+ for (i = 0; i < ARRAY_SIZE(sockets); i++)
+ uv_close((uv_handle_t*) &sockets[i], close_cb);
+
+ ASSERT(0 < recv_cb_called && recv_cb_called <= ARRAY_SIZE(sockets));
+ ASSERT(ARRAY_SIZE(sockets) == send_cb_called);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(ARRAY_SIZE(sockets) == close_cb_called);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/third-party/libuv/uv.gyp b/third-party/libuv/uv.gyp
new file mode 100644
index 0000000000..50e19357de
--- /dev/null
+++ b/third-party/libuv/uv.gyp
@@ -0,0 +1,532 @@
+{
+ 'variables': {
+ 'uv_use_dtrace%': 'false',
+ # uv_parent_path is the relative path to libuv in the parent project
+ # this is only relevant when dtrace is enabled and libuv is a child project
+ # as it's necessary to correctly locate the object files for post
+ # processing.
+ # XXX gyp is quite sensitive about paths with double / they don't normalize
+ 'uv_parent_path': '/',
+ },
+
+ 'target_defaults': {
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+ ],
+ 'conditions': [
+ ['OS=="solaris"', {
+ 'cflags': [ '-pthreads' ],
+ }],
+ ['OS not in "solaris android"', {
+ 'cflags': [ '-pthread' ],
+ }],
+ ],
+ }],
+ ],
+ },
+
+ 'targets': [
+ {
+ 'target_name': 'libuv',
+ 'type': '<(library)',
+ 'include_dirs': [
+ 'include',
+ 'src/',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [ 'include' ],
+ 'conditions': [
+ ['OS != "win"', {
+ 'defines': [
+ '_LARGEFILE_SOURCE',
+ '_FILE_OFFSET_BITS=64',
+ ],
+ }],
+ ['OS == "mac"', {
+ 'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
+ }],
+ ['OS == "linux"', {
+ 'defines': [ '_POSIX_C_SOURCE=200112' ],
+ }],
+ ],
+ },
+ 'defines': [
+ 'HAVE_CONFIG_H'
+ ],
+ 'sources': [
+ 'common.gypi',
+ 'include/uv.h',
+ 'include/tree.h',
+ 'include/uv-errno.h',
+ 'src/fs-poll.c',
+ 'src/inet.c',
+ 'src/queue.h',
+ 'src/uv-common.c',
+ 'src/uv-common.h',
+ 'src/version.c'
+ ],
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'defines': [
+ '_WIN32_WINNT=0x0600',
+ '_GNU_SOURCE',
+ ],
+ 'sources': [
+ 'include/uv-win.h',
+ 'src/win/async.c',
+ 'src/win/atomicops-inl.h',
+ 'src/win/core.c',
+ 'src/win/dl.c',
+ 'src/win/error.c',
+ 'src/win/fs.c',
+ 'src/win/fs-event.c',
+ 'src/win/getaddrinfo.c',
+ 'src/win/handle.c',
+ 'src/win/handle-inl.h',
+ 'src/win/internal.h',
+ 'src/win/loop-watcher.c',
+ 'src/win/pipe.c',
+ 'src/win/thread.c',
+ 'src/win/poll.c',
+ 'src/win/process.c',
+ 'src/win/process-stdio.c',
+ 'src/win/req.c',
+ 'src/win/req-inl.h',
+ 'src/win/signal.c',
+ 'src/win/stream.c',
+ 'src/win/stream-inl.h',
+ 'src/win/tcp.c',
+ 'src/win/tty.c',
+ 'src/win/threadpool.c',
+ 'src/win/timer.c',
+ 'src/win/udp.c',
+ 'src/win/util.c',
+ 'src/win/winapi.c',
+ 'src/win/winapi.h',
+ 'src/win/winsock.c',
+ 'src/win/winsock.h',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-ladvapi32.lib',
+ '-liphlpapi.lib',
+ '-lpsapi.lib',
+ '-lshell32.lib',
+ '-lws2_32.lib'
+ ],
+ },
+ }, { # Not Windows i.e. POSIX
+ 'cflags': [
+ '-g',
+ '--std=gnu89',
+ '-pedantic',
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter',
+ ],
+ 'sources': [
+ 'include/uv-unix.h',
+ 'include/uv-linux.h',
+ 'include/uv-sunos.h',
+ 'include/uv-darwin.h',
+ 'include/uv-bsd.h',
+ 'src/unix/async.c',
+ 'src/unix/atomic-ops.h',
+ 'src/unix/core.c',
+ 'src/unix/dl.c',
+ 'src/unix/fs.c',
+ 'src/unix/getaddrinfo.c',
+ 'src/unix/internal.h',
+ 'src/unix/loop.c',
+ 'src/unix/loop-watcher.c',
+ 'src/unix/pipe.c',
+ 'src/unix/poll.c',
+ 'src/unix/process.c',
+ 'src/unix/signal.c',
+ 'src/unix/spinlock.h',
+ 'src/unix/stream.c',
+ 'src/unix/tcp.c',
+ 'src/unix/thread.c',
+ 'src/unix/threadpool.c',
+ 'src/unix/timer.c',
+ 'src/unix/tty.c',
+ 'src/unix/udp.c',
+ ],
+ 'link_settings': {
+ 'libraries': [ '-lm' ],
+ 'conditions': [
+ ['OS=="solaris"', {
+ 'ldflags': [ '-pthreads' ],
+ }],
+ ['OS != "solaris" and OS != "android"', {
+ 'ldflags': [ '-pthread' ],
+ }],
+ ],
+ },
+ 'conditions': [
+ ['library=="shared_library"', {
+ 'cflags': [ '-fPIC' ],
+ }],
+ ['library=="shared_library" and OS!="mac"', {
+ 'link_settings': {
+ # Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
+ # in src/version.c
+ 'libraries': [ '-Wl,-soname,libuv.so.0.11' ],
+ },
+ }],
+ ],
+ }],
+ [ 'OS in "linux mac android"', {
+ 'sources': [ 'src/unix/proctitle.c' ],
+ }],
+ [ 'OS=="mac"', {
+ 'sources': [
+ 'src/unix/darwin.c',
+ 'src/unix/fsevents.c',
+ 'src/unix/darwin-proctitle.c',
+ ],
+ 'defines': [
+ '_DARWIN_USE_64_BIT_INODE=1',
+ ]
+ }],
+ [ 'OS!="mac"', {
+ # Enable on all platforms except OS X. The antique gcc/clang that
+ # ships with Xcode emits waaaay too many false positives.
+ 'cflags': [ '-Wstrict-aliasing' ],
+ }],
+ [ 'OS=="linux"', {
+ 'sources': [
+ 'src/unix/linux-core.c',
+ 'src/unix/linux-inotify.c',
+ 'src/unix/linux-syscalls.c',
+ 'src/unix/linux-syscalls.h',
+ ],
+ 'link_settings': {
+ 'libraries': [ '-ldl', '-lrt' ],
+ },
+ }],
+ [ 'OS=="android"', {
+ 'sources': [
+ 'src/unix/linux-core.c',
+ 'src/unix/linux-inotify.c',
+ 'src/unix/linux-syscalls.c',
+ 'src/unix/linux-syscalls.h',
+ 'src/unix/pthread-fixes.c',
+ ],
+ 'link_settings': {
+ 'libraries': [ '-ldl' ],
+ },
+ }],
+ [ 'OS=="solaris"', {
+ 'sources': [ 'src/unix/sunos.c' ],
+ 'defines': [
+ '__EXTENSIONS__',
+ '_XOPEN_SOURCE=500',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lkstat',
+ '-lnsl',
+ '-lsendfile',
+ '-lsocket',
+ ],
+ },
+ }],
+ [ 'OS=="aix"', {
+ 'include_dirs': [ 'src/ares/config_aix' ],
+ 'sources': [ 'src/unix/aix.c' ],
+ 'defines': [
+ '_ALL_SOURCE',
+ '_XOPEN_SOURCE=500',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lperfstat',
+ ],
+ },
+ }],
+ [ 'OS=="freebsd" or OS=="dragonflybsd"', {
+ 'sources': [ 'src/unix/freebsd.c' ],
+ }],
+ [ 'OS=="openbsd"', {
+ 'sources': [ 'src/unix/openbsd.c' ],
+ }],
+ [ 'OS=="netbsd"', {
+ 'sources': [ 'src/unix/netbsd.c' ],
+ }],
+ [ 'OS in "freebsd dragonflybsd openbsd netbsd".split()', {
+ 'link_settings': {
+ 'libraries': [ '-lkvm' ],
+ },
+ }],
+ [ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
+ 'sources': [ 'src/unix/kqueue.c' ],
+ }],
+ ['library=="shared_library"', {
+ 'defines': [ 'BUILDING_UV_SHARED=1' ]
+ }],
+ # FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
+ ['uv_use_dtrace=="true"', {
+ 'defines': [ 'HAVE_DTRACE=1' ],
+ 'dependencies': [ 'uv_dtrace_header' ],
+ 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
+ 'conditions': [
+ [ 'OS not in "mac linux"', {
+ 'sources': [ 'src/unix/dtrace.c' ],
+ }],
+ [ 'OS=="linux"', {
+ 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/dtrace.o' ]
+ }],
+ ],
+ }],
+ ]
+ },
+
+ {
+ 'target_name': 'run-tests',
+ 'type': 'executable',
+ 'dependencies': [ 'libuv' ],
+ 'sources': [
+ 'test/blackhole-server.c',
+ 'test/echo-server.c',
+ 'test/run-tests.c',
+ 'test/runner.c',
+ 'test/runner.h',
+ 'test/test-get-loadavg.c',
+ 'test/task.h',
+ 'test/test-active.c',
+ 'test/test-async.c',
+ 'test/test-async-null-cb.c',
+ 'test/test-callback-stack.c',
+ 'test/test-callback-order.c',
+ 'test/test-close-fd.c',
+ 'test/test-close-order.c',
+ 'test/test-connection-fail.c',
+ 'test/test-cwd-and-chdir.c',
+ 'test/test-delayed-accept.c',
+ 'test/test-error.c',
+ 'test/test-embed.c',
+ 'test/test-emfile.c',
+ 'test/test-fail-always.c',
+ 'test/test-fs.c',
+ 'test/test-fs-event.c',
+ 'test/test-get-currentexe.c',
+ 'test/test-get-memory.c',
+ 'test/test-getaddrinfo.c',
+ 'test/test-getsockname.c',
+ 'test/test-hrtime.c',
+ 'test/test-idle.c',
+ 'test/test-ipc.c',
+ 'test/test-ipc-send-recv.c',
+ 'test/test-list.h',
+ 'test/test-loop-handles.c',
+ 'test/test-loop-alive.c',
+ 'test/test-loop-stop.c',
+ 'test/test-loop-time.c',
+ 'test/test-walk-handles.c',
+ 'test/test-watcher-cross-stop.c',
+ 'test/test-multiple-listen.c',
+ 'test/test-osx-select.c',
+ 'test/test-pass-always.c',
+ 'test/test-ping-pong.c',
+ 'test/test-pipe-bind-error.c',
+ 'test/test-pipe-connect-error.c',
+ 'test/test-pipe-server-close.c',
+ 'test/test-platform-output.c',
+ 'test/test-poll.c',
+ 'test/test-poll-close.c',
+ 'test/test-process-title.c',
+ 'test/test-ref.c',
+ 'test/test-run-nowait.c',
+ 'test/test-run-once.c',
+ 'test/test-semaphore.c',
+ 'test/test-shutdown-close.c',
+ 'test/test-shutdown-eof.c',
+ 'test/test-signal.c',
+ 'test/test-signal-multiple-loops.c',
+ 'test/test-spawn.c',
+ 'test/test-fs-poll.c',
+ 'test/test-stdio-over-pipes.c',
+ 'test/test-tcp-bind-error.c',
+ 'test/test-tcp-bind6-error.c',
+ 'test/test-tcp-close.c',
+ 'test/test-tcp-close-accept.c',
+ 'test/test-tcp-close-while-connecting.c',
+ 'test/test-tcp-connect-error-after-write.c',
+ 'test/test-tcp-shutdown-after-write.c',
+ 'test/test-tcp-flags.c',
+ 'test/test-tcp-connect-error.c',
+ 'test/test-tcp-connect-timeout.c',
+ 'test/test-tcp-connect6-error.c',
+ 'test/test-tcp-open.c',
+ 'test/test-tcp-write-to-half-open-connection.c',
+ 'test/test-tcp-writealot.c',
+ 'test/test-tcp-try-write.c',
+ 'test/test-tcp-unexpected-read.c',
+ 'test/test-tcp-read-stop.c',
+ 'test/test-threadpool.c',
+ 'test/test-threadpool-cancel.c',
+ 'test/test-mutexes.c',
+ 'test/test-thread.c',
+ 'test/test-barrier.c',
+ 'test/test-condvar.c',
+ 'test/test-timer-again.c',
+ 'test/test-timer-from-check.c',
+ 'test/test-timer.c',
+ 'test/test-tty.c',
+ 'test/test-udp-dgram-too-big.c',
+ 'test/test-udp-ipv6.c',
+ 'test/test-udp-open.c',
+ 'test/test-udp-options.c',
+ 'test/test-udp-send-and-recv.c',
+ 'test/test-udp-multicast-join.c',
+ 'test/test-dlerror.c',
+ 'test/test-udp-multicast-ttl.c',
+ 'test/test-ip4-addr.c',
+ 'test/test-ip6-addr.c',
+ ],
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'sources': [
+ 'test/runner-win.c',
+ 'test/runner-win.h'
+ ],
+ 'libraries': [ 'ws2_32.lib' ]
+ }, { # POSIX
+ 'defines': [ '_GNU_SOURCE' ],
+ 'sources': [
+ 'test/runner-unix.c',
+ 'test/runner-unix.h',
+ ],
+ }],
+ [ 'OS=="solaris"', { # make test-fs.c compile, needs _POSIX_C_SOURCE
+ 'defines': [
+ '__EXTENSIONS__',
+ '_XOPEN_SOURCE=500',
+ ],
+ }],
+ [ 'OS=="aix"', { # make test-fs.c compile, needs _POSIX_C_SOURCE
+ 'defines': [
+ '_ALL_SOURCE',
+ '_XOPEN_SOURCE=500',
+ ],
+ }],
+ ],
+ 'msvs-settings': {
+ 'VCLinkerTool': {
+ 'SubSystem': 1, # /subsystem:console
+ },
+ },
+ },
+
+ {
+ 'target_name': 'run-benchmarks',
+ 'type': 'executable',
+ 'dependencies': [ 'libuv' ],
+ 'sources': [
+ 'test/benchmark-async.c',
+ 'test/benchmark-async-pummel.c',
+ 'test/benchmark-fs-stat.c',
+ 'test/benchmark-getaddrinfo.c',
+ 'test/benchmark-list.h',
+ 'test/benchmark-loop-count.c',
+ 'test/benchmark-million-async.c',
+ 'test/benchmark-million-timers.c',
+ 'test/benchmark-multi-accept.c',
+ 'test/benchmark-ping-pongs.c',
+ 'test/benchmark-pound.c',
+ 'test/benchmark-pump.c',
+ 'test/benchmark-sizes.c',
+ 'test/benchmark-spawn.c',
+ 'test/benchmark-thread.c',
+ 'test/benchmark-tcp-write-batch.c',
+ 'test/benchmark-udp-pummel.c',
+ 'test/dns-server.c',
+ 'test/echo-server.c',
+ 'test/blackhole-server.c',
+ 'test/run-benchmarks.c',
+ 'test/runner.c',
+ 'test/runner.h',
+ 'test/task.h',
+ ],
+ 'conditions': [
+ [ 'OS=="win"', {
+ 'sources': [
+ 'test/runner-win.c',
+ 'test/runner-win.h',
+ ],
+ 'libraries': [ 'ws2_32.lib' ]
+ }, { # POSIX
+ 'defines': [ '_GNU_SOURCE' ],
+ 'sources': [
+ 'test/runner-unix.c',
+ 'test/runner-unix.h',
+ ]
+ }]
+ ],
+ 'msvs-settings': {
+ 'VCLinkerTool': {
+ 'SubSystem': 1, # /subsystem:console
+ },
+ },
+ },
+
+ {
+ 'target_name': 'uv_dtrace_header',
+ 'type': 'none',
+ 'conditions': [
+ [ 'uv_use_dtrace=="true"', {
+ 'actions': [
+ {
+ 'action_name': 'uv_dtrace_header',
+ 'inputs': [ 'src/unix/uv-dtrace.d' ],
+ 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/uv-dtrace.h' ],
+ 'action': [ 'dtrace', '-h', '-xnolibs', '-s', '<@(_inputs)',
+ '-o', '<@(_outputs)' ],
+ },
+ ],
+ }],
+ ],
+ },
+
+ # FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
+ {
+ 'target_name': 'uv_dtrace_provider',
+ 'type': 'none',
+ 'conditions': [
+ [ 'uv_use_dtrace=="true" and OS not in "mac linux"', {
+ 'actions': [
+ {
+ 'action_name': 'uv_dtrace_o',
+ 'inputs': [
+ 'src/unix/uv-dtrace.d',
+ '<(PRODUCT_DIR)/obj.target/libuv<(uv_parent_path)src/unix/core.o',
+ ],
+ 'outputs': [
+ '<(PRODUCT_DIR)/obj.target/libuv<(uv_parent_path)src/unix/dtrace.o',
+ ],
+ 'action': [ 'dtrace', '-G', '-xnolibs', '-s', '<@(_inputs)',
+ '-o', '<@(_outputs)' ]
+ }
+ ]
+ }],
+ [ 'uv_use_dtrace=="true" and OS=="linux"', {
+ 'actions': [
+ {
+ 'action_name': 'uv_dtrace_o',
+ 'inputs': [ 'src/unix/uv-dtrace.d' ],
+ 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/dtrace.o' ],
+ 'action': [
+ 'dtrace', '-C', '-G', '-s', '<@(_inputs)', '-o', '<@(_outputs)'
+ ],
+ }
+ ]
+ }],
+ ]
+ },
+
+ ]
+}
diff --git a/third-party/libuv/vcbuild.bat b/third-party/libuv/vcbuild.bat
new file mode 100644
index 0000000000..8545b2635b
--- /dev/null
+++ b/third-party/libuv/vcbuild.bat
@@ -0,0 +1,144 @@
+@echo off
+
+cd %~dp0
+
+if /i "%1"=="help" goto help
+if /i "%1"=="--help" goto help
+if /i "%1"=="-help" goto help
+if /i "%1"=="/help" goto help
+if /i "%1"=="?" goto help
+if /i "%1"=="-?" goto help
+if /i "%1"=="--?" goto help
+if /i "%1"=="/?" goto help
+
+@rem Process arguments.
+set config=
+set target=Build
+set noprojgen=
+set nobuild=
+set run=
+set target_arch=ia32
+set vs_toolset=x86
+set platform=WIN32
+set library=static_library
+
+:next-arg
+if "%1"=="" goto args-done
+if /i "%1"=="debug" set config=Debug&goto arg-ok
+if /i "%1"=="release" set config=Release&goto arg-ok
+if /i "%1"=="test" set run=run-tests.exe&goto arg-ok
+if /i "%1"=="bench" set run=run-benchmarks.exe&goto arg-ok
+if /i "%1"=="clean" set target=Clean&goto arg-ok
+if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
+if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
+if /i "%1"=="x86" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="ia32" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
+if /i "%1"=="x64" set target_arch=x64&set platform=amd64&set vs_toolset=x64&goto arg-ok
+if /i "%1"=="shared" set library=shared_library&goto arg-ok
+if /i "%1"=="static" set library=static_library&goto arg-ok
+:arg-ok
+shift
+goto next-arg
+:args-done
+
+@rem Look for Visual Studio 2013
+if not defined VS120COMNTOOLS goto vc-set-2012
+if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
+call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2013
+goto select-target
+
+@rem Look for Visual Studio 2012
+:vc-set-2012
+if not defined VS110COMNTOOLS goto vc-set-2010
+if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010
+call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2012
+goto select-target
+
+:vc-set-2010
+@rem Look for Visual Studio 2010
+if not defined VS100COMNTOOLS goto vc-set-2008
+if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008
+call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2010
+goto select-target
+
+:vc-set-2008
+@rem Look for Visual Studio 2008
+if not defined VS90COMNTOOLS goto vc-set-notfound
+if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
+call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
+set GYP_MSVS_VERSION=2008
+goto select-target
+
+:vc-set-notfound
+echo Warning: Visual Studio not found
+
+:select-target
+if not "%config%"=="" goto project-gen
+if "%run%"=="run-tests.exe" set config=Debug& goto project-gen
+if "%run%"=="run-benchmarks.exe" set config=Release& goto project-gen
+set config=Debug
+
+:project-gen
+@rem Skip project generation if requested.
+if defined noprojgen goto msbuild
+
+@rem Generate the VS project.
+if exist build\gyp goto have_gyp
+echo git clone https://git.chromium.org/external/gyp.git build/gyp
+git clone https://git.chromium.org/external/gyp.git build/gyp
+if errorlevel 1 goto gyp_install_failed
+goto have_gyp
+
+:gyp_install_failed
+echo Failed to download gyp. Make sure you have git installed, or
+echo manually install gyp into %~dp0build\gyp.
+exit /b 1
+
+:have_gyp
+if not defined PYTHON set PYTHON="python"
+%PYTHON% gyp_uv.py -Dtarget_arch=%target_arch% -Dlibrary=%library%
+if errorlevel 1 goto create-msvs-files-failed
+if not exist uv.sln goto create-msvs-files-failed
+echo Project files generated.
+
+:msbuild
+@rem Skip project generation if requested.
+if defined nobuild goto run
+
+@rem Check if VS build env is available
+if not defined VCINSTALLDIR goto msbuild-not-found
+goto msbuild-found
+
+:msbuild-not-found
+echo Build skipped. To build, this file needs to run from VS cmd prompt.
+goto run
+
+@rem Build the sln with msbuild.
+:msbuild-found
+msbuild uv.sln /t:%target% /p:Configuration=%config% /p:Platform="%platform%" /clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal /nologo
+if errorlevel 1 exit /b 1
+
+:run
+@rem Run tests if requested.
+if "%run%"=="" goto exit
+if not exist %config%\%run% goto exit
+echo running '%config%\%run%'
+%config%\%run%
+goto exit
+
+:create-msvs-files-failed
+echo Failed to create vc project files.
+exit /b 1
+
+:help
+echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [x86/x64] [static/shared]
+echo Examples:
+echo vcbuild.bat : builds debug build
+echo vcbuild.bat test : builds debug build and runs tests
+echo vcbuild.bat release bench: builds release build and runs benchmarks
+goto exit
+
+:exit
diff --git a/vim-license.txt b/vim-license.txt
new file mode 100644
index 0000000000..dd685292ba
--- /dev/null
+++ b/vim-license.txt
@@ -0,0 +1,78 @@
+VIM LICENSE
+
+I) There are no restrictions on distributing unmodified copies of Vim except
+ that they must include this license text. You can also distribute
+ unmodified parts of Vim, likewise unrestricted except that they must
+ include this license text. You are also allowed to include executables
+ that you made from the unmodified Vim sources, plus your own usage
+ examples and Vim scripts.
+
+II) It is allowed to distribute a modified (or extended) version of Vim,
+ including executables and/or source code, when the following four
+ conditions are met:
+ 1) This license text must be included unmodified.
+ 2) The modified Vim must be distributed in one of the following five ways:
+ a) If you make changes to Vim yourself, you must clearly describe in
+ the distribution how to contact you. When the maintainer asks you
+ (in any way) for a copy of the modified Vim you distributed, you
+ must make your changes, including source code, available to the
+ maintainer without fee. The maintainer reserves the right to
+ include your changes in the official version of Vim. What the
+ maintainer will do with your changes and under what license they
+ will be distributed is negotiable. If there has been no negotiation
+ then this license, or a later version, also applies to your changes.
+ The current maintainer is Bram Moolenaar <Bram@vim.org>. If this
+ changes it will be announced in appropriate places (most likely
+ vim.sf.net, www.vim.org and/or comp.editors). When it is completely
+ impossible to contact the maintainer, the obligation to send him
+ your changes ceases. Once the maintainer has confirmed that he has
+ received your changes they will not have to be sent again.
+ b) If you have received a modified Vim that was distributed as
+ mentioned under a) you are allowed to further distribute it
+ unmodified, as mentioned at I). If you make additional changes the
+ text under a) applies to those changes.
+ c) Provide all the changes, including source code, with every copy of
+ the modified Vim you distribute. This may be done in the form of a
+ context diff. You can choose what license to use for new code you
+ add. The changes and their license must not restrict others from
+ making their own changes to the official version of Vim.
+ d) When you have a modified Vim which includes changes as mentioned
+ under c), you can distribute it without the source code for the
+ changes if the following three conditions are met:
+ - The license that applies to the changes permits you to distribute
+ the changes to the Vim maintainer without fee or restriction, and
+ permits the Vim maintainer to include the changes in the official
+ version of Vim without fee or restriction.
+ - You keep the changes for at least three years after last
+ distributing the corresponding modified Vim. When the maintainer
+ or someone who you distributed the modified Vim to asks you (in
+ any way) for the changes within this period, you must make them
+ available to him.
+ - You clearly describe in the distribution how to contact you. This
+ contact information must remain valid for at least three years
+ after last distributing the corresponding modified Vim, or as long
+ as possible.
+ e) When the GNU General Public License (GPL) applies to the changes,
+ you can distribute the modified Vim under the GNU GPL version 2 or
+ any later version.
+ 3) A message must be added, at least in the output of the ":version"
+ command and in the intro screen, such that the user of the modified Vim
+ is able to see that it was modified. When distributing as mentioned
+ under 2)e) adding the message is only required for as far as this does
+ not conflict with the license used for the changes.
+ 4) The contact information as required under 2)a) and 2)d) must not be
+ removed or changed, except that the person himself can make
+ corrections.
+
+III) If you distribute a modified version of Vim, you are encouraged to use
+ the Vim license for your changes and make them available to the
+ maintainer, including the source code. The preferred way to do this is
+ by e-mail or by uploading the files to a server and e-mailing the URL.
+ If the number of changes is small (e.g., a modified Makefile) e-mailing a
+ context diff will do. The e-mail address to be used is
+ <maintainer@vim.org>
+
+IV) It is not allowed to remove this license from the distribution of the Vim
+ sources, parts of it or from a modified version. You may use this
+ license for previous Vim releases instead of the license that they came
+ with, at your option.