xfstests: Automatic build dependency calculations
[xfstests-dev.git] / lib / str_to_bytes.c
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include <stdio.h>
19 #include <sys/param.h>
20 #include "str_to_bytes.h"
21
22 /****************************************************************************
23  * str_to_bytes(s)
24  *
25  * Computes the number of bytes described by string s.  s is assumed to be
26  * a base 10 positive (ie. >= 0) number followed by an optional single
27  * character multiplier.  The following multipliers are supported:
28  *
29  *              char    mult
30  *              -----------------
31  *              b       BSIZE  or BBSIZE
32  *              k       1024 bytes
33  *              K       1024 * sizeof(long)
34  *              m       2^20 (1048576)
35  *              M       2^20 (1048576 * sizeof(long)
36  *              g       2^30 (1073741824)
37  *              G       2^30 (1073741824) * sizeof(long)
38  *
39  * for instance, "1k" and "1024" would both cause str_to_bytes to return 1024.
40  *
41  * Returns -1 if mult is an invalid character, or if the integer portion of
42  * s is not a positive integer.
43  *
44  ****************************************************************************/
45
46 #if CRAY
47 #define B_MULT  BSIZE           /* block size */
48 #elif sgi
49 #define B_MULT  BBSIZE          /* block size */
50 #elif linux
51 #define B_MULT  DEV_BSIZE       /* block size */
52 #endif
53
54
55 #define K_MULT  1024            /* Kilo or 2^10 */
56 #define M_MULT  1048576         /* Mega or 2^20 */
57 #define G_MULT  1073741824      /* Giga or 2^30 */
58 #define T_MULT  1099511627776   /* tera or 2^40 */
59
60 int
61 str_to_bytes(s)
62 char    *s;
63 {
64     char    mult, junk;
65     int     nconv;
66     float   num;
67
68     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
69     if (nconv == 0 || nconv == 3 )
70         return -1;
71
72     if (nconv == 1)
73         return num;
74
75     switch (mult) {
76     case 'b':
77                 return (int)(num * (float)B_MULT);
78     case 'k':
79                 return (int)(num * (float)K_MULT);
80     case 'K':
81                 return (int)((num * (float)K_MULT) * sizeof(long));
82     case 'm':
83                 return (int)(num * (float)M_MULT);
84     case 'M':
85                 return (int)((num * (float)M_MULT) * sizeof(long));
86     case 'g':
87                 return (int)(num * (float)G_MULT);
88     case 'G':   
89                 return (int)((num * (float)G_MULT) * sizeof(long));
90     default:
91         return -1;
92     }
93 }
94
95 long
96 str_to_lbytes(s)
97 char    *s;
98 {
99     char    mult, junk;
100     long    nconv;
101     float   num;
102
103     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
104     if (nconv == 0 || nconv == 3 )
105         return -1;
106
107     if (nconv == 1)
108         return (long)num;
109
110     switch (mult) {
111     case 'b':
112                 return (long)(num * (float)B_MULT);
113     case 'k':
114                 return (long)(num * (float)K_MULT);
115     case 'K':
116                 return (long)((num * (float)K_MULT) * sizeof(long));
117     case 'm':
118                 return (long)(num * (float)M_MULT);
119     case 'M':
120                 return (long)((num * (float)M_MULT) * sizeof(long));
121     case 'g':
122                 return (long)(num * (float)G_MULT);
123     case 'G':   
124                 return (long)((num * (float)G_MULT) * sizeof(long));
125     default:
126         return -1;
127     }
128 }
129
130 /*
131  * Force 64 bits number when compiled as 32 IRIX binary.
132  * This allows for a number bigger than 2G.
133  */
134
135 long long
136 str_to_llbytes(s)
137 char    *s;
138 {
139     char    mult, junk;
140     long    nconv;
141     double  num;
142
143     nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
144     if (nconv == 0 || nconv == 3 )
145         return -1;
146
147     if (nconv == 1)
148         return (long long)num;
149
150     switch (mult) {
151     case 'b':
152                 return (long long)(num * (float)B_MULT);
153     case 'k':
154                 return (long long)(num * (float)K_MULT);
155     case 'K':
156                 return (long long)((num * (float)K_MULT) * sizeof(long long));
157     case 'm':
158                 return (long long)(num * (float)M_MULT);
159     case 'M':
160                 return (long long)((num * (float)M_MULT) * sizeof(long long));
161     case 'g':
162                 return (long long)(num * (float)G_MULT);
163     case 'G':   
164                 return (long long)((num * (float)G_MULT) * sizeof(long long));
165     default:
166         return -1;
167     }
168 }
169
170 #ifdef UNIT_TEST
171
172 main(int argc, char **argv)
173 {
174     int ind;
175
176     if (argc == 1 ) {
177         fprintf(stderr, "missing str_to_bytes() parameteres\n");
178         exit(1);
179     }
180    
181     for (ind=1; ind<argc; ind++) {
182
183         printf("str_to_bytes(%s) returned %d\n", 
184             argv[ind], str_to_bytes(argv[ind]));
185
186         printf("str_to_lbytes(%s) returned %ld\n", 
187             argv[ind], str_to_lbytes(argv[ind]));
188
189         printf("str_to_llbytes(%s) returned %lld\n", 
190             argv[ind], str_to_llbytes(argv[ind]));
191     }
192 }
193
194 #endif