Initial commit
[yaffs-website] / node_modules / mkdirp / node_modules / minimist / index.js
1 module.exports = function (args, opts) {
2     if (!opts) opts = {};
3     
4     var flags = { bools : {}, strings : {} };
5     
6     [].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
7         flags.bools[key] = true;
8     });
9     
10     [].concat(opts.string).filter(Boolean).forEach(function (key) {
11         flags.strings[key] = true;
12     });
13     
14     var aliases = {};
15     Object.keys(opts.alias || {}).forEach(function (key) {
16         aliases[key] = [].concat(opts.alias[key]);
17         aliases[key].forEach(function (x) {
18             aliases[x] = [key].concat(aliases[key].filter(function (y) {
19                 return x !== y;
20             }));
21         });
22     });
23     
24     var defaults = opts['default'] || {};
25     
26     var argv = { _ : [] };
27     Object.keys(flags.bools).forEach(function (key) {
28         setArg(key, defaults[key] === undefined ? false : defaults[key]);
29     });
30     
31     var notFlags = [];
32
33     if (args.indexOf('--') !== -1) {
34         notFlags = args.slice(args.indexOf('--')+1);
35         args = args.slice(0, args.indexOf('--'));
36     }
37
38     function setArg (key, val) {
39         var value = !flags.strings[key] && isNumber(val)
40             ? Number(val) : val
41         ;
42         setKey(argv, key.split('.'), value);
43         
44         (aliases[key] || []).forEach(function (x) {
45             setKey(argv, x.split('.'), value);
46         });
47     }
48     
49     for (var i = 0; i < args.length; i++) {
50         var arg = args[i];
51         
52         if (/^--.+=/.test(arg)) {
53             // Using [\s\S] instead of . because js doesn't support the
54             // 'dotall' regex modifier. See:
55             // http://stackoverflow.com/a/1068308/13216
56             var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
57             setArg(m[1], m[2]);
58         }
59         else if (/^--no-.+/.test(arg)) {
60             var key = arg.match(/^--no-(.+)/)[1];
61             setArg(key, false);
62         }
63         else if (/^--.+/.test(arg)) {
64             var key = arg.match(/^--(.+)/)[1];
65             var next = args[i + 1];
66             if (next !== undefined && !/^-/.test(next)
67             && !flags.bools[key]
68             && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
69                 setArg(key, next);
70                 i++;
71             }
72             else if (/^(true|false)$/.test(next)) {
73                 setArg(key, next === 'true');
74                 i++;
75             }
76             else {
77                 setArg(key, flags.strings[key] ? '' : true);
78             }
79         }
80         else if (/^-[^-]+/.test(arg)) {
81             var letters = arg.slice(1,-1).split('');
82             
83             var broken = false;
84             for (var j = 0; j < letters.length; j++) {
85                 var next = arg.slice(j+2);
86                 
87                 if (next === '-') {
88                     setArg(letters[j], next)
89                     continue;
90                 }
91                 
92                 if (/[A-Za-z]/.test(letters[j])
93                 && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
94                     setArg(letters[j], next);
95                     broken = true;
96                     break;
97                 }
98                 
99                 if (letters[j+1] && letters[j+1].match(/\W/)) {
100                     setArg(letters[j], arg.slice(j+2));
101                     broken = true;
102                     break;
103                 }
104                 else {
105                     setArg(letters[j], flags.strings[letters[j]] ? '' : true);
106                 }
107             }
108             
109             var key = arg.slice(-1)[0];
110             if (!broken && key !== '-') {
111                 if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
112                 && !flags.bools[key]
113                 && (aliases[key] ? !flags.bools[aliases[key]] : true)) {
114                     setArg(key, args[i+1]);
115                     i++;
116                 }
117                 else if (args[i+1] && /true|false/.test(args[i+1])) {
118                     setArg(key, args[i+1] === 'true');
119                     i++;
120                 }
121                 else {
122                     setArg(key, flags.strings[key] ? '' : true);
123                 }
124             }
125         }
126         else {
127             argv._.push(
128                 flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
129             );
130         }
131     }
132     
133     Object.keys(defaults).forEach(function (key) {
134         if (!hasKey(argv, key.split('.'))) {
135             setKey(argv, key.split('.'), defaults[key]);
136             
137             (aliases[key] || []).forEach(function (x) {
138                 setKey(argv, x.split('.'), defaults[key]);
139             });
140         }
141     });
142     
143     notFlags.forEach(function(key) {
144         argv._.push(key);
145     });
146
147     return argv;
148 };
149
150 function hasKey (obj, keys) {
151     var o = obj;
152     keys.slice(0,-1).forEach(function (key) {
153         o = (o[key] || {});
154     });
155
156     var key = keys[keys.length - 1];
157     return key in o;
158 }
159
160 function setKey (obj, keys, value) {
161     var o = obj;
162     keys.slice(0,-1).forEach(function (key) {
163         if (o[key] === undefined) o[key] = {};
164         o = o[key];
165     });
166     
167     var key = keys[keys.length - 1];
168     if (o[key] === undefined || typeof o[key] === 'boolean') {
169         o[key] = value;
170     }
171     else if (Array.isArray(o[key])) {
172         o[key].push(value);
173     }
174     else {
175         o[key] = [ o[key], value ];
176     }
177 }
178
179 function isNumber (x) {
180     if (typeof x === 'number') return true;
181     if (/^0x[0-9a-f]+$/i.test(x)) return true;
182     return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
183 }
184
185 function longest (xs) {
186     return Math.max.apply(null, xs.map(function (x) { return x.length }));
187 }