21a6de06d5
This commit enables optional features that are enabled by default in the generated parser. For now, only some of the helpers and filename are generated based on this new option, but this will change in the future most likely. Resolves #421
318 lines
6.8 KiB
JavaScript
318 lines
6.8 KiB
JavaScript
"use strict";
|
|
|
|
const fs = require( "fs" );
|
|
const path = require( "path" );
|
|
const peg = require( "../lib/peg" );
|
|
const util = peg.util;
|
|
|
|
// Options
|
|
|
|
let inputFile = null;
|
|
let outputFile = null;
|
|
let options = {
|
|
"--": [],
|
|
"cache": false,
|
|
"dependencies": {},
|
|
"exportVar": null,
|
|
"format": "commonjs",
|
|
"optimize": "speed",
|
|
"output": "source",
|
|
"parser": {},
|
|
"plugins": [],
|
|
"trace": false
|
|
};
|
|
|
|
const EXPORT_VAR_FORMATS = [ "globals", "umd" ];
|
|
const DEPENDENCY_FORMATS = [ "amd", "commonjs", "es", "umd" ];
|
|
const MODULE_FORMATS = [ "amd", "bare", "commonjs", "es", "globals", "umd" ];
|
|
const OPTIMIZATION_GOALS = [ "size", "speed" ];
|
|
|
|
// Helpers
|
|
|
|
function abort( message ) {
|
|
|
|
console.error( message );
|
|
process.exit( 1 );
|
|
|
|
}
|
|
|
|
function addExtraOptions( config ) {
|
|
|
|
if ( typeof config === "string" ) {
|
|
|
|
try {
|
|
|
|
config = JSON.parse( config );
|
|
|
|
} catch ( e ) {
|
|
|
|
if ( ! ( e instanceof SyntaxError ) ) throw e;
|
|
abort( "Error parsing JSON: " + e.message );
|
|
|
|
}
|
|
|
|
}
|
|
if ( typeof config !== "object" ) {
|
|
|
|
abort( "The JSON with extra options has to represent an object." );
|
|
|
|
}
|
|
|
|
const extraOptions = {};
|
|
util.extend( extraOptions, config );
|
|
util.extend( extraOptions, options );
|
|
options = extraOptions;
|
|
|
|
}
|
|
|
|
function formatChoicesList( list ) {
|
|
|
|
list = list.map( entry => `"${ entry }"` );
|
|
const lastOption = list.pop();
|
|
|
|
return list.length === 0
|
|
? lastOption
|
|
: list.join( ", " ) + " or " + lastOption;
|
|
|
|
}
|
|
|
|
function updateList( list, string ) {
|
|
|
|
string
|
|
.split( "," )
|
|
.forEach( entry => {
|
|
|
|
entry = entry.trim();
|
|
if ( list.indexOf( entry ) === -1 ) {
|
|
|
|
list.push( entry );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
// Arguments
|
|
|
|
let args = process.argv.slice( 2 );
|
|
|
|
function nextArg( option ) {
|
|
|
|
if ( args.length === 0 ) {
|
|
|
|
abort( `Missing parameter of the ${ option } option.` );
|
|
|
|
}
|
|
return args.shift();
|
|
|
|
}
|
|
|
|
// Parse Arguments
|
|
|
|
while ( args.length > 0 ) {
|
|
|
|
let config, mod;
|
|
let argument = args.shift();
|
|
|
|
if ( argument.indexOf( "-" ) === 0 && argument.indexOf( "=" ) > 1 ) {
|
|
|
|
argument = argument.split( "=" );
|
|
args.unshift( argument.length > 2 ? argument.slice( 1 ) : argument[ 1 ] );
|
|
argument = argument[ 0 ];
|
|
|
|
}
|
|
|
|
switch ( argument ) {
|
|
|
|
case "--":
|
|
options[ "--" ] = args;
|
|
args = [];
|
|
break;
|
|
|
|
case "-a":
|
|
case "--allowed-start-rules":
|
|
if ( ! options.allowedStartRules ) options.allowedStartRules = [];
|
|
updateList( options.allowedStartRules, nextArg( "--allowed-start-rules" ) );
|
|
break;
|
|
|
|
case "--cache":
|
|
options.cache = true;
|
|
break;
|
|
|
|
case "--no-cache":
|
|
options.cache = false;
|
|
break;
|
|
|
|
case "-d":
|
|
case "--dependency":
|
|
argument = nextArg( "-d/--dependency" );
|
|
mod = argument.split( ":" );
|
|
|
|
if ( mod.length === 1 ) mod = [ argument, argument ];
|
|
else if ( mod.length > 2 ) mod[ 1 ] = mod.slice( 1 );
|
|
|
|
options.dependencies[ mod[ 0 ] ] = mod[ 1 ];
|
|
break;
|
|
|
|
case "-e":
|
|
case "--export-var":
|
|
options.exportVar = nextArg( "-e/--export-var" );
|
|
break;
|
|
|
|
case "--extra-options":
|
|
addExtraOptions( nextArg( "--extra-options" ) );
|
|
break;
|
|
|
|
case "-c":
|
|
case "--config":
|
|
case "--extra-options-file":
|
|
argument = nextArg( "-c/--config/--extra-options-file" );
|
|
if ( path.extname( argument ) === ".js" ) {
|
|
|
|
config = require( path.resolve( argument ) );
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
config = fs.readFileSync( argument, "utf8" );
|
|
|
|
} catch ( e ) {
|
|
|
|
abort( `Can't read from file "${ argument }".` );
|
|
|
|
}
|
|
|
|
}
|
|
addExtraOptions( config );
|
|
break;
|
|
|
|
case "-f":
|
|
case "--format":
|
|
argument = nextArg( "-f/--format" );
|
|
if ( MODULE_FORMATS.indexOf( argument ) === -1 ) {
|
|
|
|
abort( `Module format must be either ${ formatChoicesList( MODULE_FORMATS ) }.` );
|
|
|
|
}
|
|
options.format = argument;
|
|
break;
|
|
|
|
case "-h":
|
|
case "--help":
|
|
console.log( require( "./usage" ) );
|
|
process.exit();
|
|
break;
|
|
|
|
case "-O":
|
|
case "--optimize":
|
|
argument = nextArg( "-O/--optimize" );
|
|
if ( OPTIMIZATION_GOALS.indexOf( argument ) === -1 ) {
|
|
|
|
abort( `Optimization goal must be either ${ formatChoicesList( OPTIMIZATION_GOALS ) }.` );
|
|
|
|
}
|
|
options.optimize = argument;
|
|
break;
|
|
|
|
case "-o":
|
|
case "--output":
|
|
outputFile = nextArg( "-o/--output" );
|
|
break;
|
|
|
|
case "-p":
|
|
case "--plugin":
|
|
argument = nextArg( "-p/--plugin" );
|
|
try {
|
|
|
|
mod = require( argument );
|
|
|
|
} catch ( ex1 ) {
|
|
|
|
if ( ex1.code !== "MODULE_NOT_FOUND" ) throw ex1;
|
|
try {
|
|
|
|
mod = require( path.resolve( argument ) );
|
|
|
|
} catch ( ex2 ) {
|
|
|
|
if ( ex2.code !== "MODULE_NOT_FOUND" ) throw ex2;
|
|
abort( `Can't load module "${ argument }".` );
|
|
|
|
}
|
|
|
|
}
|
|
options.plugins.push( mod );
|
|
break;
|
|
|
|
case "--trace":
|
|
options.trace = true;
|
|
break;
|
|
|
|
case "--no-trace":
|
|
options.trace = false;
|
|
break;
|
|
|
|
case "-v":
|
|
case "--version":
|
|
console.log( "PEG.js v" + peg.VERSION );
|
|
process.exit();
|
|
break;
|
|
|
|
default:
|
|
if ( inputFile !== null ) {
|
|
|
|
abort( `Unknown option: "${ argument }".` );
|
|
|
|
}
|
|
inputFile = argument;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Validation and defaults
|
|
|
|
if ( Object.keys( options.dependencies ).length > 0 ) {
|
|
|
|
if ( DEPENDENCY_FORMATS.indexOf( options.format ) === -1 ) {
|
|
|
|
abort( `Can't use the -d/--dependency option with the "${ options.format }" module format.` );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( options.exportVar !== null ) {
|
|
|
|
if ( EXPORT_VAR_FORMATS.indexOf( options.format ) === -1 ) {
|
|
|
|
abort( `Can't use the -e/--export-var option with the "${ options.format }" module format.` );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( inputFile === null ) inputFile = "-";
|
|
|
|
if ( outputFile === null ) {
|
|
|
|
if ( inputFile === "-" ) outputFile = "-";
|
|
else if ( inputFile ) {
|
|
|
|
outputFile = inputFile
|
|
.substr( 0, inputFile.length - path.extname( inputFile ).length )
|
|
+ ".js";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Export
|
|
|
|
options.inputFile = inputFile;
|
|
options.outputFile = outputFile;
|
|
|
|
module.exports = options;
|