distil 0.7.0

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 (552) hide show
  1. data/Rakefile +28 -0
  2. data/VERSION +1 -0
  3. data/bin/distil +45 -0
  4. data/distil.gemspec +586 -0
  5. data/lib/bootstrap-template.js +56 -0
  6. data/lib/configurable.rb +125 -0
  7. data/lib/file-set.rb +42 -0
  8. data/lib/file-types/css-file.rb +75 -0
  9. data/lib/file-types/html-file.rb +11 -0
  10. data/lib/file-types/javascript-file.rb +98 -0
  11. data/lib/file-types/json-file.rb +14 -0
  12. data/lib/file-types/nib-file.rb +9 -0
  13. data/lib/jsdoc.conf +18 -0
  14. data/lib/jsl.conf +121 -0
  15. data/lib/project.rb +96 -0
  16. data/lib/source-file.rb +181 -0
  17. data/lib/target.rb +96 -0
  18. data/lib/task.rb +239 -0
  19. data/lib/tasks/copy-task.rb +21 -0
  20. data/lib/tasks/css-task.rb +18 -0
  21. data/lib/tasks/javascript-task.rb +125 -0
  22. data/lib/tasks/multiple-output-task.rb +134 -0
  23. data/lib/tasks/nib-task.rb +83 -0
  24. data/lib/tasks/output-task.rb +73 -0
  25. data/lib/tasks/single-output-task.rb +83 -0
  26. data/lib/tasks/test-task.rb +280 -0
  27. data/lib/test/HtmlTestReporter.js +127 -0
  28. data/lib/test/Test.js +248 -0
  29. data/lib/test/TestReporter.js +79 -0
  30. data/lib/test/TestRunner.js +132 -0
  31. data/lib/test/browser.rb +97 -0
  32. data/lib/test/scriptwrapper.html +10 -0
  33. data/lib/test/unittest.html +127 -0
  34. data/vendor/Makefile +35 -0
  35. data/vendor/extconf.rb +3 -0
  36. data/vendor/jsdoc-extras/plugins/distil-plugin.js +142 -0
  37. data/vendor/jsdoc-extras/plugins/interface-plugin.js +36 -0
  38. data/vendor/jsdoc-extras/templates/coherent/allclasses.tmpl +17 -0
  39. data/vendor/jsdoc-extras/templates/coherent/allfiles.tmpl +53 -0
  40. data/vendor/jsdoc-extras/templates/coherent/class.tmpl +803 -0
  41. data/vendor/jsdoc-extras/templates/coherent/index.tmpl +37 -0
  42. data/vendor/jsdoc-extras/templates/coherent/publish.js +242 -0
  43. data/vendor/jsdoc-extras/templates/coherent/showdown.js +421 -0
  44. data/vendor/jsdoc-extras/templates/coherent/static/code-footer.html +3 -0
  45. data/vendor/jsdoc-extras/templates/coherent/static/code-header.html +7 -0
  46. data/vendor/jsdoc-extras/templates/coherent/static/default.css +297 -0
  47. data/vendor/jsdoc-extras/templates/coherent/static/header.html +2 -0
  48. data/vendor/jsdoc-extras/templates/coherent/static/index.html +19 -0
  49. data/vendor/jsdoc-extras/templates/coherent/symbol.tmpl +35 -0
  50. data/vendor/jsdoc-toolkit/README.txt +183 -0
  51. data/vendor/jsdoc-toolkit/app/frame/Chain.js +102 -0
  52. data/vendor/jsdoc-toolkit/app/frame/Dumper.js +144 -0
  53. data/vendor/jsdoc-toolkit/app/frame/Hash.js +84 -0
  54. data/vendor/jsdoc-toolkit/app/frame/Link.js +171 -0
  55. data/vendor/jsdoc-toolkit/app/frame/Namespace.js +10 -0
  56. data/vendor/jsdoc-toolkit/app/frame/Opt.js +134 -0
  57. data/vendor/jsdoc-toolkit/app/frame/Reflection.js +26 -0
  58. data/vendor/jsdoc-toolkit/app/frame/String.js +93 -0
  59. data/vendor/jsdoc-toolkit/app/frame/Testrun.js +129 -0
  60. data/vendor/jsdoc-toolkit/app/frame.js +33 -0
  61. data/vendor/jsdoc-toolkit/app/handlers/FOODOC.js +26 -0
  62. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/DomReader.js +159 -0
  63. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLDoc.js +16 -0
  64. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLParse.js +292 -0
  65. data/vendor/jsdoc-toolkit/app/handlers/XMLDOC.js +26 -0
  66. data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocComment.js +204 -0
  67. data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocTag.js +300 -0
  68. data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsDoc.js +126 -0
  69. data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsPlate.js +109 -0
  70. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Lang.js +144 -0
  71. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Parser.js +144 -0
  72. data/vendor/jsdoc-toolkit/app/lib/JSDOC/PluginManager.js +33 -0
  73. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Symbol.js +644 -0
  74. data/vendor/jsdoc-toolkit/app/lib/JSDOC/SymbolSet.js +241 -0
  75. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TextStream.js +41 -0
  76. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Token.js +18 -0
  77. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenReader.js +332 -0
  78. data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenStream.js +133 -0
  79. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Util.js +32 -0
  80. data/vendor/jsdoc-toolkit/app/lib/JSDOC/Walker.js +499 -0
  81. data/vendor/jsdoc-toolkit/app/lib/JSDOC.js +106 -0
  82. data/vendor/jsdoc-toolkit/app/main.js +129 -0
  83. data/vendor/jsdoc-toolkit/app/plugins/commentSrcJson.js +20 -0
  84. data/vendor/jsdoc-toolkit/app/plugins/frameworkPrototype.js +16 -0
  85. data/vendor/jsdoc-toolkit/app/plugins/functionCall.js +10 -0
  86. data/vendor/jsdoc-toolkit/app/plugins/publishSrcHilite.js +54 -0
  87. data/vendor/jsdoc-toolkit/app/plugins/symbolLink.js +10 -0
  88. data/vendor/jsdoc-toolkit/app/plugins/tagParamConfig.js +31 -0
  89. data/vendor/jsdoc-toolkit/app/plugins/tagSynonyms.js +43 -0
  90. data/vendor/jsdoc-toolkit/app/run.js +348 -0
  91. data/vendor/jsdoc-toolkit/app/t/TestDoc.js +144 -0
  92. data/vendor/jsdoc-toolkit/app/t/runner.js +13 -0
  93. data/vendor/jsdoc-toolkit/app/test/addon.js +24 -0
  94. data/vendor/jsdoc-toolkit/app/test/anon_inner.js +14 -0
  95. data/vendor/jsdoc-toolkit/app/test/augments.js +31 -0
  96. data/vendor/jsdoc-toolkit/app/test/augments2.js +26 -0
  97. data/vendor/jsdoc-toolkit/app/test/borrows.js +46 -0
  98. data/vendor/jsdoc-toolkit/app/test/borrows2.js +23 -0
  99. data/vendor/jsdoc-toolkit/app/test/config.js +22 -0
  100. data/vendor/jsdoc-toolkit/app/test/constructs.js +18 -0
  101. data/vendor/jsdoc-toolkit/app/test/encoding.js +10 -0
  102. data/vendor/jsdoc-toolkit/app/test/encoding_other.js +12 -0
  103. data/vendor/jsdoc-toolkit/app/test/event.js +54 -0
  104. data/vendor/jsdoc-toolkit/app/test/exports.js +14 -0
  105. data/vendor/jsdoc-toolkit/app/test/functions_anon.js +39 -0
  106. data/vendor/jsdoc-toolkit/app/test/functions_nested.js +33 -0
  107. data/vendor/jsdoc-toolkit/app/test/global.js +13 -0
  108. data/vendor/jsdoc-toolkit/app/test/globals.js +25 -0
  109. data/vendor/jsdoc-toolkit/app/test/ignore.js +10 -0
  110. data/vendor/jsdoc-toolkit/app/test/inner.js +16 -0
  111. data/vendor/jsdoc-toolkit/app/test/jsdoc_test.js +477 -0
  112. data/vendor/jsdoc-toolkit/app/test/lend.js +33 -0
  113. data/vendor/jsdoc-toolkit/app/test/memberof.js +19 -0
  114. data/vendor/jsdoc-toolkit/app/test/memberof2.js +38 -0
  115. data/vendor/jsdoc-toolkit/app/test/memberof3.js +33 -0
  116. data/vendor/jsdoc-toolkit/app/test/memberof_constructor.js +17 -0
  117. data/vendor/jsdoc-toolkit/app/test/module.js +17 -0
  118. data/vendor/jsdoc-toolkit/app/test/name.js +19 -0
  119. data/vendor/jsdoc-toolkit/app/test/namespace_nested.js +23 -0
  120. data/vendor/jsdoc-toolkit/app/test/nocode.js +13 -0
  121. data/vendor/jsdoc-toolkit/app/test/oblit_anon.js +20 -0
  122. data/vendor/jsdoc-toolkit/app/test/overview.js +20 -0
  123. data/vendor/jsdoc-toolkit/app/test/param_inline.js +37 -0
  124. data/vendor/jsdoc-toolkit/app/test/params_optional.js +8 -0
  125. data/vendor/jsdoc-toolkit/app/test/prototype.js +17 -0
  126. data/vendor/jsdoc-toolkit/app/test/prototype_nested.js +9 -0
  127. data/vendor/jsdoc-toolkit/app/test/prototype_oblit.js +13 -0
  128. data/vendor/jsdoc-toolkit/app/test/prototype_oblit_constructor.js +24 -0
  129. data/vendor/jsdoc-toolkit/app/test/public.js +10 -0
  130. data/vendor/jsdoc-toolkit/app/test/scripts/code.js +5 -0
  131. data/vendor/jsdoc-toolkit/app/test/scripts/notcode.txt +5 -0
  132. data/vendor/jsdoc-toolkit/app/test/shared.js +42 -0
  133. data/vendor/jsdoc-toolkit/app/test/shared2.js +2 -0
  134. data/vendor/jsdoc-toolkit/app/test/shortcuts.js +22 -0
  135. data/vendor/jsdoc-toolkit/app/test/static_this.js +13 -0
  136. data/vendor/jsdoc-toolkit/app/test/synonyms.js +31 -0
  137. data/vendor/jsdoc-toolkit/app/test/tosource.js +23 -0
  138. data/vendor/jsdoc-toolkit/app/test/variable_redefine.js +14 -0
  139. data/vendor/jsdoc-toolkit/app/test.js +342 -0
  140. data/vendor/jsdoc-toolkit/changes.txt +116 -0
  141. data/vendor/jsdoc-toolkit/conf/sample.conf +31 -0
  142. data/vendor/jsdoc-toolkit/java/build.xml +36 -0
  143. data/vendor/jsdoc-toolkit/java/build_1.4.xml +36 -0
  144. data/vendor/jsdoc-toolkit/java/classes/js.jar +0 -0
  145. data/vendor/jsdoc-toolkit/java/src/JsDebugRun.java +21 -0
  146. data/vendor/jsdoc-toolkit/java/src/JsRun.java +21 -0
  147. data/vendor/jsdoc-toolkit/jsdebug.jar +0 -0
  148. data/vendor/jsdoc-toolkit/jsrun.jar +0 -0
  149. data/vendor/jsdoc-toolkit/jsrun.sh +53 -0
  150. data/vendor/jsdoc-toolkit/templates/jsdoc/allclasses.tmpl +17 -0
  151. data/vendor/jsdoc-toolkit/templates/jsdoc/allfiles.tmpl +56 -0
  152. data/vendor/jsdoc-toolkit/templates/jsdoc/class.tmpl +649 -0
  153. data/vendor/jsdoc-toolkit/templates/jsdoc/index.tmpl +39 -0
  154. data/vendor/jsdoc-toolkit/templates/jsdoc/publish.js +201 -0
  155. data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-footer.html +3 -0
  156. data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-header.html +14 -0
  157. data/vendor/jsdoc-toolkit/templates/jsdoc/static/default.css +162 -0
  158. data/vendor/jsdoc-toolkit/templates/jsdoc/static/header.html +2 -0
  159. data/vendor/jsdoc-toolkit/templates/jsdoc/static/index.html +19 -0
  160. data/vendor/jsdoc-toolkit/templates/jsdoc/symbol.tmpl +35 -0
  161. data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.cpp +333 -0
  162. data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.h +86 -0
  163. data/vendor/jsl-0.3.0/src/Makefile.in +375 -0
  164. data/vendor/jsl-0.3.0/src/Makefile.ref +372 -0
  165. data/vendor/jsl-0.3.0/src/README.html +826 -0
  166. data/vendor/jsl-0.3.0/src/SpiderMonkey.rsp +12 -0
  167. data/vendor/jsl-0.3.0/src/_jsl_online.php +223 -0
  168. data/vendor/jsl-0.3.0/src/config/AIX4.1.mk +65 -0
  169. data/vendor/jsl-0.3.0/src/config/AIX4.2.mk +64 -0
  170. data/vendor/jsl-0.3.0/src/config/AIX4.3.mk +65 -0
  171. data/vendor/jsl-0.3.0/src/config/Darwin.mk +81 -0
  172. data/vendor/jsl-0.3.0/src/config/Darwin1.3.mk +81 -0
  173. data/vendor/jsl-0.3.0/src/config/Darwin1.4.mk +41 -0
  174. data/vendor/jsl-0.3.0/src/config/Darwin5.2.mk +81 -0
  175. data/vendor/jsl-0.3.0/src/config/Darwin5.3.mk +81 -0
  176. data/vendor/jsl-0.3.0/src/config/HP-UXB.10.10.mk +77 -0
  177. data/vendor/jsl-0.3.0/src/config/HP-UXB.10.20.mk +77 -0
  178. data/vendor/jsl-0.3.0/src/config/HP-UXB.11.00.mk +80 -0
  179. data/vendor/jsl-0.3.0/src/config/IRIX.mk +87 -0
  180. data/vendor/jsl-0.3.0/src/config/IRIX5.3.mk +44 -0
  181. data/vendor/jsl-0.3.0/src/config/IRIX6.1.mk +44 -0
  182. data/vendor/jsl-0.3.0/src/config/IRIX6.2.mk +44 -0
  183. data/vendor/jsl-0.3.0/src/config/IRIX6.3.mk +44 -0
  184. data/vendor/jsl-0.3.0/src/config/IRIX6.5.mk +44 -0
  185. data/vendor/jsl-0.3.0/src/config/Linux_All.mk +103 -0
  186. data/vendor/jsl-0.3.0/src/config/Mac_OS10.0.mk +82 -0
  187. data/vendor/jsl-0.3.0/src/config/OSF1V4.0.mk +72 -0
  188. data/vendor/jsl-0.3.0/src/config/OSF1V5.0.mk +69 -0
  189. data/vendor/jsl-0.3.0/src/config/SunOS4.1.4.mk +101 -0
  190. data/vendor/jsl-0.3.0/src/config/SunOS5.3.mk +91 -0
  191. data/vendor/jsl-0.3.0/src/config/SunOS5.4.mk +92 -0
  192. data/vendor/jsl-0.3.0/src/config/SunOS5.5.1.mk +44 -0
  193. data/vendor/jsl-0.3.0/src/config/SunOS5.5.mk +87 -0
  194. data/vendor/jsl-0.3.0/src/config/SunOS5.6.mk +89 -0
  195. data/vendor/jsl-0.3.0/src/config/SunOS5.7.mk +44 -0
  196. data/vendor/jsl-0.3.0/src/config/SunOS5.8.mk +44 -0
  197. data/vendor/jsl-0.3.0/src/config/SunOS5.9.mk +44 -0
  198. data/vendor/jsl-0.3.0/src/config/WINNT4.0.mk +112 -0
  199. data/vendor/jsl-0.3.0/src/config/WINNT5.0.mk +112 -0
  200. data/vendor/jsl-0.3.0/src/config/WINNT5.1.mk +112 -0
  201. data/vendor/jsl-0.3.0/src/config/WINNT5.2.mk +112 -0
  202. data/vendor/jsl-0.3.0/src/config/dgux.mk +64 -0
  203. data/vendor/jsl-0.3.0/src/config.mk +166 -0
  204. data/vendor/jsl-0.3.0/src/editline/Makefile.ref +144 -0
  205. data/vendor/jsl-0.3.0/src/editline/README +83 -0
  206. data/vendor/jsl-0.3.0/src/editline/editline.3 +175 -0
  207. data/vendor/jsl-0.3.0/src/editline/editline.c +1369 -0
  208. data/vendor/jsl-0.3.0/src/editline/editline.h +135 -0
  209. data/vendor/jsl-0.3.0/src/editline/sysunix.c +182 -0
  210. data/vendor/jsl-0.3.0/src/editline/unix.h +82 -0
  211. data/vendor/jsl-0.3.0/src/fdlibm/Makefile.in +127 -0
  212. data/vendor/jsl-0.3.0/src/fdlibm/Makefile.ref +192 -0
  213. data/vendor/jsl-0.3.0/src/fdlibm/e_acos.c +147 -0
  214. data/vendor/jsl-0.3.0/src/fdlibm/e_acosh.c +105 -0
  215. data/vendor/jsl-0.3.0/src/fdlibm/e_asin.c +156 -0
  216. data/vendor/jsl-0.3.0/src/fdlibm/e_atan2.c +165 -0
  217. data/vendor/jsl-0.3.0/src/fdlibm/e_atanh.c +110 -0
  218. data/vendor/jsl-0.3.0/src/fdlibm/e_cosh.c +133 -0
  219. data/vendor/jsl-0.3.0/src/fdlibm/e_exp.c +202 -0
  220. data/vendor/jsl-0.3.0/src/fdlibm/e_fmod.c +184 -0
  221. data/vendor/jsl-0.3.0/src/fdlibm/e_gamma.c +71 -0
  222. data/vendor/jsl-0.3.0/src/fdlibm/e_gamma_r.c +70 -0
  223. data/vendor/jsl-0.3.0/src/fdlibm/e_hypot.c +173 -0
  224. data/vendor/jsl-0.3.0/src/fdlibm/e_j0.c +524 -0
  225. data/vendor/jsl-0.3.0/src/fdlibm/e_j1.c +523 -0
  226. data/vendor/jsl-0.3.0/src/fdlibm/e_jn.c +315 -0
  227. data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma.c +71 -0
  228. data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma_r.c +347 -0
  229. data/vendor/jsl-0.3.0/src/fdlibm/e_log.c +184 -0
  230. data/vendor/jsl-0.3.0/src/fdlibm/e_log10.c +134 -0
  231. data/vendor/jsl-0.3.0/src/fdlibm/e_pow.c +386 -0
  232. data/vendor/jsl-0.3.0/src/fdlibm/e_rem_pio2.c +221 -0
  233. data/vendor/jsl-0.3.0/src/fdlibm/e_remainder.c +120 -0
  234. data/vendor/jsl-0.3.0/src/fdlibm/e_scalb.c +89 -0
  235. data/vendor/jsl-0.3.0/src/fdlibm/e_sinh.c +122 -0
  236. data/vendor/jsl-0.3.0/src/fdlibm/e_sqrt.c +497 -0
  237. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.dsp +160 -0
  238. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.h +273 -0
  239. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mak +1453 -0
  240. data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mdp +0 -0
  241. data/vendor/jsl-0.3.0/src/fdlibm/k_cos.c +134 -0
  242. data/vendor/jsl-0.3.0/src/fdlibm/k_rem_pio2.c +354 -0
  243. data/vendor/jsl-0.3.0/src/fdlibm/k_sin.c +114 -0
  244. data/vendor/jsl-0.3.0/src/fdlibm/k_standard.c +785 -0
  245. data/vendor/jsl-0.3.0/src/fdlibm/k_tan.c +170 -0
  246. data/vendor/jsl-0.3.0/src/fdlibm/s_asinh.c +101 -0
  247. data/vendor/jsl-0.3.0/src/fdlibm/s_atan.c +175 -0
  248. data/vendor/jsl-0.3.0/src/fdlibm/s_cbrt.c +133 -0
  249. data/vendor/jsl-0.3.0/src/fdlibm/s_ceil.c +120 -0
  250. data/vendor/jsl-0.3.0/src/fdlibm/s_copysign.c +72 -0
  251. data/vendor/jsl-0.3.0/src/fdlibm/s_cos.c +118 -0
  252. data/vendor/jsl-0.3.0/src/fdlibm/s_erf.c +356 -0
  253. data/vendor/jsl-0.3.0/src/fdlibm/s_expm1.c +267 -0
  254. data/vendor/jsl-0.3.0/src/fdlibm/s_fabs.c +70 -0
  255. data/vendor/jsl-0.3.0/src/fdlibm/s_finite.c +71 -0
  256. data/vendor/jsl-0.3.0/src/fdlibm/s_floor.c +121 -0
  257. data/vendor/jsl-0.3.0/src/fdlibm/s_frexp.c +99 -0
  258. data/vendor/jsl-0.3.0/src/fdlibm/s_ilogb.c +85 -0
  259. data/vendor/jsl-0.3.0/src/fdlibm/s_isnan.c +74 -0
  260. data/vendor/jsl-0.3.0/src/fdlibm/s_ldexp.c +66 -0
  261. data/vendor/jsl-0.3.0/src/fdlibm/s_lib_version.c +73 -0
  262. data/vendor/jsl-0.3.0/src/fdlibm/s_log1p.c +211 -0
  263. data/vendor/jsl-0.3.0/src/fdlibm/s_logb.c +79 -0
  264. data/vendor/jsl-0.3.0/src/fdlibm/s_matherr.c +64 -0
  265. data/vendor/jsl-0.3.0/src/fdlibm/s_modf.c +132 -0
  266. data/vendor/jsl-0.3.0/src/fdlibm/s_nextafter.c +124 -0
  267. data/vendor/jsl-0.3.0/src/fdlibm/s_rint.c +131 -0
  268. data/vendor/jsl-0.3.0/src/fdlibm/s_scalbn.c +107 -0
  269. data/vendor/jsl-0.3.0/src/fdlibm/s_signgam.c +40 -0
  270. data/vendor/jsl-0.3.0/src/fdlibm/s_significand.c +68 -0
  271. data/vendor/jsl-0.3.0/src/fdlibm/s_sin.c +118 -0
  272. data/vendor/jsl-0.3.0/src/fdlibm/s_tan.c +112 -0
  273. data/vendor/jsl-0.3.0/src/fdlibm/s_tanh.c +122 -0
  274. data/vendor/jsl-0.3.0/src/fdlibm/w_acos.c +78 -0
  275. data/vendor/jsl-0.3.0/src/fdlibm/w_acosh.c +78 -0
  276. data/vendor/jsl-0.3.0/src/fdlibm/w_asin.c +80 -0
  277. data/vendor/jsl-0.3.0/src/fdlibm/w_atan2.c +79 -0
  278. data/vendor/jsl-0.3.0/src/fdlibm/w_atanh.c +81 -0
  279. data/vendor/jsl-0.3.0/src/fdlibm/w_cosh.c +77 -0
  280. data/vendor/jsl-0.3.0/src/fdlibm/w_exp.c +88 -0
  281. data/vendor/jsl-0.3.0/src/fdlibm/w_fmod.c +78 -0
  282. data/vendor/jsl-0.3.0/src/fdlibm/w_gamma.c +85 -0
  283. data/vendor/jsl-0.3.0/src/fdlibm/w_gamma_r.c +81 -0
  284. data/vendor/jsl-0.3.0/src/fdlibm/w_hypot.c +78 -0
  285. data/vendor/jsl-0.3.0/src/fdlibm/w_j0.c +105 -0
  286. data/vendor/jsl-0.3.0/src/fdlibm/w_j1.c +106 -0
  287. data/vendor/jsl-0.3.0/src/fdlibm/w_jn.c +128 -0
  288. data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma.c +85 -0
  289. data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma_r.c +81 -0
  290. data/vendor/jsl-0.3.0/src/fdlibm/w_log.c +78 -0
  291. data/vendor/jsl-0.3.0/src/fdlibm/w_log10.c +81 -0
  292. data/vendor/jsl-0.3.0/src/fdlibm/w_pow.c +99 -0
  293. data/vendor/jsl-0.3.0/src/fdlibm/w_remainder.c +77 -0
  294. data/vendor/jsl-0.3.0/src/fdlibm/w_scalb.c +95 -0
  295. data/vendor/jsl-0.3.0/src/fdlibm/w_sinh.c +77 -0
  296. data/vendor/jsl-0.3.0/src/fdlibm/w_sqrt.c +77 -0
  297. data/vendor/jsl-0.3.0/src/js.c +2447 -0
  298. data/vendor/jsl-0.3.0/src/js.dsp +420 -0
  299. data/vendor/jsl-0.3.0/src/js.mak +4025 -0
  300. data/vendor/jsl-0.3.0/src/js.mdp +0 -0
  301. data/vendor/jsl-0.3.0/src/js.msg +291 -0
  302. data/vendor/jsl-0.3.0/src/js.pkg +2 -0
  303. data/vendor/jsl-0.3.0/src/js3240.rc +79 -0
  304. data/vendor/jsl-0.3.0/src/jsOS240.def +654 -0
  305. data/vendor/jsl-0.3.0/src/jsapi.c +4405 -0
  306. data/vendor/jsl-0.3.0/src/jsapi.h +1856 -0
  307. data/vendor/jsl-0.3.0/src/jsarena.c +567 -0
  308. data/vendor/jsl-0.3.0/src/jsarena.h +302 -0
  309. data/vendor/jsl-0.3.0/src/jsarray.c +1428 -0
  310. data/vendor/jsl-0.3.0/src/jsarray.h +77 -0
  311. data/vendor/jsl-0.3.0/src/jsatom.c +927 -0
  312. data/vendor/jsl-0.3.0/src/jsatom.h +426 -0
  313. data/vendor/jsl-0.3.0/src/jsbit.h +113 -0
  314. data/vendor/jsl-0.3.0/src/jsbool.c +220 -0
  315. data/vendor/jsl-0.3.0/src/jsbool.h +62 -0
  316. data/vendor/jsl-0.3.0/src/jsclist.h +139 -0
  317. data/vendor/jsl-0.3.0/src/jscntxt.c +1036 -0
  318. data/vendor/jsl-0.3.0/src/jscntxt.h +608 -0
  319. data/vendor/jsl-0.3.0/src/jscompat.h +57 -0
  320. data/vendor/jsl-0.3.0/src/jsconfig.h +489 -0
  321. data/vendor/jsl-0.3.0/src/jsconfig.mk +181 -0
  322. data/vendor/jsl-0.3.0/src/jscpucfg.c +377 -0
  323. data/vendor/jsl-0.3.0/src/jscpucfg.h +204 -0
  324. data/vendor/jsl-0.3.0/src/jsdate.c +2238 -0
  325. data/vendor/jsl-0.3.0/src/jsdate.h +118 -0
  326. data/vendor/jsl-0.3.0/src/jsdbgapi.c +1260 -0
  327. data/vendor/jsl-0.3.0/src/jsdbgapi.h +345 -0
  328. data/vendor/jsl-0.3.0/src/jsdhash.c +763 -0
  329. data/vendor/jsl-0.3.0/src/jsdhash.h +579 -0
  330. data/vendor/jsl-0.3.0/src/jsdtoa.c +3135 -0
  331. data/vendor/jsl-0.3.0/src/jsdtoa.h +130 -0
  332. data/vendor/jsl-0.3.0/src/jsemit.c +4851 -0
  333. data/vendor/jsl-0.3.0/src/jsemit.h +576 -0
  334. data/vendor/jsl-0.3.0/src/jsexn.c +1084 -0
  335. data/vendor/jsl-0.3.0/src/jsexn.h +102 -0
  336. data/vendor/jsl-0.3.0/src/jsfile.c +2610 -0
  337. data/vendor/jsl-0.3.0/src/jsfile.h +50 -0
  338. data/vendor/jsl-0.3.0/src/jsfile.msg +89 -0
  339. data/vendor/jsl-0.3.0/src/jsfun.c +2015 -0
  340. data/vendor/jsl-0.3.0/src/jsfun.h +158 -0
  341. data/vendor/jsl-0.3.0/src/jsgc.c +1441 -0
  342. data/vendor/jsl-0.3.0/src/jsgc.h +230 -0
  343. data/vendor/jsl-0.3.0/src/jshash.c +471 -0
  344. data/vendor/jsl-0.3.0/src/jshash.h +152 -0
  345. data/vendor/jsl-0.3.0/src/jsify.pl +485 -0
  346. data/vendor/jsl-0.3.0/src/jsinterp.c +4797 -0
  347. data/vendor/jsl-0.3.0/src/jsinterp.h +302 -0
  348. data/vendor/jsl-0.3.0/src/jsl-test.js +28 -0
  349. data/vendor/jsl-0.3.0/src/jsl.c +2371 -0
  350. data/vendor/jsl-0.3.0/src/jsl.conf +127 -0
  351. data/vendor/jsl-0.3.0/src/jsl.conf.old +124 -0
  352. data/vendor/jsl-0.3.0/src/jsl.dsp +242 -0
  353. data/vendor/jsl-0.3.0/src/jsl.dsw +59 -0
  354. data/vendor/jsl-0.3.0/src/jslibmath.h +290 -0
  355. data/vendor/jsl-0.3.0/src/jslock.c +1261 -0
  356. data/vendor/jsl-0.3.0/src/jslock.h +289 -0
  357. data/vendor/jsl-0.3.0/src/jslocko.asm +59 -0
  358. data/vendor/jsl-0.3.0/src/jslog2.c +83 -0
  359. data/vendor/jsl-0.3.0/src/jslong.c +281 -0
  360. data/vendor/jsl-0.3.0/src/jslong.h +437 -0
  361. data/vendor/jsl-0.3.0/src/jsmath.c +477 -0
  362. data/vendor/jsl-0.3.0/src/jsmath.h +55 -0
  363. data/vendor/jsl-0.3.0/src/jsnum.c +1148 -0
  364. data/vendor/jsl-0.3.0/src/jsnum.h +257 -0
  365. data/vendor/jsl-0.3.0/src/jsobj.c +4066 -0
  366. data/vendor/jsl-0.3.0/src/jsobj.h +475 -0
  367. data/vendor/jsl-0.3.0/src/jsopcode.c +2730 -0
  368. data/vendor/jsl-0.3.0/src/jsopcode.h +275 -0
  369. data/vendor/jsl-0.3.0/src/jsopcode.tbl +344 -0
  370. data/vendor/jsl-0.3.0/src/jsosdep.h +127 -0
  371. data/vendor/jsl-0.3.0/src/jsotypes.h +211 -0
  372. data/vendor/jsl-0.3.0/src/jsparse.c +4438 -0
  373. data/vendor/jsl-0.3.0/src/jsparse.h +345 -0
  374. data/vendor/jsl-0.3.0/src/jsprf.c +1212 -0
  375. data/vendor/jsl-0.3.0/src/jsprf.h +148 -0
  376. data/vendor/jsl-0.3.0/src/jsprvtd.h +174 -0
  377. data/vendor/jsl-0.3.0/src/jspubtd.h +586 -0
  378. data/vendor/jsl-0.3.0/src/jsregexp.c +3831 -0
  379. data/vendor/jsl-0.3.0/src/jsregexp.h +180 -0
  380. data/vendor/jsl-0.3.0/src/jsscan.c +1814 -0
  381. data/vendor/jsl-0.3.0/src/jsscan.h +267 -0
  382. data/vendor/jsl-0.3.0/src/jsscope.c +1639 -0
  383. data/vendor/jsl-0.3.0/src/jsscope.h +389 -0
  384. data/vendor/jsl-0.3.0/src/jsscript.c +1284 -0
  385. data/vendor/jsl-0.3.0/src/jsscript.h +179 -0
  386. data/vendor/jsl-0.3.0/src/jsshell.msg +50 -0
  387. data/vendor/jsl-0.3.0/src/jsstddef.h +83 -0
  388. data/vendor/jsl-0.3.0/src/jsstr.c +4502 -0
  389. data/vendor/jsl-0.3.0/src/jsstr.h +448 -0
  390. data/vendor/jsl-0.3.0/src/jstypes.h +391 -0
  391. data/vendor/jsl-0.3.0/src/jsutil.c +157 -0
  392. data/vendor/jsl-0.3.0/src/jsutil.h +75 -0
  393. data/vendor/jsl-0.3.0/src/jsxdrapi.c +686 -0
  394. data/vendor/jsl-0.3.0/src/jsxdrapi.h +193 -0
  395. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnect.dsp +157 -0
  396. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsp +120 -0
  397. data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsw +44 -0
  398. data/vendor/jsl-0.3.0/src/liveconnect/Makefile.in +106 -0
  399. data/vendor/jsl-0.3.0/src/liveconnect/Makefile.ref +169 -0
  400. data/vendor/jsl-0.3.0/src/liveconnect/README.html +719 -0
  401. data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  402. data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  403. data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.in +89 -0
  404. data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.ref +57 -0
  405. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/Makefile.ref +47 -0
  406. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  407. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  408. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  409. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  410. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  411. data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  412. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.1.mk +45 -0
  413. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.2.mk +45 -0
  414. data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.3.mk +50 -0
  415. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.10.mk +43 -0
  416. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.20.mk +43 -0
  417. data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.11.00.mk +43 -0
  418. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.2.mk +43 -0
  419. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.3.mk +43 -0
  420. data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.5.mk +43 -0
  421. data/vendor/jsl-0.3.0/src/liveconnect/config/Linux_All.mk +73 -0
  422. data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V4.0.mk +65 -0
  423. data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V5.0.mk +62 -0
  424. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.5.1.mk +55 -0
  425. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.6.mk +39 -0
  426. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.7.mk +39 -0
  427. data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.8.mk +39 -0
  428. data/vendor/jsl-0.3.0/src/liveconnect/config/WINNT4.0.mk +53 -0
  429. data/vendor/jsl-0.3.0/src/liveconnect/jsj.c +884 -0
  430. data/vendor/jsl-0.3.0/src/liveconnect/jsj.msg +98 -0
  431. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JSObject.c +1379 -0
  432. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaArray.c +481 -0
  433. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaClass.c +749 -0
  434. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaMember.c +186 -0
  435. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaObject.c +1099 -0
  436. data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaPackage.c +548 -0
  437. data/vendor/jsl-0.3.0/src/liveconnect/jsj_array.c +207 -0
  438. data/vendor/jsl-0.3.0/src/liveconnect/jsj_class.c +765 -0
  439. data/vendor/jsl-0.3.0/src/liveconnect/jsj_convert.c +954 -0
  440. data/vendor/jsl-0.3.0/src/liveconnect/jsj_field.c +421 -0
  441. data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.c +504 -0
  442. data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.h +161 -0
  443. data/vendor/jsl-0.3.0/src/liveconnect/jsj_method.c +1823 -0
  444. data/vendor/jsl-0.3.0/src/liveconnect/jsj_nodl.c +1 -0
  445. data/vendor/jsl-0.3.0/src/liveconnect/jsj_private.h +689 -0
  446. data/vendor/jsl-0.3.0/src/liveconnect/jsj_simpleapi.c +219 -0
  447. data/vendor/jsl-0.3.0/src/liveconnect/jsj_utils.c +513 -0
  448. data/vendor/jsl-0.3.0/src/liveconnect/jsjava.h +313 -0
  449. data/vendor/jsl-0.3.0/src/liveconnect/liveconnect.pkg +3 -0
  450. data/vendor/jsl-0.3.0/src/liveconnect/netscape_javascript_JSObject.h +155 -0
  451. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.cpp +785 -0
  452. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.h +197 -0
  453. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.cpp +163 -0
  454. data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.h +76 -0
  455. data/vendor/jsl-0.3.0/src/liveconnect/nsILiveconnect.h +195 -0
  456. data/vendor/jsl-0.3.0/src/liveconnect/nsISecureLiveconnect.h +84 -0
  457. data/vendor/jsl-0.3.0/src/liveconnect/nsISecurityContext.h +135 -0
  458. data/vendor/jsl-0.3.0/src/liveconnect/win32.order +6 -0
  459. data/vendor/jsl-0.3.0/src/lock_SunOS.s +114 -0
  460. data/vendor/jsl-0.3.0/src/perfect.js +39 -0
  461. data/vendor/jsl-0.3.0/src/perlconnect/JS.def +6 -0
  462. data/vendor/jsl-0.3.0/src/perlconnect/JS.dsp +107 -0
  463. data/vendor/jsl-0.3.0/src/perlconnect/JS.pm +318 -0
  464. data/vendor/jsl-0.3.0/src/perlconnect/JS.xs +1050 -0
  465. data/vendor/jsl-0.3.0/src/perlconnect/Makefile.PL +67 -0
  466. data/vendor/jsl-0.3.0/src/perlconnect/Makefile.ref +152 -0
  467. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsp +103 -0
  468. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsw +59 -0
  469. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.pm +126 -0
  470. data/vendor/jsl-0.3.0/src/perlconnect/PerlConnectShell.dsp +89 -0
  471. data/vendor/jsl-0.3.0/src/perlconnect/README.html +345 -0
  472. data/vendor/jsl-0.3.0/src/perlconnect/bg.jpg +0 -0
  473. data/vendor/jsl-0.3.0/src/perlconnect/jsperl.c +1100 -0
  474. data/vendor/jsl-0.3.0/src/perlconnect/jsperl.h +52 -0
  475. data/vendor/jsl-0.3.0/src/perlconnect/jsperlbuild.pl +81 -0
  476. data/vendor/jsl-0.3.0/src/perlconnect/jsperlpvt.h +57 -0
  477. data/vendor/jsl-0.3.0/src/perlconnect/test.js +73 -0
  478. data/vendor/jsl-0.3.0/src/perlconnect/test.pl +244 -0
  479. data/vendor/jsl-0.3.0/src/perlconnect/typemap +121 -0
  480. data/vendor/jsl-0.3.0/src/plify_jsdhash.sed +31 -0
  481. data/vendor/jsl-0.3.0/src/prmjtime.c +646 -0
  482. data/vendor/jsl-0.3.0/src/prmjtime.h +95 -0
  483. data/vendor/jsl-0.3.0/src/resource.h +15 -0
  484. data/vendor/jsl-0.3.0/src/rules.mk +193 -0
  485. data/vendor/jsl-0.3.0/src/win32.order +391 -0
  486. data/vendor/jsl-0.3.0/tests/conf/always_use_option_explicit.js +4 -0
  487. data/vendor/jsl-0.3.0/tests/conf/define.js +8 -0
  488. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-1.js +7 -0
  489. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-2.js +8 -0
  490. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-3.js +27 -0
  491. data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-4.js +4 -0
  492. data/vendor/jsl-0.3.0/tests/conf/lambda_assign_requires_semicolon.js +24 -0
  493. data/vendor/jsl-0.3.0/tests/conf/legacy_control_comments.js +8 -0
  494. data/vendor/jsl-0.3.0/tests/control_comments/control_comments.js +33 -0
  495. data/vendor/jsl-0.3.0/tests/control_comments/declare.js +26 -0
  496. data/vendor/jsl-0.3.0/tests/control_comments/import-overflow.js +9 -0
  497. data/vendor/jsl-0.3.0/tests/control_comments/import.js +5 -0
  498. data/vendor/jsl-0.3.0/tests/control_comments/import2.js +2 -0
  499. data/vendor/jsl-0.3.0/tests/control_comments/invalid_fallthru.js +13 -0
  500. data/vendor/jsl-0.3.0/tests/control_comments/option_explicit-with.js +12 -0
  501. data/vendor/jsl-0.3.0/tests/control_comments/option_explicit.js +64 -0
  502. data/vendor/jsl-0.3.0/tests/errors/unterminated_comment.js +8 -0
  503. data/vendor/jsl-0.3.0/tests/html/script_tag_in_js_literal.html +14 -0
  504. data/vendor/jsl-0.3.0/tests/run_tests.pl +71 -0
  505. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_else_stmt.js +21 -0
  506. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_nested_stmt.js +66 -0
  507. data/vendor/jsl-0.3.0/tests/warnings/ambiguous_newline.js +261 -0
  508. data/vendor/jsl-0.3.0/tests/warnings/anon_no_return_value.js +26 -0
  509. data/vendor/jsl-0.3.0/tests/warnings/assign_to_function_call.js +16 -0
  510. data/vendor/jsl-0.3.0/tests/warnings/block_without_braces.js +13 -0
  511. data/vendor/jsl-0.3.0/tests/warnings/comma_separated_stmts.js +17 -0
  512. data/vendor/jsl-0.3.0/tests/warnings/comparison_type_conv.js +44 -0
  513. data/vendor/jsl-0.3.0/tests/warnings/default_not_at_end.js +15 -0
  514. data/vendor/jsl-0.3.0/tests/warnings/dup_option_explicit.js +5 -0
  515. data/vendor/jsl-0.3.0/tests/warnings/duplicate_case_in_switch.js +62 -0
  516. data/vendor/jsl-0.3.0/tests/warnings/duplicate_formal.js +5 -0
  517. data/vendor/jsl-0.3.0/tests/warnings/empty_statement.js +29 -0
  518. data/vendor/jsl-0.3.0/tests/warnings/equal_as_assign.js +7 -0
  519. data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt-ignore.js +21 -0
  520. data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt.js +63 -0
  521. data/vendor/jsl-0.3.0/tests/warnings/jsl_cc_not_understood.js +5 -0
  522. data/vendor/jsl-0.3.0/tests/warnings/leading_decimal_point.js +7 -0
  523. data/vendor/jsl-0.3.0/tests/warnings/legacy_cc_not_understood.js +9 -0
  524. data/vendor/jsl-0.3.0/tests/warnings/meaningless_block.js +12 -0
  525. data/vendor/jsl-0.3.0/tests/warnings/misplaced_regex.js +20 -0
  526. data/vendor/jsl-0.3.0/tests/warnings/missing_break.js +87 -0
  527. data/vendor/jsl-0.3.0/tests/warnings/missing_break_for_last_case.js +19 -0
  528. data/vendor/jsl-0.3.0/tests/warnings/missing_default_case.js +51 -0
  529. data/vendor/jsl-0.3.0/tests/warnings/missing_option_explicit.js +5 -0
  530. data/vendor/jsl-0.3.0/tests/warnings/missing_semicolon.js +19 -0
  531. data/vendor/jsl-0.3.0/tests/warnings/multiple_plus_minus.js +10 -0
  532. data/vendor/jsl-0.3.0/tests/warnings/nested_comment.js +6 -0
  533. data/vendor/jsl-0.3.0/tests/warnings/no_return_value.js +25 -0
  534. data/vendor/jsl-0.3.0/tests/warnings/octal_number.js +5 -0
  535. data/vendor/jsl-0.3.0/tests/warnings/parseint_missing_radix.js +15 -0
  536. data/vendor/jsl-0.3.0/tests/warnings/partial_option_explicit.js +5 -0
  537. data/vendor/jsl-0.3.0/tests/warnings/redeclared_var.js +10 -0
  538. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/bad_backref.js +5 -0
  539. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/deprecated_usage.js +11 -0
  540. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/invalid_backref.js +5 -0
  541. data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/trailing_comma.js +5 -0
  542. data/vendor/jsl-0.3.0/tests/warnings/trailing_comma_in_array.js +8 -0
  543. data/vendor/jsl-0.3.0/tests/warnings/trailing_decimal_point.js +7 -0
  544. data/vendor/jsl-0.3.0/tests/warnings/unreachable_code.js +29 -0
  545. data/vendor/jsl-0.3.0/tests/warnings/use_of_label.js +19 -0
  546. data/vendor/jsl-0.3.0/tests/warnings/useless_assign.js +20 -0
  547. data/vendor/jsl-0.3.0/tests/warnings/useless_comparison.js +55 -0
  548. data/vendor/jsl-0.3.0/tests/warnings/useless_void.js +6 -0
  549. data/vendor/jsl-0.3.0/tests/warnings/var_hides_arg.js +4 -0
  550. data/vendor/jsl-0.3.0/tests/warnings/with_statement.js +7 -0
  551. data/vendor/yuicompressor-2.4.2.jar +0 -0
  552. metadata +605 -0
