format_integer.js (2717B)
1 /** 2 * @license Apache-2.0 3 * 4 * Copyright (c) 2022 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 isNumber = require( './is_number.js' ); 24 var zeroPad = require( './zero_pad.js' ); 25 26 // NOTE: for the following, we explicitly avoid using stdlib packages in this particular package in order to avoid circular dependencies. 27 var lowercase = String.prototype.toLowerCase; 28 var uppercase = String.prototype.toUpperCase; 29 30 31 // MAIN // 32 33 /** 34 * Formats a token object argument as an integer. 35 * 36 * @private 37 * @param {Object} token - token object 38 * @throws {Error} must provide a valid integer 39 * @returns {string} formatted token argument 40 */ 41 function formatInteger( token ) { 42 var base; 43 var out; 44 var i; 45 46 switch ( token.specifier ) { 47 case 'b': 48 // Case: %b (binary) 49 base = 2; 50 break; 51 case 'o': 52 // Case: %o (octal) 53 base = 8; 54 break; 55 case 'x': 56 case 'X': 57 // Case: %x, %X (hexadecimal) 58 base = 16; 59 break; 60 case 'd': 61 case 'i': 62 case 'u': 63 default: 64 // Case: %d, %i, %u (decimal) 65 base = 10; 66 break; 67 } 68 out = token.arg; 69 i = parseInt( out, 10 ); 70 if ( !isFinite( i ) ) { // NOTE: We use the global `isFinite` function here instead of `@stdlib/math/base/assert/is-finite` in order to avoid circular dependencies. 71 if ( !isNumber( out ) ) { 72 throw new Error( 'invalid integer. Value: ' + out ); 73 } 74 i = 0; 75 } 76 if ( i < 0 && ( token.specifier === 'u' || base !== 10 ) ) { 77 i = 0xffffffff + i + 1; 78 } 79 if ( i < 0 ) { 80 out = ( -i ).toString( base ); 81 if ( token.precision ) { 82 out = zeroPad( out, token.precision, token.padRight ); 83 } 84 out = '-' + out; 85 } else { 86 out = i.toString( base ); 87 if ( !i && !token.precision ) { 88 out = ''; 89 } else if ( token.precision ) { 90 out = zeroPad( out, token.precision, token.padRight ); 91 } 92 if ( token.sign ) { 93 out = token.sign + out; 94 } 95 } 96 if ( base === 16 ) { 97 if ( token.alternate ) { 98 out = '0x' + out; 99 } 100 out = ( token.specifier === uppercase.call( token.specifier ) ) ? 101 uppercase.call( out ) : 102 lowercase.call( out ); 103 } 104 if ( base === 8 ) { 105 if ( token.alternate && out.charAt( 0 ) !== '0' ) { 106 out = '0' + out; 107 } 108 } 109 return out; 110 } 111 112 113 // EXPORTS // 114 115 module.exports = formatInteger;