UNPKG

shell-split

Version:

A lighterweight alternative to shell-quote

165 lines (134 loc) 4.92 kB
(function (root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.shellSplit = factory(); } })(this, function(){ function UnterminatedSingleQuoteError() { this.message = "Unterminated single-quoted string"; var error = new Error(this.message); this.stack = error.stack; } UnterminatedSingleQuoteError.prototype = new Error(); UnterminatedSingleQuoteError.prototype.name = UnterminatedSingleQuoteError.name; UnterminatedSingleQuoteError.prototype.constructor = UnterminatedSingleQuoteError; function UnterminatedDoubleQuoteError() { this.message = "Unterminated double-quoted string"; var error = new Error(this.message); this.stack = error.stack; } UnterminatedDoubleQuoteError.prototype = new Error(); UnterminatedDoubleQuoteError.prototype.name = UnterminatedDoubleQuoteError.name; UnterminatedDoubleQuoteError.prototype.constructor = UnterminatedDoubleQuoteError; function UnterminatedEscapeError() { this.message = "Unterminated backslash-escape"; var error = new Error(this.message); this.stack = error.stack; } UnterminatedEscapeError.prototype = new Error(); UnterminatedEscapeError.prototype.name = UnterminatedEscapeError.name; UnterminatedEscapeError.prototype.constructor = UnterminatedEscapeError; function split(str) { var rest = str.replace(/^\s+/,''); if (!rest) return []; var results = ['']; var position = 0; var dq = false; var match; while (rest) { // in double-quoted context if (dq) { match = /["\\]/.exec(rest); if (!match) throw new UnterminatedDoubleQuoteError(); results[position] += rest.slice(0, match.index); // append backslash escapes if (match[0] == "\\") { if (rest.length - match.index < 2) throw new UnterminatedEscapeError(); // don't append escaped newlines if (rest.charAt(1) != '\n') results[position] += rest.charAt(match.index + 1); rest = rest.slice(match.index + 2); // for the other recognized decision point ("), exit double-quoting } else { rest = rest.slice(match.index + 1); dq = false; } // out of double-quoted context } else { // split at any whitespace out of quoted context match = /^\s+/.exec(rest); if (match) { rest = rest.slice(match[0].length); // if there is remaining non-whitespace if (rest) { results[++position] = ''; } } // find the next decision point match = /[\s'"\\]/.exec(rest); // if there is an upcoming split or context switch if (match) { results[position] += rest.slice(0, match.index); rest = rest.slice(match.index); // append backslash escapes if (match[0] == "\\") { if (rest.length < 2) throw new UnterminatedEscapeError(); // don't append escaped newlines if (rest.charAt(1) != '\n') results[position] += rest.charAt(1); rest = rest.slice(2); // append single-quoted strings } else if (match[0] == "'") { match = rest.indexOf("'", 1); if (match == -1) throw new UnterminatedSingleQuoteError(); results[position] += rest.slice(1, match); rest = rest.slice(match + 1); // enter double-quoted context } else if (match[0] == '"') { // move into double-quoted string rest = rest.slice(1); dq = true; } // otherwise, we assume it's whitespace and will reiterate // if we won't be entering any more contexts } else { // finish results results[position] += rest; rest = ''; } } } return results; } function quoteEscape(str) { str = String(str).replace(/[\\'"`${}[\]|&;<>()*?!]/g,'\\$&'); return /^$|^~|\s/.test(str) ? '"' + str + '"' : str; } function quote(args) { return Array.isArray(args) ? args.map(quoteEscape).join(' ') : quoteEscape(args); } // create a special clone of the split instance to attach exports to var exported = split.bind(null); exported.split = split; exported.unquote = split; exported.unescape = split; exported.parse = split; exported.quote = quote; exported.join = quote; exported.escape = quote; exported.stringify = quote; exported.UnterminatedSingleQuoteError = UnterminatedSingleQuoteError; exported.UnterminatedDoubleQuoteError = UnterminatedSingleQuoteError; exported.UnterminatedEscapeError = UnterminatedEscapeError; return exported; });