@@ -0,0 +1,2610 @@
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 File object
42
+ */
43
+ #if JS_HAS_FILE_OBJECT
44
+
45
+ #include "jsstddef.h"
46
+
47
+ /* ----------------- Platform-specific includes and defines ----------------- */
48
+ #ifdef XP_MAC
49
+ # define FILESEPARATOR ':'
50
+ # define FILESEPARATOR2 '\0'
51
+ # define CURRENT_DIR "HARD DISK:Desktop Folder"
52
+ /* TODO: #include <???> */
53
+ #elif defined(XP_WIN) || defined(XP_OS2)
54
+ # include <direct.h>
55
+ # include <io.h>
56
+ # include <sys/types.h>
57
+ # include <sys/stat.h>
58
+ # define FILESEPARATOR '\\'
59
+ # define FILESEPARATOR2 '/'
60
+ # define CURRENT_DIR "c:\\"
61
+ # define POPEN _popen
62
+ # define PCLOSE _pclose
63
+ #elif defined(XP_UNIX) || defined(XP_BEOS)
64
+ # include <strings.h>
65
+ # include <stdio.h>
66
+ # include <stdlib.h>
67
+ # include <unistd.h>
68
+ # define FILESEPARATOR '/'
69
+ # define FILESEPARATOR2 '\0'
70
+ # define CURRENT_DIR "/"
71
+ # define POPEN popen
72
+ # define PCLOSE pclose
73
+ #endif
74
+
75
+ /* --------------- Platform-independent includes and defines ---------------- */
76
+ #include "jsapi.h"
77
+ #include "jsatom.h"
78
+ #include "jscntxt.h"
79
+ #include "jsdate.h"
80
+ #include "jsdbgapi.h"
81
+ #include "jsemit.h"
82
+ #include "jsfun.h"
83
+ #include "jslock.h"
84
+ #include "jsobj.h"
85
+ #include "jsparse.h"
86
+ #include "jsscan.h"
87
+ #include "jsscope.h"
88
+ #include "jsscript.h"
89
+ #include "jsstr.h"
90
+ #include "jsutil.h" /* Added by JSIFY */
91
+ #include <string.h>
92
+
93
+ /* NSPR dependencies */
94
+ #include "prio.h"
95
+ #include "prerror.h"
96
+
97
+ #define SPECIAL_FILE_STRING "Special File"
98
+ #define CURRENTDIR_PROPERTY "currentDir"
99
+ #define SEPARATOR_PROPERTY "separator"
100
+ #define FILE_CONSTRUCTOR "File"
101
+ #define PIPE_SYMBOL '|'
102
+
103
+ #define ASCII 0
104
+ #define UTF8 1
105
+ #define UCS2 2
106
+
107
+ #define asciistring "text"
108
+ #define utfstring "binary"
109
+ #define unicodestring "unicode"
110
+
111
+ #define MAX_PATH_LENGTH 1024
112
+ #define MODE_SIZE 256
113
+ #define NUMBER_SIZE 32
114
+ #define MAX_LINE_LENGTH 256
115
+ #define URL_PREFIX "file://"
116
+
117
+ #define STDINPUT_NAME "Standard input stream"
118
+ #define STDOUTPUT_NAME "Standard output stream"
119
+ #define STDERROR_NAME "Standard error stream"
120
+
121
+ #define RESOLVE_PATH js_canonicalPath /* js_absolutePath */
122
+
123
+ /* Error handling */
124
+ typedef enum JSFileErrNum {
125
+ #define MSG_DEF(name, number, count, exception, format) \
126
+ name = number,
127
+ #include "jsfile.msg"
128
+ #undef MSG_DEF
129
+ JSFileErr_Limit
130
+ #undef MSGDEF
131
+ } JSFileErrNum;
132
+
133
+ #define JSFILE_HAS_DFLT_MSG_STRINGS 1
134
+
135
+ JSErrorFormatString JSFile_ErrorFormatString[JSFileErr_Limit] = {
136
+ #if JSFILE_HAS_DFLT_MSG_STRINGS
137
+ #define MSG_DEF(name, number, count, exception, format) \
138
+ { format, count } ,
139
+ #else
140
+ #define MSG_DEF(name, number, count, exception, format) \
141
+ { NULL, count } ,
142
+ #endif
143
+ #include "jsfile.msg"
144
+ #undef MSG_DEF
145
+ };
146
+
147
+ const JSErrorFormatString *
148
+ JSFile_GetErrorMessage(void *userRef, const char *locale,
149
+ const uintN errorNumber)
150
+ {
151
+ if ((errorNumber > 0) && (errorNumber < JSFileErr_Limit))
152
+ return &JSFile_ErrorFormatString[errorNumber];
153
+ else
154
+ return NULL;
155
+ }
156
+
157
+ #define JSFILE_CHECK_NATIVE(op) \
158
+ if(file->isNative){ \
159
+ JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s", \
160
+ op, file->path); \
161
+ goto out; \
162
+ }
163
+
164
+ #define JSFILE_CHECK_WRITE \
165
+ if (!file->isOpen){ \
166
+ JS_ReportWarning(cx, \
167
+ "File %s is closed, will open it for writing, proceeding", \
168
+ file->path); \
169
+ js_FileOpen(cx, obj, file, "write,append,create"); \
170
+ }else \
171
+ if(!js_canWrite(cx, file)){ \
172
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
173
+ JSFILEMSG_CANNOT_WRITE, file->path); \
174
+ goto out; \
175
+ }
176
+
177
+ #define JSFILE_CHECK_READ \
178
+ if (!file->isOpen){ \
179
+ JS_ReportWarning(cx, \
180
+ "File %s is closed, will open it for reading, proceeding", \
181
+ file->path); \
182
+ js_FileOpen(cx, obj, file, "read"); \
183
+ }else \
184
+ if(!js_canRead(cx, file)){ \
185
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
186
+ JSFILEMSG_CANNOT_READ, file->path); \
187
+ goto out; \
188
+ }
189
+
190
+ #define JSFILE_CHECK_OPEN(op) \
191
+ if(!file->isOpen){ \
192
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
193
+ JSFILEMSG_FILE_MUST_BE_CLOSED, op); \
194
+ goto out; \
195
+ }
196
+
197
+ #define JSFILE_CHECK_CLOSED(op) \
198
+ if(file->isOpen){ \
199
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
200
+ JSFILEMSG_FILE_MUST_BE_OPEN, op); \
201
+ goto out; \
202
+ }
203
+
204
+ #define JSFILE_CHECK_ONE_ARG(op) \
205
+ if (argc!=1){ \
206
+ char str[NUMBER_SIZE]; \
207
+ \
208
+ sprintf(str, "%d", argc); \
209
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \
210
+ JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str); \
211
+ goto out; \
212
+ }
213
+
214
+
215
+ /*
216
+ Security mechanism, should define a callback for this.
217
+ The parameters are as follows:
218
+ SECURITY_CHECK(JSContext *cx, JSPrincipals *ps, char *op_name, JSFile *file)
219
+ */
220
+ #define SECURITY_CHECK(cx, ps, op, file) \
221
+ /* Define a callback here... */
222
+
223
+
224
+ /* Structure representing the file internally */
225
+ typedef struct JSFile {
226
+ char *path; /* the path to the file. */
227
+ JSBool isOpen;
228
+ JSString *linebuffer; /* temp buffer used by readln. */
229
+ int32 mode; /* mode used to open the file: read, write, append, create, etc.. */
230
+ int32 type; /* Asciiz, utf, unicode */
231
+ char byteBuffer[3]; /* bytes read in advance by js_FileRead ( UTF8 encoding ) */
232
+ jsint nbBytesInBuf; /* number of bytes stored in the buffer above */
233
+ jschar charBuffer; /* character read in advance by readln ( mac files only ) */
234
+ JSBool charBufferUsed; /* flag indicating if the buffer above is being used */
235
+ JSBool hasRandomAccess; /* can the file be randomly accessed? false for stdin, and
236
+ UTF-encoded files. */
237
+ JSBool hasAutoflush; /* should we force a flush for each line break? */
238
+ JSBool isNative; /* if the file is using OS-specific file FILE type */
239
+ /* We can actually put the following two in a union since they should never be used at the same time */
240
+ PRFileDesc *handle; /* the handle for the file, if open. */
241
+ FILE *nativehandle; /* native handle, for stuff NSPR doesn't do. */
242
+ JSBool isPipe; /* if the file is really an OS pipe */
243
+ } JSFile;
244
+
245
+ /* a few forward declarations... */
246
+ static JSClass file_class;
247
+ JS_PUBLIC_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename);
248
+ static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
249
+ static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
250
+
251
+ /* --------------------------- New filename manipulation procesures -------------------------- */
252
+ /* assumes we don't have leading/trailing spaces */
253
+ static JSBool
254
+ js_filenameHasAPipe(const char *filename)
255
+ {
256
+ #ifdef XP_MAC
257
+ /* pipes are not supported on the MAC */
258
+ return JS_FALSE;
259
+ #else
260
+ if(!filename) return JS_FALSE;
261
+ return filename[0]==PIPE_SYMBOL ||
262
+ filename[strlen(filename)-1]==PIPE_SYMBOL;
263
+ #endif
264
+ }
265
+
266
+ static JSBool
267
+ js_isAbsolute(const char *name)
268
+ {
269
+ #if defined(XP_WIN) || defined(XP_OS2)
270
+ return (strlen(name)>1)?((name[1]==':')?JS_TRUE:JS_FALSE):JS_FALSE;
271
+ #else
272
+ return (name[0]
273
+ # if defined(XP_UNIX) || defined(XP_BEOS)
274
+ ==
275
+ # else
276
+ !=
277
+ # endif
278
+ FILESEPARATOR)?JS_TRUE:JS_FALSE;
279
+ #endif
280
+ }
281
+
282
+ /*
283
+ Concatinates base and name to produce a valid filename.
284
+ Returned string must be freed.
285
+ */
286
+ static char*
287
+ js_combinePath(JSContext *cx, const char *base, const char *name)
288
+ {
289
+ int len = strlen(base);
290
+ char* result = (char*)JS_malloc(cx, len+strlen(name)+2);
291
+
292
+ if (!result) return NULL;
293
+
294
+ strcpy(result, base);
295
+
296
+ if (base[len-1]!=FILESEPARATOR
297
+ #if defined(XP_WIN) || defined(XP_OS2)
298
+ && base[len-1]!=FILESEPARATOR2
299
+ #endif
300
+ ) {
301
+ result[len] = FILESEPARATOR;
302
+ result[len+1] = '\0';
303
+ }
304
+ strcat(result, name);
305
+ return result;
306
+ }
307
+
308
+ /* Extract the last component from a path name. Returned string must be freed */
309
+ static char *
310
+ js_fileBaseName(JSContext *cx, const char *pathname)
311
+ {
312
+ jsint index, aux;
313
+ char *result;
314
+
315
+ #if defined(XP_WIN) || defined(XP_OS2)
316
+ /* First, get rid of the drive selector */
317
+ if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
318
+ pathname = &pathname[2];
319
+ }
320
+ #endif
321
+ index = strlen(pathname)-1;
322
+ /*
323
+ remove trailing separators -- don't necessarily need to check for
324
+ FILESEPARATOR2, but that's fine
325
+ */
326
+ while ((index>0)&&((pathname[index]==FILESEPARATOR)||
327
+ (pathname[index]==FILESEPARATOR2))) index--;
328
+ aux = index;
329
+ /* now find the next separator */
330
+ while ((index>=0)&&(pathname[index]!=FILESEPARATOR)&&
331
+ (pathname[index]!=FILESEPARATOR2)) index--;
332
+ /* allocate and copy */
333
+ result = (char*)JS_malloc(cx, aux-index+1);
334
+ if (!result) return NULL;
335
+ strncpy(result, &pathname[index+1], aux-index);
336
+ result[aux-index] = '\0';
337
+ return result;
338
+ }
339
+
340
+ /*
341
+ Returns everytynig but the last component from a path name.
342
+ Returned string must be freed. Returned string must be freed.
343
+ */
344
+ static char *
345
+ js_fileDirectoryName(JSContext *cx, const char *pathname)
346
+ {
347
+ jsint index;
348
+ char *result;
349
+
350
+ #if defined(XP_WIN) || defined(XP_OS2)
351
+ char drive = '\0';
352
+ const char *oldpathname = pathname;
353
+
354
+ /* First, get rid of the drive selector */
355
+ if ((strlen(pathname)>=2)&&(pathname[1]==':')) {
356
+ drive = pathname[0];
357
+ pathname = &pathname[2];
358
+ }
359
+ #endif
360
+ index = strlen(pathname)-1;
361
+ while ((index>0)&&((pathname[index]==FILESEPARATOR)||
362
+ (pathname[index]==FILESEPARATOR2))) index--;
363
+ while ((index>0)&&(pathname[index]!=FILESEPARATOR)&&
364
+ (pathname[index]!=FILESEPARATOR2)) index--;
365
+
366
+ if (index>=0){
367
+ result = (char*)JS_malloc(cx, index+4);
368
+ if (!result) return NULL;
369
+ #if defined(XP_WIN) || defined(XP_OS2)
370
+ if (drive!='\0') {
371
+ result[0] = toupper(drive);
372
+ result[1] = ':';
373
+ strncpy(&result[2], pathname, index);
374
+ result[index+3] = '\0';
375
+ }else
376
+ #endif
377
+ {
378
+ strncpy(result, pathname, index);
379
+ result[index] = '\0';
380
+ }
381
+
382
+ /* add terminating separator */
383
+ index = strlen(result)-1;
384
+ result[index] = FILESEPARATOR;
385
+ result[index+1] = '\0';
386
+ } else{
387
+ #if defined(XP_WIN) || defined(XP_OS2)
388
+ result = JS_strdup(cx, oldpathname); /* may include drive selector */
389
+ #else
390
+ result = JS_strdup(cx, pathname);
391
+ #endif
392
+ }
393
+
394
+ return result;
395
+ }
396
+
397
+ static char *
398
+ js_absolutePath(JSContext *cx, const char * path)
399
+ {
400
+ JSObject *obj;
401
+ JSString *str;
402
+ jsval prop;
403
+
404
+ if (js_isAbsolute(path)){
405
+ return JS_strdup(cx, path);
406
+ }else{
407
+ obj = JS_GetGlobalObject(cx);
408
+ if (!JS_GetProperty(cx, obj, FILE_CONSTRUCTOR, &prop)) {
409
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
410
+ JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
411
+ return JS_strdup(cx, path);
412
+ }
413
+ obj = JSVAL_TO_OBJECT(prop);
414
+ if (!JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, &prop)) {
415
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
416
+ JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
417
+ return JS_strdup(cx, path);
418
+ }
419
+ str = JS_ValueToString(cx, prop);
420
+ if (!str ) {
421
+ return JS_strdup(cx, path);
422
+ }
423
+ /* should we have an array of curr dirs indexed by drive for windows? */
424
+ return js_combinePath(cx, JS_GetStringBytes(str), path);
425
+ }
426
+ }
427
+
428
+ /* Side effect: will remove spaces in the beginning/end of the filename */
429
+ static char *
430
+ js_canonicalPath(JSContext *cx, char *oldpath)
431
+ {
432
+ char *tmp;
433
+ char *path = oldpath;
434
+ char *base, *dir, *current, *result;
435
+ jsint c;
436
+ jsint back = 0;
437
+ unsigned int i = 0, j = strlen(path)-1;
438
+
439
+ /* This is probably optional */
440
+ /* Remove possible spaces in the beginning and end */
441
+ while(i<strlen(path)-1 && path[i]==' ') i++;
442
+ while(j>=0 && path[j]==' ') j--;
443
+
444
+ tmp = JS_malloc(cx, j-i+2);
445
+ strncpy(tmp, &path[i], j-i+1);
446
+ tmp[j-i+1] = '\0';
447
+
448
+ path = tmp;
449
+
450
+ /* pipe support */
451
+ if(js_filenameHasAPipe(path))
452
+ return JS_strdup(cx, path);
453
+ /* file:// support */
454
+ if(!strncmp(path, URL_PREFIX, strlen(URL_PREFIX)))
455
+ return js_canonicalPath(cx, &path[strlen(URL_PREFIX)-1]);
456
+
457
+ if (!js_isAbsolute(path))
458
+ path = js_absolutePath(cx, path);
459
+ else
460
+ path = JS_strdup(cx, path);
461
+
462
+ result = JS_strdup(cx, "");
463
+
464
+ current = path;
465
+
466
+ base = js_fileBaseName(cx, current);
467
+ dir = js_fileDirectoryName(cx, current);
468
+
469
+ /* TODO: MAC -- not going to work??? */
470
+ while (strcmp(dir, current)) {
471
+ if (!strcmp(base, "..")) {
472
+ back++;
473
+ } else
474
+ if(!strcmp(base, ".")){
475
+ /* ??? */
476
+ } else {
477
+ if (back>0)
478
+ back--;
479
+ else {
480
+ tmp = result;
481
+ result = JS_malloc(cx, strlen(base)+1+strlen(tmp)+1);
482
+ if (!result) {
483
+ JS_free(cx, dir);
484
+ JS_free(cx, base);
485
+ JS_free(cx, current);
486
+ return NULL;
487
+ }
488
+ strcpy(result, base);
489
+ c = strlen(result);
490
+ if (*tmp) {
491
+ result[c] = FILESEPARATOR;
492
+ result[c+1] = '\0';
493
+ strcat(result, tmp);
494
+ }
495
+ JS_free(cx, tmp);
496
+ }
497
+ }
498
+ JS_free(cx, current);
499
+ JS_free(cx, base);
500
+ current = dir;
501
+ base = js_fileBaseName(cx, current);
502
+ dir = js_fileDirectoryName(cx, current);
503
+ }
504
+
505
+ tmp = result;
506
+ result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1);
507
+ if (!result) {
508
+ JS_free(cx, dir);
509
+ JS_free(cx, base);
510
+ JS_free(cx, current);
511
+ return NULL;
512
+ }
513
+ strcpy(result, dir);
514
+ c = strlen(result);
515
+ if (tmp[0]!='\0') {
516
+ if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) {
517
+ result[c] = FILESEPARATOR;
518
+ result[c+1] = '\0';
519
+ }
520
+ strcat(result, tmp);
521
+ }
522
+ JS_free(cx, tmp);
523
+ JS_free(cx, dir);
524
+ JS_free(cx, base);
525
+ JS_free(cx, current);
526
+
527
+ return result;
528
+ }
529
+
530
+ /* -------------------------- Text conversion ------------------------------- */
531
+ /* The following is ripped from libi18n/unicvt.c and include files.. */
532
+
533
+ /*
534
+ * UTF8 defines and macros
535
+ */
536
+ #define ONE_OCTET_BASE 0x00 /* 0xxxxxxx */
537
+ #define ONE_OCTET_MASK 0x7F /* x1111111 */
538
+ #define CONTINUING_OCTET_BASE 0x80 /* 10xxxxxx */
539
+ #define CONTINUING_OCTET_MASK 0x3F /* 00111111 */
540
+ #define TWO_OCTET_BASE 0xC0 /* 110xxxxx */
541
+ #define TWO_OCTET_MASK 0x1F /* 00011111 */
542
+ #define THREE_OCTET_BASE 0xE0 /* 1110xxxx */
543
+ #define THREE_OCTET_MASK 0x0F /* 00001111 */
544
+ #define FOUR_OCTET_BASE 0xF0 /* 11110xxx */
545
+ #define FOUR_OCTET_MASK 0x07 /* 00000111 */
546
+ #define FIVE_OCTET_BASE 0xF8 /* 111110xx */
547
+ #define FIVE_OCTET_MASK 0x03 /* 00000011 */
548
+ #define SIX_OCTET_BASE 0xFC /* 1111110x */
549
+ #define SIX_OCTET_MASK 0x01 /* 00000001 */
550
+
551
+ #define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK ) == ONE_OCTET_BASE)
552
+ #define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK ) == TWO_OCTET_BASE)
553
+ #define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE)
554
+ #define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE)
555
+ #define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE)
556
+ #define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK ) == SIX_OCTET_BASE)
557
+ #define IS_UTF8_2ND_THRU_6TH(x) \
558
+ (( (x)&~CONTINUING_OCTET_MASK ) == CONTINUING_OCTET_BASE)
559
+ #define IS_UTF8_1ST_OF_UCS2(x) \
560
+ IS_UTF8_1ST_OF_1(x) \
561
+ || IS_UTF8_1ST_OF_2(x) \
562
+ || IS_UTF8_1ST_OF_3(x)
563
+
564
+
565
+ #define MAX_UCS2 0xFFFF
566
+ #define DEFAULT_CHAR 0x003F /* Default char is "?" */
567
+ #define BYTE_MASK 0xBF
568
+ #define BYTE_MARK 0x80
569
+
570
+
571
+ /* Function: one_ucs2_to_utf8_char
572
+ *
573
+ * Function takes one UCS-2 char and writes it to a UTF-8 buffer.
574
+ * We need a UTF-8 buffer because we don't know before this
575
+ * function how many bytes of utf-8 data will be written. It also
576
+ * takes a pointer to the end of the UTF-8 buffer so that we don't
577
+ * overwrite data. This function returns the number of UTF-8 bytes
578
+ * of data written, or -1 if the buffer would have been overrun.
579
+ */
580
+
581
+ #define LINE_SEPARATOR 0x2028
582
+ #define PARAGRAPH_SEPARATOR 0x2029
583
+ static int16 one_ucs2_to_utf8_char(unsigned char *tobufp,
584
+ unsigned char *tobufendp, uint16 onechar)
585
+ {
586
+
587
+ int16 numUTF8bytes = 0;
588
+
589
+ if((onechar == LINE_SEPARATOR)||(onechar == PARAGRAPH_SEPARATOR))
590
+ {
591
+ strcpy((char*)tobufp, "\n");
592
+ return strlen((char*)tobufp);;
593
+ }
594
+
595
+ if (onechar < 0x80) { numUTF8bytes = 1;
596
+ } else if (onechar < 0x800) { numUTF8bytes = 2;
597
+ } else if (onechar <= MAX_UCS2) { numUTF8bytes = 3;
598
+ } else { numUTF8bytes = 2;
599
+ onechar = DEFAULT_CHAR;
600
+ }
601
+
602
+ tobufp += numUTF8bytes;
603
+
604
+ /* return error if we don't have space for the whole character */
605
+ if (tobufp > tobufendp) {
606
+ return(-1);
607
+ }
608
+
609
+
610
+ switch(numUTF8bytes) {
611
+
612
+ case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
613
+ *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
614
+ *--tobufp = onechar | THREE_OCTET_BASE;
615
+ break;
616
+
617
+ case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
618
+ *--tobufp = onechar | TWO_OCTET_BASE;
619
+ break;
620
+ case 1: *--tobufp = (unsigned char)onechar; break;
621
+ }
622
+
623
+ return(numUTF8bytes);
624
+ }
625
+
626
+ /*
627
+ * utf8_to_ucs2_char
628
+ *
629
+ * Convert a utf8 multibyte character to ucs2
630
+ *
631
+ * inputs: pointer to utf8 character(s)
632
+ * length of utf8 buffer ("read" length limit)
633
+ * pointer to return ucs2 character
634
+ *
635
+ * outputs: number of bytes in the utf8 character
636
+ * -1 if not a valid utf8 character sequence
637
+ * -2 if the buffer is too short
638
+ */
639
+ static int16
640
+ utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p)
641
+ {
642
+ uint16 lead, cont1, cont2;
643
+
644
+ /*
645
+ * Check for minimum buffer length
646
+ */
647
+ if ((buflen < 1) || (utf8p == NULL)) {
648
+ return -2;
649
+ }
650
+ lead = (uint16) (*utf8p);
651
+
652
+ /*
653
+ * Check for a one octet sequence
654
+ */
655
+ if (IS_UTF8_1ST_OF_1(lead)) {
656
+ *ucs2p = lead & ONE_OCTET_MASK;
657
+ return 1;
658
+ }
659
+
660
+ /*
661
+ * Check for a two octet sequence
662
+ */
663
+ if (IS_UTF8_1ST_OF_2(*utf8p)) {
664
+ if (buflen < 2)
665
+ return -2;
666
+ cont1 = (uint16) *(utf8p+1);
667
+ if (!IS_UTF8_2ND_THRU_6TH(cont1))
668
+ return -1;
669
+ *ucs2p = (lead & TWO_OCTET_MASK) << 6;
670
+ *ucs2p |= cont1 & CONTINUING_OCTET_MASK;
671
+ return 2;
672
+ }
673
+
674
+ /*
675
+ * Check for a three octet sequence
676
+ */
677
+ else if (IS_UTF8_1ST_OF_3(lead)) {
678
+ if (buflen < 3)
679
+ return -2;
680
+ cont1 = (uint16) *(utf8p+1);
681
+ cont2 = (uint16) *(utf8p+2);
682
+ if ( (!IS_UTF8_2ND_THRU_6TH(cont1))
683
+ || (!IS_UTF8_2ND_THRU_6TH(cont2)))
684
+ return -1;
685
+ *ucs2p = (lead & THREE_OCTET_MASK) << 12;
686
+ *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6;
687
+ *ucs2p |= cont2 & CONTINUING_OCTET_MASK;
688
+ return 3;
689
+ }
690
+ else { /* not a valid utf8/ucs2 character */
691
+ return -1;
692
+ }
693
+ }
694
+
695
+ /* ----------------------------- Helper functions --------------------------- */
696
+ /* Ripped off from lm_win.c .. */
697
+ /* where is strcasecmp?.. for now, it's case sensitive..
698
+ *
699
+ * strcasecmp is in strings.h, but on windows it's called _stricmp...
700
+ * will need to #ifdef this
701
+ */
702
+
703
+ static int32
704
+ js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name)
705
+ {
706
+ char *comma, *equal, *current;
707
+ char *options = JS_strdup(cx, oldoptions);
708
+ int32 found = 0;
709
+
710
+ current = options;
711
+ for (;;) {
712
+ comma = strchr(current, ',');
713
+ if (comma) *comma = '\0';
714
+ equal = strchr(current, '=');
715
+ if (equal) *equal = '\0';
716
+ if (strcmp(current, name) == 0) {
717
+ if (!equal || strcmp(equal + 1, "yes") == 0)
718
+ found = 1;
719
+ else
720
+ found = atoi(equal + 1);
721
+ }
722
+ if (equal) *equal = '=';
723
+ if (comma) *comma = ',';
724
+ if (found || !comma)
725
+ break;
726
+ current = comma + 1;
727
+ }
728
+ JS_free(cx, options);
729
+ return found;
730
+ }
731
+
732
+ /* empty the buffer */
733
+ static void
734
+ js_ResetBuffers(JSFile * file)
735
+ {
736
+ file->charBufferUsed = JS_FALSE;
737
+ file->nbBytesInBuf = 0;
738
+ file->linebuffer = NULL; /* TODO: check for mem. leak? */
739
+ }
740
+
741
+ /* Reset file attributes */
742
+ static void
743
+ js_ResetAttributes(JSFile * file){
744
+ file->mode = file->type = 0;
745
+ file->isOpen = JS_FALSE;
746
+ file->handle = NULL;
747
+ file->nativehandle = NULL;
748
+ file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */
749
+ file->hasAutoflush = JS_FALSE;
750
+ file->isNative = JS_FALSE;
751
+ file->isPipe = JS_FALSE;
752
+
753
+ js_ResetBuffers(file);
754
+ }
755
+
756
+ static JSBool
757
+ js_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){
758
+ JSString *type, *mask;
759
+ jsval v[2];
760
+ jsval rval;
761
+
762
+ type = JS_InternString(cx, asciistring);
763
+ mask = JS_NewStringCopyZ(cx, mode);
764
+ v[0] = STRING_TO_JSVAL(mask);
765
+ v[1] = STRING_TO_JSVAL(type);
766
+
767
+ if (!file_open(cx, obj, 2, v, &rval)) {
768
+ return JS_FALSE;
769
+ }
770
+ return JS_TRUE;
771
+ }
772
+
773
+ /* Buffered version of PR_Read. Used by js_FileRead */
774
+ static int32
775
+ js_BufferedRead(JSFile * f, char *buf, int32 len)
776
+ {
777
+ int32 count = 0;
778
+
779
+ while (f->nbBytesInBuf>0&&len>0) {
780
+ buf[0] = f->byteBuffer[0];
781
+ f->byteBuffer[0] = f->byteBuffer[1];
782
+ f->byteBuffer[1] = f->byteBuffer[2];
783
+ f->nbBytesInBuf--;
784
+ len--;
785
+ buf+=1;
786
+ count++;
787
+ }
788
+
789
+ if (len>0) {
790
+ count+= (!f->isNative)?
791
+ PR_Read(f->handle, buf, len):
792
+ fread(buf, 1, len, f->nativehandle);
793
+ }
794
+ return count;
795
+ }
796
+
797
+ static int32
798
+ js_FileRead(JSContext *cx, JSFile * file, jschar*buf, int32 len, int32 mode)
799
+ {
800
+ unsigned char*aux;
801
+ int32 count, i;
802
+ jsint remainder;
803
+ unsigned char utfbuf[3];
804
+
805
+ if (file->charBufferUsed) {
806
+ buf[0] = file->charBuffer;
807
+ buf++;
808
+ len--;
809
+ file->charBufferUsed = JS_FALSE;
810
+ }
811
+
812
+ switch (mode) {
813
+ case ASCII:
814
+ aux = (unsigned char*)JS_malloc(cx, len);
815
+ if (!aux) {
816
+ return 0;
817
+ }
818
+ count = js_BufferedRead(file, aux, len);
819
+ if (count==-1) {
820
+ JS_free(cx, aux);
821
+ return 0;
822
+ }
823
+ for (i = 0;i<len;i++) {
824
+ buf[i] = (jschar)aux[i];
825
+ }
826
+ JS_free(cx, aux);
827
+ break;
828
+ case UTF8:
829
+ remainder = 0;
830
+ for (count = 0;count<len;count++) {
831
+ i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
832
+ if (i<=0) {
833
+ return count;
834
+ }
835
+ i = utf8_to_ucs2_char(utfbuf, (int16)i, &buf[count] );
836
+ if (i<0) {
837
+ return count;
838
+ } else {
839
+ if (i==1) {
840
+ utfbuf[0] = utfbuf[1];
841
+ utfbuf[1] = utfbuf[2];
842
+ remainder = 2;
843
+ } else
844
+ if (i==2) {
845
+ utfbuf[0] = utfbuf[2];
846
+ remainder = 1;
847
+ } else
848
+ if (i==3)
849
+ remainder = 0;
850
+ }
851
+ }
852
+ while (remainder>0) {
853
+ file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
854
+ file->nbBytesInBuf++;
855
+ utfbuf[0] = utfbuf[1];
856
+ utfbuf[1] = utfbuf[2];
857
+ remainder--;
858
+ }
859
+ break;
860
+ case UCS2:
861
+ count = js_BufferedRead(file, (char*)buf, len*2)>>1;
862
+ if (count==-1) {
863
+ return 0;
864
+ }
865
+ break;
866
+ }
867
+
868
+ if(count==-1){
869
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
870
+ JSFILEMSG_OP_FAILED, "read", file->path);
871
+ }
872
+
873
+ return count;
874
+ }
875
+
876
+ static int32
877
+ js_FileSeek(JSContext *cx, JSFile *file, int32 len, int32 mode)
878
+ {
879
+ int32 count, i;
880
+ jsint remainder;
881
+ unsigned char utfbuf[3];
882
+ jschar tmp;
883
+
884
+ switch (mode) {
885
+ case ASCII:
886
+ count = PR_Seek(file->handle, len, PR_SEEK_CUR);
887
+ break;
888
+ case UTF8:
889
+ remainder = 0;
890
+ for (count = 0;count<len;count++) {
891
+ i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
892
+ if (i<=0) {
893
+ return 0;
894
+ }
895
+ i = utf8_to_ucs2_char(utfbuf, (int16)i, &tmp );
896
+ if (i<0) {
897
+ return 0;
898
+ } else {
899
+
900
+ if (i==1) {
901
+ utfbuf[0] = utfbuf[1];
902
+ utfbuf[1] = utfbuf[2];
903
+ remainder = 2;
904
+ } else
905
+ if (i==2) {
906
+ utfbuf[0] = utfbuf[2];
907
+ remainder = 1;
908
+ } else
909
+ if (i==3)
910
+ remainder = 0;
911
+ }
912
+ }
913
+ while (remainder>0) {
914
+ file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
915
+ file->nbBytesInBuf++;
916
+ utfbuf[0] = utfbuf[1];
917
+ utfbuf[1] = utfbuf[2];
918
+ remainder--;
919
+ }
920
+ break;
921
+ case UCS2:
922
+ count = PR_Seek(file->handle, len*2, PR_SEEK_CUR)/2;
923
+ break;
924
+ }
925
+
926
+ if(count==-1){
927
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
928
+ JSFILEMSG_OP_FAILED, "seek", file->path);
929
+ }
930
+
931
+ return count;
932
+ }
933
+
934
+ static int32
935
+ js_FileWrite(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
936
+ {
937
+ unsigned char *aux;
938
+ int32 count, i, j;
939
+ unsigned char *utfbuf;
940
+
941
+ switch (mode) {
942
+ case ASCII:
943
+ aux = (unsigned char*)JS_malloc(cx, len);
944
+ if (!aux) return 0;
945
+
946
+ for (i = 0; i<len; i++) {
947
+ aux[i]=buf[i]%256;
948
+ }
949
+
950
+ count = (!file->isNative)?
951
+ PR_Write(file->handle, aux, len):
952
+ fwrite(aux, 1, len, file->nativehandle);
953
+
954
+ if (count==-1) {
955
+ JS_free(cx, aux);
956
+ return 0;
957
+ }
958
+ JS_free(cx, aux);
959
+ break;
960
+ case UTF8:
961
+ utfbuf = (unsigned char*)JS_malloc(cx, len*3);
962
+ if (!utfbuf) return 0;
963
+ i = 0;
964
+ for (count = 0;count<len;count++) {
965
+ j = one_ucs2_to_utf8_char(utfbuf+i, utfbuf+len*3, buf[count]);
966
+ if (j==-1) {
967
+ JS_free(cx, utfbuf);
968
+ return 0;
969
+ }
970
+ i+=j;
971
+ }
972
+ j = (!file->isNative)?
973
+ PR_Write(file->handle, utfbuf, i):
974
+ fwrite(utfbuf, 1, i, file->nativehandle);
975
+
976
+ if (j<i) {
977
+ JS_free(cx, utfbuf);
978
+ return 0;
979
+ }
980
+ JS_free(cx, utfbuf);
981
+ break;
982
+ case UCS2:
983
+ count = (!file->isNative)?
984
+ PR_Write(file->handle, buf, len*2)>>1:
985
+ fwrite(buf, 1, len*2, file->nativehandle)>>1;
986
+
987
+ if (count==-1) {
988
+ return 0;
989
+ }
990
+ break;
991
+ }
992
+ if(count==-1){
993
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
994
+ JSFILEMSG_OP_FAILED, "write", file->path);
995
+ }
996
+ return count;
997
+ }
998
+
999
+ /* ----------------------------- Property checkers -------------------------- */
1000
+ static JSBool
1001
+ js_exists(JSContext *cx, JSFile *file)
1002
+ {
1003
+ if(!file->isNative){
1004
+ return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS);
1005
+ }else{
1006
+ /* doesn't make sense for a pipe of stdstream */
1007
+ return JS_FALSE;
1008
+ }
1009
+ }
1010
+
1011
+ static JSBool
1012
+ js_canRead(JSContext *cx, JSFile *file)
1013
+ {
1014
+ if(!file->isNative){
1015
+ if(file->isOpen&&!(file->mode&PR_RDONLY)) return JS_FALSE;
1016
+ return (PR_Access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS);
1017
+ }else{
1018
+ if(file->isPipe){
1019
+ /* pipe open for reading */
1020
+ return file->path[0]==PIPE_SYMBOL;
1021
+ }else{
1022
+ return !strcmp(file->path, STDINPUT_NAME);
1023
+ }
1024
+ }
1025
+ }
1026
+
1027
+ static JSBool
1028
+ js_canWrite(JSContext *cx, JSFile *file)
1029
+ {
1030
+ if(!file->isNative){
1031
+ if(file->isOpen&&!(file->mode&PR_WRONLY)) return JS_FALSE;
1032
+ return (PR_Access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS);
1033
+ }else{
1034
+ if(file->isPipe){
1035
+ /* pipe open for writing */
1036
+ return file->path[strlen(file->path)-1]==PIPE_SYMBOL;
1037
+ }else{
1038
+ return !strcmp(file->path, STDOUTPUT_NAME) ||
1039
+ !strcmp(file->path, STDERROR_NAME);
1040
+ }
1041
+ }
1042
+ }
1043
+
1044
+ static JSBool
1045
+ js_isFile(JSContext *cx, JSFile *file)
1046
+ {
1047
+ if(!file->isNative){
1048
+ PRFileInfo info;
1049
+
1050
+ if ((file->isOpen)?
1051
+ PR_GetOpenFileInfo(file->handle, &info):
1052
+ PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1053
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1054
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1055
+ return JS_FALSE;
1056
+ }else
1057
+ return (info.type==PR_FILE_FILE);
1058
+ }else{
1059
+ /* doesn't make sense for a pipe of stdstream */
1060
+ return JS_FALSE;
1061
+ }
1062
+ }
1063
+
1064
+ static JSBool
1065
+ js_isDirectory(JSContext *cx, JSFile *file)
1066
+ {
1067
+ if(!file->isNative){
1068
+ PRFileInfo info;
1069
+
1070
+ /* hack needed to get get_property to work */
1071
+ if(!js_exists(cx, file)) return JS_FALSE;
1072
+
1073
+ if ((file->isOpen)?
1074
+ PR_GetOpenFileInfo(file->handle, &info):
1075
+ PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1076
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1077
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1078
+ return JS_FALSE;
1079
+ }else
1080
+ return (info.type==PR_FILE_DIRECTORY);
1081
+ }else{
1082
+ /* doesn't make sense for a pipe of stdstream */
1083
+ return JS_FALSE;
1084
+ }
1085
+ }
1086
+
1087
+ static jsval
1088
+ js_size(JSContext *cx, JSFile *file)
1089
+ {
1090
+ PRFileInfo info;
1091
+
1092
+ JSFILE_CHECK_NATIVE("size");
1093
+
1094
+ if ((file->isOpen)?
1095
+ PR_GetOpenFileInfo(file->handle, &info):
1096
+ PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){
1097
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1098
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
1099
+ goto out;
1100
+ }else
1101
+ return INT_TO_JSVAL(info.size);
1102
+ out:
1103
+ return JSVAL_VOID;
1104
+ }
1105
+
1106
+ /* Return the parent object */
1107
+ static jsval
1108
+ js_parent(JSContext *cx, JSFile *file)
1109
+ {
1110
+ char *str;
1111
+
1112
+ /* since we only care about pipes and native files, return NULL */
1113
+ if(file->isNative) return JSVAL_VOID;
1114
+
1115
+ str = js_fileDirectoryName(cx, file->path);
1116
+ /* root.parent = null ??? */
1117
+ if(!strcmp(file->path, str) ||
1118
+ (!strncmp(str, file->path, strlen(str)-1)&&
1119
+ file->path[strlen(file->path)]-1)==FILESEPARATOR){
1120
+ return JSVAL_NULL;
1121
+ }else{
1122
+ return OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
1123
+ JS_free(cx, str);
1124
+ }
1125
+ }
1126
+
1127
+ static jsval
1128
+ js_name(JSContext *cx, JSFile *file){
1129
+ return file->isPipe?
1130
+ JSVAL_VOID:
1131
+ STRING_TO_JSVAL(JS_NewStringCopyZ(cx, js_fileBaseName(cx, file->path)));
1132
+ }
1133
+
1134
+ /* ------------------------------ File object methods ---------------------------- */
1135
+ static JSBool
1136
+ file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1137
+ {
1138
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1139
+ JSString *strmode, *strtype;
1140
+ char *ctype, *mode;
1141
+ int32 mask, type;
1142
+ int len;
1143
+
1144
+ SECURITY_CHECK(cx, NULL, "open", file);
1145
+
1146
+ /* A native file that is already open */
1147
+ if(file->isOpen && file->isNative){
1148
+ JS_ReportWarning(cx, "Native file %s is already open, proceeding",
1149
+ file->path);
1150
+ goto good;
1151
+ }
1152
+
1153
+ /* Close before proceeding */
1154
+ if (file->isOpen) {
1155
+ JS_ReportWarning(cx,
1156
+ "File %s is already open, we will close it and reopen, proceeding",
1157
+ file->path);
1158
+ if(!file_close(cx, obj, 0, NULL, rval)) goto out;
1159
+ }
1160
+
1161
+ if(js_isDirectory(cx, file)){
1162
+ JS_ReportWarning(cx, "%s seems to be a directory, there is no point in "
1163
+ "trying to open it, proceeding", file->path);
1164
+ goto good;
1165
+ }
1166
+
1167
+ /* Path must be defined at this point */
1168
+ len = strlen(file->path);
1169
+
1170
+ /* Mode */
1171
+ if (argc>=1){
1172
+ strmode = JS_ValueToString(cx, argv[0]);
1173
+ if (!strmode){
1174
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1175
+ JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[0]);
1176
+ goto out;
1177
+ }
1178
+ mode = JS_strdup(cx, JS_GetStringBytes(strmode));
1179
+ }else{
1180
+ if(file->path[0]==PIPE_SYMBOL){
1181
+ /* pipe default mode */
1182
+ mode = JS_strdup(cx, "read");
1183
+ }else
1184
+ if(file->path[len-1]==PIPE_SYMBOL){
1185
+ /* pipe default mode */
1186
+ mode = JS_strdup(cx, "write");
1187
+ }else{
1188
+ /* non-destructive, permissive defaults. */
1189
+ mode = JS_strdup(cx, "readWrite,append,create");
1190
+ }
1191
+ }
1192
+
1193
+ /* Process the mode */
1194
+ mask = 0;
1195
+ /* TODO: this is pretty ugly, BTW, we walk thru the string too many times */
1196
+ mask|=(js_FileHasOption(cx, mode, "read"))? PR_RDONLY : 0;
1197
+ mask|=(js_FileHasOption(cx, mode, "write"))? PR_WRONLY : 0;
1198
+ mask|=(js_FileHasOption(cx, mode, "readWrite"))? PR_RDWR : 0;
1199
+ mask|=(js_FileHasOption(cx, mode, "append"))? PR_APPEND : 0;
1200
+ mask|=(js_FileHasOption(cx, mode, "create"))? PR_CREATE_FILE : 0;
1201
+ mask|=(js_FileHasOption(cx, mode, "replace"))? PR_TRUNCATE : 0;
1202
+
1203
+ if((mask&PR_RDWR)) mask|=(PR_RDONLY|PR_WRONLY);
1204
+ if((mask&PR_RDONLY)&&(mask&PR_WRONLY)) mask|=PR_RDWR;
1205
+
1206
+ file->hasAutoflush|=(js_FileHasOption(cx, mode, "autoflush"));
1207
+
1208
+ /* Type */
1209
+ if (argc>1) {
1210
+ strtype = JS_ValueToString(cx, argv[1]);
1211
+ if (!strtype) {
1212
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1213
+ JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[1]);
1214
+ goto out;
1215
+ }
1216
+ ctype = JS_GetStringBytes(strtype);
1217
+
1218
+ if(!strcmp(ctype, utfstring))
1219
+ type = UTF8;
1220
+ else
1221
+ if (!strcmp(ctype, unicodestring))
1222
+ type = UCS2;
1223
+ else{
1224
+ if(strcmp(ctype, asciistring)){
1225
+ JS_ReportWarning(cx, "File type %s is not supported, using "
1226
+ "'text' instead, proceeding", ctype);
1227
+ }
1228
+ type = ASCII;
1229
+ }
1230
+ }else{
1231
+ type = ASCII;
1232
+ }
1233
+
1234
+ /* Save the relevant fields */
1235
+ file->type = type;
1236
+ file->mode = mask;
1237
+ file->nativehandle = NULL;
1238
+ file->hasRandomAccess = (type!=UTF8);
1239
+
1240
+ /*
1241
+ Deal with pipes here. We can't use NSPR for pipes,
1242
+ so we have to use POPEN.
1243
+ */
1244
+ if(file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL){
1245
+ if(file->path[0]==PIPE_SYMBOL && file->path[len-1]==PIPE_SYMBOL){
1246
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1247
+ JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
1248
+ goto out;
1249
+ }else{
1250
+ char pipemode[3];
1251
+ SECURITY_CHECK(cx, NULL, "pipe_open", file);
1252
+
1253
+ if(file->path[0] == PIPE_SYMBOL){
1254
+ if(mask & (PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE)){
1255
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1256
+ JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
1257
+ mode, file->path);
1258
+ goto out;
1259
+ }
1260
+ /* open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") -- pipe for writing */
1261
+ pipemode[0] = 'r';
1262
+ pipemode[1] = file->type==UTF8?'b':'t';
1263
+ pipemode[2] = '\0';
1264
+ file->nativehandle = POPEN(&file->path[1], pipemode);
1265
+ }else
1266
+ if(file->path[len-1] == PIPE_SYMBOL){
1267
+ char *command = JS_malloc(cx, len);
1268
+
1269
+ strncpy(command, file->path, len-1);
1270
+ command[len-1] = '\0';
1271
+ /* open(STATUS, "netstat -an 2>&1 |") */
1272
+ pipemode[0] = 'w';
1273
+ pipemode[1] = file->type==UTF8?'b':'t';
1274
+ pipemode[2] = '\0';
1275
+ file->nativehandle = POPEN(command, pipemode);
1276
+ JS_free(cx, command);
1277
+ }
1278
+ /* set the flags */
1279
+ file->isNative = JS_TRUE;
1280
+ file->isPipe = JS_TRUE;
1281
+ file->hasRandomAccess = JS_FALSE;
1282
+ }
1283
+ }else{
1284
+ /* TODO: what about the permissions?? Java ignores the problem... */
1285
+ file->handle = PR_Open(file->path, mask, 0644);
1286
+ }
1287
+
1288
+ js_ResetBuffers(file);
1289
+ JS_free(cx, mode);
1290
+ mode = NULL;
1291
+
1292
+ /* Set the open flag and return result */
1293
+ if (file->handle==NULL && file->nativehandle==NULL){
1294
+ file->isOpen = JS_FALSE;
1295
+
1296
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1297
+ JSFILEMSG_OP_FAILED, "open", file->path);
1298
+ goto out;
1299
+ }else
1300
+ goto good;
1301
+ good:
1302
+ file->isOpen = JS_TRUE;
1303
+ *rval = JSVAL_TRUE;
1304
+ return JS_TRUE;
1305
+ out:
1306
+ if(mode) JS_free(cx, mode);
1307
+ *rval = JSVAL_VOID;
1308
+ return JS_FALSE;
1309
+ }
1310
+
1311
+ static JSBool
1312
+ file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1313
+ {
1314
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1315
+
1316
+ SECURITY_CHECK(cx, NULL, "close", file);
1317
+
1318
+ if(!file->isOpen){
1319
+ JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding",
1320
+ file->path);
1321
+ goto out;
1322
+ }
1323
+
1324
+ if(!file->isPipe){
1325
+ if(file->isNative){
1326
+ JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path);
1327
+ goto out;
1328
+ }else{
1329
+ if(file->handle && PR_Close(file->handle)){
1330
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1331
+ JSFILEMSG_OP_FAILED, "close", file->path);
1332
+
1333
+ goto out;
1334
+ }
1335
+ }
1336
+ }else{
1337
+ if(PCLOSE(file->nativehandle)==-1){
1338
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1339
+ JSFILEMSG_OP_FAILED, "pclose", file->path);
1340
+ goto out;
1341
+ }
1342
+ }
1343
+
1344
+ js_ResetAttributes(file);
1345
+ *rval = JSVAL_TRUE;
1346
+ return JS_TRUE;
1347
+ out:
1348
+ *rval = JSVAL_FALSE;
1349
+ return JS_FALSE;
1350
+ }
1351
+
1352
+
1353
+ static JSBool
1354
+ file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1355
+ {
1356
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1357
+
1358
+ SECURITY_CHECK(cx, NULL, "remove", file);
1359
+ JSFILE_CHECK_NATIVE("remove");
1360
+ JSFILE_CHECK_CLOSED("remove");
1361
+
1362
+ if ((js_isDirectory(cx, file) ?
1363
+ PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
1364
+ js_ResetAttributes(file);
1365
+ *rval = JSVAL_TRUE;
1366
+ return JS_TRUE;
1367
+ } else {
1368
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1369
+ JSFILEMSG_OP_FAILED, "remove", file->path);
1370
+ goto out;
1371
+ }
1372
+ out:
1373
+ *rval = JSVAL_FALSE;
1374
+ return JS_FALSE;
1375
+ }
1376
+
1377
+ /* Raw PR-based function. No text processing. Just raw data copying. */
1378
+ static JSBool
1379
+ file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1380
+ {
1381
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1382
+ char *dest = NULL;
1383
+ PRFileDesc *handle = NULL;
1384
+ char *buffer;
1385
+ jsval count, size;
1386
+ JSBool fileInitiallyOpen=JS_FALSE;
1387
+
1388
+ SECURITY_CHECK(cx, NULL, "copyTo", file); /* may need a second argument!*/
1389
+ JSFILE_CHECK_ONE_ARG("copyTo");
1390
+ JSFILE_CHECK_NATIVE("copyTo");
1391
+ /* remeber the state */
1392
+ fileInitiallyOpen = file->isOpen;
1393
+ JSFILE_CHECK_READ;
1394
+
1395
+ dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
1396
+
1397
+ /* make sure we are not reading a file open for writing */
1398
+ if (file->isOpen && !js_canRead(cx, file)) {
1399
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1400
+ JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path);
1401
+ goto out;
1402
+ }
1403
+
1404
+ if (file->handle==NULL){
1405
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1406
+ JSFILEMSG_OP_FAILED, "open", file->path);
1407
+ goto out;
1408
+ }
1409
+
1410
+ handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644);
1411
+
1412
+ if(!handle){
1413
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1414
+ JSFILEMSG_OP_FAILED, "open", dest);
1415
+ goto out;
1416
+ }
1417
+
1418
+ if ((size=js_size(cx, file))==JSVAL_VOID) {
1419
+ goto out;
1420
+ }
1421
+
1422
+ buffer = JS_malloc(cx, size);
1423
+
1424
+ count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size));
1425
+
1426
+ /* reading panic */
1427
+ if (count!=size) {
1428
+ JS_free(cx, buffer);
1429
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1430
+ JSFILEMSG_COPY_READ_ERROR, file->path);
1431
+ goto out;
1432
+ }
1433
+
1434
+ count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size)));
1435
+
1436
+ /* writing panic */
1437
+ if (count!=size) {
1438
+ JS_free(cx, buffer);
1439
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1440
+ JSFILEMSG_COPY_WRITE_ERROR, file->path);
1441
+ goto out;
1442
+ }
1443
+
1444
+ JS_free(cx, buffer);
1445
+
1446
+ if(!fileInitiallyOpen){
1447
+ if(!file_close(cx, obj, 0, NULL, rval)) goto out;
1448
+ }
1449
+
1450
+ if(PR_Close(handle)!=PR_SUCCESS){
1451
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1452
+ JSFILEMSG_OP_FAILED, "close", dest);
1453
+ goto out;
1454
+ }
1455
+
1456
+ *rval = JSVAL_TRUE;
1457
+ return JS_TRUE;
1458
+ out:
1459
+ if(file->isOpen && !fileInitiallyOpen){
1460
+ if(PR_Close(file->handle)!=PR_SUCCESS){
1461
+ JS_ReportWarning(cx, "Can't close %s, proceeding", file->path);
1462
+ }
1463
+ }
1464
+
1465
+ if(handle && PR_Close(handle)!=PR_SUCCESS){
1466
+ JS_ReportWarning(cx, "Can't close %s, proceeding", dest);
1467
+ }
1468
+
1469
+ *rval = JSVAL_FALSE;
1470
+ return JS_FALSE;
1471
+ }
1472
+
1473
+ static JSBool
1474
+ file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1475
+ {
1476
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1477
+ char *dest;
1478
+
1479
+ SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/
1480
+ JSFILE_CHECK_ONE_ARG("renameTo");
1481
+ JSFILE_CHECK_NATIVE("renameTo");
1482
+ JSFILE_CHECK_CLOSED("renameTo");
1483
+
1484
+ dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
1485
+
1486
+ if (PR_Rename(file->path, dest)==PR_SUCCESS){
1487
+ /* copy the new filename */
1488
+ JS_free(cx, file->path);
1489
+ file->path = dest;
1490
+ *rval = JSVAL_TRUE;
1491
+ return JS_TRUE;
1492
+ }else{
1493
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1494
+ JSFILEMSG_RENAME_FAILED, file->path, dest);
1495
+ goto out;
1496
+ }
1497
+ out:
1498
+ *rval = JSVAL_FALSE;
1499
+ return JS_FALSE;
1500
+ }
1501
+
1502
+ static JSBool
1503
+ file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1504
+ {
1505
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1506
+
1507
+ SECURITY_CHECK(cx, NULL, "flush", file);
1508
+ JSFILE_CHECK_NATIVE("flush");
1509
+ JSFILE_CHECK_OPEN("flush");
1510
+
1511
+ if (PR_Sync(file->handle)==PR_SUCCESS){
1512
+ *rval = JSVAL_TRUE;
1513
+ return JS_TRUE;
1514
+ }else{
1515
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1516
+ JSFILEMSG_OP_FAILED, "flush", file->path);
1517
+ goto out;
1518
+ }
1519
+ out:
1520
+ *rval = JSVAL_FALSE;
1521
+ return JS_FALSE;
1522
+ }
1523
+
1524
+ static JSBool
1525
+ file_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1526
+ {
1527
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1528
+ JSString *str;
1529
+ int32 count;
1530
+ uintN i;
1531
+
1532
+ SECURITY_CHECK(cx, NULL, "write", file);
1533
+ JSFILE_CHECK_WRITE;
1534
+
1535
+ for (i = 0; i<argc; i++) {
1536
+ str = JS_ValueToString(cx, argv[i]);
1537
+ count = js_FileWrite(cx, file, JS_GetStringChars(str),
1538
+ JS_GetStringLength(str), file->type);
1539
+ if (count==-1){
1540
+ *rval = JSVAL_FALSE;
1541
+ return JS_FALSE;
1542
+ }
1543
+ }
1544
+
1545
+ *rval = JSVAL_TRUE;
1546
+ return JS_TRUE;
1547
+ out:
1548
+ *rval = JSVAL_FALSE;
1549
+ return JS_FALSE;
1550
+ }
1551
+
1552
+ static JSBool
1553
+ file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1554
+ {
1555
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1556
+ JSString *str;
1557
+
1558
+ SECURITY_CHECK(cx, NULL, "writeln", file);
1559
+ JSFILE_CHECK_WRITE;
1560
+
1561
+ /* don't report an error here */
1562
+ if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE;
1563
+ /* don't do security here -- we passed the check in file_write */
1564
+ str = JS_NewStringCopyZ(cx, "\n");
1565
+
1566
+ if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str),
1567
+ file->type)==-1){
1568
+ *rval = JSVAL_FALSE;
1569
+ return JS_FALSE;
1570
+ }
1571
+
1572
+ /* eol causes flush if hasAutoflush is turned on */
1573
+ if (file->hasAutoflush)
1574
+ file_flush(cx, obj, 0, NULL, rval);
1575
+
1576
+ *rval = JSVAL_TRUE;
1577
+ return JS_TRUE;
1578
+ out:
1579
+ *rval = JSVAL_FALSE;
1580
+ return JS_FALSE;
1581
+ }
1582
+
1583
+ static JSBool
1584
+ file_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1585
+ {
1586
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1587
+ jsuint i;
1588
+ jsuint limit;
1589
+ JSObject *array;
1590
+ JSObject *elem;
1591
+ jsval elemval;
1592
+
1593
+ SECURITY_CHECK(cx, NULL, "writeAll", file);
1594
+ JSFILE_CHECK_ONE_ARG("writeAll");
1595
+ JSFILE_CHECK_WRITE;
1596
+
1597
+ if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) {
1598
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1599
+ JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR);
1600
+ goto out;
1601
+ }
1602
+
1603
+ array = JSVAL_TO_OBJECT(argv[0]);
1604
+
1605
+ JS_GetArrayLength(cx, array, &limit);
1606
+
1607
+ for (i = 0; i<limit; i++) {
1608
+ if (!JS_GetElement(cx, array, i, &elemval)) return JS_FALSE;
1609
+ elem = JSVAL_TO_OBJECT(elemval);
1610
+ file_writeln(cx, obj, 1, &elemval, rval);
1611
+ }
1612
+
1613
+ *rval = JSVAL_TRUE;
1614
+ return JS_TRUE;
1615
+ out:
1616
+ *rval = JSVAL_FALSE;
1617
+ return JS_FALSE;
1618
+ }
1619
+
1620
+ static JSBool
1621
+ file_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1622
+ {
1623
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1624
+ JSString *str;
1625
+ int32 want, count;
1626
+ jschar *buf;
1627
+
1628
+ SECURITY_CHECK(cx, NULL, "read", file);
1629
+ JSFILE_CHECK_ONE_ARG("read");
1630
+ JSFILE_CHECK_READ;
1631
+
1632
+ if (!JS_ValueToInt32(cx, argv[0], &want)){
1633
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1634
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "read", argv[0]);
1635
+ goto out;
1636
+ }
1637
+
1638
+ /* want = (want>262144)?262144:want; * arbitrary size limitation */
1639
+
1640
+ buf = JS_malloc(cx, want*sizeof buf[0]);
1641
+ if (!buf) goto out;
1642
+
1643
+ count = js_FileRead(cx, file, buf, want, file->type);
1644
+ if (count>0) {
1645
+ str = JS_NewUCStringCopyN(cx, buf, count);
1646
+ *rval = STRING_TO_JSVAL(str);
1647
+ JS_free(cx, buf);
1648
+ return JS_TRUE;
1649
+ } else {
1650
+ JS_free(cx, buf);
1651
+ goto out;
1652
+ }
1653
+ out:
1654
+ *rval = JSVAL_FALSE;
1655
+ return JS_FALSE;
1656
+ }
1657
+
1658
+ static JSBool
1659
+ file_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1660
+ {
1661
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1662
+ JSString *str;
1663
+ jschar *buf;
1664
+ int32 offset;
1665
+ intN room;
1666
+ jschar data, data2;
1667
+ JSBool endofline;
1668
+
1669
+ SECURITY_CHECK(cx, NULL, "readln", file);
1670
+ JSFILE_CHECK_READ;
1671
+
1672
+ if (!file->linebuffer) {
1673
+ buf = JS_malloc(cx, MAX_LINE_LENGTH*(sizeof data));
1674
+ if (!buf) goto out;
1675
+ file->linebuffer = JS_NewUCString(cx, buf, MAX_LINE_LENGTH);
1676
+ }
1677
+ room = JS_GetStringLength(file->linebuffer);
1678
+ offset = 0;
1679
+
1680
+ /* XXX TEST ME!! TODO: yes, please do */
1681
+ for(;;) {
1682
+ if (!js_FileRead(cx, file, &data, 1, file->type)) {
1683
+ endofline = JS_FALSE;
1684
+ goto loop;
1685
+ }
1686
+ switch (data) {
1687
+ case '\n' :
1688
+ endofline = JS_TRUE;
1689
+ goto loop;
1690
+ case '\r' :
1691
+ if (!js_FileRead(cx, file, &data2, 1, file->type)) {
1692
+ endofline = JS_TRUE;
1693
+ goto loop;
1694
+ }
1695
+ if (data2!='\n') { /* We read one char too far. Buffer it. */
1696
+ file->charBuffer = data2;
1697
+ file->charBufferUsed = JS_TRUE;
1698
+ }
1699
+ endofline = JS_TRUE;
1700
+ goto loop;
1701
+ default:
1702
+ if (--room < 0) {
1703
+ buf = JS_malloc(cx, (offset+MAX_LINE_LENGTH)*sizeof data);
1704
+ if (!buf) return JS_FALSE;
1705
+ room = MAX_LINE_LENGTH-1;
1706
+ memcpy(buf, JS_GetStringChars(file->linebuffer),
1707
+ JS_GetStringLength(file->linebuffer));
1708
+ /* what follows may not be the cleanest way. */
1709
+ file->linebuffer->chars = buf;
1710
+ file->linebuffer->length = offset+MAX_LINE_LENGTH;
1711
+ }
1712
+ file->linebuffer->chars[offset++] = data;
1713
+ break;
1714
+ }
1715
+ }
1716
+ loop:
1717
+ file->linebuffer->chars[offset] = 0;
1718
+ if ((endofline==JS_TRUE)) {
1719
+ str = JS_NewUCStringCopyN(cx, JS_GetStringChars(file->linebuffer),
1720
+ offset);
1721
+ *rval = STRING_TO_JSVAL(str);
1722
+ return JS_TRUE;
1723
+ }else{
1724
+ goto out;
1725
+ }
1726
+ out:
1727
+ *rval = JSVAL_NULL;
1728
+ return JS_FALSE;
1729
+ }
1730
+
1731
+ static JSBool
1732
+ file_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1733
+ {
1734
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1735
+ JSObject *array;
1736
+ jsint len;
1737
+ jsval line;
1738
+
1739
+ SECURITY_CHECK(cx, NULL, "readAll", file);
1740
+ JSFILE_CHECK_READ;
1741
+
1742
+ array = JS_NewArrayObject(cx, 0, NULL);
1743
+ len = 0;
1744
+
1745
+ while(file_readln(cx, obj, 0, NULL, &line)){
1746
+ JS_SetElement(cx, array, len, &line);
1747
+ len++;
1748
+ }
1749
+
1750
+ *rval = OBJECT_TO_JSVAL(array);
1751
+ return JS_TRUE;
1752
+ out:
1753
+ *rval = JSVAL_FALSE;
1754
+ return JS_FALSE;
1755
+ }
1756
+
1757
+ static JSBool
1758
+ file_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1759
+ {
1760
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1761
+ int32 toskip;
1762
+ int32 pos;
1763
+
1764
+ SECURITY_CHECK(cx, NULL, "seek", file);
1765
+ JSFILE_CHECK_ONE_ARG("seek");
1766
+ JSFILE_CHECK_NATIVE("seek");
1767
+ JSFILE_CHECK_READ;
1768
+
1769
+ if (!JS_ValueToInt32(cx, argv[0], &toskip)){
1770
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1771
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "seek", argv[0]);
1772
+ goto out;
1773
+ }
1774
+
1775
+ if(!file->hasRandomAccess){
1776
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1777
+ JSFILEMSG_NO_RANDOM_ACCESS, file->path);
1778
+ goto out;
1779
+ }
1780
+
1781
+ if(js_isDirectory(cx, file)){
1782
+ JS_ReportWarning(cx,"Seek on directories is not supported, proceeding");
1783
+ goto out;
1784
+ }
1785
+
1786
+ pos = js_FileSeek(cx, file, toskip, file->type);
1787
+
1788
+ if (pos!=-1) {
1789
+ *rval = INT_TO_JSVAL(pos);
1790
+ return JS_TRUE;
1791
+ }
1792
+ out:
1793
+ *rval = JSVAL_VOID;
1794
+ return JS_FALSE;
1795
+ }
1796
+
1797
+ static JSBool
1798
+ file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1799
+ {
1800
+ PRDir *dir;
1801
+ PRDirEntry *entry;
1802
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1803
+ JSObject *array;
1804
+ JSObject *eachFile;
1805
+ jsint len;
1806
+ jsval v;
1807
+ JSRegExp *re = NULL;
1808
+ JSFunction *func = NULL;
1809
+ JSString *str;
1810
+ jsval args[1];
1811
+ char *filePath;
1812
+
1813
+ SECURITY_CHECK(cx, NULL, "list", file);
1814
+ JSFILE_CHECK_NATIVE("list");
1815
+
1816
+ if (argc==1) {
1817
+ if (JSVAL_IS_REGEXP(cx, argv[0])) {
1818
+ re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
1819
+ }else
1820
+ if (JSVAL_IS_FUNCTION(cx, argv[0])) {
1821
+ func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
1822
+ }else{
1823
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1824
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, argv[0]);
1825
+ goto out;
1826
+ }
1827
+ }
1828
+
1829
+ if (!js_isDirectory(cx, file)) {
1830
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1831
+ JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, file->path);
1832
+ goto out;
1833
+ }
1834
+
1835
+ dir = PR_OpenDir(file->path);
1836
+ if(!dir){
1837
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1838
+ JSFILEMSG_OP_FAILED, "open", file->path);
1839
+ goto out;
1840
+ }
1841
+
1842
+ /* create JSArray here... */
1843
+ array = JS_NewArrayObject(cx, 0, NULL);
1844
+ len = 0;
1845
+
1846
+ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) {
1847
+ /* first, check if we have a regexp */
1848
+ if (re!=NULL) {
1849
+ size_t index = 0;
1850
+
1851
+ str = JS_NewStringCopyZ(cx, entry->name);
1852
+ if(!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &v)){
1853
+ /* don't report anything here */
1854
+ goto out;
1855
+ }
1856
+ /* not matched! */
1857
+ if (JSVAL_IS_NULL(v)) {
1858
+ continue;
1859
+ }
1860
+ }else
1861
+ if (func!=NULL) {
1862
+ str = JS_NewStringCopyZ(cx, entry->name);
1863
+ args[0] = STRING_TO_JSVAL(str);
1864
+ if(!JS_CallFunction(cx, obj, func, 1, args, &v)){
1865
+ goto out;
1866
+ }
1867
+
1868
+ if (v==JSVAL_FALSE) {
1869
+ continue;
1870
+ }
1871
+ }
1872
+
1873
+ filePath = js_combinePath(cx, file->path, (char*)entry->name);
1874
+
1875
+ eachFile = js_NewFileObject(cx, filePath);
1876
+ JS_free(cx, filePath);
1877
+ if (!eachFile){
1878
+ JS_ReportWarning(cx, "File %s cannot be retrieved", filePath);
1879
+ continue;
1880
+ }
1881
+ v = OBJECT_TO_JSVAL(eachFile);
1882
+ JS_SetElement(cx, array, len, &v);
1883
+ JS_SetProperty(cx, array, entry->name, &v);
1884
+ len++;
1885
+ }
1886
+
1887
+ if(PR_CloseDir(dir)!=PR_SUCCESS){
1888
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1889
+ JSFILEMSG_OP_FAILED, "close", file->path);
1890
+ goto out;
1891
+ }
1892
+ *rval = OBJECT_TO_JSVAL(array);
1893
+ return JS_TRUE;
1894
+ out:
1895
+ *rval = JSVAL_NULL;
1896
+ return JS_FALSE;
1897
+ }
1898
+
1899
+ static JSBool
1900
+ file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1901
+ {
1902
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1903
+
1904
+ SECURITY_CHECK(cx, NULL, "mkdir", file);
1905
+ JSFILE_CHECK_ONE_ARG("mkdir");
1906
+ JSFILE_CHECK_NATIVE("mkdir");
1907
+
1908
+ /* if the current file is not a directory, find out the directory name */
1909
+ if (!js_isDirectory(cx, file)) {
1910
+ char *dir = js_fileDirectoryName(cx, file->path);
1911
+ JSObject *dirObj = js_NewFileObject(cx, dir);
1912
+
1913
+ JS_free(cx, dir);
1914
+
1915
+ /* call file_mkdir with the right set of parameters if needed */
1916
+ if (file_mkdir(cx, dirObj, argc, argv, rval))
1917
+ return JS_TRUE;
1918
+ else
1919
+ goto out;
1920
+ }else{
1921
+ char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
1922
+ char *fullName;
1923
+
1924
+ fullName = js_combinePath(cx, file->path, dirName);
1925
+ if (PR_MkDir(fullName, 0755)==PR_SUCCESS){
1926
+ *rval = JSVAL_TRUE;
1927
+ JS_free(cx, fullName);
1928
+ return JS_TRUE;
1929
+ }else{
1930
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
1931
+ JSFILEMSG_OP_FAILED, "mkdir", fullName);
1932
+ JS_free(cx, fullName);
1933
+ goto out;
1934
+ }
1935
+ }
1936
+ out:
1937
+ *rval = JSVAL_FALSE;
1938
+ return JS_FALSE;
1939
+ }
1940
+
1941
+ static JSBool
1942
+ file_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*rval)
1943
+ {
1944
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1945
+
1946
+ *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
1947
+ return JS_TRUE;
1948
+ }
1949
+
1950
+ static JSBool
1951
+ file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1952
+ {
1953
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1954
+ char url[MAX_PATH_LENGTH];
1955
+ jschar *urlChars;
1956
+
1957
+ JSFILE_CHECK_NATIVE("toURL");
1958
+
1959
+ sprintf(url, "file://%s", file->path);
1960
+ /* TODO: js_escape in jsstr.h may go away at some point */
1961
+
1962
+ urlChars = js_InflateString(cx, url, strlen(url));
1963
+ if (urlChars == NULL) return JS_FALSE;
1964
+ *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, strlen(url), 0));
1965
+ if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE;
1966
+
1967
+ return JS_TRUE;
1968
+ out:
1969
+ *rval = JSVAL_VOID;
1970
+ return JS_FALSE;
1971
+ }
1972
+
1973
+
1974
+ static void
1975
+ file_finalize(JSContext *cx, JSObject *obj)
1976
+ {
1977
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
1978
+
1979
+ if(file){
1980
+ /* close the file before exiting */
1981
+ if(file->isOpen && !file->isNative){
1982
+ jsval vp;
1983
+ file_close(cx, obj, 0, NULL, &vp);
1984
+ }
1985
+
1986
+ if (file->path)
1987
+ JS_free(cx, file->path);
1988
+
1989
+ JS_free(cx, file);
1990
+ }
1991
+ }
1992
+
1993
+ /*
1994
+ Allocates memory for the file object, sets fields to defaults.
1995
+ */
1996
+ static JSFile*
1997
+ file_init(JSContext *cx, JSObject *obj, char *bytes)
1998
+ {
1999
+ JSFile *file;
2000
+
2001
+ file = JS_malloc(cx, sizeof *file);
2002
+ if (!file) return NULL;
2003
+ memset(file, 0 , sizeof *file);
2004
+
2005
+ js_ResetAttributes(file);
2006
+
2007
+ file->path = RESOLVE_PATH(cx, bytes);
2008
+
2009
+ if (!JS_SetPrivate(cx, obj, file)) {
2010
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2011
+ JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
2012
+ JS_free(cx, file);
2013
+ return NULL;
2014
+ }else
2015
+ return file;
2016
+ }
2017
+
2018
+ /* Returns a JSObject. This function is globally visible */
2019
+ JS_PUBLIC_API(JSObject*)
2020
+ js_NewFileObject(JSContext *cx, char *filename)
2021
+ {
2022
+ JSObject *obj;
2023
+ JSFile *file;
2024
+
2025
+ obj = JS_NewObject(cx, &file_class, NULL, NULL);
2026
+ if (!obj){
2027
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2028
+ JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObject");
2029
+ return NULL;
2030
+ }
2031
+ file = file_init(cx, obj, filename);
2032
+ if(!file) return NULL;
2033
+ return obj;
2034
+ }
2035
+
2036
+ /* Internal function, used for cases which NSPR file support doesn't cover */
2037
+ JSObject*
2038
+ js_NewFileObjectFromFILE(JSContext *cx, FILE *nativehandle, char *filename,
2039
+ int32 mode, JSBool open, JSBool randomAccess)
2040
+ {
2041
+ JSObject *obj;
2042
+ JSFile *file;
2043
+ #ifdef XP_MAC
2044
+ JS_ReportWarning(cx, "Native files are not fully supported on the MAC");
2045
+ #endif
2046
+
2047
+ obj = JS_NewObject(cx, &file_class, NULL, NULL);
2048
+ if (!obj){
2049
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2050
+ JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObjectFromFILE");
2051
+ return NULL;
2052
+ }
2053
+ file = file_init(cx, obj, filename);
2054
+ if(!file) return NULL;
2055
+
2056
+ file->nativehandle = nativehandle;
2057
+
2058
+ /* free result of RESOLVE_PATH from file_init. */
2059
+ JS_ASSERT(file->path != NULL);
2060
+ JS_free(cx, file->path);
2061
+
2062
+ file->path = strdup(filename);
2063
+ file->isOpen = open;
2064
+ file->mode = mode;
2065
+ file->hasRandomAccess = randomAccess;
2066
+ file->isNative = JS_TRUE;
2067
+ return obj;
2068
+ }
2069
+
2070
+ /*
2071
+ Real file constructor that is called from JavaScript.
2072
+ Basically, does error processing and calls file_init.
2073
+ */
2074
+ static JSBool
2075
+ file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
2076
+ jsval *rval)
2077
+ {
2078
+ JSString *str;
2079
+ JSFile *file;
2080
+
2081
+ str = (argc==0)?JS_InternString(cx, ""):JS_ValueToString(cx, argv[0]);
2082
+
2083
+ if (!str){
2084
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2085
+ JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR, argv[0]);
2086
+ goto out;
2087
+ }
2088
+
2089
+ file = file_init(cx, obj, JS_GetStringBytes(str));
2090
+ if (!file) goto out;
2091
+
2092
+ SECURITY_CHECK(cx, NULL, "constructor", file);
2093
+
2094
+ return JS_TRUE;
2095
+ out:
2096
+ *rval = JSVAL_VOID;
2097
+ return JS_FALSE;
2098
+ }
2099
+
2100
+ /* -------------------- File methods and properties ------------------------- */
2101
+ static JSFunctionSpec file_functions[] = {
2102
+ { "open", file_open, 0},
2103
+ { "close", file_close, 0},
2104
+ { "remove", file_remove, 0},
2105
+ { "copyTo", file_copyTo, 0},
2106
+ { "renameTo", file_renameTo, 0},
2107
+ { "flush", file_flush, 0},
2108
+ { "seek", file_seek, 0},
2109
+ { "read", file_read, 0},
2110
+ { "readln", file_readln, 0},
2111
+ { "readAll", file_readAll, 0},
2112
+ { "write", file_write, 0},
2113
+ { "writeln", file_writeln, 0},
2114
+ { "writeAll", file_writeAll, 0},
2115
+ { "list", file_list, 0},
2116
+ { "mkdir", file_mkdir, 0},
2117
+ { "toString", file_toString, 0},
2118
+ { "toURL", file_toURL, 0},
2119
+ {0}
2120
+ };
2121
+
2122
+ enum file_tinyid {
2123
+ FILE_LENGTH = -2,
2124
+ FILE_PARENT = -3,
2125
+ FILE_PATH = -4,
2126
+ FILE_NAME = -5,
2127
+ FILE_ISDIR = -6,
2128
+ FILE_ISFILE = -7,
2129
+ FILE_EXISTS = -8,
2130
+ FILE_CANREAD = -9,
2131
+ FILE_CANWRITE = -10,
2132
+ FILE_OPEN = -11,
2133
+ FILE_TYPE = -12,
2134
+ FILE_MODE = -13,
2135
+ FILE_CREATED = -14,
2136
+ FILE_MODIFIED = -15,
2137
+ FILE_SIZE = -16,
2138
+ FILE_RANDOMACCESS = -17,
2139
+ FILE_POSITION = -18,
2140
+ FILE_APPEND = -19,
2141
+ FILE_REPLACE = -20,
2142
+ FILE_AUTOFLUSH = -21,
2143
+ FILE_ISNATIVE = -22,
2144
+ };
2145
+
2146
+ static JSPropertySpec file_props[] = {
2147
+ {"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY },
2148
+ {"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY },
2149
+ {"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY },
2150
+ {"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY },
2151
+ {"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY },
2152
+ {"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY },
2153
+ {"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY },
2154
+ {"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY },
2155
+ {"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY },
2156
+ {"canAppend", FILE_APPEND, JSPROP_ENUMERATE | JSPROP_READONLY },
2157
+ {"canReplace", FILE_REPLACE, JSPROP_ENUMERATE | JSPROP_READONLY },
2158
+ {"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY },
2159
+ {"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY },
2160
+ {"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY },
2161
+ {"creationTime", FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY },
2162
+ {"lastModified", FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY },
2163
+ {"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY },
2164
+ {"hasRandomAccess", FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY },
2165
+ {"hasAutoFlush", FILE_AUTOFLUSH, JSPROP_ENUMERATE | JSPROP_READONLY },
2166
+ {"position", FILE_POSITION, JSPROP_ENUMERATE },
2167
+ {"isNative", FILE_ISNATIVE, JSPROP_ENUMERATE | JSPROP_READONLY },
2168
+ {0}
2169
+ };
2170
+
2171
+ /* ------------------------- Property getter/setter ------------------------- */
2172
+ static JSBool
2173
+ file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2174
+ {
2175
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2176
+ char *str;
2177
+ jsint tiny;
2178
+ PRFileInfo info;
2179
+ JSBool flag;
2180
+ PRExplodedTime
2181
+ expandedTime;
2182
+
2183
+ tiny = JSVAL_TO_INT(id);
2184
+ if(!file) return JS_TRUE;
2185
+
2186
+ switch (tiny) {
2187
+ case FILE_PARENT:
2188
+ SECURITY_CHECK(cx, NULL, "parent", file);
2189
+ *vp = js_parent(cx, file);
2190
+ break;
2191
+ case FILE_PATH:
2192
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
2193
+ break;
2194
+ case FILE_NAME:
2195
+ *vp = js_name(cx, file);
2196
+ break;
2197
+ case FILE_ISDIR:
2198
+ SECURITY_CHECK(cx, NULL, "isDirectory", file);
2199
+ *vp = BOOLEAN_TO_JSVAL(js_isDirectory(cx, file));
2200
+ break;
2201
+ case FILE_ISFILE:
2202
+ SECURITY_CHECK(cx, NULL, "isFile", file);
2203
+ *vp = BOOLEAN_TO_JSVAL(js_isFile(cx, file));
2204
+ break;
2205
+ case FILE_EXISTS:
2206
+ SECURITY_CHECK(cx, NULL, "exists", file);
2207
+ *vp = BOOLEAN_TO_JSVAL(js_exists(cx, file));
2208
+ break;
2209
+ case FILE_ISNATIVE:
2210
+ SECURITY_CHECK(cx, NULL, "isNative", file);
2211
+ *vp = BOOLEAN_TO_JSVAL(file->isNative);
2212
+ break;
2213
+ case FILE_CANREAD:
2214
+ SECURITY_CHECK(cx, NULL, "canRead", file);
2215
+ *vp = BOOLEAN_TO_JSVAL(js_canRead(cx, file));
2216
+ break;
2217
+ case FILE_CANWRITE:
2218
+ SECURITY_CHECK(cx, NULL, "canWrite", file);
2219
+ *vp = BOOLEAN_TO_JSVAL(js_canWrite(cx, file));
2220
+ break;
2221
+ case FILE_OPEN:
2222
+ SECURITY_CHECK(cx, NULL, "isOpen", file);
2223
+ *vp = BOOLEAN_TO_JSVAL(file->isOpen);
2224
+ break;
2225
+ case FILE_APPEND :
2226
+ SECURITY_CHECK(cx, NULL, "canAppend", file);
2227
+ JSFILE_CHECK_OPEN("canAppend");
2228
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
2229
+ (file->mode&PR_APPEND)==PR_APPEND);
2230
+ break;
2231
+ case FILE_REPLACE :
2232
+ SECURITY_CHECK(cx, NULL, "canReplace", file);
2233
+ JSFILE_CHECK_OPEN("canReplace");
2234
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
2235
+ (file->mode&PR_TRUNCATE)==PR_TRUNCATE);
2236
+ break;
2237
+ case FILE_AUTOFLUSH :
2238
+ SECURITY_CHECK(cx, NULL, "hasAutoFlush", file);
2239
+ JSFILE_CHECK_OPEN("hasAutoFlush");
2240
+ *vp = BOOLEAN_TO_JSVAL(!file->isNative && file->hasAutoflush);
2241
+ break;
2242
+ case FILE_TYPE:
2243
+ SECURITY_CHECK(cx, NULL, "type", file);
2244
+ JSFILE_CHECK_OPEN("type");
2245
+ if(js_isDirectory(cx, file)){
2246
+ *vp = JSVAL_VOID;
2247
+ break;
2248
+ }
2249
+
2250
+ switch (file->type) {
2251
+ case ASCII:
2252
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, asciistring));
2253
+ break;
2254
+ case UTF8:
2255
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, utfstring));
2256
+ break;
2257
+ case UCS2:
2258
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, unicodestring));
2259
+ break;
2260
+ default:
2261
+ JS_ReportWarning(cx, "Unsupported file type %d, proceeding",
2262
+ file->type);
2263
+ }
2264
+ break;
2265
+ case FILE_MODE:
2266
+ SECURITY_CHECK(cx, NULL, "mode", file);
2267
+ JSFILE_CHECK_OPEN("mode");
2268
+ str = (char*)JS_malloc(cx, MODE_SIZE);
2269
+ str[0] = '\0';
2270
+ flag = JS_FALSE;
2271
+
2272
+ if ((file->mode&PR_RDONLY)==PR_RDONLY) {
2273
+ if (flag) strcat(str, ",");
2274
+ strcat(str, "read");
2275
+ flag = JS_TRUE;
2276
+ }
2277
+ if ((file->mode&PR_WRONLY)==PR_WRONLY) {
2278
+ if (flag) strcat(str, ",");
2279
+ strcat(str, "write");
2280
+ flag = JS_TRUE;
2281
+ }
2282
+ if ((file->mode&PR_RDWR)==PR_RDWR) {
2283
+ if (flag) strcat(str, ",");
2284
+ strcat(str, "readWrite");
2285
+ flag = JS_TRUE;
2286
+ }
2287
+ if ((file->mode&PR_APPEND)==PR_APPEND) {
2288
+ if (flag) strcat(str, ",");
2289
+ strcat(str, "append");
2290
+ flag = JS_TRUE;
2291
+ }
2292
+ if ((file->mode&PR_CREATE_FILE)==PR_CREATE_FILE) {
2293
+ if (flag) strcat(str, ",");
2294
+ strcat(str, "create");
2295
+ flag = JS_TRUE;
2296
+ }
2297
+ if ((file->mode&PR_TRUNCATE)==PR_TRUNCATE) {
2298
+ if (flag) strcat(str, ",");
2299
+ strcat(str, "replace");
2300
+ flag = JS_TRUE;
2301
+ }
2302
+ if (file->hasAutoflush) {
2303
+ if (flag) strcat(str, ",");
2304
+ strcat(str, "hasAutoFlush");
2305
+ flag = JS_TRUE;
2306
+ }
2307
+ *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str));
2308
+ JS_free(cx, str);
2309
+ break;
2310
+ case FILE_CREATED:
2311
+ SECURITY_CHECK(cx, NULL, "creationTime", file);
2312
+ JSFILE_CHECK_NATIVE("creationTime");
2313
+ if(((file->isOpen)?
2314
+ PR_GetOpenFileInfo(file->handle, &info):
2315
+ PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
2316
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2317
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
2318
+ goto out;
2319
+ }
2320
+
2321
+ PR_ExplodeTime(info.creationTime, PR_LocalTimeParameters,&expandedTime);
2322
+ *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
2323
+ expandedTime.tm_month,
2324
+ expandedTime.tm_mday,
2325
+ expandedTime.tm_hour,
2326
+ expandedTime.tm_min,
2327
+ expandedTime.tm_sec));
2328
+ break;
2329
+ case FILE_MODIFIED:
2330
+ SECURITY_CHECK(cx, NULL, "lastModified", file);
2331
+ JSFILE_CHECK_NATIVE("lastModified");
2332
+ if(((file->isOpen)?
2333
+ PR_GetOpenFileInfo(file->handle, &info):
2334
+ PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
2335
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2336
+ JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
2337
+ goto out;
2338
+ }
2339
+
2340
+ PR_ExplodeTime(info.modifyTime, PR_LocalTimeParameters, &expandedTime);
2341
+ *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
2342
+ expandedTime.tm_month,
2343
+ expandedTime.tm_mday,
2344
+ expandedTime.tm_hour,
2345
+ expandedTime.tm_min,
2346
+ expandedTime.tm_sec));
2347
+ break;
2348
+ case FILE_SIZE:
2349
+ SECURITY_CHECK(cx, NULL, "size", file);
2350
+ *vp = js_size(cx, file);
2351
+ break;
2352
+ case FILE_LENGTH:
2353
+ SECURITY_CHECK(cx, NULL, "length", file);
2354
+ JSFILE_CHECK_NATIVE("length");
2355
+
2356
+ if (js_isDirectory(cx, file)) { /* XXX debug me */
2357
+ PRDir *dir;
2358
+ PRDirEntry *entry;
2359
+ jsint count = 0;
2360
+
2361
+ if(!(dir = PR_OpenDir(file->path))){
2362
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2363
+ JSFILEMSG_CANNOT_OPEN_DIR, file->path);
2364
+ goto out;
2365
+ }
2366
+
2367
+ while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
2368
+ count++;
2369
+ }
2370
+
2371
+ if(!PR_CloseDir(dir)){
2372
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2373
+ JSFILEMSG_OP_FAILED, "close", file->path);
2374
+
2375
+ goto out;
2376
+ }
2377
+
2378
+ *vp = INT_TO_JSVAL(count);
2379
+ break;
2380
+ }else{
2381
+ /* return file size */
2382
+ *vp = js_size(cx, file);
2383
+ }
2384
+ break;
2385
+ case FILE_RANDOMACCESS:
2386
+ SECURITY_CHECK(cx, NULL, "hasRandomAccess", file);
2387
+ JSFILE_CHECK_OPEN("hasRandomAccess");
2388
+ *vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess);
2389
+ break;
2390
+ case FILE_POSITION:
2391
+ SECURITY_CHECK(cx, NULL, "position", file);
2392
+ JSFILE_CHECK_NATIVE("position");
2393
+ JSFILE_CHECK_OPEN("position");
2394
+
2395
+ if(!file->hasRandomAccess){
2396
+ JS_ReportWarning(cx, "File %s doesn't support random access, can't report the position, proceeding");
2397
+ *vp = JSVAL_VOID;
2398
+ break;
2399
+ }
2400
+
2401
+ if (file->isOpen && js_isFile(cx, file)) {
2402
+ int pos = PR_Seek(file->handle, 0, PR_SEEK_CUR);
2403
+ if(pos!=-1){
2404
+ *vp = INT_TO_JSVAL(pos);
2405
+ }else{
2406
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2407
+ JSFILEMSG_CANNOT_REPORT_POSITION, file->path);
2408
+ goto out;
2409
+ }
2410
+ }else {
2411
+ JS_ReportWarning(cx, "File %s is closed or not a plain file,"
2412
+ " can't report position, proceeding");
2413
+ goto out;
2414
+ }
2415
+ break;
2416
+ default:
2417
+ SECURITY_CHECK(cx, NULL, "file_access", file);
2418
+ /* this is some other property -- try to use the dir["file"] syntax */
2419
+ if(js_isDirectory(cx, file)){
2420
+ PRDir *dir = NULL;
2421
+ PRDirEntry *entry = NULL;
2422
+ char *prop_name = JS_GetStringBytes(JS_ValueToString(cx, id));
2423
+
2424
+ /* no native files past this point */
2425
+ dir = PR_OpenDir(file->path);
2426
+ if(!dir) {
2427
+ /* This is probably not a directory */
2428
+ JS_ReportWarning(cx, "Can't open directory %s", file->path);
2429
+ return JS_FALSE;
2430
+ }
2431
+
2432
+ while((entry = PR_ReadDir(dir, PR_SKIP_NONE))!=NULL){
2433
+ if(!strcmp(entry->name, prop_name)){
2434
+ str = js_combinePath(cx, file->path, prop_name);
2435
+ *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, str));
2436
+ JS_free(cx, str);
2437
+ return JS_TRUE;
2438
+ }
2439
+ }
2440
+ }
2441
+ }
2442
+ return JS_TRUE;
2443
+ out:
2444
+ *vp = JSVAL_VOID;
2445
+ return JS_FALSE;
2446
+ }
2447
+
2448
+ static JSBool
2449
+ file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2450
+ {
2451
+ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
2452
+ jsint slot;
2453
+
2454
+ if (JSVAL_IS_STRING(id)){
2455
+ return JS_TRUE;
2456
+ }
2457
+
2458
+ slot = JSVAL_TO_INT(id);
2459
+
2460
+ switch (slot) {
2461
+ /* File.position = 10 */
2462
+ case FILE_POSITION:
2463
+ SECURITY_CHECK(cx, NULL, "set_position", file);
2464
+ JSFILE_CHECK_NATIVE("set_position");
2465
+
2466
+ if(!file->hasRandomAccess){
2467
+ JS_ReportWarning(cx, "File %s doesn't support random access, can't "
2468
+ "report the position, proceeding");
2469
+ goto out;
2470
+ }
2471
+
2472
+ if (file->isOpen && js_isFile(cx, file)) {
2473
+ int32 pos;
2474
+ int32 offset;
2475
+
2476
+ if (!JS_ValueToInt32(cx, *vp, &offset)){
2477
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2478
+ JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "position", *vp);
2479
+ goto out;
2480
+ }
2481
+
2482
+ pos = PR_Seek(file->handle, offset, PR_SEEK_SET);
2483
+
2484
+ if(pos!=-1){
2485
+ *vp = INT_TO_JSVAL(pos);
2486
+ }else{
2487
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2488
+ JSFILEMSG_CANNOT_SET_POSITION, file->path);
2489
+ goto out;
2490
+ }
2491
+ } else {
2492
+ JS_ReportWarning(cx, "File %s is closed or not a file, can't set "
2493
+ "position, proceeding", file->path);
2494
+ goto out;
2495
+ }
2496
+ }
2497
+
2498
+ return JS_TRUE;
2499
+ out:
2500
+ *vp = JSVAL_VOID;
2501
+ return JS_FALSE;
2502
+ }
2503
+
2504
+ /*
2505
+ File.currentDir = new File("D:\") or File.currentDir = "D:\"
2506
+ */
2507
+ static JSBool
2508
+ file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
2509
+ {
2510
+ JSObject *rhsObject;
2511
+ char *path;
2512
+ JSFile *file = JS_GetInstancePrivate(cx, rhsObject, &file_class, NULL);
2513
+
2514
+ /* Look at the rhs and extract a file object from it */
2515
+ if (JSVAL_IS_OBJECT(*vp)){
2516
+ if (JS_InstanceOf(cx, rhsObject, &file_class, NULL)){
2517
+ /* Braindamaged rhs -- just return the old value */
2518
+ if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))){
2519
+ JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
2520
+ goto out;
2521
+ }else{
2522
+ rhsObject = JSVAL_TO_OBJECT(*vp);
2523
+ chdir(file->path);
2524
+ return JS_TRUE;
2525
+ }
2526
+ }else
2527
+ goto out;
2528
+ }else{
2529
+ path = JS_GetStringBytes(JS_ValueToString(cx, *vp));
2530
+ rhsObject = js_NewFileObject(cx, path);
2531
+ if (!rhsObject) goto out;
2532
+
2533
+ if (!file || !js_exists(cx, file) || !js_isDirectory(cx, file)){
2534
+ JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
2535
+ }else{
2536
+ *vp = OBJECT_TO_JSVAL(rhsObject);
2537
+ chdir(path);
2538
+ }
2539
+ }
2540
+ return JS_TRUE;
2541
+ out:
2542
+ *vp = JSVAL_VOID;
2543
+ return JS_FALSE;
2544
+ }
2545
+
2546
+ /* Declare class */
2547
+ static JSClass file_class = {
2548
+ FILE_CONSTRUCTOR, JSCLASS_HAS_PRIVATE,
2549
+ JS_PropertyStub, JS_PropertyStub, file_getProperty, file_setProperty,
2550
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, file_finalize
2551
+ };
2552
+
2553
+ /* -------------------- Functions exposed to the outside -------------------- */
2554
+ JS_PUBLIC_API(JSObject*)
2555
+ js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams)
2556
+ {
2557
+ JSObject *file, *ctor, *afile;
2558
+ jsval vp;
2559
+ char *currentdir;
2560
+ char separator[2];
2561
+
2562
+ file = JS_InitClass(cx, obj, NULL, &file_class, file_constructor, 1,
2563
+ file_props, file_functions, NULL, NULL);
2564
+ if (!file) {
2565
+ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
2566
+ JSFILEMSG_INIT_FAILED);
2567
+ return NULL;
2568
+ }
2569
+
2570
+ ctor = JS_GetConstructor(cx, file);
2571
+ if (!ctor) return NULL;
2572
+
2573
+ /* Define CURRENTDIR property. We are doing this to get a
2574
+ slash at the end of the current dir */
2575
+ afile = js_NewFileObject(cx, CURRENT_DIR);
2576
+ currentdir = JS_malloc(cx, MAX_PATH_LENGTH);
2577
+ currentdir = getcwd(currentdir, MAX_PATH_LENGTH);
2578
+ afile = js_NewFileObject(cx, currentdir);
2579
+ JS_free(cx, currentdir);
2580
+ vp = OBJECT_TO_JSVAL(afile);
2581
+ JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp,
2582
+ JS_PropertyStub, file_currentDirSetter,
2583
+ JSPROP_ENUMERATE | JSPROP_READONLY );
2584
+
2585
+ if(initStandardStreams){
2586
+ /* Code to create stdin, stdout, and stderr. Insert in the appropriate place. */
2587
+ /* Define input */
2588
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
2589
+ STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
2590
+ JS_SetProperty(cx, ctor, "input", &vp);
2591
+
2592
+ /* Define output */
2593
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
2594
+ STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
2595
+ JS_SetProperty(cx, ctor, "output", &vp);
2596
+
2597
+ /* Define error */
2598
+ vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
2599
+ STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
2600
+ JS_SetProperty(cx, ctor, "error", &vp);
2601
+ }
2602
+ separator[0] = FILESEPARATOR;
2603
+ separator[1] = '\0';
2604
+ vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, separator));
2605
+ JS_DefinePropertyWithTinyId(cx, ctor, SEPARATOR_PROPERTY, 0, vp,
2606
+ JS_PropertyStub, JS_PropertyStub,
2607
+ JSPROP_ENUMERATE | JSPROP_READONLY );
2608
+ return file;
2609
+ }
2610
+ #endif /* JS_HAS_FILE_OBJECT */