1 /* 2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program with 17 * other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 24 * Mountain View, CA 94043, or: 25 * 26 * http://www.sgi.com 27 * 28 * For further information regarding this notice, see: 29 * 30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ 31 */ 32 #include <stdio.h> 33 #include <sys/param.h> 34 35 #include "bytes_by_prefix.h" 36 37 /**************************************************************************** 38 * bytes_by_prefix(s) 39 * 40 * Computes the number of bytes described by string s. s is assumed to be 41 * a base 10 positive (ie. >= 0) number followed by an optional single 42 * character multiplier. The following multipliers are supported: 43 * 44 * char mult 45 * ----------------- 46 * b BSIZE or BBSIZE 47 * k 1024 bytes 48 * K 1024 * sizeof(long) 49 * m 2^20 (1048576) 50 * M 2^20 (1048576 * sizeof(long) 51 * g 2^30 (1073741824) 52 * G 2^30 (1073741824) * sizeof(long) 53 * 54 * for instance, "1k" and "1024" would both cause bytes_by_prefix to return 1024 55 * 56 * Returns -1 if mult is an invalid character, or if the integer portion of 57 * s is not a positive integer. 58 * 59 ****************************************************************************/ 60 61 #if CRAY 62 #define B_MULT BSIZE /* block size */ 63 #elif sgi 64 #define B_MULT BBSIZE /* block size */ 65 #elif defined(__linux__) || defined(__sun) || defined(__hpux) 66 #define B_MULT DEV_BSIZE /* block size */ 67 #elif defined(_AIX) 68 #define B_MULT UBSIZE 69 #endif 70 71 #define K_MULT 1024 /* Kilo or 2^10 */ 72 #define M_MULT 1048576 /* Mega or 2^20 */ 73 #define G_MULT 1073741824 /* Giga or 2^30 */ 74 #define T_MULT 1099511627776 /* tera or 2^40 */ 75 76 int bytes_by_prefix(char *s) 77 { 78 char mult, junk; 79 int nconv; 80 float num; 81 int result; 82 83 nconv = sscanf(s, "%f%c%c", &num, &mult, &junk); 84 if (nconv == 0 || nconv == 3) 85 return -1; 86 87 if (nconv == 1) { 88 result = num; 89 return result < 0 ? -1 : result; 90 } 91 92 switch (mult) { 93 case 'b': 94 result = (int)(num * (float)B_MULT); 95 break; 96 case 'k': 97 result = (int)(num * (float)K_MULT); 98 break; 99 case 'K': 100 result = (int)((num * (float)K_MULT) * sizeof(long)); 101 break; 102 case 'm': 103 result = (int)(num * (float)M_MULT); 104 break; 105 case 'M': 106 result = (int)((num * (float)M_MULT) * sizeof(long)); 107 break; 108 case 'g': 109 result = (int)(num * (float)G_MULT); 110 break; 111 case 'G': 112 result = (int)((num * (float)G_MULT) * sizeof(long)); 113 break; 114 default: 115 return -1; 116 } 117 118 if (result < 0) 119 return -1; 120 121 return result; 122 } 123 124 long lbytes_by_prefix(char *s) 125 { 126 char mult, junk; 127 int nconv; 128 float num; 129 long result; 130 131 nconv = sscanf(s, "%f%c%c", &num, &mult, &junk); 132 if (nconv == 0 || nconv == 3) 133 return -1; 134 135 if (nconv == 1) { 136 result = (long)num; 137 return result < 0 ? -1 : result; 138 } 139 140 switch (mult) { 141 case 'b': 142 result = (long)(num * (float)B_MULT); 143 break; 144 case 'k': 145 result = (long)(num * (float)K_MULT); 146 break; 147 case 'K': 148 result = (long)((num * (float)K_MULT) * sizeof(long)); 149 break; 150 case 'm': 151 result = (long)(num * (float)M_MULT); 152 break; 153 case 'M': 154 result = (long)((num * (float)M_MULT) * sizeof(long)); 155 break; 156 case 'g': 157 result = (long)(num * (float)G_MULT); 158 break; 159 case 'G': 160 result = (long)((num * (float)G_MULT) * sizeof(long)); 161 break; 162 default: 163 return -1; 164 } 165 166 if (result < 0) 167 return -1; 168 169 return result; 170 } 171 172 /* 173 * Force 64 bits number when compiled as 32 IRIX binary. 174 * This allows for a number bigger than 2G. 175 */ 176 long long llbytes_by_prefix(char *s) 177 { 178 char mult, junk; 179 int nconv; 180 double num; 181 long long result; 182 183 nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk); 184 if (nconv == 0 || nconv == 3) 185 return -1; 186 if (nconv == 1) { 187 result = (long long)num; 188 return result < 0 ? -1 : result; 189 } 190 191 switch (mult) { 192 case 'b': 193 result = (long long)(num * (float)B_MULT); 194 break; 195 case 'k': 196 result = (long long)(num * (float)K_MULT); 197 break; 198 case 'K': 199 result = (long long)((num * (float)K_MULT) * sizeof(long long)); 200 break; 201 case 'm': 202 result = (long long)(num * (float)M_MULT); 203 break; 204 case 'M': 205 result = (long long)((num * (float)M_MULT) * sizeof(long long)); 206 break; 207 case 'g': 208 result = (long long)(num * (float)G_MULT); 209 break; 210 case 'G': 211 result = (long long)((num * (float)G_MULT) * sizeof(long long)); 212 break; 213 default: 214 return -1; 215 } 216 217 if (result < 0) 218 return -1; 219 220 return result; 221 } 222