HarshvardhanCn01/Voice-Assistant
0
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23
24
25var isWindows = process.platform === 'win32';
26var util = require('util');
27
28
29// resolves . and .. elements in a path array with directory names there
30// must be no slashes or device names (c:\) in the array
31// (so also no leading and trailing slashes - it does not distinguish
32// relative and absolute paths)
33function normalizeArray(parts, allowAboveRoot) {
34 var res = [];
35 for (var i = 0; i < parts.length; i++) {
36 var p = parts[i];
37
38 // ignore empty parts
39 if (!p || p === '.')
40 continue;
41
42 if (p === '..') {
43 if (res.length && res[res.length - 1] !== '..') {
44 res.pop();
45 } else if (allowAboveRoot) {
46 res.push('..');
47 }
48 } else {
49 res.push(p);
50 }
51 }
52
53 return res;
54}
55
56// returns an array with empty elements removed from either end of the input
57// array or the original array if no elements need to be removed
58function trimArray(arr) {
59 var lastIndex = arr.length - 1;
60 var start = 0;
61 for (; start <= lastIndex; start++) {
62 if (arr[start])
63 break;
64 }
65
66 var end = lastIndex;
67 for (; end >= 0; end--) {
68 if (arr[end])
69 break;
70 }
71
72 if (start === 0 && end === lastIndex)
73 return arr;
74 if (start > end)
75 return [];
76 return arr.slice(start, end + 1);
77}
78
79// Regex to split a windows path into three parts: [*, device, slash,
80// tail] windows-only
81var splitDeviceRe =
82 /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
83
84// Regex to split the tail part of the above into [*, dir, basename, ext]
85var splitTailRe =
86 /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
87
88var win32 = {};
89
90// Function to split a filename into [root, dir, basename, ext]
91function win32SplitPath(filename) {
92 // Separate device+slash from tail
93 var result = splitDeviceRe.exec(filename),
94 device = (result[1] || '') + (result[2] || ''),
95 tail = result[3] || '';
96 // Split the tail into dir, basename and extension
97 var result2 = splitTailRe.exec(tail),
98 dir = result2[1],
99 basename = result2[2],
100 ext = result2[3];
101 return [device, dir, basename, ext];
102}
103
104function win32StatPath(path) {
105 var result = splitDeviceRe.exec(path),
106 device = result[1] || '',
107 isUnc = !!device && device[1] !== ':';
108 return {
109 device: device,
110 isUnc: isUnc,
111 isAbsolute: isUnc || !!result[2], // UNC paths are always absolute
112 tail: result[3]
113 };
114}
115
116function normalizeUNCRoot(device) {
117 return '\\\\' + device.replace(/^[\\\/]+/, '').replace(/[\\\/]+/g, '\\');
118}
119
120// path.resolve([from ...], to)
121win32.resolve = function() {
122 var resolvedDevice = '',
123 resolvedTail = '',
124 resolvedAbsolute = false;
125
126 for (var i = arguments.length - 1; i >= -1; i--) {
127 var path;
128 if (i >= 0) {
129 path = arguments[i];
130 } else if (!resolvedDevice) {
131 path = process.cwd();
132 } else {
133 // Windows has the concept of drive-specific current working
134 // directories. If we've resolved a drive letter but not yet an
135 // absolute path, get cwd for that drive. We're sure the device is not
136 // an unc path at this points, because unc paths are always absolute.
137 path = process.env['=' + resolvedDevice];
138 // Verify that a drive-local cwd was found and that it actually points
139 // to our drive. If not, default to the drive's root.
140 if (!path || path.substr(0, 3).toLowerCase() !==
141 resolvedDevice.toLowerCase() + '\\') {
142 path = resolvedDevice + '\\';
143 }
144 }
145
146 // Skip empty and invalid entries
147 if (!util.isString(path)) {
148 throw new TypeError('Arguments to path.resolve must be strings');
149 } else if (!path) {
150 continue;
151 }
152
153 var result = win32StatPath(path),
154 device = result.device,
155 isUnc = result.isUnc,
156 isAbsolute = result.isAbsolute,
157 tail = result.tail;
158
159 if (device &&
160 resolvedDevice &&
161 device.toLowerCase() !== resolvedDevice.toLowerCase()) {
162 // This path points to another device so it is not applicable
163 continue;
164 }
165
166 if (!resolvedDevice) {
167 resolvedDevice = device;
168 }
169 if (!resolvedAbsolute) {
170 resolvedTail = tail + '\\' + resolvedTail;
171 resolvedAbsolute = isAbsolute;
172 }
173
174 if (resolvedDevice && resolvedAbsolute) {
175 break;
176 }
177 }
178
179 // Convert slashes to backslashes when `resolvedDevice` points to an UNC
180 // root. Also squash multiple slashes into a single one where appropriate.
181 if (isUnc) {
182 resolvedDevice = normalizeUNCRoot(resolvedDevice);
183 }
184
185 // At this point the path should be resolved to a full absolute path,
186 // but handle relative paths to be safe (might happen when process.cwd()
187 // fails)
188
189 // Normalize the tail path
190 resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/),
191 !resolvedAbsolute).join('\\');
192
193 return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ||
194 '.';
195};
196
197
198win32.normalize = function(path) {
199 var result = win32StatPath(path),
200 device = result.device,
201 isUnc = result.isUnc,
202 isAbsolute = result.isAbsolute,
203 tail = result.tail,
204 trailingSlash = /[\\\/]$/.test(tail);
205
206 // Normalize the tail path
207 tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\');
208
209 if (!tail && !isAbsolute) {
210 tail = '.';
211 }
212 if (tail && trailingSlash) {
213 tail += '\\';
214 }
215
216 // Convert slashes to backslashes when `device` points to an UNC root.
217 // Also squash multiple slashes into a single one where appropriate.
218 if (isUnc) {
219 device = normalizeUNCRoot(device);
220 }
221
222 return device + (isAbsolute ? '\\' : '') + tail;
223};
224
225
226win32.isAbsolute = function(path) {
227 return win32StatPath(path).isAbsolute;
228};
229
230win32.join = function() {
231 var paths = [];
232 for (var i = 0; i < arguments.length; i++) {
233 var arg = arguments[i];
234 if (!util.isString(arg)) {
235 throw new TypeError('Arguments to path.join must be strings');
236 }
237 if (arg) {
238 paths.push(arg);
239 }
240 }
241
242 var joined = paths.join('\\');
243
244 // Make sure that the joined path doesn't start with two slashes, because
245 // normalize() will mistake it for an UNC path then.
246 //
247 // This step is skipped when it is very clear that the user actually
248 // intended to point at an UNC path. This is assumed when the first
249 // non-empty string arguments starts with exactly two slashes followed by
250 // at least one more non-slash character.
251 //
252 // Note that for normalize() to treat a path as an UNC path it needs to
253 // have at least 2 components, so we don't filter for that here.
254 // This means that the user can use join to construct UNC paths from
255 // a server name and a share name; for example:
256 // path.join('//server', 'share') -> '\\\\server\\share\')
257 if (!/^[\\\/]{2}[^\\\/]/.test(paths[0])) {
258 joined = joined.replace(/^[\\\/]{2,}/, '\\');
259 }
260
261 return win32.normalize(joined);
262};
263
264
265// path.relative(from, to)
266// it will solve the relative path from 'from' to 'to', for instance:
267// from = 'C:\\orandea\\test\\aaa'
268// to = 'C:\\orandea\\impl\\bbb'
269// The output of the function should be: '..\\..\\impl\\bbb'
270win32.relative = function(from, to) {
271 from = win32.resolve(from);
272 to = win32.resolve(to);
273
274 // windows is not case sensitive
275 var lowerFrom = from.toLowerCase();
276 var lowerTo = to.toLowerCase();
277
278 var toParts = trimArray(to.split('\\'));
279
280 var lowerFromParts = trimArray(lowerFrom.split('\\'));
281 var lowerToParts = trimArray(lowerTo.split('\\'));
282
283 var length = Math.min(lowerFromParts.length, lowerToParts.length);
284 var samePartsLength = length;
285 for (var i = 0; i < length; i++) {
286 if (lowerFromParts[i] !== lowerToParts[i]) {
287 samePartsLength = i;
288 break;
289 }
290 }
291
292 if (samePartsLength == 0) {
293 return to;
294 }
295
296 var outputParts = [];
297 for (var i = samePartsLength; i < lowerFromParts.length; i++) {
298 outputParts.push('..');
299 }
300
301 outputParts = outputParts.concat(toParts.slice(samePartsLength));
302
303 return outputParts.join('\\');
304};
305
306
307win32._makeLong = function(path) {
308 // Note: this will *probably* throw somewhere.
309 if (!util.isString(path))
310 return path;
311
312 if (!path) {
313 return '';
314 }
315
316 var resolvedPath = win32.resolve(path);
317
318 if (/^[a-zA-Z]\:\\/.test(resolvedPath)) {
319 // path is local filesystem path, which needs to be converted
320 // to long UNC path.
321 return '\\\\?\\' + resolvedPath;
322 } else if (/^\\\\[^?.]/.test(resolvedPath)) {
323 // path is network UNC path, which needs to be converted
324 // to long UNC path.
325 return '\\\\?\\UNC\\' + resolvedPath.substring(2);
326 }
327
328 return path;
329};
330
331
332win32.dirname = function(path) {
333 var result = win32SplitPath(path),
334 root = result[0],
335 dir = result[1];
336
337 if (!root && !dir) {
338 // No dirname whatsoever
339 return '.';
340 }
341
342 if (dir) {
343 // It has a dirname, strip trailing slash
344 dir = dir.substr(0, dir.length - 1);
345 }
346
347 return root + dir;
348};
349
350
351win32.basename = function(path, ext) {
352 var f = win32SplitPath(path)[2];
353 // TODO: make this comparison case-insensitive on windows?
354 if (ext && f.substr(-1 * ext.length) === ext) {
355 f = f.substr(0, f.length - ext.length);
356 }
357 return f;
358};
359
360
361win32.extname = function(path) {
362 return win32SplitPath(path)[3];
363};
364
365
366win32.format = function(pathObject) {
367 if (!util.isObject(pathObject)) {
368 throw new TypeError(
369 "Parameter 'pathObject' must be an object, not " + typeof pathObject
370 );
371 }
372
373 var root = pathObject.root || '';
374
375 if (!util.isString(root)) {
376 throw new TypeError(
377 "'pathObject.root' must be a string or undefined, not " +
378 typeof pathObject.root
379 );
380 }
381
382 var dir = pathObject.dir;
383 var base = pathObject.base || '';
384 if (!dir) {
385 return base;
386 }
387 if (dir[dir.length - 1] === win32.sep) {
388 return dir + base;
389 }
390 return dir + win32.sep + base;
391};
392
393
394win32.parse = function(pathString) {
395 if (!util.isString(pathString)) {
396 throw new TypeError(
397 "Parameter 'pathString' must be a string, not " + typeof pathString
398 );
399 }
400 var allParts = win32SplitPath(pathString);
401 if (!allParts || allParts.length !== 4) {
402 throw new TypeError("Invalid path '" + pathString + "'");
403 }
404 return {
405 root: allParts[0],
406 dir: allParts[0] + allParts[1].slice(0, -1),
407 base: allParts[2],
408 ext: allParts[3],
409 name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
410 };
411};
412
413
414win32.sep = '\\';
415win32.delimiter = ';';
416
417
418// Split a filename into [root, dir, basename, ext], unix version
419// 'root' is just a slash, or nothing.
420var splitPathRe =
421 /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
422var posix = {};
423
424
425function posixSplitPath(filename) {
426 return splitPathRe.exec(filename).slice(1);
427}
428
429
430// path.resolve([from ...], to)
431// posix version
432posix.resolve = function() {
433 var resolvedPath = '',
434 resolvedAbsolute = false;
435
436 for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
437 var path = (i >= 0) ? arguments[i] : process.cwd();
438
439 // Skip empty and invalid entries
440 if (!util.isString(path)) {
441 throw new TypeError('Arguments to path.resolve must be strings');
442 } else if (!path) {
443 continue;
444 }
445
446 resolvedPath = path + '/' + resolvedPath;
447 resolvedAbsolute = path[0] === '/';
448 }
449
450 // At this point the path should be resolved to a full absolute path, but
451 // handle relative paths to be safe (might happen when process.cwd() fails)
452
453 // Normalize the path
454 resolvedPath = normalizeArray(resolvedPath.split('/'),
455 !resolvedAbsolute).join('/');
456
457 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
458};
459
460// path.normalize(path)
461// posix version
462posix.normalize = function(path) {
463 var isAbsolute = posix.isAbsolute(path),
464 trailingSlash = path && path[path.length - 1] === '/';
465
466 // Normalize the path
467 path = normalizeArray(path.split('/'), !isAbsolute).join('/');
468
469 if (!path && !isAbsolute) {
470 path = '.';
471 }
472 if (path && trailingSlash) {
473 path += '/';
474 }
475
476 return (isAbsolute ? '/' : '') + path;
477};
478
479// posix version
480posix.isAbsolute = function(path) {
481 return path.charAt(0) === '/';
482};
483
484// posix version
485posix.join = function() {
486 var path = '';
487 for (var i = 0; i < arguments.length; i++) {
488 var segment = arguments[i];
489 if (!util.isString(segment)) {
490 throw new TypeError('Arguments to path.join must be strings');
491 }
492 if (segment) {
493 if (!path) {
494 path += segment;
495 } else {
496 path += '/' + segment;
497 }
498 }
499 }
500 return posix.normalize(path);
501};
502
503
504// path.relative(from, to)
505// posix version
506posix.relative = function(from, to) {
507 from = posix.resolve(from).substr(1);
508 to = posix.resolve(to).substr(1);
509
510 var fromParts = trimArray(from.split('/'));
511 var toParts = trimArray(to.split('/'));
512
513 var length = Math.min(fromParts.length, toParts.length);
514 var samePartsLength = length;
515 for (var i = 0; i < length; i++) {
516 if (fromParts[i] !== toParts[i]) {
517 samePartsLength = i;
518 break;
519 }
520 }
521
522 var outputParts = [];
523 for (var i = samePartsLength; i < fromParts.length; i++) {
524 outputParts.push('..');
525 }
526
527 outputParts = outputParts.concat(toParts.slice(samePartsLength));
528
529 return outputParts.join('/');
530};
531
532
533posix._makeLong = function(path) {
534 return path;
535};
536
537
538posix.dirname = function(path) {
539 var result = posixSplitPath(path),
540 root = result[0],
541 dir = result[1];
542
543 if (!root && !dir) {
544 // No dirname whatsoever
545 return '.';
546 }
547
548 if (dir) {
549 // It has a dirname, strip trailing slash
550 dir = dir.substr(0, dir.length - 1);
551 }
552
553 return root + dir;
554};
555
556
557posix.basename = function(path, ext) {
558 var f = posixSplitPath(path)[2];
559 // TODO: make this comparison case-insensitive on windows?
560 if (ext && f.substr(-1 * ext.length) === ext) {
561 f = f.substr(0, f.length - ext.length);
562 }
563 return f;
564};
565
566
567posix.extname = function(path) {
568 return posixSplitPath(path)[3];
569};
570
571
572posix.format = function(pathObject) {
573 if (!util.isObject(pathObject)) {
574 throw new TypeError(
575 "Parameter 'pathObject' must be an object, not " + typeof pathObject
576 );
577 }
578
579 var root = pathObject.root || '';
580
581 if (!util.isString(root)) {
582 throw new TypeError(
583 "'pathObject.root' must be a string or undefined, not " +
584 typeof pathObject.root
585 );
586 }
587
588 var dir = pathObject.dir ? pathObject.dir + posix.sep : '';
589 var base = pathObject.base || '';
590 return dir + base;
591};
592
593
594posix.parse = function(pathString) {
595 if (!util.isString(pathString)) {
596 throw new TypeError(
597 "Parameter 'pathString' must be a string, not " + typeof pathString
598 );
599 }
600 var allParts = posixSplitPath(pathString);
601 if (!allParts || allParts.length !== 4) {
602 throw new TypeError("Invalid path '" + pathString + "'");
603 }
604 allParts[1] = allParts[1] || '';
605 allParts[2] = allParts[2] || '';
606 allParts[3] = allParts[3] || '';
607
608 return {
609 root: allParts[0],
610 dir: allParts[0] + allParts[1].slice(0, -1),
611 base: allParts[2],
612 ext: allParts[3],
613 name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
614 };
615};
616
617
618posix.sep = '/';
619posix.delimiter = ':';
620
621
622if (isWindows)
623 module.exports = win32;
624else /* posix */
625 module.exports = posix;
626
627module.exports.posix = posix;
628module.exports.win32 = win32;
629 