sproutit-narwhal 0.1.106

Sign up to get free protection for your applications and to get access to all the features.
Files changed (291) hide show
  1. data/DISTRIBUTION.yml +15 -0
  2. data/README.md +86 -0
  3. data/Rakefile +349 -0
  4. data/VERSION.yml +7 -0
  5. data/bin/activate +50 -0
  6. data/bin/activate.bash +50 -0
  7. data/bin/activate.cmd +3 -0
  8. data/bin/js +67 -0
  9. data/bin/json +2 -0
  10. data/bin/narwhal +67 -0
  11. data/bin/narwhal.cmd +29 -0
  12. data/bin/sea +45 -0
  13. data/bin/sea.cmd +25 -0
  14. data/bin/tusk +2 -0
  15. data/bin/tusk.cmd +5 -0
  16. data/catalog.json +902 -0
  17. data/docs/available-packages.md +32 -0
  18. data/docs/browser-api-plan.md +290 -0
  19. data/docs/browser-api.md +153 -0
  20. data/docs/download.md +25 -0
  21. data/docs/engines.md +32 -0
  22. data/docs/json-tool.md +121 -0
  23. data/docs/lib/binary.wiki +242 -0
  24. data/docs/lib/file.wiki +325 -0
  25. data/docs/lib/os/popen.md +70 -0
  26. data/docs/modules.md +38 -0
  27. data/docs/narwhal.md +487 -0
  28. data/docs/packages-howto.md +32 -0
  29. data/docs/packages.md +30 -0
  30. data/docs/posts/2009-07-29-hello-0.1.md +19 -0
  31. data/docs/quick-start.md +69 -0
  32. data/docs/sea.md +49 -0
  33. data/engines/browser/lib/binary.js +2 -0
  34. data/engines/browser/lib/reactor.js +21 -0
  35. data/engines/browser/lib/system.js +3 -0
  36. data/engines/default/lib/array.js +164 -0
  37. data/engines/default/lib/binary-engine.js +53 -0
  38. data/engines/default/lib/binary.js +755 -0
  39. data/engines/default/lib/date.js +8 -0
  40. data/engines/default/lib/file-engine.js +119 -0
  41. data/engines/default/lib/function.js +119 -0
  42. data/engines/default/lib/global.js +11 -0
  43. data/engines/default/lib/io-engine.js +26 -0
  44. data/engines/default/lib/json.js +488 -0
  45. data/engines/default/lib/object.js +69 -0
  46. data/engines/default/lib/os-engine.js +3 -0
  47. data/engines/default/lib/reactor.js +12 -0
  48. data/engines/default/lib/string.js +84 -0
  49. data/engines/default/lib/system.js +20 -0
  50. data/engines/default/lib/worker.js +133 -0
  51. data/engines/jsc/README.md +18 -0
  52. data/engines/jsc/bootstrap.js +53 -0
  53. data/engines/jsc/deps/http-parser/LICENSE +77 -0
  54. data/engines/jsc/deps/http-parser/README.md +145 -0
  55. data/engines/jsc/deps/http-parser/http_parser.c +6087 -0
  56. data/engines/jsc/deps/http-parser/http_parser.h +141 -0
  57. data/engines/jsc/deps/http-parser/http_parser.rl +500 -0
  58. data/engines/jsc/deps/http-parser/test.c +858 -0
  59. data/engines/jsc/include/binary-engine.h +11 -0
  60. data/engines/jsc/include/io-engine.h +23 -0
  61. data/engines/jsc/include/narwhal.h +427 -0
  62. data/engines/jsc/lib/file-engine.js +31 -0
  63. data/engines/jsc/lib/http.js +1 -0
  64. data/engines/jsc/lib/io-engine.js +202 -0
  65. data/engines/jsc/lib/os-engine.js +25 -0
  66. data/engines/jsc/lib/system.js +18 -0
  67. data/engines/jsc/lib/zip.js +1 -0
  68. data/engines/jsc/narwhal-jsc.c +273 -0
  69. data/engines/jsc/narwhal.c +29 -0
  70. data/engines/jsc/package.json +8 -0
  71. data/engines/jsc/src/binary-engine.cc +290 -0
  72. data/engines/jsc/src/file-engine.cc +405 -0
  73. data/engines/jsc/src/io-engine.cc +423 -0
  74. data/engines/jsc/src/jack/handler/jill.cc +710 -0
  75. data/engines/jsc/src/os-engine.cc +210 -0
  76. data/engines/rhino/bin/narwhal-rhino +68 -0
  77. data/engines/rhino/bin/narwhal-rhino.cmd +34 -0
  78. data/engines/rhino/bootstrap.js +119 -0
  79. data/engines/rhino/jars/jline.jar +0 -0
  80. data/engines/rhino/jars/jna.jar +0 -0
  81. data/engines/rhino/jars/js.jar +0 -0
  82. data/engines/rhino/lib/binary-engine.js +83 -0
  83. data/engines/rhino/lib/concurrency.js +6 -0
  84. data/engines/rhino/lib/event-queue.js +18 -0
  85. data/engines/rhino/lib/file-engine.js +216 -0
  86. data/engines/rhino/lib/http-client-engine.js +90 -0
  87. data/engines/rhino/lib/http-engine.js +10 -0
  88. data/engines/rhino/lib/io-engine.js +347 -0
  89. data/engines/rhino/lib/md5-engine.js +40 -0
  90. data/engines/rhino/lib/os-engine.js +150 -0
  91. data/engines/rhino/lib/packages-engine.js +71 -0
  92. data/engines/rhino/lib/sandbox-engine.js +70 -0
  93. data/engines/rhino/lib/system.js +38 -0
  94. data/engines/rhino/lib/worker-engine.js +23 -0
  95. data/engines/rhino/lib/zip.js +78 -0
  96. data/engines/rhino/package.json +4 -0
  97. data/engines/secure/lib/file.js +6 -0
  98. data/engines/secure/lib/system.js +6 -0
  99. data/engines/template/bin/narwhal-engine-name +32 -0
  100. data/engines/template/bootstrap.js +40 -0
  101. data/engines/template/lib/file-engine.js +118 -0
  102. data/engines/template/lib/system.js +17 -0
  103. data/examples/browser-deployment-jackconfig.js +35 -0
  104. data/examples/fibonacci-worker.js +35 -0
  105. data/examples/fibonacci.js +19 -0
  106. data/examples/hello +2 -0
  107. data/examples/narwhal +3 -0
  108. data/examples/not-quite-a-quine.js +1 -0
  109. data/extconf.rb +44 -0
  110. data/gem_bin/narwhal +5 -0
  111. data/gem_bin/sea +4 -0
  112. data/gem_bin/tusk +4 -0
  113. data/lib/args.js +849 -0
  114. data/lib/base16.js +16 -0
  115. data/lib/base64.js +120 -0
  116. data/lib/codec/base64.js +8 -0
  117. data/lib/crc32.js +60 -0
  118. data/lib/file-bootstrap.js +187 -0
  119. data/lib/file.js +659 -0
  120. data/lib/hash.js +28 -0
  121. data/lib/hashp.js +65 -0
  122. data/lib/html.js +16 -0
  123. data/lib/http-client.js +134 -0
  124. data/lib/http.js +17 -0
  125. data/lib/io.js +98 -0
  126. data/lib/jsmin.js +315 -0
  127. data/lib/jsonpath.js +89 -0
  128. data/lib/logger.js +55 -0
  129. data/lib/md4.js +146 -0
  130. data/lib/md5.js +164 -0
  131. data/lib/mime.js +166 -0
  132. data/lib/narwhal.js +102 -0
  133. data/lib/narwhal/client.js +261 -0
  134. data/lib/narwhal/compile.js +99 -0
  135. data/lib/narwhal/env.js +140 -0
  136. data/lib/narwhal/inline.js +106 -0
  137. data/lib/narwhal/json.js +324 -0
  138. data/lib/narwhal/json.md +178 -0
  139. data/lib/narwhal/repl.js +96 -0
  140. data/lib/narwhal/server-test.js +6 -0
  141. data/lib/narwhal/server.js +270 -0
  142. data/lib/narwhal/tusk.js +170 -0
  143. data/lib/narwhal/tusk/bin.js +13 -0
  144. data/lib/narwhal/tusk/bundle.js +0 -0
  145. data/lib/narwhal/tusk/catalog.js +22 -0
  146. data/lib/narwhal/tusk/clone.js +66 -0
  147. data/lib/narwhal/tusk/consolidate.js +25 -0
  148. data/lib/narwhal/tusk/create-catalog.js +80 -0
  149. data/lib/narwhal/tusk/engine.js +42 -0
  150. data/lib/narwhal/tusk/freeze.js +0 -0
  151. data/lib/narwhal/tusk/init.js +56 -0
  152. data/lib/narwhal/tusk/install.js +288 -0
  153. data/lib/narwhal/tusk/list.js +20 -0
  154. data/lib/narwhal/tusk/orphans.js +0 -0
  155. data/lib/narwhal/tusk/reheat.js +15 -0
  156. data/lib/narwhal/tusk/remove.js +15 -0
  157. data/lib/narwhal/tusk/search.js +145 -0
  158. data/lib/narwhal/tusk/update.js +21 -0
  159. data/lib/narwhal/tusk/upgrade.js +0 -0
  160. data/lib/os.js +33 -0
  161. data/lib/packages.js +423 -0
  162. data/lib/printf.js +169 -0
  163. data/lib/promise.js +352 -0
  164. data/lib/querystring.js +176 -0
  165. data/lib/ref-send.js +257 -0
  166. data/lib/regexp.js +12 -0
  167. data/lib/sandbox.js +422 -0
  168. data/lib/sha.js +112 -0
  169. data/lib/sha256.js +102 -0
  170. data/lib/struct.js +228 -0
  171. data/lib/term.js +179 -0
  172. data/lib/test/assert.js +95 -0
  173. data/lib/test/equiv.js +188 -0
  174. data/lib/test/jsdump.js +165 -0
  175. data/lib/test/runner.js +129 -0
  176. data/lib/unload.js +13 -0
  177. data/lib/uri.js +378 -0
  178. data/lib/url.js +5 -0
  179. data/lib/utf8.js +64 -0
  180. data/lib/util.js +985 -0
  181. data/lib/uuid.js +89 -0
  182. data/lib/xregexp.js +521 -0
  183. data/local.json.template +1 -0
  184. data/narwhal.gemspec +105 -0
  185. data/narwhal.js +213 -0
  186. data/package.json +26 -0
  187. data/packages/readline/engines/default/lib/readline.js +4 -0
  188. data/packages/readline/engines/rhino/lib/readline.js +6 -0
  189. data/packages/readline/package.json +5 -0
  190. data/sources.json +207 -0
  191. data/tests/all-tests.js +17 -0
  192. data/tests/args.js +31 -0
  193. data/tests/args/domain.js +215 -0
  194. data/tests/args/options.js +36 -0
  195. data/tests/args/shifting.js +92 -0
  196. data/tests/args/validation.js +31 -0
  197. data/tests/base64.js +23 -0
  198. data/tests/commonjs.js +3 -0
  199. data/tests/commonjs/all-tests.js +12 -0
  200. data/tests/commonjs/bytearray-encodings-tests.js +69 -0
  201. data/tests/commonjs/bytearray-tests.js +465 -0
  202. data/tests/commonjs/bytestring-encodings-tests.js +89 -0
  203. data/tests/commonjs/bytestring-tests.js +263 -0
  204. data/tests/commonjs/es5/all-tests.js +3 -0
  205. data/tests/commonjs/es5/bind.js +29 -0
  206. data/tests/commonjs/file-tests.js +315 -0
  207. data/tests/commonjs/file/dirname.js +31 -0
  208. data/tests/commonjs/file/extension.js +45 -0
  209. data/tests/commonjs/file/is-absolute.js +11 -0
  210. data/tests/commonjs/file/iterator.js +101 -0
  211. data/tests/commonjs/file/normal.js +27 -0
  212. data/tests/commonjs/file/path.js +17 -0
  213. data/tests/commonjs/file/relative.js +42 -0
  214. data/tests/commonjs/file/resolve.js +44 -0
  215. data/tests/commonjs/module-tests.js +9 -0
  216. data/tests/commonjs/modules/absolute/b.js +1 -0
  217. data/tests/commonjs/modules/absolute/program.js +5 -0
  218. data/tests/commonjs/modules/absolute/submodule/a.js +3 -0
  219. data/tests/commonjs/modules/absolute/test.js +9 -0
  220. data/tests/commonjs/modules/all-tests.js +47 -0
  221. data/tests/commonjs/modules/config.js +11 -0
  222. data/tests/commonjs/modules/cyclic/a.js +4 -0
  223. data/tests/commonjs/modules/cyclic/b.js +4 -0
  224. data/tests/commonjs/modules/cyclic/program.js +10 -0
  225. data/tests/commonjs/modules/cyclic/test.js +9 -0
  226. data/tests/commonjs/modules/determinism/program.js +3 -0
  227. data/tests/commonjs/modules/determinism/submodule/a.js +8 -0
  228. data/tests/commonjs/modules/determinism/submodule/b.js +2 -0
  229. data/tests/commonjs/modules/determinism/test.js +9 -0
  230. data/tests/commonjs/modules/exactExports/a.js +3 -0
  231. data/tests/commonjs/modules/exactExports/program.js +4 -0
  232. data/tests/commonjs/modules/exactExports/test.js +9 -0
  233. data/tests/commonjs/modules/hasOwnProperty/hasOwnProperty.js +0 -0
  234. data/tests/commonjs/modules/hasOwnProperty/program.js +3 -0
  235. data/tests/commonjs/modules/hasOwnProperty/test.js +9 -0
  236. data/tests/commonjs/modules/hasOwnProperty/toString.js +0 -0
  237. data/tests/commonjs/modules/method/a.js +12 -0
  238. data/tests/commonjs/modules/method/program.js +8 -0
  239. data/tests/commonjs/modules/method/test.js +9 -0
  240. data/tests/commonjs/modules/missing/program.js +8 -0
  241. data/tests/commonjs/modules/missing/test.js +9 -0
  242. data/tests/commonjs/modules/monkeys/a.js +1 -0
  243. data/tests/commonjs/modules/monkeys/program.js +4 -0
  244. data/tests/commonjs/modules/monkeys/test.js +9 -0
  245. data/tests/commonjs/modules/nested/a/b/c/d.js +3 -0
  246. data/tests/commonjs/modules/nested/program.js +3 -0
  247. data/tests/commonjs/modules/nested/test.js +9 -0
  248. data/tests/commonjs/modules/relative/program.js +5 -0
  249. data/tests/commonjs/modules/relative/submodule/a.js +1 -0
  250. data/tests/commonjs/modules/relative/submodule/b.js +2 -0
  251. data/tests/commonjs/modules/relative/test.js +9 -0
  252. data/tests/commonjs/modules/transitive/a.js +1 -0
  253. data/tests/commonjs/modules/transitive/b.js +1 -0
  254. data/tests/commonjs/modules/transitive/c.js +3 -0
  255. data/tests/commonjs/modules/transitive/program.js +3 -0
  256. data/tests/commonjs/modules/transitive/test.js +9 -0
  257. data/tests/file/all-tests.js +61 -0
  258. data/tests/file/fnmatch.js +102 -0
  259. data/tests/file/glob.js +466 -0
  260. data/tests/file/match.js +102 -0
  261. data/tests/global.js +6 -0
  262. data/tests/global/array.js +19 -0
  263. data/tests/hashes.js +94 -0
  264. data/tests/html.js +13 -0
  265. data/tests/io/stringio.js +21 -0
  266. data/tests/os/all-tests.js +4 -0
  267. data/tests/os/popen.js +41 -0
  268. data/tests/os/system.js +22 -0
  269. data/tests/printf.js +123 -0
  270. data/tests/query-string.js +87 -0
  271. data/tests/sandbox/byte-io.js +20 -0
  272. data/tests/sandbox/fileName.js +3 -0
  273. data/tests/sandbox/foo.js +0 -0
  274. data/tests/sandbox/reload.js +79 -0
  275. data/tests/string.js +35 -0
  276. data/tests/uri.js +41 -0
  277. data/tests/util/all-tests.js +79 -0
  278. data/tests/util/array.js +207 -0
  279. data/tests/util/array/is-arguments.js +29 -0
  280. data/tests/util/array/is-array-like.js +29 -0
  281. data/tests/util/case.js +9 -0
  282. data/tests/util/collection.js +104 -0
  283. data/tests/util/eq.js +57 -0
  284. data/tests/util/expand.js +45 -0
  285. data/tests/util/object.js +125 -0
  286. data/tests/util/operator.js +25 -0
  287. data/tests/util/range.js +19 -0
  288. data/tests/util/repr.js +26 -0
  289. data/tests/util/string.js +34 -0
  290. data/tests/util/unique.js +12 -0
  291. metadata +434 -0
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "narwhal-rhino",
3
+ "engine": "rhino"
4
+ }
@@ -0,0 +1,6 @@
1
+
2
+ for (var name in system.fs) {
3
+ if (Object.prototype.hasOwnProperty.call(system.fs, name))
4
+ exports[name] = system.fs[name];
5
+ }
6
+
@@ -0,0 +1,6 @@
1
+
2
+ for (var name in system) {
3
+ if (Object.prototype.hasOwnProperty.call(system, name)) {
4
+ exports[name] = system[name];
5
+ }
6
+ }
@@ -0,0 +1,32 @@
1
+ #!/bin/bash
2
+
3
+ # get the absolute path of the executable
4
+ SELF_PATH=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && SELF_PATH=$SELF_PATH/$(basename -- "$0")
5
+
6
+ # resolve symlinks
7
+ while [ -h "$SELF_PATH" ]; do
8
+ DIR=$(dirname -- "$SELF_PATH")
9
+ SYM=$(readlink -- "$SELF_PATH")
10
+ SELF_PATH=$(cd -- "$DIR" && cd -- $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
11
+ done
12
+
13
+ NARWHAL_ENGINE_HOME=$(dirname -- $(dirname -- $SELF_PATH))
14
+ BOOTSTRAP="$NARWHAL_ENGINE_HOME/bootstrap.js"
15
+
16
+ if [ ! "$NARWHAL_HOME" ]; then
17
+ NARWHAL_HOME=$(dirname -- $(dirname -- $NARWHAL_ENGINE_HOME))
18
+ fi
19
+
20
+ export NARWHAL_HOME
21
+
22
+ # uses rlwrap (readline wrapper) if present
23
+ NARWHAL="$(which rlwrap) narwhal-engine" # TODO replace narwhal-engine with js bin
24
+
25
+ # drop into shell if there are no additional arguments
26
+ if [ $# -lt 1 ]; then
27
+ # FIXME: no way to explicitly drop into shell
28
+ $NARWHAL $BOOTSTRAP "$@"
29
+ else
30
+ MAIN=$(cd -P -- "$(dirname -- "$1")" && pwd -P) && MAIN=$MAIN/$(basename -- "$1" .js)
31
+ $NARWHAL $BOOTSTRAP $MAIN "$0" "$@"
32
+ fi
@@ -0,0 +1,40 @@
1
+ (function (evalGlobal) {
2
+
3
+ var read = /*TODO*/; // function(path:string):string
4
+
5
+ var isFile = /*TODO*/; // function(path:string):boolean
6
+
7
+ var prefix = "/path/to/narwhal"; /*TODO*/
8
+ var enginePrefix = "/path/to/engine"; /*TODO*/
9
+
10
+ eval(read(prefix + "/narwhal.js"))({
11
+ global: this,
12
+ evalGlobal: evalGlobal,
13
+ engine: '<<<name>>>', /*TODO*/
14
+ engines: ['<<<name>>>', 'default'], /*TODO*/
15
+ os: "", /* TODO /\bwindows\b/i for Windows FS support */
16
+ // XXX engines may include any number of
17
+ // prioritized generic engines like:
18
+ // rhino, java, c, v8, default
19
+ print: print,
20
+ evaluate: function (text) {
21
+ // TODO maybe something better here:
22
+ return eval(
23
+ "(function(require,exports,module,system,print){" +
24
+ text +
25
+ "/**/\n})"
26
+ );
27
+ },
28
+ fs: {
29
+ read: read,
30
+ isFile: isFile
31
+ },
32
+ prefix: prefix,
33
+ prefixes: [prefix, enginePrefix],
34
+ debug: false,
35
+ verbose: false
36
+ });
37
+
38
+ }).call(this, function () {
39
+ return eval(arguments[0]);
40
+ });
@@ -0,0 +1,118 @@
1
+
2
+ var exports = require('./file');
3
+
4
+ exports.SEPARATOR = '/';
5
+
6
+ exports.cwd = function () {
7
+ throw Error("cwd not yet implemented.");
8
+ };
9
+
10
+ // TODO necessary for package loading
11
+ exports.list = function (path) {
12
+ throw Error("list not yet implemented.");
13
+ };
14
+
15
+ // TODO necessary for package loading
16
+ exports.canonical = function (path) {
17
+ throw Error("canonical not yet implemented.");
18
+ };
19
+
20
+ exports.exists = function (path) {
21
+ throw Error("exists not yet implemented.");
22
+ };
23
+
24
+ // TODO necessary for lazy module reloading in sandboxes
25
+ exports.mtime = function (path) {
26
+ throw Error("mtime not yet implemented.");
27
+ };
28
+
29
+ exports.size = function (path) {
30
+ throw Error("size not yet implemented.");
31
+ };
32
+
33
+ exports.stat = function (path) {
34
+ return {
35
+ mtime: exports.mtime(path),
36
+ size: exports.size(path)
37
+ }
38
+ };
39
+
40
+ // TODO necessary for package loading
41
+ exports.isDirectory = function (path) {
42
+ throw Error("isDirectory not yet implemented.");
43
+ };
44
+
45
+ // TODO necessary for module loading
46
+ exports.isFile = function (path) {
47
+ throw Error("isFile not yet implemented.");
48
+ };
49
+ // XXX remove this if you implement isFile here
50
+ // from bootstrap system object:
51
+ exports.isFile = system.fs.isFile;
52
+
53
+ exports.isFile = system.fs.isFile; // TEMPORARY HACK
54
+
55
+ exports.isLink = function (path) {
56
+ throw Error("isLink not yet implemented.");
57
+ };
58
+
59
+ exports.isReadable = function (path) {
60
+ throw Error("isReadable not yet implemented.");
61
+ };
62
+
63
+ exports.isWritable = function (path) {
64
+ throw Error("isWritable not yet implemented.");
65
+ };
66
+
67
+ exports.rename = function (source, target) {
68
+ throw Error("rename not yet implemented.");
69
+ };
70
+
71
+ exports.move = function (source, target) {
72
+ throw Error("move not yet implemented.");
73
+ };
74
+
75
+ exports.remove = function (path) {
76
+ throw Error("remove not yet implemented.");
77
+ };
78
+
79
+ exports.mkdir = function (path) {
80
+ throw Error("mkdir not yet implemented.");
81
+ };
82
+
83
+ exports.rmdir = function(path) {
84
+ throw Error("rmdir not yet implemented.");
85
+ };
86
+
87
+ exports.touch = function (path, mtime) {
88
+ throw Error("touch not yet implemented.");
89
+ };
90
+
91
+ // FIXME temporary hack
92
+ var read = system.fs.read; // from bootstrap system object
93
+
94
+ exports.FileIO = function (path, mode, permissions) {
95
+ mode = exports.mode(mode);
96
+ var read = mode.read,
97
+ write = mode.write,
98
+ append = mode.append,
99
+ update = mode.update;
100
+
101
+ if (update) {
102
+ throw new Error("Updating IO not yet implemented.");
103
+ } else if (write || append) {
104
+ throw new Error("Writing IO not yet implemented.");
105
+ } else if (read) {
106
+ // FIXME temporary hack
107
+ return {
108
+ 'read': function () {
109
+ return read(path);
110
+ },
111
+ 'close': function () {
112
+ }
113
+ };
114
+ } else {
115
+ throw new Error("Files must be opened either for read, write, or update mode.");
116
+ }
117
+ };
118
+
@@ -0,0 +1,17 @@
1
+
2
+ var IO = require("./io").IO;
3
+
4
+ exports.stdin = /*TODO*/
5
+ exports.stdout = /*TODO*/
6
+ exports.stderr = /*TODO*/
7
+
8
+ exports.args = [/*TODO*/];
9
+
10
+ exports.env = {}; /*TODO*/
11
+
12
+ exports.fs = require('./file');
13
+
14
+ // default logger
15
+ var Logger = require("./logger").Logger;
16
+ exports.log = new Logger(exports.stdout);
17
+
@@ -0,0 +1,35 @@
1
+
2
+ var jackutil = require("jack/utils");
3
+
4
+ var app = function (env) {
5
+ if (/^../.test(env.PATH_INFO))
6
+ return jackutil.responseForStatus(404, env.PATH_INFO);
7
+ return {
8
+ "status": 200,
9
+ "headers": {"Content-type": "text/html"},
10
+ "body": [
11
+ "<html><head><script>" +
12
+
13
+ // 1.) preload transitive dependencies and
14
+ // then require.
15
+ env.script.require("narwhal/server-test") +
16
+
17
+ // 2.) embed with transitive dependencies
18
+ //env.script.embed("narwhal/server-test") +
19
+
20
+ // 3.) no preloading, all async
21
+ //env.script.loader("narwhal/server-test") +
22
+ //".async('narwhal/server-test');" +
23
+
24
+ "</script></head><body></body></html>"
25
+ ]
26
+ };
27
+ };
28
+ app = require("narwhal/server").App(app, {
29
+ "debug": true // turn off debug for minification
30
+ //"path": "javascript/", // to use an alternate path to the module tree
31
+ //"proxy": "http://example.com/.js/", // to use a caching proxy
32
+ });
33
+ app = require("jack").ContentLength(app);
34
+ exports.app = app;
35
+
@@ -0,0 +1,35 @@
1
+ // Adapted from https://developer.mozilla.org/En/Using_web_workers
2
+
3
+ var Worker = require("worker").Worker;
4
+
5
+ var results = [];
6
+
7
+ function resultReceiver(event) {
8
+ results.push(parseInt(event.data));
9
+ if (results.length == 2) {
10
+ postMessage(results[0] + results[1]);
11
+ }
12
+ }
13
+
14
+ function errorReceiver(event) {
15
+ throw event.data;
16
+ }
17
+
18
+ onmessage = function(event) {
19
+ var n = parseInt(event.data);
20
+
21
+ if (n == 0 || n == 1) {
22
+ postMessage(n);
23
+ return;
24
+ }
25
+
26
+ for (var i = 1; i <= 2; i++) {
27
+ var worker = new Worker(module.path);
28
+ worker.onmessage = resultReceiver;
29
+ worker.onerror = errorReceiver;
30
+ worker.postMessage(n - i);
31
+ }
32
+ };
33
+
34
+ if (module.id == require.main)
35
+ print("Run fibonacci.js instead of fibonacci-worker.js");
@@ -0,0 +1,19 @@
1
+ // Adapted from https://developer.mozilla.org/En/Using_web_workers
2
+
3
+ var FILE = require("file"),
4
+ Worker = require("worker").Worker;
5
+
6
+ var worker = new Worker(FILE.join(FILE.dirname(module.path), "fibonacci-worker.js"));
7
+
8
+ worker.onmessage = function(event) {
9
+ print("Got: " + event.data);
10
+ }
11
+
12
+ worker.onerror = function(error) {
13
+ print("Worker error: " + error.message);
14
+ }
15
+
16
+ worker.postMessage(5);
17
+
18
+ // event loop
19
+ while(true) require("event-queue").nextEvent()();
data/examples/hello ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env narwhal
2
+ print("Hello, World!");
data/examples/narwhal ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env narwhal
2
+ var narwhal = require('narwhal');
3
+ print(narwhal.LEFT);
@@ -0,0 +1 @@
1
+ system.stdout.write(system.fs.read(module.path)).flush();
data/extconf.rb ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # Choose the best default engine for this platform and make it if needed.
5
+
6
+ NARWHAL_ROOT = File.expand_path(File.dirname(__FILE__))
7
+ CONF_PATH = File.join(NARWHAL_ROOT, 'narwhal.conf')
8
+ MAKEFILE = File.join(NARWHAL_ROOT, 'Makefile')
9
+
10
+ TEST_PATH = File.join("", "System", "Library", "Frameworks", "JavaScriptCore.framework")
11
+ JSC_ENGINE = File.join(NARWHAL_ROOT, 'engines', 'jsc')
12
+
13
+ # Detect JSC
14
+ if File.exists?(TEST_PATH) && File.exists?(JSC_ENGINE)
15
+ puts "Using JavaScript Core Engine"
16
+
17
+ fp = File.open(CONF_PATH, 'w+')
18
+ fp.write %(NARWHAL_ENGINE="jsc"\n)
19
+ fp.write %(NARWHAL_ENGINE_HOME="engines/jsc"\n)
20
+ fp.close
21
+
22
+ fp = File.open(MAKEFILE, 'w+')
23
+ fp.write %(default:\n)
24
+ fp.write %(\tcd #{JSC_ENGINE}; make\n)
25
+ fp.write %(\n)
26
+
27
+ fp.write %(install:\n)
28
+ fp.write %(\t# do nothing\n)
29
+ fp.close
30
+
31
+ # Fallback
32
+ else
33
+ puts "Using Default Rhino Engine"
34
+ fp = File.open(MAKEFILE, 'w+')
35
+ fp.write %(default:\n)
36
+ fp.write %(\n)
37
+ fp.write %(install:\n)
38
+ fp.write %(\n)
39
+ fp.close
40
+ end
41
+
42
+
43
+
44
+
data/gem_bin/narwhal ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BIN_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin'))
4
+ exec File.join(BIN_ROOT, 'narwhal'), *ARGV
5
+
data/gem_bin/sea ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BIN_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin'))
4
+ exec File.join(BIN_ROOT, 'sea'), *ARGV
data/gem_bin/tusk ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BIN_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin'))
4
+ exec File.join(BIN_ROOT, 'tusk'), *ARGV
data/lib/args.js ADDED
@@ -0,0 +1,849 @@
1
+
2
+ var os = require('os');
3
+ var util = require('util');
4
+ var stream = require('term').stream;
5
+ var system = require('system');
6
+
7
+ exports.UsageError = function (message) {
8
+ this.name = "UsageError";
9
+ this.message = message;
10
+ };
11
+
12
+ exports.UsageError.prototype = Object.create(Error.prototype);
13
+
14
+ exports.ConfigurationError = function (message) {
15
+ this.name = "ConfigurationError";
16
+ this.message = message;
17
+ };
18
+
19
+ exports.ConfigurationError.prototype = Object.create(Error.prototype);
20
+
21
+ exports.Parser = function () {
22
+ this._options = [];
23
+ this._def = {};
24
+ this._long = {};
25
+ this._short = {};
26
+ this._commands = {};
27
+ this._args = [];
28
+ this._vargs = undefined;
29
+ };
30
+
31
+ exports.Parser.prototype.option = function () {
32
+ var option = new this.Option(this, arguments);
33
+ this._options.push(option);
34
+ return option;
35
+ };
36
+
37
+ exports.Parser.prototype.group = function (name) {
38
+ var group = new this.Group(this, this, name);
39
+ this._options.push(group);
40
+ return group;
41
+ };
42
+
43
+ exports.Parser.prototype.def = function (name, value) {
44
+ this._def[name] = value;
45
+ return this;
46
+ };
47
+
48
+ exports.Parser.prototype.reset = function (options) {
49
+ for (var name in this._def) {
50
+ if (util.has(this._def, name))
51
+ options[name] = util.copy(this._def[name]);
52
+ }
53
+ this._options.forEach(function (option) {
54
+ options[option.getName()] = option._def;
55
+ });
56
+ };
57
+
58
+ exports.Parser.prototype.command = function (name, handler) {
59
+ var parent = this;
60
+ if (!handler) {
61
+ var parser = new exports.Parser();
62
+ this._commands[name] = function () {
63
+ return parser;
64
+ };
65
+ return parser;
66
+ } else if (typeof handler == "string") {
67
+ this._commands[name] = function () {
68
+ return require(handler).parser;
69
+ };
70
+ return;
71
+ } else {
72
+ var parser = new this.Parser();
73
+ parser.action(handler);
74
+ this._commands[name] = function () {
75
+ return parser;
76
+ };
77
+ return parser;
78
+ }
79
+ };
80
+
81
+ exports.Parser.prototype.arg = function (name) {
82
+ var argument = new exports.Argument(this).name(name);
83
+ this._args.push(argument);
84
+ return argument;
85
+ };
86
+
87
+ exports.Parser.prototype.args = function (name) {
88
+ var argument = new exports.Argument(this).name(name);
89
+ this._vargs = argument;
90
+ return argument;
91
+ };
92
+
93
+ exports.Parser.prototype.act = function (args, options) {
94
+ if (!this._action) {
95
+ this.error(options, "Not yet implemented.");
96
+ this.exit(-1);
97
+ }
98
+ options.acted = true;
99
+ this._action.call(this, this.parse(args), options);
100
+ };
101
+
102
+ exports.Parser.prototype.action = function (action) {
103
+ if (this._action) {
104
+ action = (function (previous) {
105
+ return function () {
106
+ previous.apply(this, arguments);
107
+ action.apply(this, arguments);
108
+ };
109
+ })(action);
110
+ }
111
+ this._action = action;
112
+ return this;
113
+ };
114
+
115
+ // should be called last
116
+ exports.Parser.prototype.helpful = function () {
117
+ var self = this;
118
+ this.option('-h', '--help')
119
+ .help('displays usage information')
120
+ .action(function (options) {
121
+ return self.printHelp(options);
122
+ })
123
+ .halt();
124
+ if (util.len(this._commands))
125
+ this.command('help', function (options) {
126
+ self.printHelp(options);
127
+ }).help('displays usage information');
128
+ return this;
129
+ };
130
+
131
+ exports.Parser.prototype.usage = function (usage) {
132
+ this._usage = usage;
133
+ return this;
134
+ };
135
+
136
+ exports.Parser.prototype.help = function (help) {
137
+ this._help = help;
138
+ return this;
139
+ };
140
+
141
+ exports.Parser.prototype.printHelp = function (options) {
142
+ var args = options.args || [];
143
+ if (args.length) {
144
+ // parse args for deep help
145
+ // TODO offer extended help for options
146
+ if (!util.has(this._commands, args[0])) {
147
+ this.error(options, util.repr(args[0]) + ' is not a command.');
148
+ this.printCommands(options);
149
+ this.exit(options);
150
+ } else {
151
+ util.put(args, 1, '--help');
152
+ this._commands[args[0]]().act(args, options);
153
+ this.exit(options);
154
+ }
155
+ } else {
156
+ this.printUsage(options);
157
+ if (this._help)
158
+ this.print('' + this._help + '');
159
+ this.printCommands(options);
160
+ this.printOptions(options);
161
+ this.exit(options);
162
+ }
163
+ };
164
+
165
+ exports.Parser.prototype.printUsage = function (options) {
166
+ this.print(
167
+ 'Usage: \0bold(\0blue(' + system.fs.basename(options.command || '<unknown>') + ' [OPTIONS]' +
168
+ (util.len(this._commands) ?
169
+ ' COMMAND' :
170
+ ''
171
+ ) +
172
+ (util.len(this._args) ?
173
+ ' ' + this._args.map(function (arg) {
174
+ if (arg._optional) {
175
+ return '[' + arg._name.toUpperCase() + ']';
176
+ } else {
177
+ return arg._name.toUpperCase();
178
+ }
179
+ }).join(' ') :
180
+ ''
181
+ ) +
182
+ (this._vargs ?
183
+ ' [' + this._vargs._name.toUpperCase() + ' ...]':
184
+ ''
185
+ ) +
186
+ (this._usage ?
187
+ ' ' + this._usage :
188
+ ''
189
+ ) + "\0)\0)"
190
+ );
191
+ };
192
+
193
+ exports.Parser.prototype.printCommands = function (options) {
194
+ var self = this;
195
+ util.forEachApply(
196
+ util.items(this._commands),
197
+ function (name, command) {
198
+ var parser = command();
199
+ self.print(' \0bold(\0green(' + name + '\0)\0)' + (
200
+ parser._help ?
201
+ (
202
+ ': ' +
203
+ (
204
+ parser._action?
205
+ '': '\0red(NYI\0): '
206
+ ) +
207
+ parser._help
208
+ ) : ''
209
+ ));
210
+ }
211
+ );
212
+ };
213
+
214
+ exports.Parser.prototype.printOption = function (options, option, depth, parent) {
215
+ var self = this;
216
+ depth = depth || 0;
217
+ var indent = util.mul(' ', depth);
218
+
219
+ if (option._hidden)
220
+ return;
221
+ if (option._group !== parent)
222
+ return;
223
+
224
+ if (option instanceof exports.Group) {
225
+ self.print(indent + ' \0yellow(' + option._name + ':\0)');
226
+ var parent = option;
227
+ option._options.forEach(function (option) {
228
+ return self.printOption(options, option, depth + 1, parent);
229
+ });
230
+ return;
231
+ }
232
+
233
+ var message = [];
234
+ if (option._short.length)
235
+ message.push(option._short.map(function (_short) {
236
+ return ' \0bold(\0green(-' + _short + '\0)\0)';
237
+ }).join(''));
238
+ if (option._long.length)
239
+ message.push(option._long.map(function (_long) {
240
+ return ' \0bold(\0green(--' + _long + '\0)\0)';
241
+ }).join(''));
242
+ if (option._action && option._action.length > 2)
243
+ message.push(
244
+ ' ' +
245
+ util.range(option._action.length - 2)
246
+ .map(function () {
247
+ return '\0bold(\0green(' + util.upper(
248
+ option.getDisplayName()
249
+ ) + '\0)\0)';
250
+ }).join(' ')
251
+ );
252
+ if (option._help)
253
+ message.push(': ' + option._help + '');
254
+ if (option._choices) {
255
+ var choices = option._choices;
256
+ if (!util.isArrayLike(choices))
257
+ choices = util.keys(choices);
258
+ message.push(' \0bold(\0blue((' + choices.join(', ') + ')\0)\0)');
259
+ }
260
+ if (option._halt)
261
+ message.push(' \0bold(\0blue((final option)\0)\0)');
262
+ self.print(indent + message.join(''));
263
+
264
+ };
265
+
266
+ exports.Parser.prototype.printOptions = function (options) {
267
+ var self = this;
268
+ self._options.forEach(function (option) {
269
+ self.printOption(options, option);
270
+ });
271
+ };
272
+
273
+ exports.Parser.prototype.error = function (options, message) {
274
+ if (this._parser) {
275
+ this._parser.error.apply(
276
+ this._parser,
277
+ arguments
278
+ );
279
+ } else {
280
+ this.print('\0red(' + message + '\0)');
281
+ this.exit();
282
+ }
283
+ };
284
+
285
+ exports.Parser.prototype.exit = function (status) {
286
+ if (this._parser) {
287
+ this._parser.exit.apply(
288
+ this._parser,
289
+ arguments
290
+ );
291
+ } else {
292
+ os.exit(status);
293
+ throw new Error("exit failed");
294
+ }
295
+ };
296
+
297
+ exports.Parser.prototype.print = function () {
298
+ if (this._parser)
299
+ this._parser.print.apply(
300
+ this._parser,
301
+ arguments
302
+ );
303
+ else
304
+ stream.print.apply(null, arguments);
305
+ };
306
+
307
+ // verifies that the parser is fully configured
308
+ exports.Parser.prototype.check = function () {
309
+ // make sure all options have associated actions
310
+ var self = this;
311
+ self._options.forEach(function (option) {
312
+ if (!(option instanceof self.Option))
313
+ return;
314
+ if (!option._action)
315
+ throw new exports.ConfigurationError(
316
+ "No action associated with the option " +
317
+ util.repr(option.getDisplayName())
318
+ );
319
+ });
320
+ };
321
+
322
+ // TODO break this into sub-functions
323
+ // TODO wrap with a try catch and print the progress through the arguments
324
+ exports.Parser.prototype.parse = function (args, options, noCommand) {
325
+ var self = this;
326
+
327
+ this.check();
328
+
329
+ if (!args)
330
+ args = system.args;
331
+ if (!options)
332
+ options = {};
333
+
334
+ options.args = args;
335
+ if (!noCommand && args.length && !/^-/.test(args[0]))
336
+ options.command = args.shift();
337
+
338
+ function mandatoryShift(n, name) {
339
+ if (n > args.length) {
340
+ this.error(
341
+ options,
342
+ 'Error: The ' + util.enquote(name) +
343
+ ' option requires ' + n + ' arguments.'
344
+ );
345
+ }
346
+ var result = args.slice(0, n);
347
+ for (var i = 0; i < n; i++)
348
+ args.shift()
349
+ return result;
350
+ };
351
+
352
+ function validate(option, value) {
353
+ try {
354
+ return option._validate.call(self, value);
355
+ } catch (exception) {
356
+ self.error(options, exception);
357
+ }
358
+ };
359
+
360
+ // initial values
361
+ for (var name in this._def) {
362
+ if (util.has(this._def, name) && !util.has(options, name))
363
+ options[name] = util.copy(this._def[name]);
364
+ }
365
+ this._options.forEach(function (option) {
366
+ if (!(option instanceof self.Option))
367
+ return;
368
+ if (!util.has(options, option.getName()))
369
+ options[option.getName()] = option._def;
370
+ });
371
+
372
+ // walk args
373
+ ARGS: while (args.length) {
374
+ var arg = args.shift();
375
+ if (arg == "--") {
376
+ break;
377
+
378
+ } else if (/^--/.test(arg)) {
379
+
380
+ var pattern = arg.match(/^--([^=]+)(?:=(.*))?/).slice(1);
381
+ var word = pattern[0];
382
+ var value = pattern[1];
383
+
384
+ if (!!value) {
385
+ args.unshift(value);
386
+ }
387
+
388
+ if (util.has(this._long, word)) {
389
+
390
+ var option = this._long[word];
391
+ if (!option._action) {
392
+ self.error(
393
+ options,
394
+ "Programmer error: The " + word +
395
+ " option does not have an associated action."
396
+ );
397
+ }
398
+
399
+ option._action.apply(
400
+ self,
401
+ [
402
+ options,
403
+ option.getName()
404
+ ].concat(
405
+ validate(option, mandatoryShift.call(
406
+ this,
407
+ Math.max(0, option._action.length - 2),
408
+ option.getName()
409
+ ))
410
+ )
411
+ );
412
+
413
+ if (option._halt)
414
+ break ARGS;
415
+
416
+ } else {
417
+ this.error(options, 'Error: Unrecognized option: ' + util.enquote(word));
418
+ }
419
+
420
+ } else if (/^-/.test(arg)) {
421
+
422
+ var letters = arg.match(/^-(.*)/)[1].split('');
423
+ while (letters.length) {
424
+ var letter = letters.shift();
425
+ if (util.has(this._short, letter)) {
426
+ var option = this._short[letter];
427
+
428
+ if (option._action.length > 2) {
429
+ if (letters.length) {
430
+ args.unshift(letters.join(''));
431
+ letters = [];
432
+ }
433
+ }
434
+
435
+ option._action.apply(
436
+ self,
437
+ [
438
+ options,
439
+ option.getName(),
440
+ ].concat(
441
+ validate(
442
+ option,
443
+ mandatoryShift.call(
444
+ this,
445
+ Math.max(0, option._action.length - 2),
446
+ option.getName()
447
+ )
448
+ )
449
+ )
450
+ );
451
+
452
+ if (option._halt)
453
+ break ARGS;
454
+
455
+ } else {
456
+ this.error(options, 'Error: unrecognized option: ' + util.enquote(letter));
457
+ }
458
+ }
459
+
460
+ } else {
461
+ // TODO permit options interleaved with arguments,
462
+ // with associated actions, for any of positional
463
+ // args, variadic args, and accumulated args
464
+ args.unshift(arg);
465
+ break;
466
+ }
467
+
468
+ }
469
+
470
+ if (util.len(this._commands)) {
471
+ if (args.length) {
472
+ if (util.has(this._commands, args[0])) {
473
+ var command = this._commands[args[0]];
474
+ command().act(args, options);
475
+ } else {
476
+ this.error(options, 'Error: unrecognized command');
477
+ }
478
+ } else {
479
+ this.error(options, 'Error: command required');
480
+ this.exit(0);
481
+ }
482
+ }
483
+
484
+ return options;
485
+ };
486
+
487
+ exports.Argument = function (parser) {
488
+ this._parser = parser;
489
+ return this;
490
+ };
491
+
492
+ exports.Argument.prototype.name = function (name) {
493
+ this._name = name;
494
+ return this;
495
+ };
496
+
497
+ exports.Argument.prototype.optional = function () {
498
+ this._optional = true;
499
+ return this;
500
+ };
501
+
502
+ exports.Option = function (parser, args) {
503
+ var self = this;
504
+ this._parser = parser;
505
+ this._validate = function (value) {
506
+ return value;
507
+ };
508
+ this._long = [];
509
+ this._short = [];
510
+ util.forEach(args, function (arg) {
511
+ if (typeof arg == "function") {
512
+ self.action(arg);
513
+ } else if (typeof arg !== "string") {
514
+ for (var name in arg) {
515
+ var value = arg[name];
516
+ self[name](value);
517
+ }
518
+ } else if (/ /.test(arg)) {
519
+ self.help(arg);
520
+ } else if (/^--/.test(arg)) {
521
+ arg = arg.match(/^--(.*)/)[1];
522
+ self.__(arg);
523
+ } else if (/^-.$/.test(arg)) {
524
+ arg = arg.match(/^-(.)/)[1];
525
+ self._(arg);
526
+ } else if (/^-/.test(arg)) {
527
+ throw new Error("option names with one dash can only have one letter.");
528
+ } else {
529
+ if (!self._name) {
530
+ self.name(arg);
531
+ self.displayName(arg);
532
+ } else {
533
+ self.name(arg);
534
+ }
535
+ }
536
+ });
537
+ if (!(self._short.length || self._long.length || self._name))
538
+ throw new exports.ConfigurationError("Option has no name.");
539
+ return this;
540
+ };
541
+
542
+ exports.Option.prototype._ = function (letter) {
543
+ this._short.push(letter);
544
+ this._parser._short[letter] = this;
545
+ return this;
546
+ };
547
+
548
+ exports.Option.prototype.__ = function (word) {
549
+ this._long.push(word);
550
+ this._parser._long[word] = this;
551
+ return this;
552
+ };
553
+
554
+ exports.Option.prototype.name = function (name) {
555
+ this._name = name;
556
+ return this;
557
+ };
558
+
559
+ exports.Option.prototype.displayName = function (displayName) {
560
+ this._displayName = displayName;
561
+ return this;
562
+ };
563
+
564
+ exports.Option.prototype.getDisplayName = function () {
565
+ if (this._displayName)
566
+ return this._displayName;
567
+ return this.getName();
568
+ };
569
+
570
+ exports.Option.prototype.getName = function () {
571
+ if (this._name) {
572
+ return this._name;
573
+ }
574
+ if (this._long.length > 0) {
575
+ return this._long[0];
576
+ }
577
+ if (this._short.length > 0) {
578
+ return this._short[0];
579
+ }
580
+ throw new Error("Programmer error: unnamed option");
581
+ };
582
+
583
+ exports.Option.prototype.action = function (action) {
584
+ var self = this;
585
+ if (typeof action == "string") {
586
+ this._action = self._parser[action];
587
+ } else {
588
+ this._action = action;
589
+ }
590
+ return this;
591
+ };
592
+
593
+ exports.Option.prototype.set = function (value) {
594
+ var option = this;
595
+ if (arguments.length == 0)
596
+ return this.action(function (options, name, value) {
597
+ options[name] = value;
598
+ });
599
+ else if (arguments.length == 1)
600
+ return this.action(function (options, name) {
601
+ options[name] = value;
602
+ });
603
+ else
604
+ throw new exports.UsageError("Option().set takes 0 or 1 arguments");
605
+ };
606
+
607
+ exports.Option.prototype.push = function () {
608
+ var option = this;
609
+ return this.def([]).action(function (options, name, value) {
610
+ options[name].push(option._validate.call(
611
+ this,
612
+ value
613
+ ));
614
+ });
615
+ };
616
+
617
+ exports.Option.prototype.inc = function () {
618
+ return this.def(0).action(function (options, name) {
619
+ options[name]++;
620
+ });
621
+ };
622
+
623
+ exports.Option.prototype.dec = function () {
624
+ return this.def(0).action(function (options, name) {
625
+ options[name]--;
626
+ });
627
+ };
628
+
629
+ exports.Option.prototype.choices = function (choices) {
630
+ this.set();
631
+ this._choices = choices;
632
+ var self = this;
633
+ if (util.isArrayLike(choices)) {
634
+ return this.validate(function (value) {
635
+ if (choices.indexOf(value) < 0)
636
+ throw new exports.UsageError(
637
+ "choice for " + util.upper(self.getDisplayName()) +
638
+ " is invalid: " + util.enquote(value) + "\n" +
639
+ "Use one of: " + choices.map(function (choice) {
640
+ return util.enquote(choice);
641
+ }).join(', ')
642
+ );
643
+ return value;
644
+ })
645
+ } else {
646
+ return this.validate(function (value) {
647
+ if (!util.has(choices, value))
648
+ throw new exports.UsageError(
649
+ "choice for " + util.upper(self.getDisplayName()) +
650
+ " is invalid: " + util.enquote(value) + "\n" +
651
+ "Use one of: " + util.keys(choices).map(function (choice) {
652
+ return util.enquote(choice);
653
+ }).join(', ')
654
+ );
655
+ return choices[value];
656
+ });
657
+ }
658
+ };
659
+
660
+ exports.Option.prototype.def = function (value) {
661
+ if (this._def === undefined)
662
+ this._def = value;
663
+ return this;
664
+ };
665
+
666
+ exports.Option.prototype.validate = function (validate) {
667
+ var current = this._validate;
668
+ if (this._validate) {
669
+ validate = (function (previous) {
670
+ return function () {
671
+ return current.call(
672
+ this,
673
+ previous.apply(this, arguments)
674
+ );
675
+ };
676
+ })(validate);
677
+ }
678
+ this._validate = validate;
679
+ return this;
680
+ };
681
+
682
+ exports.Option.prototype.input = function () {
683
+ this.set().validate(function (value) {
684
+ if (value == "-")
685
+ return system.stdin;
686
+ else
687
+ return system.fs.open(value, 'r');
688
+ });
689
+ };
690
+
691
+ exports.Option.prototype.output = function () {
692
+ this.set().validate(function (value) {
693
+ if (value == "-")
694
+ return system.stdout;
695
+ else
696
+ return system.fs.open(value, 'w');
697
+ });
698
+ };
699
+
700
+ exports.Option.prototype.number = function () {
701
+ return this.set().validate(function (value) {
702
+ var result = +value;
703
+ if (isNaN(result))
704
+ throw new exports.UsageError("not a number");
705
+ return result;
706
+ });
707
+ };
708
+
709
+ exports.Option.prototype.oct = function () {
710
+ return this.set().validate(function (value) {
711
+ var result = parseInt(value, 8);
712
+ if (isNaN(result))
713
+ throw new exports.UsageError("not an octal value");
714
+ return result;
715
+ });
716
+ };
717
+
718
+ exports.Option.prototype.hex = function () {
719
+ return this.set().validate(function (value) {
720
+ var result = parseInt(value, 16);
721
+ if (isNaN(result))
722
+ throw new exports.UsageError("not an hex value");
723
+ return result;
724
+ });
725
+ };
726
+
727
+ exports.Option.prototype.integer = function () {
728
+ return this.set().validate(function (value) {
729
+ var result = parseInt(value, 10);
730
+ if (isNaN(result) || result !== +value)
731
+ throw new exports.UsageError("not an integer");
732
+ return result;
733
+ });
734
+ };
735
+
736
+ exports.Option.prototype.natural = function () {
737
+ return this.set().validate(function (value) {
738
+ var result = value >>> 0;
739
+ if (result !== +value || result < 0)
740
+ throw new exports.UsageError("not a natural number");
741
+ return result;
742
+ });
743
+ };
744
+
745
+ exports.Option.prototype.whole = function () {
746
+ return this.set().validate(function (value) {
747
+ var result = value >>> 0;
748
+ if (result !== +value || result < 1)
749
+ throw new exports.UsageError("not a whole number");
750
+ return result;
751
+ });
752
+ };
753
+
754
+ exports.Option.prototype.bool = function (def) {
755
+ if (def === undefined)
756
+ def = true;
757
+ return this.def(!def).set(!!def);
758
+ };
759
+
760
+ exports.Option.prototype.todo = function (command, value) {
761
+ this._parser.def('todo', []);
762
+ command = command || this.getName();
763
+ if (value)
764
+ return this.action(function (options, name, value) {
765
+ options.todo.push([command, value]);
766
+ });
767
+ else
768
+ return this.action(function (options, name) {
769
+ options.todo.push([command]);
770
+ });
771
+ };
772
+
773
+ exports.Option.prototype.inverse = function () {
774
+ var args = arguments;
775
+ if (!args.length) {
776
+ args = [];
777
+ this._short.forEach(function (_) {
778
+ args.push('-' + _.toUpperCase());
779
+ });
780
+ this._long.forEach(function (__) {
781
+ args.push('--no-' + __);
782
+ });
783
+ if (this.getName())
784
+ args.push(this.getName());
785
+ }
786
+ var parser = this._parser;
787
+ var inverse = this._inverse = parser.option.apply(
788
+ parser,
789
+ args
790
+ ).set(!this._def).help('^ inverse');
791
+ return this;
792
+ };
793
+
794
+ exports.Option.prototype.help = function (text) {
795
+ this._help = text;
796
+ return this;
797
+ };
798
+
799
+ exports.Option.prototype.halt = function () {
800
+ this._halt = true;
801
+ return this;
802
+ };
803
+
804
+ exports.Option.prototype.hidden = function () {
805
+ this._hidden = true;
806
+ return this;
807
+ };
808
+
809
+ exports.Option.prototype.end = function () {
810
+ return this._parser;
811
+ };
812
+
813
+ exports.Option.prototype.option = function () {
814
+ return this.end().option.apply(this, arguments);
815
+ };
816
+
817
+ exports.Parser.prototype.end = function () {
818
+ return this._parser;
819
+ };
820
+
821
+ exports.Group = function (parser, parent, name) {
822
+ this._name = name;
823
+ this._parser = parser;
824
+ this._parent = parent;
825
+ this._options = [];
826
+ return this;
827
+ };
828
+
829
+ exports.Group.prototype.option = function () {
830
+ var option = this._parser.option.apply(this._parser, arguments);
831
+ option._group = this;
832
+ this._options.push(option);
833
+ return option;
834
+ };
835
+
836
+ exports.Group.prototype.group = function (name) {
837
+ var Group = this.Group || this._parser.Group;
838
+ var group = new Group(this._parser, this, name);
839
+ return group;
840
+ };
841
+
842
+ exports.Group.prototype.end = function () {
843
+ return this._parent;
844
+ };
845
+
846
+ exports.Parser.prototype.Parser = exports.Parser;
847
+ exports.Parser.prototype.Option = exports.Option;
848
+ exports.Parser.prototype.Group = exports.Group;
849
+