time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

convert_path.js (3910B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
     24 var reExtendedLengthPath = require( '@stdlib/regexp/extended-length-path' );
     25 var lowercase = require( '@stdlib/string/lowercase' );
     26 var replace = require( '@stdlib/string/replace' );
     27 
     28 
     29 // VARIABLES //
     30 
     31 var RE_WIN_DEVICE_ROOT = /^([A-Za-z]):[\\\/]+/; // eslint-disable-line no-useless-escape
     32 var RE_POSIX_DEVICE_ROOT =/^\/([A-Za-z])\//;
     33 
     34 
     35 // MAIN //
     36 
     37 /**
     38 * Converts between POSIX and Windows paths.
     39 *
     40 * @param {string} from - path to convert
     41 * @param {string} to - output path convention
     42 * @throws {TypeError} first argument must be a string
     43 * @throws {TypeError} second argument must be a string
     44 * @throws {RangeError} second argument must be a recognized output path convention
     45 * @throws {Error} cannot convert a Windows extended-length path to a non-Windows path convention
     46 * @returns {string} converted path
     47 *
     48 * @example
     49 * var p = convertPath( '/c/foo/bar/beep.c', 'win32' );
     50 * // returns 'c:\foo\bar\beep.c'
     51 *
     52 * @example
     53 * var p = convertPath( '/c/foo/bar/beep.c', 'mixed' );
     54 * // returns 'c:/foo/bar/beep.c'
     55 *
     56 * @example
     57 * var p = convertPath( 'C:\\foo\\bar\\beep.c', 'posix' );
     58 * // returns '/c/foo/bar/beep.c'
     59 *
     60 * @example
     61 * var p = convertPath( 'C:\\foo\\bar\\beep.c', 'mixed' );
     62 * // returns 'C:/foo/bar/beep.c'
     63 */
     64 function convertPath( from, to ) {
     65 	var device;
     66 	var parts;
     67 	var out;
     68 	if ( !isString( from ) ) {
     69 		throw new TypeError( 'invalid argument. First argument must be a string primitive. Value: `'+from+'`.' );
     70 	}
     71 	if ( !isString( to ) ) {
     72 		throw new TypeError( 'invalid argument. Second argument must be a string primitive. Value: `'+to+'`.' );
     73 	}
     74 	if (
     75 		to !== 'win32' &&
     76 		to !== 'mixed' &&
     77 		to !== 'posix'
     78 	) {
     79 		throw new Error( 'invalid argument. Second argument must be a recognized output path convention. Value: `'+to+'`.' );
     80 	}
     81 	out = from;
     82 
     83 	// Convert to a Windows path convention by transforming a POSIX device root (if present) and using a Windows path separator...
     84 	if ( to === 'win32' ) {
     85 		parts = RE_POSIX_DEVICE_ROOT.exec( out );
     86 		if ( parts ) {
     87 			device = parts[ 1 ]+':\\';
     88 			out = replace( out, RE_POSIX_DEVICE_ROOT, device );
     89 		}
     90 		return replace( out, '/', '\\' );
     91 	}
     92 	// Check for Windows extended-length paths...
     93 	if ( reExtendedLengthPath.REGEXP.test( from ) ) {
     94 		throw new Error( 'invalid argument. Cannot convert Windows extended-length paths to POSIX paths. Value: `'+from+'`.' );
     95 	}
     96 	// Convert to a mixed path convention by combining a Windows drive letter convention with a POSIX path separator...
     97 	if ( to === 'mixed' ) {
     98 		parts = RE_POSIX_DEVICE_ROOT.exec( out );
     99 		if ( parts ) {
    100 			device = parts[ 1 ]+':/';
    101 			out = replace( out, RE_POSIX_DEVICE_ROOT, device );
    102 		} else {
    103 			parts = RE_WIN_DEVICE_ROOT.exec( out );
    104 			if ( parts ) {
    105 				device = parts[ 1 ]+':/';
    106 				out = replace( out, RE_WIN_DEVICE_ROOT, device );
    107 			}
    108 		}
    109 		return replace( out, '\\', '/' );
    110 	}
    111 	// Convert to a POSIX path convention by transforming a Windows device root (if present) and using a POSIX path separator...
    112 	parts = RE_WIN_DEVICE_ROOT.exec( out );
    113 	if ( parts ) {
    114 		device = '/'+lowercase( parts[ 1 ] )+'/';
    115 		out = replace( out, RE_WIN_DEVICE_ROOT, device );
    116 	}
    117 	return replace( out, '\\', '/' );
    118 }
    119 
    120 
    121 // EXPORTS //
    122 
    123 module.exports = convertPath;