2010-02-14 15:16:33 -05:00
|
|
|
(function(){
|
2010-06-12 19:05:13 -04:00
|
|
|
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments;
|
2010-02-27 19:46:45 -05:00
|
|
|
exports.OptionParser = (function() {
|
2010-05-14 23:40:04 -04:00
|
|
|
OptionParser = function(rules, banner) {
|
2010-02-27 19:46:45 -05:00
|
|
|
this.banner = banner;
|
2010-06-12 19:05:13 -04:00
|
|
|
this.rules = buildRules(rules);
|
2010-02-27 19:46:45 -05:00
|
|
|
return this;
|
2010-02-24 17:57:58 -05:00
|
|
|
};
|
2010-05-14 23:40:04 -04:00
|
|
|
OptionParser.prototype.parse = function(args) {
|
2010-06-12 19:05:13 -04:00
|
|
|
var _a, _b, _c, arg, isOption, matchedRule, options, rule;
|
2010-02-27 19:46:45 -05:00
|
|
|
options = {
|
|
|
|
arguments: []
|
|
|
|
};
|
2010-06-12 19:05:13 -04:00
|
|
|
args = normalizeArguments(args);
|
2010-03-30 18:27:53 -04:00
|
|
|
while ((arg = args.shift())) {
|
2010-06-12 19:05:13 -04:00
|
|
|
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
|
|
|
|
matchedRule = false;
|
2010-03-27 16:04:47 -04:00
|
|
|
_b = this.rules;
|
|
|
|
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
|
|
|
rule = _b[_a];
|
2010-06-12 19:05:13 -04:00
|
|
|
if (rule.shortFlag === arg || rule.longFlag === arg) {
|
|
|
|
options[rule.name] = rule.hasArgument ? args.shift() : true;
|
|
|
|
matchedRule = true;
|
2010-02-27 19:46:45 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2010-06-12 19:05:13 -04:00
|
|
|
if (isOption && !matchedRule) {
|
2010-06-27 23:55:18 -04:00
|
|
|
throw new Error("unrecognized option: " + arg);
|
2010-02-27 19:46:45 -05:00
|
|
|
}
|
2010-06-12 19:05:13 -04:00
|
|
|
if (!(isOption)) {
|
2010-02-27 19:46:45 -05:00
|
|
|
options.arguments.push(arg);
|
2010-02-14 15:16:33 -05:00
|
|
|
}
|
|
|
|
}
|
2010-02-27 19:46:45 -05:00
|
|
|
return options;
|
|
|
|
};
|
2010-05-14 23:40:04 -04:00
|
|
|
OptionParser.prototype.help = function() {
|
2010-06-12 19:05:13 -04:00
|
|
|
var _a, _b, _c, _d, i, letPart, lines, rule, spaces;
|
2010-02-27 19:46:45 -05:00
|
|
|
lines = ['Available options:'];
|
|
|
|
if (this.banner) {
|
2010-06-27 23:55:18 -04:00
|
|
|
lines.unshift("" + this.banner + "\n");
|
2010-02-25 18:54:08 -05:00
|
|
|
}
|
2010-03-27 16:04:47 -04:00
|
|
|
_b = this.rules;
|
|
|
|
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
|
|
|
rule = _b[_a];
|
2010-06-12 19:05:13 -04:00
|
|
|
spaces = 15 - rule.longFlag.length;
|
2010-02-27 19:46:45 -05:00
|
|
|
spaces = spaces > 0 ? (function() {
|
2010-05-31 19:38:45 -04:00
|
|
|
_d = [];
|
|
|
|
for (i = 0; i <= spaces; i += 1) {
|
2010-02-27 19:46:45 -05:00
|
|
|
_d.push(' ');
|
|
|
|
}
|
|
|
|
return _d;
|
2010-04-10 14:40:05 -04:00
|
|
|
})().join('') : '';
|
2010-06-12 19:05:13 -04:00
|
|
|
letPart = rule.shortFlag ? rule.shortFlag + ', ' : ' ';
|
2010-06-27 23:55:18 -04:00
|
|
|
lines.push(" " + letPart + rule.longFlag + spaces + rule.description);
|
2010-02-14 15:16:33 -05:00
|
|
|
}
|
2010-03-06 13:59:11 -05:00
|
|
|
return "\n" + (lines.join('\n')) + "\n";
|
2010-02-27 19:46:45 -05:00
|
|
|
};
|
|
|
|
return OptionParser;
|
2010-04-10 14:40:05 -04:00
|
|
|
})();
|
2010-02-25 18:36:43 -05:00
|
|
|
LONG_FLAG = /^(--\w[\w\-]+)/;
|
2010-02-25 19:06:08 -05:00
|
|
|
SHORT_FLAG = /^(-\w)/;
|
|
|
|
MULTI_FLAG = /^-(\w{2,})/;
|
2010-02-14 15:16:33 -05:00
|
|
|
OPTIONAL = /\[(.+)\]/;
|
2010-06-12 19:05:13 -04:00
|
|
|
buildRules = function(rules) {
|
2010-02-25 23:39:14 -05:00
|
|
|
var _a, _b, _c, _d, tuple;
|
2010-03-27 16:04:47 -04:00
|
|
|
_a = []; _c = rules;
|
|
|
|
for (_b = 0, _d = _c.length; _b < _d; _b++) {
|
|
|
|
tuple = _c[_b];
|
2010-02-16 18:00:40 -05:00
|
|
|
_a.push((function() {
|
2010-02-14 15:16:33 -05:00
|
|
|
if (tuple.length < 3) {
|
|
|
|
tuple.unshift(null);
|
|
|
|
}
|
2010-06-12 19:05:13 -04:00
|
|
|
return buildRule.apply(this, tuple);
|
2010-04-10 14:40:05 -04:00
|
|
|
})());
|
2010-02-14 15:16:33 -05:00
|
|
|
}
|
2010-02-16 18:00:40 -05:00
|
|
|
return _a;
|
2010-02-14 15:16:33 -05:00
|
|
|
};
|
2010-06-12 19:05:13 -04:00
|
|
|
buildRule = function(shortFlag, longFlag, description) {
|
2010-02-14 15:16:33 -05:00
|
|
|
var match;
|
2010-06-12 19:05:13 -04:00
|
|
|
match = longFlag.match(OPTIONAL);
|
|
|
|
longFlag = longFlag.match(LONG_FLAG)[1];
|
2010-02-14 15:16:33 -05:00
|
|
|
return {
|
2010-06-12 19:05:13 -04:00
|
|
|
name: longFlag.substr(2),
|
|
|
|
shortFlag: shortFlag,
|
|
|
|
longFlag: longFlag,
|
2010-02-14 15:16:33 -05:00
|
|
|
description: description,
|
2010-06-12 19:05:13 -04:00
|
|
|
hasArgument: !!(match && match[1])
|
2010-02-14 15:16:33 -05:00
|
|
|
};
|
|
|
|
};
|
2010-06-12 19:05:13 -04:00
|
|
|
normalizeArguments = function(args) {
|
2010-02-25 23:39:14 -05:00
|
|
|
var _a, _b, _c, _d, _e, _f, arg, l, match, result;
|
2010-02-25 19:06:08 -05:00
|
|
|
args = args.slice(0);
|
|
|
|
result = [];
|
2010-03-27 16:04:47 -04:00
|
|
|
_b = args;
|
|
|
|
for (_a = 0, _c = _b.length; _a < _c; _a++) {
|
|
|
|
arg = _b[_a];
|
2010-02-25 19:06:08 -05:00
|
|
|
if ((match = arg.match(MULTI_FLAG))) {
|
2010-03-27 16:04:47 -04:00
|
|
|
_e = match[1].split('');
|
|
|
|
for (_d = 0, _f = _e.length; _d < _f; _d++) {
|
|
|
|
l = _e[_d];
|
2010-02-25 19:06:08 -05:00
|
|
|
result.push('-' + l);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
result.push(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
2010-02-24 18:56:32 -05:00
|
|
|
})();
|