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.
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/bin/distil +45 -0
- data/distil.gemspec +586 -0
- data/lib/bootstrap-template.js +56 -0
- data/lib/configurable.rb +125 -0
- data/lib/file-set.rb +42 -0
- data/lib/file-types/css-file.rb +75 -0
- data/lib/file-types/html-file.rb +11 -0
- data/lib/file-types/javascript-file.rb +98 -0
- data/lib/file-types/json-file.rb +14 -0
- data/lib/file-types/nib-file.rb +9 -0
- data/lib/jsdoc.conf +18 -0
- data/lib/jsl.conf +121 -0
- data/lib/project.rb +96 -0
- data/lib/source-file.rb +181 -0
- data/lib/target.rb +96 -0
- data/lib/task.rb +239 -0
- data/lib/tasks/copy-task.rb +21 -0
- data/lib/tasks/css-task.rb +18 -0
- data/lib/tasks/javascript-task.rb +125 -0
- data/lib/tasks/multiple-output-task.rb +134 -0
- data/lib/tasks/nib-task.rb +83 -0
- data/lib/tasks/output-task.rb +73 -0
- data/lib/tasks/single-output-task.rb +83 -0
- data/lib/tasks/test-task.rb +280 -0
- data/lib/test/HtmlTestReporter.js +127 -0
- data/lib/test/Test.js +248 -0
- data/lib/test/TestReporter.js +79 -0
- data/lib/test/TestRunner.js +132 -0
- data/lib/test/browser.rb +97 -0
- data/lib/test/scriptwrapper.html +10 -0
- data/lib/test/unittest.html +127 -0
- data/vendor/Makefile +35 -0
- data/vendor/extconf.rb +3 -0
- data/vendor/jsdoc-extras/plugins/distil-plugin.js +142 -0
- data/vendor/jsdoc-extras/plugins/interface-plugin.js +36 -0
- data/vendor/jsdoc-extras/templates/coherent/allclasses.tmpl +17 -0
- data/vendor/jsdoc-extras/templates/coherent/allfiles.tmpl +53 -0
- data/vendor/jsdoc-extras/templates/coherent/class.tmpl +803 -0
- data/vendor/jsdoc-extras/templates/coherent/index.tmpl +37 -0
- data/vendor/jsdoc-extras/templates/coherent/publish.js +242 -0
- data/vendor/jsdoc-extras/templates/coherent/showdown.js +421 -0
- data/vendor/jsdoc-extras/templates/coherent/static/code-footer.html +3 -0
- data/vendor/jsdoc-extras/templates/coherent/static/code-header.html +7 -0
- data/vendor/jsdoc-extras/templates/coherent/static/default.css +297 -0
- data/vendor/jsdoc-extras/templates/coherent/static/header.html +2 -0
- data/vendor/jsdoc-extras/templates/coherent/static/index.html +19 -0
- data/vendor/jsdoc-extras/templates/coherent/symbol.tmpl +35 -0
- data/vendor/jsdoc-toolkit/README.txt +183 -0
- data/vendor/jsdoc-toolkit/app/frame/Chain.js +102 -0
- data/vendor/jsdoc-toolkit/app/frame/Dumper.js +144 -0
- data/vendor/jsdoc-toolkit/app/frame/Hash.js +84 -0
- data/vendor/jsdoc-toolkit/app/frame/Link.js +171 -0
- data/vendor/jsdoc-toolkit/app/frame/Namespace.js +10 -0
- data/vendor/jsdoc-toolkit/app/frame/Opt.js +134 -0
- data/vendor/jsdoc-toolkit/app/frame/Reflection.js +26 -0
- data/vendor/jsdoc-toolkit/app/frame/String.js +93 -0
- data/vendor/jsdoc-toolkit/app/frame/Testrun.js +129 -0
- data/vendor/jsdoc-toolkit/app/frame.js +33 -0
- data/vendor/jsdoc-toolkit/app/handlers/FOODOC.js +26 -0
- data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/DomReader.js +159 -0
- data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLDoc.js +16 -0
- data/vendor/jsdoc-toolkit/app/handlers/XMLDOC/XMLParse.js +292 -0
- data/vendor/jsdoc-toolkit/app/handlers/XMLDOC.js +26 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocComment.js +204 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/DocTag.js +300 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsDoc.js +126 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/JsPlate.js +109 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Lang.js +144 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Parser.js +144 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/PluginManager.js +33 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Symbol.js +644 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/SymbolSet.js +241 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/TextStream.js +41 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Token.js +18 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenReader.js +332 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/TokenStream.js +133 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Util.js +32 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC/Walker.js +499 -0
- data/vendor/jsdoc-toolkit/app/lib/JSDOC.js +106 -0
- data/vendor/jsdoc-toolkit/app/main.js +129 -0
- data/vendor/jsdoc-toolkit/app/plugins/commentSrcJson.js +20 -0
- data/vendor/jsdoc-toolkit/app/plugins/frameworkPrototype.js +16 -0
- data/vendor/jsdoc-toolkit/app/plugins/functionCall.js +10 -0
- data/vendor/jsdoc-toolkit/app/plugins/publishSrcHilite.js +54 -0
- data/vendor/jsdoc-toolkit/app/plugins/symbolLink.js +10 -0
- data/vendor/jsdoc-toolkit/app/plugins/tagParamConfig.js +31 -0
- data/vendor/jsdoc-toolkit/app/plugins/tagSynonyms.js +43 -0
- data/vendor/jsdoc-toolkit/app/run.js +348 -0
- data/vendor/jsdoc-toolkit/app/t/TestDoc.js +144 -0
- data/vendor/jsdoc-toolkit/app/t/runner.js +13 -0
- data/vendor/jsdoc-toolkit/app/test/addon.js +24 -0
- data/vendor/jsdoc-toolkit/app/test/anon_inner.js +14 -0
- data/vendor/jsdoc-toolkit/app/test/augments.js +31 -0
- data/vendor/jsdoc-toolkit/app/test/augments2.js +26 -0
- data/vendor/jsdoc-toolkit/app/test/borrows.js +46 -0
- data/vendor/jsdoc-toolkit/app/test/borrows2.js +23 -0
- data/vendor/jsdoc-toolkit/app/test/config.js +22 -0
- data/vendor/jsdoc-toolkit/app/test/constructs.js +18 -0
- data/vendor/jsdoc-toolkit/app/test/encoding.js +10 -0
- data/vendor/jsdoc-toolkit/app/test/encoding_other.js +12 -0
- data/vendor/jsdoc-toolkit/app/test/event.js +54 -0
- data/vendor/jsdoc-toolkit/app/test/exports.js +14 -0
- data/vendor/jsdoc-toolkit/app/test/functions_anon.js +39 -0
- data/vendor/jsdoc-toolkit/app/test/functions_nested.js +33 -0
- data/vendor/jsdoc-toolkit/app/test/global.js +13 -0
- data/vendor/jsdoc-toolkit/app/test/globals.js +25 -0
- data/vendor/jsdoc-toolkit/app/test/ignore.js +10 -0
- data/vendor/jsdoc-toolkit/app/test/inner.js +16 -0
- data/vendor/jsdoc-toolkit/app/test/jsdoc_test.js +477 -0
- data/vendor/jsdoc-toolkit/app/test/lend.js +33 -0
- data/vendor/jsdoc-toolkit/app/test/memberof.js +19 -0
- data/vendor/jsdoc-toolkit/app/test/memberof2.js +38 -0
- data/vendor/jsdoc-toolkit/app/test/memberof3.js +33 -0
- data/vendor/jsdoc-toolkit/app/test/memberof_constructor.js +17 -0
- data/vendor/jsdoc-toolkit/app/test/module.js +17 -0
- data/vendor/jsdoc-toolkit/app/test/name.js +19 -0
- data/vendor/jsdoc-toolkit/app/test/namespace_nested.js +23 -0
- data/vendor/jsdoc-toolkit/app/test/nocode.js +13 -0
- data/vendor/jsdoc-toolkit/app/test/oblit_anon.js +20 -0
- data/vendor/jsdoc-toolkit/app/test/overview.js +20 -0
- data/vendor/jsdoc-toolkit/app/test/param_inline.js +37 -0
- data/vendor/jsdoc-toolkit/app/test/params_optional.js +8 -0
- data/vendor/jsdoc-toolkit/app/test/prototype.js +17 -0
- data/vendor/jsdoc-toolkit/app/test/prototype_nested.js +9 -0
- data/vendor/jsdoc-toolkit/app/test/prototype_oblit.js +13 -0
- data/vendor/jsdoc-toolkit/app/test/prototype_oblit_constructor.js +24 -0
- data/vendor/jsdoc-toolkit/app/test/public.js +10 -0
- data/vendor/jsdoc-toolkit/app/test/scripts/code.js +5 -0
- data/vendor/jsdoc-toolkit/app/test/scripts/notcode.txt +5 -0
- data/vendor/jsdoc-toolkit/app/test/shared.js +42 -0
- data/vendor/jsdoc-toolkit/app/test/shared2.js +2 -0
- data/vendor/jsdoc-toolkit/app/test/shortcuts.js +22 -0
- data/vendor/jsdoc-toolkit/app/test/static_this.js +13 -0
- data/vendor/jsdoc-toolkit/app/test/synonyms.js +31 -0
- data/vendor/jsdoc-toolkit/app/test/tosource.js +23 -0
- data/vendor/jsdoc-toolkit/app/test/variable_redefine.js +14 -0
- data/vendor/jsdoc-toolkit/app/test.js +342 -0
- data/vendor/jsdoc-toolkit/changes.txt +116 -0
- data/vendor/jsdoc-toolkit/conf/sample.conf +31 -0
- data/vendor/jsdoc-toolkit/java/build.xml +36 -0
- data/vendor/jsdoc-toolkit/java/build_1.4.xml +36 -0
- data/vendor/jsdoc-toolkit/java/classes/js.jar +0 -0
- data/vendor/jsdoc-toolkit/java/src/JsDebugRun.java +21 -0
- data/vendor/jsdoc-toolkit/java/src/JsRun.java +21 -0
- data/vendor/jsdoc-toolkit/jsdebug.jar +0 -0
- data/vendor/jsdoc-toolkit/jsrun.jar +0 -0
- data/vendor/jsdoc-toolkit/jsrun.sh +53 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/allclasses.tmpl +17 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/allfiles.tmpl +56 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/class.tmpl +649 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/index.tmpl +39 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/publish.js +201 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-footer.html +3 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/static/code-header.html +14 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/static/default.css +162 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/static/header.html +2 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/static/index.html +19 -0
- data/vendor/jsdoc-toolkit/templates/jsdoc/symbol.tmpl +35 -0
- data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.cpp +333 -0
- data/vendor/jsl-0.3.0/src/JavaScriptLintAPI.h +86 -0
- data/vendor/jsl-0.3.0/src/Makefile.in +375 -0
- data/vendor/jsl-0.3.0/src/Makefile.ref +372 -0
- data/vendor/jsl-0.3.0/src/README.html +826 -0
- data/vendor/jsl-0.3.0/src/SpiderMonkey.rsp +12 -0
- data/vendor/jsl-0.3.0/src/_jsl_online.php +223 -0
- data/vendor/jsl-0.3.0/src/config/AIX4.1.mk +65 -0
- data/vendor/jsl-0.3.0/src/config/AIX4.2.mk +64 -0
- data/vendor/jsl-0.3.0/src/config/AIX4.3.mk +65 -0
- data/vendor/jsl-0.3.0/src/config/Darwin.mk +81 -0
- data/vendor/jsl-0.3.0/src/config/Darwin1.3.mk +81 -0
- data/vendor/jsl-0.3.0/src/config/Darwin1.4.mk +41 -0
- data/vendor/jsl-0.3.0/src/config/Darwin5.2.mk +81 -0
- data/vendor/jsl-0.3.0/src/config/Darwin5.3.mk +81 -0
- data/vendor/jsl-0.3.0/src/config/HP-UXB.10.10.mk +77 -0
- data/vendor/jsl-0.3.0/src/config/HP-UXB.10.20.mk +77 -0
- data/vendor/jsl-0.3.0/src/config/HP-UXB.11.00.mk +80 -0
- data/vendor/jsl-0.3.0/src/config/IRIX.mk +87 -0
- data/vendor/jsl-0.3.0/src/config/IRIX5.3.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/IRIX6.1.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/IRIX6.2.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/IRIX6.3.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/IRIX6.5.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/Linux_All.mk +103 -0
- data/vendor/jsl-0.3.0/src/config/Mac_OS10.0.mk +82 -0
- data/vendor/jsl-0.3.0/src/config/OSF1V4.0.mk +72 -0
- data/vendor/jsl-0.3.0/src/config/OSF1V5.0.mk +69 -0
- data/vendor/jsl-0.3.0/src/config/SunOS4.1.4.mk +101 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.3.mk +91 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.4.mk +92 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.5.1.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.5.mk +87 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.6.mk +89 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.7.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.8.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/SunOS5.9.mk +44 -0
- data/vendor/jsl-0.3.0/src/config/WINNT4.0.mk +112 -0
- data/vendor/jsl-0.3.0/src/config/WINNT5.0.mk +112 -0
- data/vendor/jsl-0.3.0/src/config/WINNT5.1.mk +112 -0
- data/vendor/jsl-0.3.0/src/config/WINNT5.2.mk +112 -0
- data/vendor/jsl-0.3.0/src/config/dgux.mk +64 -0
- data/vendor/jsl-0.3.0/src/config.mk +166 -0
- data/vendor/jsl-0.3.0/src/editline/Makefile.ref +144 -0
- data/vendor/jsl-0.3.0/src/editline/README +83 -0
- data/vendor/jsl-0.3.0/src/editline/editline.3 +175 -0
- data/vendor/jsl-0.3.0/src/editline/editline.c +1369 -0
- data/vendor/jsl-0.3.0/src/editline/editline.h +135 -0
- data/vendor/jsl-0.3.0/src/editline/sysunix.c +182 -0
- data/vendor/jsl-0.3.0/src/editline/unix.h +82 -0
- data/vendor/jsl-0.3.0/src/fdlibm/Makefile.in +127 -0
- data/vendor/jsl-0.3.0/src/fdlibm/Makefile.ref +192 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_acos.c +147 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_acosh.c +105 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_asin.c +156 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_atan2.c +165 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_atanh.c +110 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_cosh.c +133 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_exp.c +202 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_fmod.c +184 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_gamma.c +71 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_gamma_r.c +70 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_hypot.c +173 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_j0.c +524 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_j1.c +523 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_jn.c +315 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma.c +71 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_lgamma_r.c +347 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_log.c +184 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_log10.c +134 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_pow.c +386 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_rem_pio2.c +221 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_remainder.c +120 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_scalb.c +89 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_sinh.c +122 -0
- data/vendor/jsl-0.3.0/src/fdlibm/e_sqrt.c +497 -0
- data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.dsp +160 -0
- data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.h +273 -0
- data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mak +1453 -0
- data/vendor/jsl-0.3.0/src/fdlibm/fdlibm.mdp +0 -0
- data/vendor/jsl-0.3.0/src/fdlibm/k_cos.c +134 -0
- data/vendor/jsl-0.3.0/src/fdlibm/k_rem_pio2.c +354 -0
- data/vendor/jsl-0.3.0/src/fdlibm/k_sin.c +114 -0
- data/vendor/jsl-0.3.0/src/fdlibm/k_standard.c +785 -0
- data/vendor/jsl-0.3.0/src/fdlibm/k_tan.c +170 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_asinh.c +101 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_atan.c +175 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_cbrt.c +133 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_ceil.c +120 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_copysign.c +72 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_cos.c +118 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_erf.c +356 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_expm1.c +267 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_fabs.c +70 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_finite.c +71 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_floor.c +121 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_frexp.c +99 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_ilogb.c +85 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_isnan.c +74 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_ldexp.c +66 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_lib_version.c +73 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_log1p.c +211 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_logb.c +79 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_matherr.c +64 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_modf.c +132 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_nextafter.c +124 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_rint.c +131 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_scalbn.c +107 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_signgam.c +40 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_significand.c +68 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_sin.c +118 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_tan.c +112 -0
- data/vendor/jsl-0.3.0/src/fdlibm/s_tanh.c +122 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_acos.c +78 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_acosh.c +78 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_asin.c +80 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_atan2.c +79 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_atanh.c +81 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_cosh.c +77 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_exp.c +88 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_fmod.c +78 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_gamma.c +85 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_gamma_r.c +81 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_hypot.c +78 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_j0.c +105 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_j1.c +106 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_jn.c +128 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma.c +85 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_lgamma_r.c +81 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_log.c +78 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_log10.c +81 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_pow.c +99 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_remainder.c +77 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_scalb.c +95 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_sinh.c +77 -0
- data/vendor/jsl-0.3.0/src/fdlibm/w_sqrt.c +77 -0
- data/vendor/jsl-0.3.0/src/js.c +2447 -0
- data/vendor/jsl-0.3.0/src/js.dsp +420 -0
- data/vendor/jsl-0.3.0/src/js.mak +4025 -0
- data/vendor/jsl-0.3.0/src/js.mdp +0 -0
- data/vendor/jsl-0.3.0/src/js.msg +291 -0
- data/vendor/jsl-0.3.0/src/js.pkg +2 -0
- data/vendor/jsl-0.3.0/src/js3240.rc +79 -0
- data/vendor/jsl-0.3.0/src/jsOS240.def +654 -0
- data/vendor/jsl-0.3.0/src/jsapi.c +4405 -0
- data/vendor/jsl-0.3.0/src/jsapi.h +1856 -0
- data/vendor/jsl-0.3.0/src/jsarena.c +567 -0
- data/vendor/jsl-0.3.0/src/jsarena.h +302 -0
- data/vendor/jsl-0.3.0/src/jsarray.c +1428 -0
- data/vendor/jsl-0.3.0/src/jsarray.h +77 -0
- data/vendor/jsl-0.3.0/src/jsatom.c +927 -0
- data/vendor/jsl-0.3.0/src/jsatom.h +426 -0
- data/vendor/jsl-0.3.0/src/jsbit.h +113 -0
- data/vendor/jsl-0.3.0/src/jsbool.c +220 -0
- data/vendor/jsl-0.3.0/src/jsbool.h +62 -0
- data/vendor/jsl-0.3.0/src/jsclist.h +139 -0
- data/vendor/jsl-0.3.0/src/jscntxt.c +1036 -0
- data/vendor/jsl-0.3.0/src/jscntxt.h +608 -0
- data/vendor/jsl-0.3.0/src/jscompat.h +57 -0
- data/vendor/jsl-0.3.0/src/jsconfig.h +489 -0
- data/vendor/jsl-0.3.0/src/jsconfig.mk +181 -0
- data/vendor/jsl-0.3.0/src/jscpucfg.c +377 -0
- data/vendor/jsl-0.3.0/src/jscpucfg.h +204 -0
- data/vendor/jsl-0.3.0/src/jsdate.c +2238 -0
- data/vendor/jsl-0.3.0/src/jsdate.h +118 -0
- data/vendor/jsl-0.3.0/src/jsdbgapi.c +1260 -0
- data/vendor/jsl-0.3.0/src/jsdbgapi.h +345 -0
- data/vendor/jsl-0.3.0/src/jsdhash.c +763 -0
- data/vendor/jsl-0.3.0/src/jsdhash.h +579 -0
- data/vendor/jsl-0.3.0/src/jsdtoa.c +3135 -0
- data/vendor/jsl-0.3.0/src/jsdtoa.h +130 -0
- data/vendor/jsl-0.3.0/src/jsemit.c +4851 -0
- data/vendor/jsl-0.3.0/src/jsemit.h +576 -0
- data/vendor/jsl-0.3.0/src/jsexn.c +1084 -0
- data/vendor/jsl-0.3.0/src/jsexn.h +102 -0
- data/vendor/jsl-0.3.0/src/jsfile.c +2610 -0
- data/vendor/jsl-0.3.0/src/jsfile.h +50 -0
- data/vendor/jsl-0.3.0/src/jsfile.msg +89 -0
- data/vendor/jsl-0.3.0/src/jsfun.c +2015 -0
- data/vendor/jsl-0.3.0/src/jsfun.h +158 -0
- data/vendor/jsl-0.3.0/src/jsgc.c +1441 -0
- data/vendor/jsl-0.3.0/src/jsgc.h +230 -0
- data/vendor/jsl-0.3.0/src/jshash.c +471 -0
- data/vendor/jsl-0.3.0/src/jshash.h +152 -0
- data/vendor/jsl-0.3.0/src/jsify.pl +485 -0
- data/vendor/jsl-0.3.0/src/jsinterp.c +4797 -0
- data/vendor/jsl-0.3.0/src/jsinterp.h +302 -0
- data/vendor/jsl-0.3.0/src/jsl-test.js +28 -0
- data/vendor/jsl-0.3.0/src/jsl.c +2371 -0
- data/vendor/jsl-0.3.0/src/jsl.conf +127 -0
- data/vendor/jsl-0.3.0/src/jsl.conf.old +124 -0
- data/vendor/jsl-0.3.0/src/jsl.dsp +242 -0
- data/vendor/jsl-0.3.0/src/jsl.dsw +59 -0
- data/vendor/jsl-0.3.0/src/jslibmath.h +290 -0
- data/vendor/jsl-0.3.0/src/jslock.c +1261 -0
- data/vendor/jsl-0.3.0/src/jslock.h +289 -0
- data/vendor/jsl-0.3.0/src/jslocko.asm +59 -0
- data/vendor/jsl-0.3.0/src/jslog2.c +83 -0
- data/vendor/jsl-0.3.0/src/jslong.c +281 -0
- data/vendor/jsl-0.3.0/src/jslong.h +437 -0
- data/vendor/jsl-0.3.0/src/jsmath.c +477 -0
- data/vendor/jsl-0.3.0/src/jsmath.h +55 -0
- data/vendor/jsl-0.3.0/src/jsnum.c +1148 -0
- data/vendor/jsl-0.3.0/src/jsnum.h +257 -0
- data/vendor/jsl-0.3.0/src/jsobj.c +4066 -0
- data/vendor/jsl-0.3.0/src/jsobj.h +475 -0
- data/vendor/jsl-0.3.0/src/jsopcode.c +2730 -0
- data/vendor/jsl-0.3.0/src/jsopcode.h +275 -0
- data/vendor/jsl-0.3.0/src/jsopcode.tbl +344 -0
- data/vendor/jsl-0.3.0/src/jsosdep.h +127 -0
- data/vendor/jsl-0.3.0/src/jsotypes.h +211 -0
- data/vendor/jsl-0.3.0/src/jsparse.c +4438 -0
- data/vendor/jsl-0.3.0/src/jsparse.h +345 -0
- data/vendor/jsl-0.3.0/src/jsprf.c +1212 -0
- data/vendor/jsl-0.3.0/src/jsprf.h +148 -0
- data/vendor/jsl-0.3.0/src/jsprvtd.h +174 -0
- data/vendor/jsl-0.3.0/src/jspubtd.h +586 -0
- data/vendor/jsl-0.3.0/src/jsregexp.c +3831 -0
- data/vendor/jsl-0.3.0/src/jsregexp.h +180 -0
- data/vendor/jsl-0.3.0/src/jsscan.c +1814 -0
- data/vendor/jsl-0.3.0/src/jsscan.h +267 -0
- data/vendor/jsl-0.3.0/src/jsscope.c +1639 -0
- data/vendor/jsl-0.3.0/src/jsscope.h +389 -0
- data/vendor/jsl-0.3.0/src/jsscript.c +1284 -0
- data/vendor/jsl-0.3.0/src/jsscript.h +179 -0
- data/vendor/jsl-0.3.0/src/jsshell.msg +50 -0
- data/vendor/jsl-0.3.0/src/jsstddef.h +83 -0
- data/vendor/jsl-0.3.0/src/jsstr.c +4502 -0
- data/vendor/jsl-0.3.0/src/jsstr.h +448 -0
- data/vendor/jsl-0.3.0/src/jstypes.h +391 -0
- data/vendor/jsl-0.3.0/src/jsutil.c +157 -0
- data/vendor/jsl-0.3.0/src/jsutil.h +75 -0
- data/vendor/jsl-0.3.0/src/jsxdrapi.c +686 -0
- data/vendor/jsl-0.3.0/src/jsxdrapi.h +193 -0
- data/vendor/jsl-0.3.0/src/liveconnect/LiveConnect.dsp +157 -0
- data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsp +120 -0
- data/vendor/jsl-0.3.0/src/liveconnect/LiveConnectShell.dsw +44 -0
- data/vendor/jsl-0.3.0/src/liveconnect/Makefile.in +106 -0
- data/vendor/jsl-0.3.0/src/liveconnect/Makefile.ref +169 -0
- data/vendor/jsl-0.3.0/src/liveconnect/README.html +719 -0
- data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
- data/vendor/jsl-0.3.0/src/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.in +89 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/Makefile.ref +57 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/Makefile.ref +47 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSException.java +140 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
- data/vendor/jsl-0.3.0/src/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.1.mk +45 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.2.mk +45 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/AIX4.3.mk +50 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.10.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.10.20.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/HP-UXB.11.00.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.2.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.3.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/IRIX6.5.mk +43 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/Linux_All.mk +73 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V4.0.mk +65 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/OSF1V5.0.mk +62 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.5.1.mk +55 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.6.mk +39 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.7.mk +39 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/SunOS5.8.mk +39 -0
- data/vendor/jsl-0.3.0/src/liveconnect/config/WINNT4.0.mk +53 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj.c +884 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj.msg +98 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JSObject.c +1379 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaArray.c +481 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaClass.c +749 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaMember.c +186 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaObject.c +1099 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_JavaPackage.c +548 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_array.c +207 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_class.c +765 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_convert.c +954 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_field.c +421 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.c +504 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_hash.h +161 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_method.c +1823 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_nodl.c +1 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_private.h +689 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_simpleapi.c +219 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsj_utils.c +513 -0
- data/vendor/jsl-0.3.0/src/liveconnect/jsjava.h +313 -0
- data/vendor/jsl-0.3.0/src/liveconnect/liveconnect.pkg +3 -0
- data/vendor/jsl-0.3.0/src/liveconnect/netscape_javascript_JSObject.h +155 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.cpp +785 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnect.h +197 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.cpp +163 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsCLiveconnectFactory.h +76 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsILiveconnect.h +195 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsISecureLiveconnect.h +84 -0
- data/vendor/jsl-0.3.0/src/liveconnect/nsISecurityContext.h +135 -0
- data/vendor/jsl-0.3.0/src/liveconnect/win32.order +6 -0
- data/vendor/jsl-0.3.0/src/lock_SunOS.s +114 -0
- data/vendor/jsl-0.3.0/src/perfect.js +39 -0
- data/vendor/jsl-0.3.0/src/perlconnect/JS.def +6 -0
- data/vendor/jsl-0.3.0/src/perlconnect/JS.dsp +107 -0
- data/vendor/jsl-0.3.0/src/perlconnect/JS.pm +318 -0
- data/vendor/jsl-0.3.0/src/perlconnect/JS.xs +1050 -0
- data/vendor/jsl-0.3.0/src/perlconnect/Makefile.PL +67 -0
- data/vendor/jsl-0.3.0/src/perlconnect/Makefile.ref +152 -0
- data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsp +103 -0
- data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.dsw +59 -0
- data/vendor/jsl-0.3.0/src/perlconnect/PerlConnect.pm +126 -0
- data/vendor/jsl-0.3.0/src/perlconnect/PerlConnectShell.dsp +89 -0
- data/vendor/jsl-0.3.0/src/perlconnect/README.html +345 -0
- data/vendor/jsl-0.3.0/src/perlconnect/bg.jpg +0 -0
- data/vendor/jsl-0.3.0/src/perlconnect/jsperl.c +1100 -0
- data/vendor/jsl-0.3.0/src/perlconnect/jsperl.h +52 -0
- data/vendor/jsl-0.3.0/src/perlconnect/jsperlbuild.pl +81 -0
- data/vendor/jsl-0.3.0/src/perlconnect/jsperlpvt.h +57 -0
- data/vendor/jsl-0.3.0/src/perlconnect/test.js +73 -0
- data/vendor/jsl-0.3.0/src/perlconnect/test.pl +244 -0
- data/vendor/jsl-0.3.0/src/perlconnect/typemap +121 -0
- data/vendor/jsl-0.3.0/src/plify_jsdhash.sed +31 -0
- data/vendor/jsl-0.3.0/src/prmjtime.c +646 -0
- data/vendor/jsl-0.3.0/src/prmjtime.h +95 -0
- data/vendor/jsl-0.3.0/src/resource.h +15 -0
- data/vendor/jsl-0.3.0/src/rules.mk +193 -0
- data/vendor/jsl-0.3.0/src/win32.order +391 -0
- data/vendor/jsl-0.3.0/tests/conf/always_use_option_explicit.js +4 -0
- data/vendor/jsl-0.3.0/tests/conf/define.js +8 -0
- data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-1.js +7 -0
- data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-2.js +8 -0
- data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-3.js +27 -0
- data/vendor/jsl-0.3.0/tests/conf/jscript_function_extensions-4.js +4 -0
- data/vendor/jsl-0.3.0/tests/conf/lambda_assign_requires_semicolon.js +24 -0
- data/vendor/jsl-0.3.0/tests/conf/legacy_control_comments.js +8 -0
- data/vendor/jsl-0.3.0/tests/control_comments/control_comments.js +33 -0
- data/vendor/jsl-0.3.0/tests/control_comments/declare.js +26 -0
- data/vendor/jsl-0.3.0/tests/control_comments/import-overflow.js +9 -0
- data/vendor/jsl-0.3.0/tests/control_comments/import.js +5 -0
- data/vendor/jsl-0.3.0/tests/control_comments/import2.js +2 -0
- data/vendor/jsl-0.3.0/tests/control_comments/invalid_fallthru.js +13 -0
- data/vendor/jsl-0.3.0/tests/control_comments/option_explicit-with.js +12 -0
- data/vendor/jsl-0.3.0/tests/control_comments/option_explicit.js +64 -0
- data/vendor/jsl-0.3.0/tests/errors/unterminated_comment.js +8 -0
- data/vendor/jsl-0.3.0/tests/html/script_tag_in_js_literal.html +14 -0
- data/vendor/jsl-0.3.0/tests/run_tests.pl +71 -0
- data/vendor/jsl-0.3.0/tests/warnings/ambiguous_else_stmt.js +21 -0
- data/vendor/jsl-0.3.0/tests/warnings/ambiguous_nested_stmt.js +66 -0
- data/vendor/jsl-0.3.0/tests/warnings/ambiguous_newline.js +261 -0
- data/vendor/jsl-0.3.0/tests/warnings/anon_no_return_value.js +26 -0
- data/vendor/jsl-0.3.0/tests/warnings/assign_to_function_call.js +16 -0
- data/vendor/jsl-0.3.0/tests/warnings/block_without_braces.js +13 -0
- data/vendor/jsl-0.3.0/tests/warnings/comma_separated_stmts.js +17 -0
- data/vendor/jsl-0.3.0/tests/warnings/comparison_type_conv.js +44 -0
- data/vendor/jsl-0.3.0/tests/warnings/default_not_at_end.js +15 -0
- data/vendor/jsl-0.3.0/tests/warnings/dup_option_explicit.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/duplicate_case_in_switch.js +62 -0
- data/vendor/jsl-0.3.0/tests/warnings/duplicate_formal.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/empty_statement.js +29 -0
- data/vendor/jsl-0.3.0/tests/warnings/equal_as_assign.js +7 -0
- data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt-ignore.js +21 -0
- data/vendor/jsl-0.3.0/tests/warnings/inc_dec_within_stmt.js +63 -0
- data/vendor/jsl-0.3.0/tests/warnings/jsl_cc_not_understood.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/leading_decimal_point.js +7 -0
- data/vendor/jsl-0.3.0/tests/warnings/legacy_cc_not_understood.js +9 -0
- data/vendor/jsl-0.3.0/tests/warnings/meaningless_block.js +12 -0
- data/vendor/jsl-0.3.0/tests/warnings/misplaced_regex.js +20 -0
- data/vendor/jsl-0.3.0/tests/warnings/missing_break.js +87 -0
- data/vendor/jsl-0.3.0/tests/warnings/missing_break_for_last_case.js +19 -0
- data/vendor/jsl-0.3.0/tests/warnings/missing_default_case.js +51 -0
- data/vendor/jsl-0.3.0/tests/warnings/missing_option_explicit.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/missing_semicolon.js +19 -0
- data/vendor/jsl-0.3.0/tests/warnings/multiple_plus_minus.js +10 -0
- data/vendor/jsl-0.3.0/tests/warnings/nested_comment.js +6 -0
- data/vendor/jsl-0.3.0/tests/warnings/no_return_value.js +25 -0
- data/vendor/jsl-0.3.0/tests/warnings/octal_number.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/parseint_missing_radix.js +15 -0
- data/vendor/jsl-0.3.0/tests/warnings/partial_option_explicit.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/redeclared_var.js +10 -0
- data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/bad_backref.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/deprecated_usage.js +11 -0
- data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/invalid_backref.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/spidermonkey/trailing_comma.js +5 -0
- data/vendor/jsl-0.3.0/tests/warnings/trailing_comma_in_array.js +8 -0
- data/vendor/jsl-0.3.0/tests/warnings/trailing_decimal_point.js +7 -0
- data/vendor/jsl-0.3.0/tests/warnings/unreachable_code.js +29 -0
- data/vendor/jsl-0.3.0/tests/warnings/use_of_label.js +19 -0
- data/vendor/jsl-0.3.0/tests/warnings/useless_assign.js +20 -0
- data/vendor/jsl-0.3.0/tests/warnings/useless_comparison.js +55 -0
- data/vendor/jsl-0.3.0/tests/warnings/useless_void.js +6 -0
- data/vendor/jsl-0.3.0/tests/warnings/var_hides_arg.js +4 -0
- data/vendor/jsl-0.3.0/tests/warnings/with_statement.js +7 -0
- data/vendor/yuicompressor-2.4.2.jar +0 -0
- 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 */
|