johnson 1.2.0 → 2.0.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,96 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ *
3
+ * ***** BEGIN LICENSE BLOCK *****
4
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5
+ *
6
+ * The contents of this file are subject to the Mozilla Public License Version
7
+ * 1.1 (the "License"); you may not use this file except in compliance with
8
+ * the License. You may obtain a copy of the License at
9
+ * http://www.mozilla.org/MPL/
10
+ *
11
+ * Software distributed under the License is distributed on an "AS IS" basis,
12
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
+ * for the specific language governing rights and limitations under the
14
+ * License.
15
+ *
16
+ * The Original Code is Mozilla Communicator client code, released
17
+ * March 31, 1998.
18
+ *
19
+ * The Initial Developer of the Original Code is
20
+ * Netscape Communications Corporation.
21
+ * Portions created by the Initial Developer are Copyright (C) 1998
22
+ * the Initial Developer. All Rights Reserved.
23
+ *
24
+ * Contributor(s):
25
+ *
26
+ * Alternatively, the contents of this file may be used under the terms of
27
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
28
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
+ * in which case the provisions of the GPL or the LGPL are applicable instead
30
+ * of those above. If you wish to allow use of your version of this file only
31
+ * under the terms of either the GPL or the LGPL, and not to allow others to
32
+ * use your version of this file under the terms of the MPL, indicate your
33
+ * decision by deleting the provisions above and replace them with the notice
34
+ * and other provisions required by the GPL or the LGPL. If you do not delete
35
+ * the provisions above, a recipient may use your version of this file under
36
+ * the terms of any one of the MPL, the GPL or the LGPL.
37
+ *
38
+ * ***** END LICENSE BLOCK ***** */
39
+
40
+ /*
41
+ * JS runtime exception classes.
42
+ */
43
+
44
+ #ifndef jsexn_h___
45
+ #define jsexn_h___
46
+
47
+ JS_BEGIN_EXTERN_C
48
+
49
+ extern JSClass js_ErrorClass;
50
+
51
+ /*
52
+ * Initialize the exception constructor/prototype hierarchy.
53
+ */
54
+ extern JSObject *
55
+ js_InitExceptionClasses(JSContext *cx, JSObject *obj);
56
+
57
+ /*
58
+ * Given a JSErrorReport, check to see if there is an exception associated with
59
+ * the error number. If there is, then create an appropriate exception object,
60
+ * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
61
+ * error report. Exception-aware host error reporters should probably ignore
62
+ * error reports so flagged. Returns JS_TRUE if an associated exception is
63
+ * found and set, JS_FALSE otherwise.
64
+ */
65
+ extern JSBool
66
+ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
67
+
68
+ /*
69
+ * Called if a JS API call to js_Execute or js_InternalCall fails; calls the
70
+ * error reporter with the error report associated with any uncaught exception
71
+ * that has been raised. Returns true if there was an exception pending, and
72
+ * the error reporter was actually called.
73
+ *
74
+ * The JSErrorReport * that the error reporter is called with is currently
75
+ * associated with a JavaScript object, and is not guaranteed to persist after
76
+ * the object is collected. Any persistent uses of the JSErrorReport contents
77
+ * should make their own copy.
78
+ *
79
+ * The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag
80
+ * set; embeddings that want to silently propagate JavaScript exceptions to
81
+ * other contexts may want to use an error reporter that ignores errors with
82
+ * this flag.
83
+ */
84
+ extern JSBool
85
+ js_ReportUncaughtException(JSContext *cx);
86
+
87
+ extern JSErrorReport *
88
+ js_ErrorFromException(JSContext *cx, jsval exn);
89
+
90
+ extern const JSErrorFormatString *
91
+ js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale,
92
+ const uintN errorNumber);
93
+
94
+ JS_END_EXTERN_C
95
+
96
+ #endif /* jsexn_h___ */
@@ -0,0 +1,2747 @@
1
+ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
+ * vim: set ts=8 sw=4 et tw=78:
3
+ *
4
+ * ***** BEGIN LICENSE BLOCK *****
5
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
+ *
7
+ * The contents of this file are subject to the Mozilla Public License Version
8
+ * 1.1 (the "License"); you may not use this file except in compliance with
9
+ * the License. You may obtain a copy of the License at
10
+ * http://www.mozilla.org/MPL/
11
+ *
12
+ * Software distributed under the License is distributed on an "AS IS" basis,
13
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14
+ * for the specific language governing rights and limitations under the
15
+ * License.
16
+ *
17
+ * The Original Code is Mozilla Communicator client code, released
18
+ * March 31, 1998.
19
+ *
20
+ * The Initial Developer of the Original Code is
21
+ * Netscape Communications Corporation.
22
+ * Portions created by the Initial Developer are Copyright (C) 1998
23
+ * the Initial Developer. All Rights Reserved.
24
+ *
25
+ * Contributor(s):
26
+ *
27
+ * Alternatively, the contents of this file may be used under the terms of
28
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
29
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
+ * in which case the provisions of the GPL or the LGPL are applicable instead
31
+ * of those above. If you wish to allow use of your version of this file only
32
+ * under the terms of either the GPL or the LGPL, and not to allow others to
33
+ * use your version of this file under the terms of the MPL, indicate your
34
+ * decision by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL or the LGPL. If you do not delete
36
+ * the provisions above, a recipient may use your version of this file under
37
+ * the terms of any one of the MPL, the GPL or the LGPL.
38
+ *
39
+ * ***** END LICENSE BLOCK ***** */
40
+
41
+ /*
42
+ * JS File object
43
+ */
44
+ #if JS_HAS_FILE_OBJECT
45
+
46
+ #include "jsstddef.h"
47
+ #include "jsfile.h"
48
+
49
+ /* ----------------- Platform-specific includes and defines ----------------- */
50
+ #if defined(XP_WIN) || defined(XP_OS2)
51
+ # include <direct.h>
52
+ # include <io.h>
53
+ # include <sys/types.h>
54
+ # include <sys/stat.h>
55
+ # define FILESEPARATOR '\\'
56
+ # define FILESEPARATOR2 '/'
57
+ # define CURRENT_DIR "c:\\"
58
+ # define POPEN _popen
59
+ # define PCLOSE _pclose
60
+ #elif defined(SYMBIAN)
61
+ # include <strings.h>
62
+ # include <stdio.h>
63
+ # include <stdlib.h>
64
+ # include <unistd.h>
65
+ # include <limits.h>
66
+ # define FILESEPARATOR '\\'
67
+ # define FILESEPARATOR2 '/'
68
+ # define CURRENT_DIR "c:\\"
69
+ # define POPEN popen
70
+ # define PCLOSE pclose
71
+ #elif defined(XP_UNIX) || defined(XP_BEOS)
72
+ # include <strings.h>
73
+ # include <stdio.h>
74
+ # include <stdlib.h>
75
+ # include <unistd.h>
76
+ # define FILESEPARATOR '/'
77
+ # define FILESEPARATOR2 '\0'
78
+ # define CURRENT_DIR "/"
79
+ # define POPEN popen
80
+ # define PCLOSE pclose
81
+ #endif
82
+
83
+ /* --------------- Platform-independent includes and defines ---------------- */
84
+ #include "jsapi.h"
85
+ #include "jsatom.h"
86
+ #include "jscntxt.h"
87
+ #include "jsdate.h"
88
+ #include "jsdbgapi.h"
89
+ #include "jsemit.h"
90
+ #include "jsfun.h"
91
+ #include "jslock.h"
92
+ #include "jsobj.h"
93
+ #include "jsparse.h"
94
+ #include "jsscan.h"
95
+ #include "jsscope.h"
96
+ #include "jsscript.h"
97
+ #include "jsstr.h"
98
+ #include "jsutil.h" /* Added by JSIFY */
99
+ #include <string.h>
100
+
101
+ /* NSPR dependencies */
102
+ #include "prio.h"
103
+ #include "prerror.h"
104
+
105
+ #define SPECIAL_FILE_STRING "Special File"
106
+ #define CURRENTDIR_PROPERTY "currentDir"
107
+ #define SEPARATOR_PROPERTY "separator"
108
+ #define FILE_CONSTRUCTOR "File"
109
+ #define PIPE_SYMBOL '|'
110
+
111
+ #define ASCII 0
112
+ #define UTF8 1
113
+ #define UCS2 2
114
+
115
+ #define asciistring "text"
116
+ #define utfstring "binary"
117
+ #define unicodestring "unicode"
118
+
119
+ #define MAX_PATH_LENGTH 1024
120
+ #define MODE_SIZE 256
121
+ #define NUMBER_SIZE 32
122
+ #define MAX_LINE_LENGTH 256
123
+ #define URL_PREFIX "file://"
124
+
125
+ #define STDINPUT_NAME "Standard input stream"
126
+ #define STDOUTPUT_NAME "Standard output stream"
127
+ #define STDERROR_NAME "Standard error stream"
128
+
129
+ #define RESOLVE_PATH js_canonicalPath /* js_absolutePath */
130
+
131
+ /* Error handling */
132
+ typedef enum JSFileErrNum {
133
+ #define MSG_DEF(name, number, count, exception, format) \
134
+ name = number,
135
+ #include "jsfile.msg"
136
+ #undef MSG_DEF
137
+ JSFileErr_Limit
138
+ #undef MSGDEF
139
+ } JSFileErrNum;
140
+
141
+ #define JSFILE_HAS_DFLT_MSG_STRINGS 1
142
+
143
+ JSErrorFormatString JSFile_ErrorFormatString[JSFileErr_Limit] = {
144
+ #if JSFILE_HAS_DFLT_MSG_STRINGS
145
+ #define MSG_DEF(name, number, count, exception, format) \
146
+ { format, count },
147
+ #else
148
+ #define MSG_DEF(name, number, count, exception, format) \
149
+ { NULL, count },
150
+ #endif
151
+ #include "jsfile.msg"
152
+ #undef MSG_DEF
153
+ };
154
+
155
+ const JSErrorFormatString *
156
+ JSFile_GetErrorMessage(void *userRef, const char *locale,
157
+ const uintN errorNumber)
158
+ {
159
+ if ((errorNumber > 0) && (errorNumber < JSFileErr_Limit))
160
+ return &JSFile_ErrorFormatString[errorNumber];
161
+ else
162
+ return NULL;
163
+ }
164
+
165
+ #define JSFILE_CHECK_NATIVE(op) \
166
+ if (file->isNative) { \
167
+ JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s",\
168
+ op, file->path); \
169
+ goto out; \
170
+ }
171
+
172
+ #define JSFILE_CHECK_WRITE \
173
+ if (!file->isOpen) { \
174
+ JS_ReportWarning(cx, \
175
+ "File %s is closed, will open it for writing, proceeding", \
176
+ file->path); \
177
+ js_FileOpen(cx, obj, file, "write,append,create"); \
178
+ } \
179
+ if (!js_canWrite(cx, file)) { \
180
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
181
+ JSFILEMSG_CANNOT_WRITE, file->path); \
182
+ goto out; \
183
+ }
184
+
185
+ #define JSFILE_CHECK_READ \
186
+ if (!file->isOpen) { \
187
+ JS_ReportWarning(cx, \
188
+ "File %s is closed, will open it for reading, proceeding", \
189
+ file->path); \
190
+ js_FileOpen(cx, obj, file, "read"); \
191
+ } \
192
+ if (!js_canRead(cx, file)) { \
193
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
194
+ JSFILEMSG_CANNOT_READ, file->path); \
195
+ goto out; \
196
+ }
197
+
198
+ #define JSFILE_CHECK_OPEN(op) \
199
+ if (!file->isOpen) { \
200
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
201
+ JSFILEMSG_FILE_MUST_BE_OPEN, op); \
202
+ goto out; \
203
+ }
204
+
205
+ #define JSFILE_CHECK_CLOSED(op) \
206
+ if (file->isOpen) { \
207
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
208
+ JSFILEMSG_FILE_MUST_BE_CLOSED, op); \
209
+ goto out; \
210
+ }
211
+
212
+ #define JSFILE_CHECK_ONE_ARG(op) \
213
+ if (argc != 1) { \
214
+ char str[NUMBER_SIZE]; \
215
+ sprintf(str, "%d", argc); \
216
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
217
+ JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str); \
218
+ goto out; \
219
+ }
220
+
221
+
222
+ /*
223
+ Security mechanism, should define a callback for this.
224
+ The parameters are as follows:
225
+ SECURITY_CHECK(JSContext *cx, JSPrincipals *ps, char *op_name, JSFile *file)
226
+ XXX Should this be a real function returning a JSBool result (and getting
227
+ some typesafety help from the compiler?).
228
+ */
229
+ #define SECURITY_CHECK(cx, ps, op, file) \
230
+ /* Define a callback here... */
231
+
232
+
233
+ /* Structure representing the file internally */
234
+ typedef struct JSFile {
235
+ char *path; /* the path to the file. */
236
+ JSBool isOpen;
237
+ int32 mode; /* mode used to open the file: read, write, append, create, etc.. */
238
+ int32 type; /* Asciiz, utf, unicode */
239
+ char byteBuffer[3]; /* bytes read in advance by js_FileRead ( UTF8 encoding ) */
240
+ jsint nbBytesInBuf; /* number of bytes stored in the buffer above */
241
+ jschar charBuffer; /* character read in advance by readln ( mac files only ) */
242
+ JSBool charBufferUsed; /* flag indicating if the buffer above is being used */
243
+ JSBool hasRandomAccess;/* can the file be randomly accessed? false for stdin, and
244
+ UTF-encoded files. */
245
+ JSBool hasAutoflush; /* should we force a flush for each line break? */
246
+ JSBool isNative; /* if the file is using OS-specific file FILE type */
247
+ /* We can actually put the following two in a union since they should never be used at the same time */
248
+ PRFileDesc *handle; /* the handle for the file, if open. */
249
+ FILE *nativehandle; /* native handle, for stuff NSPR doesn't do. */
250
+ JSBool isPipe; /* if the file is really an OS pipe */
251
+ } JSFile;
252
+
253
+ /* a few forward declarations... */
254
+ JS_PUBLIC_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename);
255
+ static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
256
+ static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
257
+
258
+ /* New filename manipulation procesures */
259
+ /* assumes we don't have leading/trailing spaces */
260
+ static JSBool
261
+ js_filenameHasAPipe(const char *filename)
262
+ {
263
+ if (!filename)
264
+ return JS_FALSE;
265
+
266
+ return filename[0] == PIPE_SYMBOL ||
267
+ filename[strlen(filename) - 1] == PIPE_SYMBOL;
268
+ }
269
+
270
+ static JSBool
271
+ js_isAbsolute(const char *name)
272
+ {
273
+ #if defined(XP_WIN) || defined(XP_OS2) || defined(SYMBIAN)
274
+ return *name && name[1] == ':';
275
+ #else
276
+ return (name[0]
277
+ # if defined(XP_UNIX) || defined(XP_BEOS)
278
+ ==
279
+ # else
280
+ !=
281
+ # endif
282
+ FILESEPARATOR);
283
+ #endif
284
+ }
285
+
286
+ /*
287
+ * Concatenates base and name to produce a valid filename.
288
+ * Returned string must be freed.
289
+ */
290
+ static char*
291
+ js_combinePath(JSContext *cx, const char *base, const char *name)
292
+ {
293
+ int len = strlen(base);
294
+ char* result = JS_malloc(cx, len + strlen(name) + 2);
295
+
296
+ if (!result)
297
+ return NULL;
298
+
299
+ strcpy(result, base);
300
+
301
+ if (base[len - 1] != FILESEPARATOR && base[len - 1] != FILESEPARATOR2) {
302
+ result[len] = FILESEPARATOR;
303
+ result[len + 1] = '\0';
304
+ }
305
+ strcat(result, name);
306
+ return result;
307
+ }
308
+
309
+ /* Extract the last component from a path name. Returned string must be freed */
310
+ static char *
311
+ js_fileBaseName(JSContext *cx, const char *pathname)
312
+ {
313
+ jsint index, aux;
314
+ char *result;
315
+
316
+ index = strlen(pathname)-1;
317
+
318
+ /* Chop off trailing seperators. */
319
+ while (index > 0 && (pathname[index]==FILESEPARATOR ||
320
+ pathname[index]==FILESEPARATOR2)) {
321
+ --index;
322
+ }
323
+
324
+ aux = index;
325
+
326
+ /* Now find the next separator. */
327
+ while (index >= 0 && pathname[index] != FILESEPARATOR &&
328
+ pathname[index] != FILESEPARATOR2) {
329
+ --index;
330
+ }
331
+
332
+ /* Allocate and copy. */
333
+ result = JS_malloc(cx, aux - index + 1);
334
+ if (!result)
335
+ return NULL;
336
+ strncpy(result, pathname + index + 1, aux - index);
337
+ result[aux - index] = '\0';
338
+ return result;
339
+ }
340
+
341
+ /*
342
+ * Returns everything but the last component from a path name.
343
+ * Returned string must be freed.
344
+ */
345
+ static char *
346
+ js_fileDirectoryName(JSContext *cx, const char *pathname)
347
+ {
348
+ char *result;
349
+ const char *cp, *end;
350
+ size_t pathsize;
351
+
352
+ end = pathname + strlen(pathname);
353
+ cp = end - 1;
354
+
355
+ /* If this is already a directory, chop off the trailing /s. */
356
+ while (cp >= pathname) {
357
+ if (*cp != FILESEPARATOR && *cp != FILESEPARATOR2)
358
+ break;
359
+ --cp;
360
+ }
361
+
362
+ if (cp < pathname && end != pathname) {
363
+ /* There were just /s, return the root. */
364
+ result = JS_malloc(cx, 1 + 1); /* The separator + trailing NUL. */
365
+ result[0] = FILESEPARATOR;
366
+ result[1] = '\0';
367
+ return result;
368
+ }
369
+
370
+ /* Now chop off the last portion. */
371
+ while (cp >= pathname) {
372
+ if (*cp == FILESEPARATOR || *cp == FILESEPARATOR2)
373
+ break;
374
+ --cp;
375
+ }
376
+
377
+ /* Check if this is a leaf. */
378
+ if (cp < pathname) {
379
+ /* It is, return "pathname/". */
380
+ if (end[-1] == FILESEPARATOR || end[-1] == FILESEPARATOR2) {
381
+ /* Already has its terminating /. */
382
+ return JS_strdup(cx, pathname);
383
+ }
384
+
385
+ pathsize = end - pathname + 1;
386
+ result = JS_malloc(cx, pathsize + 1);
387
+ if (!result)
388
+ return NULL;
389
+
390
+ strcpy(result, pathname);
391
+ result[pathsize - 1] = FILESEPARATOR;
392
+ result[pathsize] = '\0';
393
+
394
+ return result;
395
+ }
396
+
397
+ /* Return everything up to and including the seperator. */
398
+ pathsize = cp - pathname + 1;
399
+ result = JS_malloc(cx, pathsize + 1);
400
+ if (!result)
401
+ return NULL;
402
+
403
+ strncpy(result, pathname, pathsize);
404
+ result[pathsize] = '\0';
405
+
406
+ return result;
407
+ }
408
+
409
+ static char *
410
+ js_absolutePath(JSContext *cx, const char * path)
411
+ {
412
+ JSObject *obj;
413
+ JSString *str;
414
+ jsval prop;
415
+
416
+ if (js_isAbsolute(path)) {
417
+ return JS_strdup(cx, path);
418
+ } else {
419
+ obj = JS_GetGlobalObject(cx);
420
+ if (!JS_GetProperty(cx, obj, FILE_CONSTRUCTOR, &prop)) {
421
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
422
+ JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
423
+ return JS_strdup(cx, path);
424
+ }
425
+
426
+ obj = JSVAL_TO_OBJECT(prop);
427
+ if (!JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, &prop)) {
428
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
429
+ JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
430
+ return JS_strdup(cx, path);
431
+ }
432
+
433
+ str = JS_ValueToString(cx, prop);
434
+ if (!str)
435
+ return JS_strdup(cx, path);
436
+
437
+ /* should we have an array of curr dirs indexed by drive for windows? */
438
+ return js_combinePath(cx, JS_GetStringBytes(str), path);
439
+ }
440
+ }
441
+
442
+ /* Side effect: will remove spaces in the beginning/end of the filename */
443
+ static char *
444
+ js_canonicalPath(JSContext *cx, char *oldpath)
445
+ {
446
+ char *tmp;
447
+ char *path = oldpath;
448
+ char *base, *dir, *current, *result;
449
+ jsint c;
450
+ jsint back = 0;
451
+ unsigned int i = 0, j = strlen(path)-1;
452
+
453
+ /* This is probably optional */
454
+ /* Remove possible spaces in the beginning and end */
455
+ while (i < j && path[i] == ' ')
456
+ i++;
457
+ while (j >= 0 && path[j] == ' ')
458
+ j--;
459
+
460
+ tmp = JS_malloc(cx, j-i+2);
461
+ if (!tmp)
462
+ return NULL;
463
+
464
+ strncpy(tmp, path + i, j - i + 1);
465
+ tmp[j - i + 1] = '\0';
466
+
467
+ path = tmp;
468
+
469
+ /* Pipe support. */
470
+ if (js_filenameHasAPipe(path))
471
+ return path;
472
+
473
+ /* file:// support. */
474
+ if (!strncmp(path, URL_PREFIX, strlen(URL_PREFIX))) {
475
+ tmp = js_canonicalPath(cx, path + strlen(URL_PREFIX));
476
+ JS_free(cx, path);
477
+ return tmp;
478
+ }
479
+
480
+ if (!js_isAbsolute(path)) {
481
+ tmp = js_absolutePath(cx, path);
482
+ if (!tmp)
483
+ return NULL;
484
+ JS_free(cx, path);
485
+ path = tmp;
486
+ }
487
+
488
+ result = JS_strdup(cx, "");
489
+
490
+ current = path;
491
+
492
+ base = js_fileBaseName(cx, current);
493
+ dir = js_fileDirectoryName(cx, current);
494
+
495
+ while (strcmp(dir, current)) {
496
+ if (!strcmp(base, "..")) {
497
+ back++;
498
+ } else {
499
+ if (back > 0) {
500
+ back--;
501
+ } else {
502
+ tmp = result;
503
+ result = JS_malloc(cx, strlen(base) + 1 + strlen(tmp) + 1);
504
+ if (!result)
505
+ goto out;
506
+
507
+ strcpy(result, base);
508
+ c = strlen(result);
509
+ if (*tmp) {
510
+ result[c] = FILESEPARATOR;
511
+ result[c + 1] = '\0';
512
+ strcat(result, tmp);
513
+ }
514
+ JS_free(cx, tmp);
515
+ }
516
+ }
517
+ JS_free(cx, current);
518
+ JS_free(cx, base);
519
+ current = dir;
520
+ base = js_fileBaseName(cx, current);
521
+ dir = js_fileDirectoryName(cx, current);
522
+ }
523
+
524
+ tmp = result;
525
+ result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1);
526
+ if (!result)
527
+ goto out;
528
+
529
+ strcpy(result, dir);
530
+ c = strlen(result);
531
+ if (tmp[0]!='\0') {
532
+ if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) {
533
+ result[c] = FILESEPARATOR;
534
+ result[c+1] = '\0';
535
+ }
536
+ strcat(result, tmp);
537
+ }
538
+
539
+ out:
540
+ if (tmp)
541
+ JS_free(cx, tmp);
542
+ if (dir)
543
+ JS_free(cx, dir);
544
+ if (base)
545
+ JS_free(cx, base);
546
+ if (current)
547
+ JS_free(cx, current);
548
+
549
+ return result;
550
+ }
551
+
552
+ /* -------------------------- Text conversion ------------------------------- */
553
+ /* The following is ripped from libi18n/unicvt.c and include files.. */
554
+
555
+ /*
556
+ * UTF8 defines and macros
557
+ */
558
+ #define ONE_OCTET_BASE 0x00 /* 0xxxxxxx */
559
+ #define ONE_OCTET_MASK 0x7F /* x1111111 */
560
+ #define CONTINUING_OCTET_BASE 0x80 /* 10xxxxxx */
561
+ #define CONTINUING_OCTET_MASK 0x3F /* 00111111 */
562
+ #define TWO_OCTET_BASE 0xC0 /* 110xxxxx */
563
+ #define TWO_OCTET_MASK 0x1F /* 00011111 */
564
+ #define THREE_OCTET_BASE 0xE0 /* 1110xxxx */
565
+ #define THREE_OCTET_MASK 0x0F /* 00001111 */
566
+ #define FOUR_OCTET_BASE 0xF0 /* 11110xxx */
567
+ #define FOUR_OCTET_MASK 0x07 /* 00000111 */
568
+ #define FIVE_OCTET_BASE 0xF8 /* 111110xx */
569
+ #define FIVE_OCTET_MASK 0x03 /* 00000011 */
570
+ #define SIX_OCTET_BASE 0xFC /* 1111110x */
571
+ #define SIX_OCTET_MASK 0x01 /* 00000001 */
572
+
573
+ #define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK ) == ONE_OCTET_BASE)
574
+ #define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK ) == TWO_OCTET_BASE)
575
+ #define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE)
576
+ #define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE)
577
+ #define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE)
578
+ #define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK ) == SIX_OCTET_BASE)
579
+ #define IS_UTF8_2ND_THRU_6TH(x) \
580
+ (( (x)&~CONTINUING_OCTET_MASK ) == CONTINUING_OCTET_BASE)
581
+ #define IS_UTF8_1ST_OF_UCS2(x) \
582
+ IS_UTF8_1ST_OF_1(x) \
583
+ || IS_UTF8_1ST_OF_2(x) \
584
+ || IS_UTF8_1ST_OF_3(x)
585
+
586
+
587
+ #define MAX_UCS2 0xFFFF
588
+ #define DEFAULT_CHAR 0x003F /* Default char is "?" */
589
+ #define BYTE_MASK 0xBF
590
+ #define BYTE_MARK 0x80
591
+
592
+
593
+ /* Function: one_ucs2_to_utf8_char
594
+ *
595
+ * Function takes one UCS-2 char and writes it to a UTF-8 buffer.
596
+ * We need a UTF-8 buffer because we don't know before this
597
+ * function how many bytes of utf-8 data will be written. It also
598
+ * takes a pointer to the end of the UTF-8 buffer so that we don't
599
+ * overwrite data. This function returns the number of UTF-8 bytes
600
+ * of data written, or -1 if the buffer would have been overrun.
601
+ */
602
+
603
+ #define LINE_SEPARATOR 0x2028
604
+ #define PARAGRAPH_SEPARATOR 0x2029
605
+ static int16 one_ucs2_to_utf8_char(unsigned char *tobufp,
606
+ unsigned char *tobufendp,
607
+ uint16 onechar)
608
+ {
609
+ int16 numUTF8bytes = 0;
610
+
611
+ if (onechar == LINE_SEPARATOR || onechar == PARAGRAPH_SEPARATOR) {
612
+ strcpy((char*)tobufp, "\n");
613
+ return strlen((char*)tobufp);
614
+ }
615
+
616
+ if (onechar < 0x80) {
617
+ numUTF8bytes = 1;
618
+ } else if (onechar < 0x800) {
619
+ numUTF8bytes = 2;
620
+ } else {
621
+ /* 0x800 >= onechar <= MAX_UCS2 */
622
+ numUTF8bytes = 3;
623
+ }
624
+
625
+ tobufp += numUTF8bytes;
626
+
627
+ /* return error if we don't have space for the whole character */
628
+ if (tobufp > tobufendp) {
629
+ return(-1);
630
+ }
631
+
632
+ switch(numUTF8bytes) {
633
+ case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
634
+ *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
635
+ *--tobufp = onechar | THREE_OCTET_BASE;
636
+ break;
637
+
638
+ case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
639
+ *--tobufp = onechar | TWO_OCTET_BASE;
640
+ break;
641
+
642
+ case 1: *--tobufp = (unsigned char)onechar;
643
+ break;
644
+ }
645
+
646
+ return numUTF8bytes;
647
+ }
648
+
649
+ /*
650
+ * utf8_to_ucs2_char
651
+ *
652
+ * Convert a utf8 multibyte character to ucs2
653
+ *
654
+ * inputs: pointer to utf8 character(s)
655
+ * length of utf8 buffer ("read" length limit)
656
+ * pointer to return ucs2 character
657
+ *
658
+ * outputs: number of bytes in the utf8 character
659
+ * -1 if not a valid utf8 character sequence
660
+ * -2 if the buffer is too short
661
+ */
662
+ static int16
663
+ utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p)
664
+ {
665
+ uint16 lead, cont1, cont2;
666
+
667
+ /*
668
+ * Check for minimum buffer length
669
+ */
670
+ if ((buflen < 1) || (utf8p == NULL)) {
671
+ return -2;
672
+ }
673
+ lead = (uint16) (*utf8p);
674
+
675
+ /*
676
+ * Check for a one octet sequence
677
+ */
678
+ if (IS_UTF8_1ST_OF_1(lead)) {
679
+ *ucs2p = lead & ONE_OCTET_MASK;
680
+ return 1;
681
+ }
682
+
683
+ /*
684
+ * Check for a two octet sequence
685
+ */
686
+ if (IS_UTF8_1ST_OF_2(*utf8p)) {
687
+ if (buflen < 2)
688
+ return -2;
689
+ cont1 = (uint16) *(utf8p+1);
690
+ if (!IS_UTF8_2ND_THRU_6TH(cont1))
691
+ return -1;
692
+ *ucs2p = (lead & TWO_OCTET_MASK) << 6;
693
+ *ucs2p |= cont1 & CONTINUING_OCTET_MASK;
694
+ return 2;
695
+ }
696
+
697
+ /*
698
+ * Check for a three octet sequence
699
+ */
700
+ else if (IS_UTF8_1ST_OF_3(lead)) {
701
+ if (buflen < 3)
702
+ return -2;
703
+ cont1 = (uint16) *(utf8p+1);
704
+ cont2 = (uint16) *(utf8p+2);
705
+ if ( (!IS_UTF8_2ND_THRU_6TH(cont1))
706
+ || (!IS_UTF8_2ND_THRU_6TH(cont2)))
707
+ return -1;
708
+ *ucs2p = (lead & THREE_OCTET_MASK) << 12;
709
+ *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6;
710
+ *ucs2p |= cont2 & CONTINUING_OCTET_MASK;
711
+ return 3;
712
+ }
713
+ else { /* not a valid utf8/ucs2 character */
714
+ return -1;
715
+ }
716
+ }
717
+
718
+ /* ----------------------------- Helper functions --------------------------- */
719
+ /* Ripped off from lm_win.c .. */
720
+ /* where is strcasecmp?.. for now, it's case sensitive..
721
+ *
722
+ * strcasecmp is in strings.h, but on windows it's called _stricmp...
723
+ * will need to #ifdef this
724
+ */
725
+
726
+ static int32
727
+ js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name)
728
+ {
729
+ char *comma, *equal, *current;
730
+ char *options = JS_strdup(cx, oldoptions);
731
+ int32 found = 0;
732
+
733
+ current = options;
734
+ for (;;) {
735
+ comma = strchr(current, ',');
736
+ if (comma) *comma = '\0';
737
+ equal = strchr(current, '=');
738
+ if (equal) *equal = '\0';
739
+ if (strcmp(current, name) == 0) {
740
+ if (!equal || strcmp(equal + 1, "yes") == 0)
741
+ found = 1;
742
+ else
743
+ found = atoi(equal + 1);
744
+ }
745
+ if (equal) *equal = '=';
746
+ if (comma) *comma = ',';
747
+ if (found || !comma)
748
+ break;
749
+ current = comma + 1;
750
+ }
751
+ JS_free(cx, options);
752
+ return found;
753
+ }
754
+
755
+ /* empty the buffer */
756
+ static void
757
+ js_ResetBuffers(JSFile * file)
758
+ {
759
+ file->charBufferUsed = JS_FALSE;
760
+ file->nbBytesInBuf = 0;
761
+ }
762
+
763
+ /* Reset file attributes */
764
+ static void
765
+ js_ResetAttributes(JSFile * file)
766
+ {
767
+ file->mode = file->type = 0;
768
+ file->isOpen = JS_FALSE;
769
+ file->handle = NULL;
770
+ file->nativehandle = NULL;
771
+ file->hasRandomAccess = JS_TRUE; /* Innocent until proven guilty. */
772
+ file->hasAutoflush = JS_FALSE;
773
+ file->isNative = JS_FALSE;
774
+ file->isPipe = JS_FALSE;
775
+
776
+ js_ResetBuffers(file);
777
+ }
778
+
779
+ static JSBool
780
+ js_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){
781
+ JSString *type, *mask;
782
+ jsval v[2];
783
+ jsval rval;
784
+
785
+ type = JS_InternString(cx, asciistring);
786
+ mask = JS_NewStringCopyZ(cx, mode);
787
+ v[0] = STRING_TO_JSVAL(mask);
788
+ v[1] = STRING_TO_JSVAL(type);
789
+
790
+ if (!file_open(cx, obj, 2, v, &rval))
791
+ return JS_FALSE;
792
+ return JS_TRUE;
793
+ }
794
+
795
+ /* Buffered version of PR_Read. Used by js_FileRead */
796
+ static int32
797
+ js_BufferedRead(JSFile *f, unsigned char *buf, int32 len)
798
+ {
799
+ int32 count = 0;
800
+
801
+ while (f->nbBytesInBuf>0&&len>0) {
802
+ buf[0] = f->byteBuffer[0];
803
+ f->byteBuffer[0] = f->byteBuffer[1];
804
+ f->byteBuffer[1] = f->byteBuffer[2];
805
+ f->nbBytesInBuf--;
806
+ len--;
807
+ buf+=1;
808
+ count++;
809
+ }
810
+
811
+ if (len > 0) {
812
+ count += (!f->isNative)
813
+ ? PR_Read(f->handle, buf, len)
814
+ : fread(buf, 1, len, f->nativehandle);
815
+ }
816
+ return count;
817
+ }
818
+
819
+ static int32
820
+ js_FileRead(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
821
+ {
822
+ unsigned char *aux;
823
+ int32 count = 0, i;
824
+ jsint remainder;
825
+ unsigned char utfbuf[3];
826
+
827
+ if (file->charBufferUsed) {
828
+ buf[0] = file->charBuffer;
829
+ buf++;
830
+ len--;
831
+ file->charBufferUsed = JS_FALSE;
832
+ }
833
+
834
+ switch (mode) {
835
+ case ASCII:
836
+ aux = (unsigned char*)JS_malloc(cx, len);
837
+ if (!aux)
838
+ return 0;
839
+
840
+ count = js_BufferedRead(file, aux, len);
841
+ if (count == -1) {
842
+ JS_free(cx, aux);
843
+ return 0;
844
+ }
845
+
846
+ for (i = 0; i < len; i++)
847
+ buf[i] = (jschar)aux[i];
848
+
849
+ JS_free(cx, aux);
850
+ break;
851
+
852
+ case UTF8:
853
+ remainder = 0;
854
+ for (count = 0;count<len;count++) {
855
+ i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
856
+ if (i<=0) {
857
+ return count;
858
+ }
859
+ i = utf8_to_ucs2_char(utfbuf, (int16)i, &buf[count] );
860
+ if (i<0) {
861
+ return count;
862
+ } else {
863
+ if (i==1) {
864
+ utfbuf[0] = utfbuf[1];
865
+ utfbuf[1] = utfbuf[2];
866
+ remainder = 2;
867
+ } else if (i==2) {
868
+ utfbuf[0] = utfbuf[2];
869
+ remainder = 1;
870
+ } else if (i==3) {
871
+ remainder = 0;
872
+ }
873
+ }
874
+ }
875
+ while (remainder>0) {
876
+ file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
877
+ file->nbBytesInBuf++;
878
+ utfbuf[0] = utfbuf[1];
879
+ utfbuf[1] = utfbuf[2];
880
+ remainder--;
881
+ }
882
+ break;
883
+
884
+ case UCS2:
885
+ count = js_BufferedRead(file, (unsigned char *)buf, len * 2) >> 1;
886
+ if (count == -1)
887
+ return 0;
888
+
889
+ break;
890
+
891
+ default:
892
+ /* Not reached. */
893
+ JS_ASSERT(0);
894
+ }
895
+
896
+ if(count == -1) {
897
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
898
+ JSFILEMSG_OP_FAILED, "read", file->path);
899
+ }
900
+
901
+ return count;
902
+ }
903
+
904
+ static int32
905
+ js_FileSeek(JSContext *cx, JSFile *file, int32 len, int32 mode)
906
+ {
907
+ int32 count = 0, i;
908
+ jsint remainder;
909
+ unsigned char utfbuf[3];
910
+ jschar tmp;
911
+
912
+ switch (mode) {
913
+ case ASCII:
914
+ count = PR_Seek(file->handle, len, PR_SEEK_CUR);
915
+ break;
916
+
917
+ case UTF8:
918
+ remainder = 0;
919
+ for (count = 0;count<len;count++) {
920
+ i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
921
+ if (i<=0) {
922
+ return 0;
923
+ }
924
+ i = utf8_to_ucs2_char(utfbuf, (int16)i, &tmp );
925
+ if (i<0) {
926
+ return 0;
927
+ } else {
928
+ if (i==1) {
929
+ utfbuf[0] = utfbuf[1];
930
+ utfbuf[1] = utfbuf[2];
931
+ remainder = 2;
932
+ } else if (i==2) {
933
+ utfbuf[0] = utfbuf[2];
934
+ remainder = 1;
935
+ } else if (i==3) {
936
+ remainder = 0;
937
+ }
938
+ }
939
+ }
940
+ while (remainder>0) {
941
+ file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
942
+ file->nbBytesInBuf++;
943
+ utfbuf[0] = utfbuf[1];
944
+ utfbuf[1] = utfbuf[2];
945
+ remainder--;
946
+ }
947
+ break;
948
+
949
+ case UCS2:
950
+ count = PR_Seek(file->handle, len*2, PR_SEEK_CUR)/2;
951
+ break;
952
+
953
+ default:
954
+ /* Not reached. */
955
+ JS_ASSERT(0);
956
+ }
957
+
958
+ if(count == -1) {
959
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
960
+ JSFILEMSG_OP_FAILED, "seek", file->path);
961
+ }
962
+
963
+ return count;
964
+ }
965
+
966
+ static int32
967
+ js_FileWrite(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
968
+ {
969
+ unsigned char *aux;
970
+ int32 count = 0, i, j;
971
+ unsigned char *utfbuf;
972
+
973
+ switch (mode) {
974
+ case ASCII:
975
+ aux = (unsigned char*)JS_malloc(cx, len);
976
+ if (!aux)
977
+ return 0;
978
+
979
+ for (i = 0; i<len; i++)
980
+ aux[i] = buf[i] % 256;
981
+
982
+ count = (!file->isNative)
983
+ ? PR_Write(file->handle, aux, len)
984
+ : fwrite(aux, 1, len, file->nativehandle);
985
+
986
+ if (count==-1) {
987
+ JS_free(cx, aux);
988
+ return 0;
989
+ }
990
+
991
+ JS_free(cx, aux);
992
+ break;
993
+
994
+ case UTF8:
995
+ utfbuf = (unsigned char*)JS_malloc(cx, len*3);
996
+ if (!utfbuf) return 0;
997
+ i = 0;
998
+ for (count = 0;count<len;count++) {
999
+ j = one_ucs2_to_utf8_char(utfbuf+i, utfbuf+len*3, buf[count]);
1000
+ if (j==-1) {
1001
+ JS_free(cx, utfbuf);
1002
+ return 0;
1003
+ }
1004
+ i+=j;
1005
+ }
1006
+ j = (!file->isNative)
1007
+ ? PR_Write(file->handle, utfbuf, i)
1008
+ : fwrite(utfbuf, 1, i, file->nativehandle);
1009
+
1010
+ if (j<i) {
1011
+ JS_free(cx, utfbuf);
1012
+ return 0;
1013
+ }
1014
+ JS_free(cx, utfbuf);
1015
+ break;
1016
+
1017
+ case UCS2:
1018
+ count = (!file->isNative)
1019
+ ? PR_Write(file->handle, buf, len*2) >> 1
1020
+ : fwrite(buf, 1, len*2, file->nativehandle) >> 1;
1021
+
1022
+ if (count == -1)
1023
+ return 0;
1024
+ break;
1025
+
1026
+ default:
1027
+ /* Not reached. */
1028
+ JS_ASSERT(0);
1029
+ }
1030
+
1031
+ if(count == -1) {
1032
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1033
+ JSFILEMSG_OP_FAILED, "write", file->path);
1034
+ }
1035
+
1036
+ return count;
1037
+ }
1038
+
1039
+ /* ----------------------------- Property checkers -------------------------- */
1040
+ static JSBool
1041
+ js_exists(JSContext *cx, JSFile *file)
1042
+ {
1043
+ if (file->isNative) {
1044
+ /* It doesn't make sense for a pipe of stdstream. */
1045
+ return JS_FALSE;
1046
+ }
1047
+
1048
+ return PR_Access(file->path, PR_ACCESS_EXISTS) == PR_SUCCESS;
1049
+ }
1050
+
1051
+ static JSBool
1052
+ js_canRead(JSContext *cx, JSFile *file)
1053
+ {
1054
+ if (!file->isNative) {
1055
+ if (file->isOpen && !(file->mode & PR_RDONLY))
1056
+ return JS_FALSE;
1057
+ return PR_Access(file->path, PR_ACCESS_READ_OK) == PR_SUCCESS;
1058
+ }
1059
+
1060
+ if (file->isPipe) {
1061
+ /* Is this pipe open for reading? */
1062
+ return file->path[0] == PIPE_SYMBOL;
1063
+ }
1064
+
1065
+ return !strcmp(file->path, STDINPUT_NAME);
1066
+ }
1067
+
1068
+ static JSBool
1069
+ js_canWrite(JSContext *cx, JSFile *file)
1070
+ {
1071
+ if (!file->isNative) {
1072
+ if (file->isOpen && !(file->mode & PR_WRONLY))
1073
+ return JS_FALSE;
1074
+ return PR_Access(file->path, PR_ACCESS_WRITE_OK) == PR_SUCCESS;
1075
+ }
1076
+
1077
+ if(file->isPipe) {
1078
+ /* Is this pipe open for writing? */
1079
+ return file->path[strlen(file->path)-1] == PIPE_SYMBOL;
1080
+ }
1081
+
1082
+ return !strcmp(file->path, STDOUTPUT_NAME) ||
1083
+ !strcmp(file->path, STDERROR_NAME);
1084
+ }
1085
+
1086
+ static JSBool
1087
+ js_isFile(JSContext *cx, JSFile *file)
1088
+ {
1089
+ if (!file->isNative) {
1090
+ PRFileInfo info;
1091
+
1092
+ if (file->isOpen
1093
+ ? PR_GetOpenFileInfo(file->handle, &info)
1094
+ : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
1095
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1096
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1097
+ return JS_FALSE;
1098
+ }
1099
+
1100
+ return info.type == PR_FILE_FILE;
1101
+ }
1102
+
1103
+ /* This doesn't make sense for a pipe of stdstream. */
1104
+ return JS_FALSE;
1105
+ }
1106
+
1107
+ static JSBool
1108
+ js_isDirectory(JSContext *cx, JSFile *file)
1109
+ {
1110
+ if(!file->isNative){
1111
+ PRFileInfo info;
1112
+
1113
+ /* Hack needed to get get_property to work. */
1114
+ if (!js_exists(cx, file))
1115
+ return JS_FALSE;
1116
+
1117
+ if (file->isOpen
1118
+ ? PR_GetOpenFileInfo(file->handle, &info)
1119
+ : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
1120
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1121
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1122
+ return JS_FALSE;
1123
+ }
1124
+
1125
+ return info.type == PR_FILE_DIRECTORY;
1126
+ }
1127
+
1128
+ /* This doesn't make sense for a pipe of stdstream. */
1129
+ return JS_FALSE;
1130
+ }
1131
+
1132
+ static jsval
1133
+ js_size(JSContext *cx, JSFile *file)
1134
+ {
1135
+ PRFileInfo info;
1136
+
1137
+ JSFILE_CHECK_NATIVE("size");
1138
+
1139
+ if (file->isOpen
1140
+ ? PR_GetOpenFileInfo(file->handle, &info)
1141
+ : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
1142
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1143
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1144
+ return JSVAL_VOID;
1145
+ }
1146
+
1147
+ return INT_TO_JSVAL(info.size);
1148
+
1149
+ out:
1150
+ return JSVAL_VOID;
1151
+ }
1152
+
1153
+ /*
1154
+ * Return the parent object
1155
+ */
1156
+ static JSBool
1157
+ js_parent(JSContext *cx, JSFile *file, jsval *resultp)
1158
+ {
1159
+ char *str;
1160
+
1161
+ /* Since we only care about pipes and native files, return NULL. */
1162
+ if (file->isNative) {
1163
+ *resultp = JSVAL_VOID;
1164
+ return JS_TRUE;
1165
+ }
1166
+
1167
+ str = js_fileDirectoryName(cx, file->path);
1168
+ if (!str)
1169
+ return JS_FALSE;
1170
+
1171
+ /* If the directory is equal to the original path, we're at the root. */
1172
+ if (!strcmp(file->path, str)) {
1173
+ *resultp = JSVAL_NULL;
1174
+ } else {
1175
+ JSObject *obj = js_NewFileObject(cx, str);
1176
+ if (!obj) {
1177
+ JS_free(cx, str);
1178
+ return JS_FALSE;
1179
+ }
1180
+ *resultp = OBJECT_TO_JSVAL(obj);
1181
+ }
1182
+
1183
+ JS_free(cx, str);
1184
+ return JS_TRUE;
1185
+ }
1186
+
1187
+ static JSBool
1188
+ js_name(JSContext *cx, JSFile *file, jsval *vp)
1189
+ {
1190
+ char *name;
1191
+ JSString *str;
1192
+
1193
+ if (file->isPipe) {
1194
+ *vp = JSVAL_VOID;
1195
+ return JS_TRUE;
1196
+ }
1197
+
1198
+ name = js_fileBaseName(cx, file->path);
1199
+ if (!name)
1200
+ return JS_FALSE;
1201
+
1202
+ str = JS_NewString(cx, name, strlen(name));
1203
+ if (!str) {
1204
+ JS_free(cx, name);
1205
+ return JS_FALSE;
1206
+ }
1207
+
1208
+ *vp = STRING_TO_JSVAL(str);
1209
+ return JS_TRUE;
1210
+ }
1211
+
1212
+ /* ------------------------------ File object methods ---------------------------- */
1213
+ static JSBool
1214
+ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1215
+ {
1216
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1217
+ JSString *strmode, *strtype;
1218
+ char *ctype, *mode;
1219
+ int32 mask, type;
1220
+ int len;
1221
+
1222
+ mode = NULL;
1223
+
1224
+ SECURITY_CHECK(cx, NULL, "open", file);
1225
+
1226
+ /* A native file that is already open */
1227
+ if(file->isOpen && file->isNative) {
1228
+ JS_ReportWarning(cx, "Native file %s is already open, proceeding",
1229
+ file->path);
1230
+ goto good;
1231
+ }
1232
+
1233
+ /* Close before proceeding */
1234
+ if (file->isOpen) {
1235
+ JS_ReportWarning(cx, "File %s is already open, we will close it and "
1236
+ "reopen, proceeding", file->path);
1237
+ if(!file_close(cx, obj, 0, NULL, rval))
1238
+ goto out;
1239
+ }
1240
+
1241
+ if (js_isDirectory(cx, file)) {
1242
+ JS_ReportWarning(cx, "%s seems to be a directory, there is no point in "
1243
+ "trying to open it, proceeding", file->path);
1244
+ goto good;
1245
+ }
1246
+
1247
+ /* Path must be defined at this point */
1248
+ len = strlen(file->path);
1249
+
1250
+ /* Mode */
1251
+ if (argc >= 1) {
1252
+ strmode = JS_ValueToString(cx, argv[0]);
1253
+ if (!strmode) {
1254
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1255
+ JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR,
1256
+ argv[0]);
1257
+ goto out;
1258
+ }
1259
+ mode = JS_strdup(cx, JS_GetStringBytes(strmode));
1260
+ } else {
1261
+ if(file->path[0]==PIPE_SYMBOL) {
1262
+ /* pipe default mode */
1263
+ mode = JS_strdup(cx, "read");
1264
+ } else if(file->path[len-1]==PIPE_SYMBOL) {
1265
+ /* pipe default mode */
1266
+ mode = JS_strdup(cx, "write");
1267
+ } else {
1268
+ /* non-destructive, permissive defaults. */
1269
+ mode = JS_strdup(cx, "readWrite,append,create");
1270
+ }
1271
+ }
1272
+
1273
+ /* Process the mode */
1274
+ mask = 0;
1275
+ /* TODO: this is pretty ugly, we walk thru the string too many times */
1276
+ mask |= js_FileHasOption(cx, mode, "read") ? PR_RDONLY : 0;
1277
+ mask |= js_FileHasOption(cx, mode, "write") ? PR_WRONLY : 0;
1278
+ mask |= js_FileHasOption(cx, mode, "readWrite")? PR_RDWR : 0;
1279
+ mask |= js_FileHasOption(cx, mode, "append") ? PR_APPEND : 0;
1280
+ mask |= js_FileHasOption(cx, mode, "create") ? PR_CREATE_FILE : 0;
1281
+ mask |= js_FileHasOption(cx, mode, "replace") ? PR_TRUNCATE : 0;
1282
+
1283
+ if (mask & PR_RDWR)
1284
+ mask |= (PR_RDONLY | PR_WRONLY);
1285
+ if ((mask & PR_RDONLY) && (mask & PR_WRONLY))
1286
+ mask |= PR_RDWR;
1287
+
1288
+ file->hasAutoflush |= js_FileHasOption(cx, mode, "autoflush");
1289
+
1290
+ /* Type */
1291
+ if (argc > 1) {
1292
+ strtype = JS_ValueToString(cx, argv[1]);
1293
+ if (!strtype) {
1294
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1295
+ JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR,
1296
+ argv[1]);
1297
+ goto out;
1298
+ }
1299
+ ctype = JS_GetStringBytes(strtype);
1300
+
1301
+ if(!strcmp(ctype, utfstring)) {
1302
+ type = UTF8;
1303
+ } else if (!strcmp(ctype, unicodestring)) {
1304
+ type = UCS2;
1305
+ } else {
1306
+ if (strcmp(ctype, asciistring)) {
1307
+ JS_ReportWarning(cx, "File type %s is not supported, using "
1308
+ "'text' instead, proceeding", ctype);
1309
+ }
1310
+ type = ASCII;
1311
+ }
1312
+ } else {
1313
+ type = ASCII;
1314
+ }
1315
+
1316
+ /* Save the relevant fields */
1317
+ file->type = type;
1318
+ file->mode = mask;
1319
+ file->nativehandle = NULL;
1320
+ file->hasRandomAccess = (type != UTF8);
1321
+
1322
+ /*
1323
+ * Deal with pipes here. We can't use NSPR for pipes, so we have to use
1324
+ * POPEN.
1325
+ */
1326
+ if (file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL) {
1327
+ if (file->path[0] == PIPE_SYMBOL && file->path[len-1] == PIPE_SYMBOL) {
1328
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1329
+ JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
1330
+ goto out;
1331
+ } else {
1332
+ int i = 0;
1333
+ char pipemode[3];
1334
+ SECURITY_CHECK(cx, NULL, "pipe_open", file);
1335
+
1336
+ if(file->path[0] == PIPE_SYMBOL){
1337
+ if(mask & (PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE)){
1338
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1339
+ JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
1340
+ mode, file->path);
1341
+ goto out;
1342
+ }
1343
+ /* open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") -- pipe for writing */
1344
+ pipemode[i++] = 'r';
1345
+ #ifndef XP_UNIX
1346
+ pipemode[i++] = file->type==UTF8 ? 'b' : 't';
1347
+ #endif
1348
+ pipemode[i++] = '\0';
1349
+ file->nativehandle = POPEN(&file->path[1], pipemode);
1350
+ } else if(file->path[len-1] == PIPE_SYMBOL) {
1351
+ char *command = JS_malloc(cx, len);
1352
+
1353
+ strncpy(command, file->path, len-1);
1354
+ command[len-1] = '\0';
1355
+ /* open(STATUS, "netstat -an 2>&1 |") */
1356
+ pipemode[i++] = 'w';
1357
+ #ifndef XP_UNIX
1358
+ pipemode[i++] = file->type==UTF8 ? 'b' : 't';
1359
+ #endif
1360
+ pipemode[i++] = '\0';
1361
+ file->nativehandle = POPEN(command, pipemode);
1362
+ JS_free(cx, command);
1363
+ }
1364
+ /* set the flags */
1365
+ file->isNative = JS_TRUE;
1366
+ file->isPipe = JS_TRUE;
1367
+ file->hasRandomAccess = JS_FALSE;
1368
+ }
1369
+ } else {
1370
+ /* TODO: what about the permissions?? Java ignores the problem... */
1371
+ file->handle = PR_Open(file->path, mask, 0644);
1372
+ }
1373
+
1374
+ js_ResetBuffers(file);
1375
+ JS_free(cx, mode);
1376
+ mode = NULL;
1377
+
1378
+ /* Set the open flag and return result */
1379
+ if (file->handle == NULL && file->nativehandle == NULL) {
1380
+ file->isOpen = JS_FALSE;
1381
+
1382
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1383
+ JSFILEMSG_OP_FAILED, "open", file->path);
1384
+ goto out;
1385
+ }
1386
+
1387
+ good:
1388
+ file->isOpen = JS_TRUE;
1389
+ *rval = JSVAL_TRUE;
1390
+ return JS_TRUE;
1391
+
1392
+ out:
1393
+ if(mode)
1394
+ JS_free(cx, mode);
1395
+ return JS_FALSE;
1396
+ }
1397
+
1398
+ static JSBool
1399
+ file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1400
+ {
1401
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1402
+
1403
+ SECURITY_CHECK(cx, NULL, "close", file);
1404
+
1405
+ if(!file->isOpen){
1406
+ JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding",
1407
+ file->path);
1408
+ goto out;
1409
+ }
1410
+
1411
+ if(!file->isPipe){
1412
+ if(file->isNative){
1413
+ JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path);
1414
+ goto out;
1415
+ }else{
1416
+ if(file->handle && PR_Close(file->handle)){
1417
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1418
+ JSFILEMSG_OP_FAILED, "close", file->path);
1419
+
1420
+ goto out;
1421
+ }
1422
+ }
1423
+ }else{
1424
+ if(PCLOSE(file->nativehandle)==-1){
1425
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1426
+ JSFILEMSG_OP_FAILED, "pclose", file->path);
1427
+ goto out;
1428
+ }
1429
+ }
1430
+
1431
+ js_ResetAttributes(file);
1432
+ *rval = JSVAL_TRUE;
1433
+ return JS_TRUE;
1434
+
1435
+ out:
1436
+ return JS_FALSE;
1437
+ }
1438
+
1439
+
1440
+ static JSBool
1441
+ file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1442
+ {
1443
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1444
+
1445
+ SECURITY_CHECK(cx, NULL, "remove", file);
1446
+ JSFILE_CHECK_NATIVE("remove");
1447
+ JSFILE_CHECK_CLOSED("remove");
1448
+
1449
+ if ((js_isDirectory(cx, file) ?
1450
+ PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
1451
+ js_ResetAttributes(file);
1452
+ *rval = JSVAL_TRUE;
1453
+ return JS_TRUE;
1454
+ } else {
1455
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1456
+ JSFILEMSG_OP_FAILED, "remove", file->path);
1457
+ goto out;
1458
+ }
1459
+ out:
1460
+ *rval = JSVAL_FALSE;
1461
+ return JS_FALSE;
1462
+ }
1463
+
1464
+ /* Raw PR-based function. No text processing. Just raw data copying. */
1465
+ static JSBool
1466
+ file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1467
+ {
1468
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1469
+ char *dest = NULL;
1470
+ PRFileDesc *handle = NULL;
1471
+ char *buffer;
1472
+ jsval count, size;
1473
+ JSBool fileInitiallyOpen=JS_FALSE;
1474
+
1475
+ SECURITY_CHECK(cx, NULL, "copyTo", file); /* may need a second argument!*/
1476
+ JSFILE_CHECK_ONE_ARG("copyTo");
1477
+ JSFILE_CHECK_NATIVE("copyTo");
1478
+ /* remeber the state */
1479
+ fileInitiallyOpen = file->isOpen;
1480
+ JSFILE_CHECK_READ;
1481
+
1482
+ dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
1483
+
1484
+ /* make sure we are not reading a file open for writing */
1485
+ if (file->isOpen && !js_canRead(cx, file)) {
1486
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1487
+ JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path);
1488
+ goto out;
1489
+ }
1490
+
1491
+ if (file->handle==NULL){
1492
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1493
+ JSFILEMSG_OP_FAILED, "open", file->path);
1494
+ goto out;
1495
+ }
1496
+
1497
+ handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644);
1498
+
1499
+ if(!handle){
1500
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1501
+ JSFILEMSG_OP_FAILED, "open", dest);
1502
+ goto out;
1503
+ }
1504
+
1505
+ if ((size=js_size(cx, file))==JSVAL_VOID) {
1506
+ goto out;
1507
+ }
1508
+
1509
+ buffer = JS_malloc(cx, size);
1510
+
1511
+ count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size));
1512
+
1513
+ /* reading panic */
1514
+ if (count!=size) {
1515
+ JS_free(cx, buffer);
1516
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1517
+ JSFILEMSG_COPY_READ_ERROR, file->path);
1518
+ goto out;
1519
+ }
1520
+
1521
+ count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size)));
1522
+
1523
+ /* writing panic */
1524
+ if (count!=size) {
1525
+ JS_free(cx, buffer);
1526
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1527
+ JSFILEMSG_COPY_WRITE_ERROR, file->path);
1528
+ goto out;
1529
+ }
1530
+
1531
+ JS_free(cx, buffer);
1532
+
1533
+ if(!fileInitiallyOpen){
1534
+ if(!file_close(cx, obj, 0, NULL, rval)) goto out;
1535
+ }
1536
+
1537
+ if(PR_Close(handle)!=PR_SUCCESS){
1538
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1539
+ JSFILEMSG_OP_FAILED, "close", dest);
1540
+ goto out;
1541
+ }
1542
+
1543
+ *rval = JSVAL_TRUE;
1544
+ return JS_TRUE;
1545
+ out:
1546
+ if(file->isOpen && !fileInitiallyOpen){
1547
+ if(PR_Close(file->handle)!=PR_SUCCESS){
1548
+ JS_ReportWarning(cx, "Can't close %s, proceeding", file->path);
1549
+ }
1550
+ }
1551
+
1552
+ if(handle && PR_Close(handle)!=PR_SUCCESS){
1553
+ JS_ReportWarning(cx, "Can't close %s, proceeding", dest);
1554
+ }
1555
+
1556
+ *rval = JSVAL_FALSE;
1557
+ return JS_FALSE;
1558
+ }
1559
+
1560
+ static JSBool
1561
+ file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1562
+ {
1563
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1564
+ char *dest;
1565
+
1566
+ SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/
1567
+ JSFILE_CHECK_ONE_ARG("renameTo");
1568
+ JSFILE_CHECK_NATIVE("renameTo");
1569
+ JSFILE_CHECK_CLOSED("renameTo");
1570
+
1571
+ dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
1572
+
1573
+ if (PR_Rename(file->path, dest)==PR_SUCCESS){
1574
+ /* copy the new filename */
1575
+ JS_free(cx, file->path);
1576
+ file->path = dest;
1577
+ *rval = JSVAL_TRUE;
1578
+ return JS_TRUE;
1579
+ }else{
1580
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1581
+ JSFILEMSG_RENAME_FAILED, file->path, dest);
1582
+ goto out;
1583
+ }
1584
+ out:
1585
+ *rval = JSVAL_FALSE;
1586
+ return JS_FALSE;
1587
+ }
1588
+
1589
+ static JSBool
1590
+ file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1591
+ {
1592
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1593
+
1594
+ SECURITY_CHECK(cx, NULL, "flush", file);
1595
+ JSFILE_CHECK_NATIVE("flush");
1596
+ JSFILE_CHECK_OPEN("flush");
1597
+
1598
+ if (PR_Sync(file->handle)==PR_SUCCESS){
1599
+ *rval = JSVAL_TRUE;
1600
+ return JS_TRUE;
1601
+ }else{
1602
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1603
+ JSFILEMSG_OP_FAILED, "flush", file->path);
1604
+ goto out;
1605
+ }
1606
+ out:
1607
+ *rval = JSVAL_FALSE;
1608
+ return JS_FALSE;
1609
+ }
1610
+
1611
+ static JSBool
1612
+ file_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1613
+ {
1614
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1615
+ JSString *str;
1616
+ int32 count;
1617
+ uintN i;
1618
+
1619
+ SECURITY_CHECK(cx, NULL, "write", file);
1620
+ JSFILE_CHECK_WRITE;
1621
+
1622
+ for (i = 0; i<argc; i++) {
1623
+ str = JS_ValueToString(cx, argv[i]);
1624
+ count = js_FileWrite(cx, file, JS_GetStringChars(str),
1625
+ JS_GetStringLength(str), file->type);
1626
+ if (count==-1){
1627
+ *rval = JSVAL_FALSE;
1628
+ return JS_FALSE;
1629
+ }
1630
+ }
1631
+
1632
+ *rval = JSVAL_TRUE;
1633
+ return JS_TRUE;
1634
+ out:
1635
+ *rval = JSVAL_FALSE;
1636
+ return JS_FALSE;
1637
+ }
1638
+
1639
+ static JSBool
1640
+ file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1641
+ {
1642
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1643
+ JSString *str;
1644
+
1645
+ SECURITY_CHECK(cx, NULL, "writeln", file);
1646
+ JSFILE_CHECK_WRITE;
1647
+
1648
+ /* don't report an error here */
1649
+ if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE;
1650
+ /* don't do security here -- we passed the check in file_write */
1651
+ str = JS_NewStringCopyZ(cx, "\n");
1652
+
1653
+ if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str),
1654
+ file->type)==-1){
1655
+ *rval = JSVAL_FALSE;
1656
+ return JS_FALSE;
1657
+ }
1658
+
1659
+ /* eol causes flush if hasAutoflush is turned on */
1660
+ if (file->hasAutoflush)
1661
+ file_flush(cx, obj, 0, NULL, rval);
1662
+
1663
+ *rval = JSVAL_TRUE;
1664
+ return JS_TRUE;
1665
+ out:
1666
+ *rval = JSVAL_FALSE;
1667
+ return JS_FALSE;
1668
+ }
1669
+
1670
+ static JSBool
1671
+ file_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1672
+ {
1673
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1674
+ jsuint i;
1675
+ jsuint limit;
1676
+ JSObject *array;
1677
+ JSObject *elem;
1678
+ jsval elemval;
1679
+
1680
+ SECURITY_CHECK(cx, NULL, "writeAll", file);
1681
+ JSFILE_CHECK_ONE_ARG("writeAll");
1682
+ JSFILE_CHECK_WRITE;
1683
+
1684
+ if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) {
1685
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1686
+ JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR);
1687
+ goto out;
1688
+ }
1689
+
1690
+ array = JSVAL_TO_OBJECT(argv[0]);
1691
+
1692
+ JS_GetArrayLength(cx, array, &limit);
1693
+
1694
+ for (i = 0; i<limit; i++) {
1695
+ if (!JS_GetElement(cx, array, i, &elemval)) return JS_FALSE;
1696
+ elem = JSVAL_TO_OBJECT(elemval);
1697
+ file_writeln(cx, obj, 1, &elemval, rval);
1698
+ }
1699
+
1700
+ *rval = JSVAL_TRUE;
1701
+ return JS_TRUE;
1702
+ out:
1703
+ *rval = JSVAL_FALSE;
1704
+ return JS_FALSE;
1705
+ }
1706
+
1707
+ static JSBool
1708
+ file_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1709
+ {
1710
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1711
+ JSString *str;
1712
+ int32 want, count;
1713
+ jschar *buf;
1714
+
1715
+ SECURITY_CHECK(cx, NULL, "read", file);
1716
+ JSFILE_CHECK_ONE_ARG("read");
1717
+ JSFILE_CHECK_READ;
1718
+
1719
+ if (!JS_ValueToInt32(cx, argv[0], &want)){
1720
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1721
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "read", argv[0]);
1722
+ goto out;
1723
+ }
1724
+
1725
+ /* want = (want>262144)?262144:want; * arbitrary size limitation */
1726
+
1727
+ buf = JS_malloc(cx, want*sizeof buf[0]);
1728
+ if (!buf) goto out;
1729
+
1730
+ count = js_FileRead(cx, file, buf, want, file->type);
1731
+ if (count>0) {
1732
+ str = JS_NewUCStringCopyN(cx, buf, count);
1733
+ *rval = STRING_TO_JSVAL(str);
1734
+ JS_free(cx, buf);
1735
+ return JS_TRUE;
1736
+ } else {
1737
+ JS_free(cx, buf);
1738
+ goto out;
1739
+ }
1740
+ out:
1741
+ *rval = JSVAL_FALSE;
1742
+ return JS_FALSE;
1743
+ }
1744
+
1745
+ static JSBool
1746
+ file_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1747
+ {
1748
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1749
+ JSString *str;
1750
+ jschar *buf = NULL, *tmp;
1751
+ int32 offset, read;
1752
+ intN room;
1753
+ jschar data, data2;
1754
+
1755
+ SECURITY_CHECK(cx, NULL, "readln", file);
1756
+ JSFILE_CHECK_READ;
1757
+
1758
+ buf = JS_malloc(cx, MAX_LINE_LENGTH * sizeof data);
1759
+ if (!buf)
1760
+ return JS_FALSE;
1761
+
1762
+ room = MAX_LINE_LENGTH - 1;
1763
+ offset = 0;
1764
+
1765
+ for (;;) {
1766
+ read = js_FileRead(cx, file, &data, 1, file->type);
1767
+ if (read < 0)
1768
+ goto out;
1769
+ if (read == 0)
1770
+ goto eof;
1771
+
1772
+ switch (data) {
1773
+ case '\r':
1774
+ read = js_FileRead(cx, file, &data2, 1, file->type);
1775
+ if (read < 0)
1776
+ goto out;
1777
+
1778
+ if (read == 1 && data2 != '\n') {
1779
+ /* We read one char too far. Buffer it. */
1780
+ file->charBuffer = data2;
1781
+ file->charBufferUsed = JS_TRUE;
1782
+ }
1783
+
1784
+ /* Fall through. */
1785
+ case '\n':
1786
+ goto done;
1787
+
1788
+ default:
1789
+ if (--room < 0) {
1790
+ tmp = JS_realloc(cx, buf,
1791
+ (offset + MAX_LINE_LENGTH) * sizeof data);
1792
+ if (!tmp)
1793
+ goto out;
1794
+
1795
+ room = MAX_LINE_LENGTH - 1;
1796
+ buf = tmp;
1797
+ }
1798
+
1799
+ buf[offset++] = data;
1800
+ break;
1801
+ }
1802
+ }
1803
+
1804
+ eof:
1805
+ if (offset == 0) {
1806
+ *rval = JSVAL_NULL;
1807
+ return JS_TRUE;
1808
+ }
1809
+
1810
+ done:
1811
+ buf[offset] = 0;
1812
+ tmp = JS_realloc(cx, buf, (offset + 1) * sizeof data);
1813
+ if (!tmp)
1814
+ goto out;
1815
+
1816
+ str = JS_NewUCString(cx, tmp, offset);
1817
+ if (!str)
1818
+ goto out;
1819
+
1820
+ *rval = STRING_TO_JSVAL(str);
1821
+ return JS_TRUE;
1822
+
1823
+ out:
1824
+ if (buf)
1825
+ JS_free(cx, buf);
1826
+
1827
+ return JS_FALSE;
1828
+ }
1829
+
1830
+ static JSBool
1831
+ file_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1832
+ {
1833
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1834
+ JSObject *array;
1835
+ jsint len;
1836
+ jsval line;
1837
+ JSBool lineok = JS_FALSE;
1838
+
1839
+ SECURITY_CHECK(cx, NULL, "readAll", file);
1840
+ JSFILE_CHECK_READ;
1841
+
1842
+ array = JS_NewArrayObject(cx, 0, NULL);
1843
+ if (!array)
1844
+ return JS_FALSE;
1845
+ *rval = OBJECT_TO_JSVAL(array);
1846
+
1847
+ len = 0;
1848
+
1849
+ lineok = file_readln(cx, obj, 0, NULL, &line);
1850
+ while (lineok && !JSVAL_IS_NULL(line)) {
1851
+ JS_SetElement(cx, array, len++, &line);
1852
+ lineok = file_readln(cx, obj, 0, NULL, &line);
1853
+ }
1854
+
1855
+ out:
1856
+ return lineok;
1857
+ }
1858
+
1859
+ static JSBool
1860
+ file_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1861
+ {
1862
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1863
+ int32 toskip;
1864
+ int32 pos;
1865
+
1866
+ SECURITY_CHECK(cx, NULL, "seek", file);
1867
+ JSFILE_CHECK_ONE_ARG("seek");
1868
+ JSFILE_CHECK_NATIVE("seek");
1869
+ JSFILE_CHECK_READ;
1870
+
1871
+ if (!JS_ValueToInt32(cx, argv[0], &toskip)){
1872
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1873
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "seek", argv[0]);
1874
+ goto out;
1875
+ }
1876
+
1877
+ if(!file->hasRandomAccess){
1878
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1879
+ JSFILEMSG_NO_RANDOM_ACCESS, file->path);
1880
+ goto out;
1881
+ }
1882
+
1883
+ if(js_isDirectory(cx, file)){
1884
+ JS_ReportWarning(cx,"Seek on directories is not supported, proceeding");
1885
+ goto out;
1886
+ }
1887
+
1888
+ pos = js_FileSeek(cx, file, toskip, file->type);
1889
+
1890
+ if (pos!=-1) {
1891
+ *rval = INT_TO_JSVAL(pos);
1892
+ return JS_TRUE;
1893
+ }
1894
+ out:
1895
+ *rval = JSVAL_VOID;
1896
+ return JS_FALSE;
1897
+ }
1898
+
1899
+ static JSBool
1900
+ file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1901
+ {
1902
+ PRDir *dir;
1903
+ PRDirEntry *entry;
1904
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
1905
+ JSObject *array;
1906
+ JSObject *eachFile;
1907
+ jsint len;
1908
+ jsval v;
1909
+ JSRegExp *re = NULL;
1910
+ JSFunction *func = NULL;
1911
+ JSString *str;
1912
+ jsval args[1];
1913
+ char *filePath;
1914
+
1915
+ SECURITY_CHECK(cx, NULL, "list", file);
1916
+ JSFILE_CHECK_NATIVE("list");
1917
+
1918
+ if (argc==1) {
1919
+ if (VALUE_IS_REGEXP(cx, argv[0])) {
1920
+ re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
1921
+ }else
1922
+ if (VALUE_IS_FUNCTION(cx, argv[0])) {
1923
+ func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
1924
+ }else{
1925
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1926
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, argv[0]);
1927
+ goto out;
1928
+ }
1929
+ }
1930
+
1931
+ if (!js_isDirectory(cx, file)) {
1932
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1933
+ JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, file->path);
1934
+ goto out;
1935
+ }
1936
+
1937
+ dir = PR_OpenDir(file->path);
1938
+ if(!dir){
1939
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1940
+ JSFILEMSG_OP_FAILED, "open", file->path);
1941
+ goto out;
1942
+ }
1943
+
1944
+ /* create JSArray here... */
1945
+ array = JS_NewArrayObject(cx, 0, NULL);
1946
+ len = 0;
1947
+
1948
+ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) {
1949
+ /* first, check if we have a regexp */
1950
+ if (re!=NULL) {
1951
+ size_t index = 0;
1952
+
1953
+ str = JS_NewStringCopyZ(cx, entry->name);
1954
+ if(!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &v)){
1955
+ /* don't report anything here */
1956
+ goto out;
1957
+ }
1958
+ /* not matched! */
1959
+ if (JSVAL_IS_NULL(v)) {
1960
+ continue;
1961
+ }
1962
+ }else
1963
+ if (func!=NULL) {
1964
+ str = JS_NewStringCopyZ(cx, entry->name);
1965
+ args[0] = STRING_TO_JSVAL(str);
1966
+ if(!JS_CallFunction(cx, obj, func, 1, args, &v)){
1967
+ goto out;
1968
+ }
1969
+
1970
+ if (v==JSVAL_FALSE) {
1971
+ continue;
1972
+ }
1973
+ }
1974
+
1975
+ filePath = js_combinePath(cx, file->path, (char*)entry->name);
1976
+
1977
+ eachFile = js_NewFileObject(cx, filePath);
1978
+ JS_free(cx, filePath);
1979
+ if (!eachFile){
1980
+ JS_ReportWarning(cx, "File %s cannot be retrieved", filePath);
1981
+ continue;
1982
+ }
1983
+ v = OBJECT_TO_JSVAL(eachFile);
1984
+ JS_SetElement(cx, array, len, &v);
1985
+ JS_SetProperty(cx, array, entry->name, &v);
1986
+ len++;
1987
+ }
1988
+
1989
+ if(PR_CloseDir(dir)!=PR_SUCCESS){
1990
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1991
+ JSFILEMSG_OP_FAILED, "close", file->path);
1992
+ goto out;
1993
+ }
1994
+ *rval = OBJECT_TO_JSVAL(array);
1995
+ return JS_TRUE;
1996
+ out:
1997
+ *rval = JSVAL_NULL;
1998
+ return JS_FALSE;
1999
+ }
2000
+
2001
+ static JSBool
2002
+ file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2003
+ {
2004
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2005
+
2006
+ SECURITY_CHECK(cx, NULL, "mkdir", file);
2007
+ JSFILE_CHECK_ONE_ARG("mkdir");
2008
+ JSFILE_CHECK_NATIVE("mkdir");
2009
+
2010
+ /* if the current file is not a directory, find out the directory name */
2011
+ if (!js_isDirectory(cx, file)) {
2012
+ char *dir = js_fileDirectoryName(cx, file->path);
2013
+ JSObject *dirObj = js_NewFileObject(cx, dir);
2014
+
2015
+ JS_free(cx, dir);
2016
+
2017
+ /* call file_mkdir with the right set of parameters if needed */
2018
+ if (file_mkdir(cx, dirObj, argc, argv, rval))
2019
+ return JS_TRUE;
2020
+ else
2021
+ goto out;
2022
+ }else{
2023
+ char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
2024
+ char *fullName;
2025
+
2026
+ fullName = js_combinePath(cx, file->path, dirName);
2027
+ if (PR_MkDir(fullName, 0755)==PR_SUCCESS){
2028
+ *rval = JSVAL_TRUE;
2029
+ JS_free(cx, fullName);
2030
+ return JS_TRUE;
2031
+ }else{
2032
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2033
+ JSFILEMSG_OP_FAILED, "mkdir", fullName);
2034
+ JS_free(cx, fullName);
2035
+ goto out;
2036
+ }
2037
+ }
2038
+ out:
2039
+ *rval = JSVAL_FALSE;
2040
+ return JS_FALSE;
2041
+ }
2042
+
2043
+ static JSBool
2044
+ file_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*rval)
2045
+ {
2046
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2047
+ JSString *str;
2048
+
2049
+ str = JS_NewStringCopyZ(cx, file->path);
2050
+ if (!str)
2051
+ return JS_FALSE;
2052
+ *rval = STRING_TO_JSVAL(str);
2053
+ return JS_TRUE;
2054
+ }
2055
+
2056
+ static JSBool
2057
+ file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2058
+ {
2059
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2060
+ char url[MAX_PATH_LENGTH];
2061
+ jschar *urlChars;
2062
+ size_t len;
2063
+ JSString *str;
2064
+
2065
+ JSFILE_CHECK_NATIVE("toURL");
2066
+
2067
+ sprintf(url, "file://%s", file->path);
2068
+
2069
+ len = strlen(url);
2070
+ urlChars = js_InflateString(cx, url, &len);
2071
+ if (!urlChars)
2072
+ return JS_FALSE;
2073
+ str = js_NewString(cx, urlChars, len);
2074
+ if (!str) {
2075
+ JS_free(cx, urlChars);
2076
+ return JS_FALSE;
2077
+ }
2078
+ *rval = STRING_TO_JSVAL(str);
2079
+
2080
+ /* TODO: js_escape in jsstr.h may go away at some point */
2081
+ return js_str_escape(cx, obj, 0, rval, rval);
2082
+
2083
+ out:
2084
+ *rval = JSVAL_VOID;
2085
+ return JS_FALSE;
2086
+ }
2087
+
2088
+
2089
+ static void
2090
+ file_finalize(JSContext *cx, JSObject *obj)
2091
+ {
2092
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2093
+
2094
+ if(file) {
2095
+ /* Close the file before exiting. */
2096
+ if(file->isOpen && !file->isNative) {
2097
+ jsval vp;
2098
+ file_close(cx, obj, 0, NULL, &vp);
2099
+ }
2100
+
2101
+ if (file->path)
2102
+ JS_free(cx, file->path);
2103
+
2104
+ JS_free(cx, file);
2105
+ }
2106
+ }
2107
+
2108
+ /*
2109
+ Allocates memory for the file object, sets fields to defaults.
2110
+ */
2111
+ static JSFile*
2112
+ file_init(JSContext *cx, JSObject *obj, char *bytes)
2113
+ {
2114
+ JSFile *file;
2115
+
2116
+ file = JS_malloc(cx, sizeof *file);
2117
+ if (!file)
2118
+ return NULL;
2119
+ memset(file, 0 , sizeof *file);
2120
+
2121
+ js_ResetAttributes(file);
2122
+
2123
+ file->path = RESOLVE_PATH(cx, bytes);
2124
+
2125
+ if (!JS_SetPrivate(cx, obj, file)) {
2126
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2127
+ JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
2128
+ JS_free(cx, file);
2129
+ return NULL;
2130
+ }
2131
+
2132
+ return file;
2133
+ }
2134
+
2135
+ /* Returns a JSObject. This function is globally visible */
2136
+ JS_PUBLIC_API(JSObject*)
2137
+ js_NewFileObject(JSContext *cx, char *filename)
2138
+ {
2139
+ JSObject *obj;
2140
+ JSFile *file;
2141
+
2142
+ obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
2143
+ if (!obj){
2144
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2145
+ JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObject");
2146
+ return NULL;
2147
+ }
2148
+ file = file_init(cx, obj, filename);
2149
+ if(!file) return NULL;
2150
+ return obj;
2151
+ }
2152
+
2153
+ /* Internal function, used for cases which NSPR file support doesn't cover */
2154
+ JSObject*
2155
+ js_NewFileObjectFromFILE(JSContext *cx, FILE *nativehandle, char *filename,
2156
+ int32 mode, JSBool open, JSBool randomAccess)
2157
+ {
2158
+ JSObject *obj;
2159
+ JSFile *file;
2160
+
2161
+ obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
2162
+ if (!obj){
2163
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2164
+ JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObjectFromFILE");
2165
+ return NULL;
2166
+ }
2167
+ file = file_init(cx, obj, filename);
2168
+ if(!file) return NULL;
2169
+
2170
+ file->nativehandle = nativehandle;
2171
+
2172
+ /* free result of RESOLVE_PATH from file_init. */
2173
+ JS_ASSERT(file->path != NULL);
2174
+ JS_free(cx, file->path);
2175
+
2176
+ file->path = strdup(filename);
2177
+ file->isOpen = open;
2178
+ file->mode = mode;
2179
+ file->hasRandomAccess = randomAccess;
2180
+ file->isNative = JS_TRUE;
2181
+ return obj;
2182
+ }
2183
+
2184
+ /*
2185
+ Real file constructor that is called from JavaScript.
2186
+ Basically, does error processing and calls file_init.
2187
+ */
2188
+ static JSBool
2189
+ file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
2190
+ jsval *rval)
2191
+ {
2192
+ JSString *str;
2193
+ JSFile *file;
2194
+
2195
+ if (!JS_IsConstructing(cx)) {
2196
+ /* Replace obj with a new File object. */
2197
+ obj = JS_NewObject(cx, &js_FileClass, NULL, NULL);
2198
+ if (!obj)
2199
+ return JS_FALSE;
2200
+ *rval = OBJECT_TO_JSVAL(obj);
2201
+ }
2202
+
2203
+ str = (argc == 0)
2204
+ ? JS_InternString(cx, "")
2205
+ : JS_ValueToString(cx, argv[0]);
2206
+
2207
+ if (!str) {
2208
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2209
+ JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR,
2210
+ argv[0]);
2211
+ return JS_FALSE;
2212
+ }
2213
+
2214
+ file = file_init(cx, obj, JS_GetStringBytes(str));
2215
+ if (!file)
2216
+ return JS_FALSE;
2217
+
2218
+ SECURITY_CHECK(cx, NULL, "constructor", file);
2219
+
2220
+ return JS_TRUE;
2221
+ }
2222
+
2223
+ /* -------------------- File methods and properties ------------------------- */
2224
+ static JSFunctionSpec file_functions[] = {
2225
+ { "open", file_open, 0},
2226
+ { "close", file_close, 0},
2227
+ { "remove", file_remove, 0},
2228
+ { "copyTo", file_copyTo, 0},
2229
+ { "renameTo", file_renameTo, 0},
2230
+ { "flush", file_flush, 0},
2231
+ { "seek", file_seek, 0},
2232
+ { "read", file_read, 0},
2233
+ { "readln", file_readln, 0},
2234
+ { "readAll", file_readAll, 0},
2235
+ { "write", file_write, 0},
2236
+ { "writeln", file_writeln, 0},
2237
+ { "writeAll", file_writeAll, 0},
2238
+ { "list", file_list, 0},
2239
+ { "mkdir", file_mkdir, 0},
2240
+ { "toString", file_toString, 0},
2241
+ { "toURL", file_toURL, 0},
2242
+ {0}
2243
+ };
2244
+
2245
+ enum file_tinyid {
2246
+ FILE_LENGTH = -2,
2247
+ FILE_PARENT = -3,
2248
+ FILE_PATH = -4,
2249
+ FILE_NAME = -5,
2250
+ FILE_ISDIR = -6,
2251
+ FILE_ISFILE = -7,
2252
+ FILE_EXISTS = -8,
2253
+ FILE_CANREAD = -9,
2254
+ FILE_CANWRITE = -10,
2255
+ FILE_OPEN = -11,
2256
+ FILE_TYPE = -12,
2257
+ FILE_MODE = -13,
2258
+ FILE_CREATED = -14,
2259
+ FILE_MODIFIED = -15,
2260
+ FILE_SIZE = -16,
2261
+ FILE_RANDOMACCESS = -17,
2262
+ FILE_POSITION = -18,
2263
+ FILE_APPEND = -19,
2264
+ FILE_REPLACE = -20,
2265
+ FILE_AUTOFLUSH = -21,
2266
+ FILE_ISNATIVE = -22,
2267
+ };
2268
+
2269
+ static JSPropertySpec file_props[] = {
2270
+ {"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
2271
+ {"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
2272
+ {"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY },
2273
+ {"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
2274
+ {"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY },
2275
+ {"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY },
2276
+ {"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY },
2277
+ {"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY },
2278
+ {"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY },
2279
+ {"canAppend", FILE_APPEND, JSPROP_ENUMERATE | JSPROP_READONLY },
2280
+ {"canReplace", FILE_REPLACE, JSPROP_ENUMERATE | JSPROP_READONLY },
2281
+ {"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY },
2282
+ {"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY },
2283
+ {"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY },
2284
+ {"creationTime", FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY },
2285
+ {"lastModified", FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY },
2286
+ {"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY },
2287
+ {"hasRandomAccess", FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY },
2288
+ {"hasAutoFlush", FILE_AUTOFLUSH, JSPROP_ENUMERATE | JSPROP_READONLY },
2289
+ {"position", FILE_POSITION, JSPROP_ENUMERATE },
2290
+ {"isNative", FILE_ISNATIVE, JSPROP_ENUMERATE | JSPROP_READONLY },
2291
+ {0}
2292
+ };
2293
+
2294
+ /* ------------------------- Property getter/setter ------------------------- */
2295
+ static JSBool
2296
+ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2297
+ {
2298
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2299
+ char *bytes;
2300
+ JSString *str;
2301
+ jsint tiny;
2302
+ PRFileInfo info;
2303
+ JSBool flag;
2304
+ PRExplodedTime expandedTime;
2305
+
2306
+ tiny = JSVAL_TO_INT(id);
2307
+ if (!file)
2308
+ return JS_TRUE;
2309
+
2310
+ switch (tiny) {
2311
+ case FILE_PARENT:
2312
+ SECURITY_CHECK(cx, NULL, "parent", file);
2313
+ if (!js_parent(cx, file, vp))
2314
+ return JS_FALSE;
2315
+ break;
2316
+ case FILE_PATH:
2317
+ str = JS_NewStringCopyZ(cx, file->path);
2318
+ if (!str)
2319
+ return JS_FALSE;
2320
+ *vp = STRING_TO_JSVAL(str);
2321
+ break;
2322
+ case FILE_NAME:
2323
+ if (!js_name(cx, file, vp))
2324
+ return JS_FALSE;
2325
+ break;
2326
+ case FILE_ISDIR:
2327
+ SECURITY_CHECK(cx, NULL, "isDirectory", file);
2328
+ *vp = BOOLEAN_TO_JSVAL(js_isDirectory(cx, file));
2329
+ break;
2330
+ case FILE_ISFILE:
2331
+ SECURITY_CHECK(cx, NULL, "isFile", file);
2332
+ *vp = BOOLEAN_TO_JSVAL(js_isFile(cx, file));
2333
+ break;
2334
+ case FILE_EXISTS:
2335
+ SECURITY_CHECK(cx, NULL, "exists", file);
2336
+ *vp = BOOLEAN_TO_JSVAL(js_exists(cx, file));
2337
+ break;
2338
+ case FILE_ISNATIVE:
2339
+ SECURITY_CHECK(cx, NULL, "isNative", file);
2340
+ *vp = BOOLEAN_TO_JSVAL(file->isNative);
2341
+ break;
2342
+ case FILE_CANREAD:
2343
+ SECURITY_CHECK(cx, NULL, "canRead", file);
2344
+ *vp = BOOLEAN_TO_JSVAL(js_canRead(cx, file));
2345
+ break;
2346
+ case FILE_CANWRITE:
2347
+ SECURITY_CHECK(cx, NULL, "canWrite", file);
2348
+ *vp = BOOLEAN_TO_JSVAL(js_canWrite(cx, file));
2349
+ break;
2350
+ case FILE_OPEN:
2351
+ SECURITY_CHECK(cx, NULL, "isOpen", file);
2352
+ *vp = BOOLEAN_TO_JSVAL(file->isOpen);
2353
+ break;
2354
+ case FILE_APPEND :
2355
+ SECURITY_CHECK(cx, NULL, "canAppend", file);
2356
+ JSFILE_CHECK_OPEN("canAppend");
2357
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
2358
+ (file->mode&PR_APPEND)==PR_APPEND);
2359
+ break;
2360
+ case FILE_REPLACE :
2361
+ SECURITY_CHECK(cx, NULL, "canReplace", file);
2362
+ JSFILE_CHECK_OPEN("canReplace");
2363
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
2364
+ (file->mode&PR_TRUNCATE)==PR_TRUNCATE);
2365
+ break;
2366
+ case FILE_AUTOFLUSH :
2367
+ SECURITY_CHECK(cx, NULL, "hasAutoFlush", file);
2368
+ JSFILE_CHECK_OPEN("hasAutoFlush");
2369
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative && file->hasAutoflush);
2370
+ break;
2371
+ case FILE_TYPE:
2372
+ SECURITY_CHECK(cx, NULL, "type", file);
2373
+ JSFILE_CHECK_OPEN("type");
2374
+ if(js_isDirectory(cx, file)){
2375
+ *vp = JSVAL_VOID;
2376
+ break;
2377
+ }
2378
+
2379
+ switch (file->type) {
2380
+ case ASCII:
2381
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, asciistring));
2382
+ break;
2383
+ case UTF8:
2384
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, utfstring));
2385
+ break;
2386
+ case UCS2:
2387
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, unicodestring));
2388
+ break;
2389
+ default:
2390
+ JS_ReportWarning(cx, "Unsupported file type %d, proceeding",
2391
+ file->type);
2392
+ }
2393
+ break;
2394
+ case FILE_MODE:
2395
+ SECURITY_CHECK(cx, NULL, "mode", file);
2396
+ JSFILE_CHECK_OPEN("mode");
2397
+ bytes = JS_malloc(cx, MODE_SIZE);
2398
+ bytes[0] = '\0';
2399
+ flag = JS_FALSE;
2400
+
2401
+ if ((file->mode&PR_RDONLY)==PR_RDONLY) {
2402
+ if (flag) strcat(bytes, ",");
2403
+ strcat(bytes, "read");
2404
+ flag = JS_TRUE;
2405
+ }
2406
+ if ((file->mode&PR_WRONLY)==PR_WRONLY) {
2407
+ if (flag) strcat(bytes, ",");
2408
+ strcat(bytes, "write");
2409
+ flag = JS_TRUE;
2410
+ }
2411
+ if ((file->mode&PR_RDWR)==PR_RDWR) {
2412
+ if (flag) strcat(bytes, ",");
2413
+ strcat(bytes, "readWrite");
2414
+ flag = JS_TRUE;
2415
+ }
2416
+ if ((file->mode&PR_APPEND)==PR_APPEND) {
2417
+ if (flag) strcat(bytes, ",");
2418
+ strcat(bytes, "append");
2419
+ flag = JS_TRUE;
2420
+ }
2421
+ if ((file->mode&PR_CREATE_FILE)==PR_CREATE_FILE) {
2422
+ if (flag) strcat(bytes, ",");
2423
+ strcat(bytes, "create");
2424
+ flag = JS_TRUE;
2425
+ }
2426
+ if ((file->mode&PR_TRUNCATE)==PR_TRUNCATE) {
2427
+ if (flag) strcat(bytes, ",");
2428
+ strcat(bytes, "replace");
2429
+ flag = JS_TRUE;
2430
+ }
2431
+ if (file->hasAutoflush) {
2432
+ if (flag) strcat(bytes, ",");
2433
+ strcat(bytes, "hasAutoFlush");
2434
+ flag = JS_TRUE;
2435
+ }
2436
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, bytes));
2437
+ JS_free(cx, bytes);
2438
+ break;
2439
+ case FILE_CREATED:
2440
+ SECURITY_CHECK(cx, NULL, "creationTime", file);
2441
+ JSFILE_CHECK_NATIVE("creationTime");
2442
+ if(((file->isOpen)?
2443
+ PR_GetOpenFileInfo(file->handle, &info):
2444
+ PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
2445
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2446
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
2447
+ goto out;
2448
+ }
2449
+
2450
+ PR_ExplodeTime(info.creationTime, PR_LocalTimeParameters,&expandedTime);
2451
+ *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
2452
+ expandedTime.tm_month,
2453
+ expandedTime.tm_mday,
2454
+ expandedTime.tm_hour,
2455
+ expandedTime.tm_min,
2456
+ expandedTime.tm_sec));
2457
+ break;
2458
+ case FILE_MODIFIED:
2459
+ SECURITY_CHECK(cx, NULL, "lastModified", file);
2460
+ JSFILE_CHECK_NATIVE("lastModified");
2461
+ if(((file->isOpen)?
2462
+ PR_GetOpenFileInfo(file->handle, &info):
2463
+ PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
2464
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2465
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
2466
+ goto out;
2467
+ }
2468
+
2469
+ PR_ExplodeTime(info.modifyTime, PR_LocalTimeParameters, &expandedTime);
2470
+ *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
2471
+ expandedTime.tm_month,
2472
+ expandedTime.tm_mday,
2473
+ expandedTime.tm_hour,
2474
+ expandedTime.tm_min,
2475
+ expandedTime.tm_sec));
2476
+ break;
2477
+ case FILE_SIZE:
2478
+ SECURITY_CHECK(cx, NULL, "size", file);
2479
+ *vp = js_size(cx, file);
2480
+ break;
2481
+ case FILE_LENGTH:
2482
+ SECURITY_CHECK(cx, NULL, "length", file);
2483
+ JSFILE_CHECK_NATIVE("length");
2484
+
2485
+ if (js_isDirectory(cx, file)) { /* XXX debug me */
2486
+ PRDir *dir;
2487
+ PRDirEntry *entry;
2488
+ jsint count = 0;
2489
+
2490
+ if(!(dir = PR_OpenDir(file->path))){
2491
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2492
+ JSFILEMSG_CANNOT_OPEN_DIR, file->path);
2493
+ goto out;
2494
+ }
2495
+
2496
+ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
2497
+ count++;
2498
+ }
2499
+
2500
+ if(!PR_CloseDir(dir)){
2501
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2502
+ JSFILEMSG_OP_FAILED, "close", file->path);
2503
+
2504
+ goto out;
2505
+ }
2506
+
2507
+ *vp = INT_TO_JSVAL(count);
2508
+ break;
2509
+ }else{
2510
+ /* return file size */
2511
+ *vp = js_size(cx, file);
2512
+ }
2513
+ break;
2514
+ case FILE_RANDOMACCESS:
2515
+ SECURITY_CHECK(cx, NULL, "hasRandomAccess", file);
2516
+ JSFILE_CHECK_OPEN("hasRandomAccess");
2517
+ *vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess);
2518
+ break;
2519
+ case FILE_POSITION:
2520
+ SECURITY_CHECK(cx, NULL, "position", file);
2521
+ JSFILE_CHECK_NATIVE("position");
2522
+ JSFILE_CHECK_OPEN("position");
2523
+
2524
+ if(!file->hasRandomAccess){
2525
+ JS_ReportWarning(cx, "File %s doesn't support random access, can't report the position, proceeding");
2526
+ *vp = JSVAL_VOID;
2527
+ break;
2528
+ }
2529
+
2530
+ if (file->isOpen && js_isFile(cx, file)) {
2531
+ int pos = PR_Seek(file->handle, 0, PR_SEEK_CUR);
2532
+ if(pos!=-1){
2533
+ *vp = INT_TO_JSVAL(pos);
2534
+ }else{
2535
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2536
+ JSFILEMSG_CANNOT_REPORT_POSITION, file->path);
2537
+ goto out;
2538
+ }
2539
+ }else {
2540
+ JS_ReportWarning(cx, "File %s is closed or not a plain file,"
2541
+ " can't report position, proceeding");
2542
+ goto out;
2543
+ }
2544
+ break;
2545
+ default:
2546
+ SECURITY_CHECK(cx, NULL, "file_access", file);
2547
+
2548
+ /* this is some other property -- try to use the dir["file"] syntax */
2549
+ if (js_isDirectory(cx, file)) {
2550
+ PRDir *dir = NULL;
2551
+ PRDirEntry *entry = NULL;
2552
+ char *prop_name;
2553
+
2554
+ str = JS_ValueToString(cx, id);
2555
+ if (!str)
2556
+ return JS_FALSE;
2557
+
2558
+ prop_name = JS_GetStringBytes(str);
2559
+
2560
+ /* no native files past this point */
2561
+ dir = PR_OpenDir(file->path);
2562
+ if(!dir) {
2563
+ /* This is probably not a directory */
2564
+ JS_ReportWarning(cx, "Can't open directory %s", file->path);
2565
+ return JS_FALSE;
2566
+ }
2567
+
2568
+ while ((entry = PR_ReadDir(dir, PR_SKIP_NONE)) != NULL) {
2569
+ if (!strcmp(entry->name, prop_name)){
2570
+ bytes = js_combinePath(cx, file->path, prop_name);
2571
+ *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, bytes));
2572
+ PR_CloseDir(dir);
2573
+ JS_free(cx, bytes);
2574
+ return !JSVAL_IS_NULL(*vp);
2575
+ }
2576
+ }
2577
+ PR_CloseDir(dir);
2578
+ }
2579
+ }
2580
+ return JS_TRUE;
2581
+
2582
+ out:
2583
+ return JS_FALSE;
2584
+ }
2585
+
2586
+ static JSBool
2587
+ file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2588
+ {
2589
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2590
+ jsint slot;
2591
+
2592
+ if (JSVAL_IS_STRING(id)){
2593
+ return JS_TRUE;
2594
+ }
2595
+
2596
+ slot = JSVAL_TO_INT(id);
2597
+
2598
+ switch (slot) {
2599
+ /* File.position = 10 */
2600
+ case FILE_POSITION:
2601
+ SECURITY_CHECK(cx, NULL, "set_position", file);
2602
+ JSFILE_CHECK_NATIVE("set_position");
2603
+
2604
+ if(!file->hasRandomAccess){
2605
+ JS_ReportWarning(cx, "File %s doesn't support random access, can't "
2606
+ "report the position, proceeding");
2607
+ goto out;
2608
+ }
2609
+
2610
+ if (file->isOpen && js_isFile(cx, file)) {
2611
+ int32 pos;
2612
+ int32 offset;
2613
+
2614
+ if (!JS_ValueToInt32(cx, *vp, &offset)){
2615
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2616
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "position", *vp);
2617
+ goto out;
2618
+ }
2619
+
2620
+ pos = PR_Seek(file->handle, offset, PR_SEEK_SET);
2621
+
2622
+ if(pos!=-1){
2623
+ *vp = INT_TO_JSVAL(pos);
2624
+ }else{
2625
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2626
+ JSFILEMSG_CANNOT_SET_POSITION, file->path);
2627
+ goto out;
2628
+ }
2629
+ } else {
2630
+ JS_ReportWarning(cx, "File %s is closed or not a file, can't set "
2631
+ "position, proceeding", file->path);
2632
+ goto out;
2633
+ }
2634
+ }
2635
+
2636
+ return JS_TRUE;
2637
+ out:
2638
+ return JS_FALSE;
2639
+ }
2640
+
2641
+ /*
2642
+ File.currentDir = new File("D:\") or File.currentDir = "D:\"
2643
+ */
2644
+ static JSBool
2645
+ file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2646
+ {
2647
+ JSFile *file;
2648
+
2649
+ file = JS_GetInstancePrivate(cx, obj, &js_FileClass, NULL);
2650
+
2651
+ /* Look at the rhs and extract a file object from it */
2652
+ if (JSVAL_IS_OBJECT(*vp)) {
2653
+ if (JS_InstanceOf(cx, obj, &js_FileClass, NULL)) {
2654
+ /* Braindamaged rhs -- just return the old value */
2655
+ if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))) {
2656
+ JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
2657
+ return JS_FALSE;
2658
+ } else {
2659
+ chdir(file->path);
2660
+ return JS_TRUE;
2661
+ }
2662
+ } else {
2663
+ return JS_FALSE;
2664
+ }
2665
+ } else {
2666
+ JSObject *rhsObject;
2667
+ char *path;
2668
+
2669
+ path = JS_GetStringBytes(JS_ValueToString(cx, *vp));
2670
+ rhsObject = js_NewFileObject(cx, path);
2671
+ if (!rhsObject)
2672
+ return JS_FALSE;
2673
+
2674
+ if (!file || !js_exists(cx, file) || !js_isDirectory(cx, file)){
2675
+ JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
2676
+ } else {
2677
+ *vp = OBJECT_TO_JSVAL(rhsObject);
2678
+ chdir(path);
2679
+ }
2680
+ }
2681
+
2682
+ return JS_TRUE;
2683
+ }
2684
+
2685
+ /* Declare class */
2686
+ JSClass js_FileClass = {
2687
+ "File", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_File),
2688
+ JS_PropertyStub, JS_PropertyStub, file_getProperty, file_setProperty,
2689
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, file_finalize
2690
+ };
2691
+
2692
+ /* -------------------- Functions exposed to the outside -------------------- */
2693
+ JS_PUBLIC_API(JSObject*)
2694
+ js_InitFileClass(JSContext *cx, JSObject* obj)
2695
+ {
2696
+ JSObject *file, *ctor, *afile;
2697
+ jsval vp;
2698
+ char *currentdir;
2699
+ char separator[2];
2700
+
2701
+ file = JS_InitClass(cx, obj, NULL, &js_FileClass, file_constructor, 1,
2702
+ file_props, file_functions, NULL, NULL);
2703
+ if (!file) {
2704
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2705
+ JSFILEMSG_INIT_FAILED);
2706
+ return NULL;
2707
+ }
2708
+
2709
+ ctor = JS_GetConstructor(cx, file);
2710
+ if (!ctor) return NULL;
2711
+
2712
+ /* Define CURRENTDIR property. We are doing this to get a
2713
+ slash at the end of the current dir */
2714
+ afile = js_NewFileObject(cx, CURRENT_DIR);
2715
+ currentdir = JS_malloc(cx, MAX_PATH_LENGTH);
2716
+ currentdir = getcwd(currentdir, MAX_PATH_LENGTH);
2717
+ afile = js_NewFileObject(cx, currentdir);
2718
+ JS_free(cx, currentdir);
2719
+ vp = OBJECT_TO_JSVAL(afile);
2720
+ JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp,
2721
+ JS_PropertyStub, file_currentDirSetter,
2722
+ JSPROP_ENUMERATE | JSPROP_READONLY );
2723
+
2724
+ /* Define input */
2725
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
2726
+ STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
2727
+ JS_SetProperty(cx, ctor, "input", &vp);
2728
+
2729
+ /* Define output */
2730
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
2731
+ STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
2732
+ JS_SetProperty(cx, ctor, "output", &vp);
2733
+
2734
+ /* Define error */
2735
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
2736
+ STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
2737
+ JS_SetProperty(cx, ctor, "error", &vp);
2738
+
2739
+ separator[0] = FILESEPARATOR;
2740
+ separator[1] = '\0';
2741
+ vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, separator));
2742
+ JS_DefinePropertyWithTinyId(cx, ctor, SEPARATOR_PROPERTY, 0, vp,
2743
+ JS_PropertyStub, JS_PropertyStub,
2744
+ JSPROP_ENUMERATE | JSPROP_READONLY );
2745
+ return file;
2746
+ }
2747
+ #endif /* JS_HAS_FILE_OBJECT */