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
bytes_by_prefix(char * s)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
lbytes_by_prefix(char * s)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 */
llbytes_by_prefix(char * s)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