// Copyright 2013 Traceur
Authors. // // Licensed under the Apache License, Version 2.0 (the “License”); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an “AS IS” BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.
var format = require('util').format;
function addAbbrev(o) {
var ks = [''].concat(Object.keys(o).sort()), k, kprev = ''; for (var i = ks.length - 1; i > 0; i--) { var ka = k = ks[i], pre = 0; // find length of common prefix, clamp to min of 1. while (kprev[pre] === k[pre]) { pre++; } pre = pre || 1; // add all unique prefixes for k. while (!o[ka = ka.slice(0, -1)] && ka.length > pre && ka > ks[i - 1]) { o[ka] = o[k]; } kprev = k; }
}
function Getopt(opts) {
this.opt = null; this.optarg = null; this.optopt = null; this.optdata = null; this.optind = 2; this.nextchar = 0; this.opts_ = Object.create(null); for (var i = 0; i < opts.length; i++) { var opt = opts[i], data = null, m; if (Array.isArray(opt)) { data = opt[1] || null; opt = opt[0]; } if (!(m = opt.match(/^([\w\-]+)(:{0,2})$/))) { throw new Error('invalid option initializer: ' + opt); } this.opts_[m[1]] = {name: m[1], arg: m[2], data: data}; } addAbbrev(this.opts_);
}
Getopt.prototype = {
getopt: function(argv) { var m, arg, optInf; this.opt = this.optarg = this.optopt = this.optdata = null; if (this.optind >= argv.length) { return false; } arg = argv[this.optind]; if (!this.nextchar && /^-[^\-]/.test(arg)) { this.nextchar = 1; } if (this.nextchar) { // short opt this.opt = arg[this.nextchar] || null; this.optarg = arg.slice(++this.nextchar) || null; } else if (m = arg.match(/^--([^=]+)(?:=(.*))?$|^--(.+)$/)) { // long opt this.opt = m[1] || m[3]; this.optarg = m[2] === undefined ? null : m[2]; } else { // free arg this.optind++; this.opt = '='; this.optarg = arg; return true; } if (optInf = this.opts_[this.opt]) { this.opt = optInf.name; this.optdata = optInf.data; switch (optInf.arg) { case '': // no arg if (!this.nextchar && this.optarg) { // unexpected arg this.optopt = this.opt; this.opt = '!'; break; } this.optarg = null; break; case ':': // required arg if (this.optarg === null) { if (++this.optind >= argv.length) { // missing arg this.optopt = this.opt; this.opt = ':'; break; } this.optarg = argv[this.optind]; } // fall through case '::': // optional arg this.nextchar = 0; break; } } else { // unknown opt this.optopt = this.opt; this.opt = '?'; } this.optind += !(this.nextchar %= arg.length); return true; }, message: function() { switch (this.opt) { case ':': return format('missing argument for \'%s\'.', this.optopt); case '?': return format('unknown option \'%s\'.', this.optopt); case '!': return format('\'%s\' does not take an argument.', this.optopt); case '=': return format('optarg \'%s\'.', this.optarg); default: if (this.optarg === null) return format('opt \'%s\'.', this.opt); else return format('opt \'%s\', optarg \'%s\'.', this.opt, this.optarg); } }
}
exports.Getopt = Getopt;