Initial commit
[yaffs-website] / node_modules / esprima / bin / esvalidate.js
1 #!/usr/bin/env node
2 /*
3   Copyright JS Foundation and other contributors, https://js.foundation/
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13
14   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17   ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
18   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 /*jslint sloppy:true plusplus:true node:true rhino:true */
27 /*global phantom:true */
28
29 var fs, system, esprima, options, fnames, forceFile, count;
30
31 if (typeof esprima === 'undefined') {
32     // PhantomJS can only require() relative files
33     if (typeof phantom === 'object') {
34         fs = require('fs');
35         system = require('system');
36         esprima = require('./esprima');
37     } else if (typeof require === 'function') {
38         fs = require('fs');
39         try {
40             esprima = require('esprima');
41         } catch (e) {
42             esprima = require('../');
43         }
44     } else if (typeof load === 'function') {
45         try {
46             load('esprima.js');
47         } catch (e) {
48             load('../esprima.js');
49         }
50     }
51 }
52
53 // Shims to Node.js objects when running under PhantomJS 1.7+.
54 if (typeof phantom === 'object') {
55     fs.readFileSync = fs.read;
56     process = {
57         argv: [].slice.call(system.args),
58         exit: phantom.exit,
59         on: function (evt, callback) {
60             callback();
61         }
62     };
63     process.argv.unshift('phantomjs');
64 }
65
66 // Shims to Node.js objects when running under Rhino.
67 if (typeof console === 'undefined' && typeof process === 'undefined') {
68     console = { log: print };
69     fs = { readFileSync: readFile };
70     process = {
71         argv: arguments,
72         exit: quit,
73         on: function (evt, callback) {
74             callback();
75         }
76     };
77     process.argv.unshift('esvalidate.js');
78     process.argv.unshift('rhino');
79 }
80
81 function showUsage() {
82     console.log('Usage:');
83     console.log('   esvalidate [options] [file.js...]');
84     console.log();
85     console.log('Available options:');
86     console.log();
87     console.log('  --format=type  Set the report format, plain (default) or junit');
88     console.log('  -v, --version  Print program version');
89     console.log();
90     process.exit(1);
91 }
92
93 options = {
94     format: 'plain'
95 };
96
97 fnames = [];
98
99 process.argv.splice(2).forEach(function (entry) {
100
101     if (forceFile || entry === '-' || entry.slice(0, 1) !== '-') {
102         fnames.push(entry);
103     } else if (entry === '-h' || entry === '--help') {
104         showUsage();
105     } else if (entry === '-v' || entry === '--version') {
106         console.log('ECMAScript Validator (using Esprima version', esprima.version, ')');
107         console.log();
108         process.exit(0);
109     } else if (entry.slice(0, 9) === '--format=') {
110         options.format = entry.slice(9);
111         if (options.format !== 'plain' && options.format !== 'junit') {
112             console.log('Error: unknown report format ' + options.format + '.');
113             process.exit(1);
114         }
115     } else if (entry === '--') {
116         forceFile = true;
117     } else {
118         console.log('Error: unknown option ' + entry + '.');
119         process.exit(1);
120     }
121 });
122
123 if (fnames.length === 0) {
124     fnames.push('');
125 }
126
127 if (options.format === 'junit') {
128     console.log('<?xml version="1.0" encoding="UTF-8"?>');
129     console.log('<testsuites>');
130 }
131
132 count = 0;
133
134 function run(fname, content) {
135     var timestamp, syntax, name;
136     try {
137         if (typeof content !== 'string') {
138             throw content;
139         }
140
141         if (content[0] === '#' && content[1] === '!') {
142             content = '//' + content.substr(2, content.length);
143         }
144
145         timestamp = Date.now();
146         syntax = esprima.parse(content, { tolerant: true });
147
148         if (options.format === 'junit') {
149
150             name = fname;
151             if (name.lastIndexOf('/') >= 0) {
152                 name = name.slice(name.lastIndexOf('/') + 1);
153             }
154
155             console.log('<testsuite name="' + fname + '" errors="0" ' +
156                 ' failures="' + syntax.errors.length + '" ' +
157                 ' tests="' + syntax.errors.length + '" ' +
158                 ' time="' + Math.round((Date.now() - timestamp) / 1000) +
159                 '">');
160
161             syntax.errors.forEach(function (error) {
162                 var msg = error.message;
163                 msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
164                 console.log('  <testcase name="Line ' + error.lineNumber + ': ' + msg + '" ' +
165                     ' time="0">');
166                 console.log('    <error type="SyntaxError" message="' + error.message + '">' +
167                     error.message + '(' + name + ':' + error.lineNumber + ')' +
168                     '</error>');
169                 console.log('  </testcase>');
170             });
171
172             console.log('</testsuite>');
173
174         } else if (options.format === 'plain') {
175
176             syntax.errors.forEach(function (error) {
177                 var msg = error.message;
178                 msg = msg.replace(/^Line\ [0-9]*\:\ /, '');
179                 msg = fname + ':' + error.lineNumber + ': ' + msg;
180                 console.log(msg);
181                 ++count;
182             });
183
184         }
185     } catch (e) {
186         ++count;
187         if (options.format === 'junit') {
188             console.log('<testsuite name="' + fname + '" errors="1" failures="0" tests="1" ' +
189                 ' time="' + Math.round((Date.now() - timestamp) / 1000) + '">');
190             console.log(' <testcase name="' + e.message + '" ' + ' time="0">');
191             console.log(' <error type="ParseError" message="' + e.message + '">' +
192                 e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') +
193                 ')</error>');
194             console.log(' </testcase>');
195             console.log('</testsuite>');
196         } else {
197             console.log('Error: ' + e.message);
198         }
199     }
200 }
201
202 fnames.forEach(function (fname) {
203     var content = '';
204     try {
205         if (fname && (fname !== '-' || forceFile)) {
206             content = fs.readFileSync(fname, 'utf-8');
207         } else {
208             fname = '';
209             process.stdin.resume();
210             process.stdin.on('data', function(chunk) {
211                 content += chunk;
212             });
213             process.stdin.on('end', function() {
214                 run(fname, content);
215             });
216             return;
217         }
218     } catch (e) {
219         content = e;
220     }
221     run(fname, content);
222 });
223
224 process.on('exit', function () {
225     if (options.format === 'junit') {
226         console.log('</testsuites>');
227     }
228
229     if (count > 0) {
230         process.exit(1);
231     }
232
233     if (count === 0 && typeof phantom === 'object') {
234         process.exit(0);
235     }
236 });