This module processes the command line arguments into a completed configuration
and returns a config
object.
It takes the node
command line arguments less the first two. e.g. process.argv.slice(2)
and can be a free mix of keys and key/value pairs.
Run
npm run apg -- --help
or
./bin/apg.sh -- help
to see all the options.
module.exports = function commandLine(args) {
const fs = require('fs');
const path = require('path');
const { Buffer } = require('buffer');
const converter = require('../apg-conv-api/converter');
const helpScreen = function helpScreen(helpArgs) {
let help = 'Usage: apg options\n';
let options = '';
helpArgs.forEach((arg) => {
options += `${arg} `;
});
help += `options: ${options}\n`;
help += '-h, --help : print this help screen\n';
help += '-v, --version : display version information\n';
help += '-s, --strict : only ABNF grammar (RFC 5234 & 7405) allowed, no Superset features\n';
help += '-l, --lite : generate an apg-lite ESM grammar object\n';
help += '-i <path>[,<path>[,...]] : input file(s)*\n';
help += '--in=<path>[,<path>[,...]] : input file(s)*\n';
help += '-o <path> : output filename**\n';
help += '--out=<path> : output filename**\n';
help += '-n <function name> : the grammar function name***\n';
help += '--name=<function name> : the grammar function name***\n';
help += '--display-rules : display the rule names\n';
help += '--display-rule-dependencies: display => rules referenced <= rules referring to this rule\n';
help += '--display-attributes : display the attributes\n';
help += '\n';
help += 'Options are case insensitive.\n';
help += '* Multiple input files allowed.\n';
help += ' Multiple file names must be comma separated with no spaces.\n';
help += ' File names from multiple input options are concatenated.\n';
help += ' Content of all resulting input files is concatenated.\n';
help += '** Output file name is optional.\n';
help += ' If no output file name is given, no parser is generated.\n';
help += ' If the output file name does not have a ".js" extension,\n';
help += ' the existing extension, if any, is stripped and ".js" is added.\n';
help += '*** Grammar function name is optional.\n';
help += ' If present, must be a valid JavaScript function name\n';
help += ' If absent, uses "module.exports" for apg-js application\n';
help += ' or "export default" for apg-lite application.\n';
return help;
};
const version = function version() {
return 'JavaScript APG, version 4.3.0\nCopyright (C) 2023 Lowell D. Thomas, all rights reserved\n';
};
const STRICTL = '--strict';
const STRICTS = '-s';
const LITEL = '--lite';
const LITES = '-l';
const HELPL = '--help';
const HELPS = '-h';
const VERSIONL = '--version';
const VERSIONS = '-v';
const DISPLAY_RULES = '--display-rules';
const DISPLAY_RULE_DEPENDENCIES = '--display-rule-dependencies';
const DISPLAY_ATTRIBUTES = '--display-attributes';
const INL = '--in';
const INS = '-i';
const OUTL = '--out';
const OUTS = '-o';
const NAMEL = '--name';
const NAMES = '-n';
let inFilenames = [];
const config = {
help: '',
version: '',
error: '',
strict: false,
lite: false,
noAttrs: false,
displayRules: false,
displayRuleDependencies: false,
displayAttributes: false,
src: null,
outFilename: '',
outfd: process.stdout.fd,
funcName: null,
};
let key;
let value;
let i = 0;
try {
while (i < args.length) {
const kv = args[i].split('=');
if (kv.length === 2) {
key = kv[0].toLowerCase();