Permalink
Browse files

Integrated OS.parse.

  • Loading branch information...
1 parent 9542129 commit 0e42a8b5db05fad9858c5b53458d5c7a6cb76f52 @kriskowal kriskowal committed Mar 1, 2010
Showing with 136 additions and 57 deletions.
  1. +62 −12 lib/os.js
  2. +74 −45 tests/os/parse.js
View
@@ -1,5 +1,7 @@
// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- penwellr TODO
+// contributed "parse"
var engine = require('os-engine');
for (var name in engine) {
@@ -63,21 +65,49 @@ exports.command = function (command) {
/**
* enquotes a string such that it is guaranteed to be a single
* argument with no interpolated values for a shell.
+ *
+ * /!\ WARNING: as yet, this implementation only handles
+ * enquoting for Unix shell script style arguments. Further
+ * development is necessary to enquote and escape arguments
+ * on Windows.
*/
exports.enquote = function (word) {
return "'" + String(word).replace(/'/g, "'\"'\"'") + "'";
};
-exports.parse = function (args)
-{
- var startsWith = function(self, str) { return (self.match("^"+str.replace('\\', '\\\\'))==str) }
- var endsWith = function(self, str) { return (self.match(str.replace('\\', '\\\\')+"$")==str) }
+/**
+ * parses command line arguments
+ * @param command {String} a command composed of space delimited,
+ * quoted, or backslash escaped arguments.
+ * @returns an Array of unquoted arguments.
+ *
+ * /!\ WARNING: this does not handle all of the edge cases
+ * of command line argument parsing, nor is suitable for
+ * general purpose argument enquoting on all platforms. It
+ * also will never be able to handle environment variable
+ * interpolation or other forms of shell quote expansion.
+ * This utility is used by Narwhal to pare arguments from
+ * system.env.NARWHAL_OPT.
+ */
+exports.parse = function (args) {
+ var startsWith = function(self, str) {
+ return (self.match("^"+str.replace('\\', '\\\\'))==str)
+ }
+ var endsWith = function(self, str) {
+ return (self.match(str.replace('\\', '\\\\')+"$")==str)
+ }
var results = [], quoteType = null, quotedElement = null;
args.split(' ').forEach(function(element) {
- if (quoteType || endsWith(element, '\\') || startsWith(element, '\'') || startsWith(element, '"')) {
+ if (
+ quoteType || endsWith(element, '\\') ||
+ startsWith(element, '\'') || startsWith(element, '"')
+ ) {
if (quoteType) {
if (endsWith(element, quoteType)) {
- results.push(quotedElement + " " + element.substring(0, element.length - 1));
+ results.push(
+ quotedElement + " " +
+ element.substring(0, element.length - 1)
+ );
quotedElement = null;
quoteType = null;
return;
@@ -96,16 +126,36 @@ exports.parse = function (args)
}
if (!quoteType) {
if (endsWith(element, '\\')) {
- if (quotedElement) { quotedElement += " " + element.substring(0, element.length - 1); }
- else { quotedElement = element.substring(0, element.length - 1); }
+ if (quotedElement) {
+ quotedElement += " " + element.substring(
+ 0,
+ element.length - 1
+ );
+ }
+ else {
+ quotedElement = element.substring(
+ 0,
+ element.length - 1
+ );
+ }
+ }
+ else {
+ results.push(quotedElement + ' ' + element);
+ quotedElement = null;
+ return;
}
- else { results.push(quotedElement + ' ' + element); quotedElement = null; return; }
}
}
else {
- if (quotedElement) { results.push(quotedElement+' '+element); quotedElement = null;}
- else { results.push(element); }
+ if (quotedElement) {
+ results.push(quotedElement + ' ' + element);
+ quotedElement = null;
+ }
+ else {
+ results.push(element);
+ }
}
});
return results;
-}
+};
+
View
@@ -1,68 +1,97 @@
-var assert = require("test/assert");
-var os = require("os");
-var io = require("io");
+
+var ASSERT = require("assert");
+var OS = require("os");
+
+// TODO parameterize on whether the system.os is Win(nt|dows).
exports.testNoEscapedPaths = function() {
- var result = os.parse('command -option -with other option');
- assert.eq(5, result.length);
- assert.eq("command", result[0]);
- assert.eq("-option", result[1]);
- assert.eq("-with", result[2]);
- assert.eq("other", result[3]);
- assert.eq("option", result[4]);
+ var result = OS.parse('command -option -with other option');
+ ASSERT.equal(5, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-option", result[1]);
+ ASSERT.equal("-with", result[2]);
+ ASSERT.equal("other", result[3]);
+ ASSERT.equal("option", result[4]);
};
exports.testSlashEscapedPath = function() {
- var result = os.parse('command -path /Volume/path\\ with\\ space/dir');
- assert.eq(3, result.length);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path with space/dir", result[2]);
+ var result = OS.parse('command -path /Volume/path\\ with\\ space/dir');
+ ASSERT.equal(3, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path with space/dir", result[2]);
};
exports.testSingleQuotedPath = function() {
- var result = os.parse("command -path '/Volume/path with space/dir'");
- assert.eq(3, result.length);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path with space/dir", result[2]);
+ var result = OS.parse("command -path '/Volume/path with space/dir'");
+ ASSERT.equal(3, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path with space/dir", result[2]);
};
exports.testDoubleQuotedPath = function() {
- var result = os.parse('command -path "/Volume/path with space/dir"');
- assert.eq(3, result.length);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path with space/dir", result[2]);
+ var result = OS.parse('command -path "/Volume/path with space/dir"');
+ ASSERT.equal(3, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path with space/dir", result[2]);
};
exports.testQuoteInsideQuote = function() {
- var result = os.parse('command -path "/Volume/path with space/dir \'yet more quotes\'"');
- assert.eq(3, result.length);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path with space/dir 'yet more quotes'", result[2]);
+ var result = OS.parse('command -path "/Volume/path with space/dir \'yet more quotes\'"');
+ ASSERT.equal(3, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path with space/dir 'yet more quotes'", result[2]);
};
exports.testQuotedAndSlashed = function() {
- var result = os.parse('command -path "/Volume/path\\ with\\ space/dir"');
- assert.eq(3, result.length);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path\\ with\\ space/dir", result[2]);
+ var result = OS.parse('command -path "/Volume/path\\ with\\ space/dir"');
+ ASSERT.equal(3, result.length);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path\\ with\\ space/dir", result[2]);
+};
+
+/* TODO unix sh specific details
+exports.testSingleQuoteAndSlash = function () {
+ var result = OS.parse("'\\'");
+ ASSERT.equal(result.length, 1);
+ ASSERT.equal(result[0], '\\');
+};
+
+exports.testAdjacentSingleQuotes = function () {
+ var result = OS.parse("'a''b'");
+ ASSERT.equal(result.length, 1);
+ ASSERT.equal(result[0], 'ab');
};
+exports.testAdjacentDoubleQuotes = function () {
+ var result = OS.parse('"a""b"');
+ ASSERT.equal(result.length, 1);
+ ASSERT.equal(result[0], 'ab');
+};
+
+exports.testAdjacentMixedQuotes = function () {
+ var result = OS.parse('"a"\'b\'');
+ ASSERT.equal(result.length, 1);
+ ASSERT.equal(result[0], 'ab');
+};
+*/
+
exports.testAllEscapeTypes = function() {
- var result = os.parse('command -path "/Volume/path with space/dir" -I \'/volume/path with space\' -L /volume/libs\\ with\\ space/lib');
- assert.eq(result.length, 7);
- assert.eq("command", result[0]);
- assert.eq("-path", result[1]);
- assert.eq("/Volume/path with space/dir", result[2]);
- assert.eq("-I", result[3]);
- assert.eq("/volume/path with space", result[4]);
- assert.eq("-L", result[5]);
- assert.eq("/volume/libs with space/lib", result[6]);
+ var result = OS.parse('command -path "/Volume/path with space/dir" -I \'/volume/path with space\' -L /volume/libs\\ with\\ space/lib');
+ ASSERT.equal(result.length, 7);
+ ASSERT.equal("command", result[0]);
+ ASSERT.equal("-path", result[1]);
+ ASSERT.equal("/Volume/path with space/dir", result[2]);
+ ASSERT.equal("-I", result[3]);
+ ASSERT.equal("/volume/path with space", result[4]);
+ ASSERT.equal("-L", result[5]);
+ ASSERT.equal("/volume/libs with space/lib", result[6]);
};
if (require.main == module.id)
- os.exit(require("test/runner").run(exports));
+ OS.exit(require("test").run(exports));
+

0 comments on commit 0e42a8b

Please sign in to comment.