xfs: functional testing of V5-relevant options
[xfstests-dev.git] / lib / str_to_bytes.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6 #include <stdio.h>
7 #include <sys/param.h>
8 #include "str_to_bytes.h"
9
10 /****************************************************************************
11  * str_to_bytes(s)
12  *
13  * Computes the number of bytes described by string s.  s is assumed to be
14  * a base 10 positive (ie. >= 0) number followed by an optional single
15  * character multiplier.  The following multipliers are supported:
16  *
17  *              char    mult
18  *              -----------------
19  *              b       BSIZE  or BBSIZE
20  *              k       1024 bytes
21  *              K       1024 * sizeof(long)
22  *              m       2^20 (1048576)
23  *              M       2^20 (1048576 * sizeof(long)
24  *              g       2^30 (1073741824)
25  *              G       2^30 (1073741824) * sizeof(long)
26  *
27  * for instance, "1k" and "1024" would both cause str_to_bytes to return 1024.
28  *
29  * Returns -1 if mult is an invalid character, or if the integer portion of
30  * s is not a positive integer.
31  *
32  ****************************************************************************/
33
34 #if linux
35 #define B_MULT  DEV_BSIZE       /* block size */
36 #endif
37
38
39 #define K_MULT  1024            /* Kilo or 2^10 */
40 #define M_MULT  1048576         /* Mega or 2^20 */
41 #define G_MULT  1073741824      /* Giga or 2^30 */
42 #define T_MULT  1099511627776   /* tera or 2^40 */
43
44 int
45 str_to_bytes(s)
46 char    *s;
47 {
48     char    mult, junk;
49     int     nconv;
50     float   num;
51
52     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
53     if (nconv == 0 || nconv == 3 )
54         return -1;
55
56     if (nconv == 1)
57         return num;
58
59     switch (mult) {
60     case 'b':
61                 return (int)(num * (float)B_MULT);
62     case 'k':
63                 return (int)(num * (float)K_MULT);
64     case 'K':
65                 return (int)((num * (float)K_MULT) * sizeof(long));
66     case 'm':
67                 return (int)(num * (float)M_MULT);
68     case 'M':
69                 return (int)((num * (float)M_MULT) * sizeof(long));
70     case 'g':
71                 return (int)(num * (float)G_MULT);
72     case 'G':   
73                 return (int)((num * (float)G_MULT) * sizeof(long));
74     default:
75         return -1;
76     }
77 }
78
79 long
80 str_to_lbytes(s)
81 char    *s;
82 {
83     char    mult, junk;
84     long    nconv;
85     float   num;
86
87     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
88     if (nconv == 0 || nconv == 3 )
89         return -1;
90
91     if (nconv == 1)
92         return (long)num;
93
94     switch (mult) {
95     case 'b':
96                 return (long)(num * (float)B_MULT);
97     case 'k':
98                 return (long)(num * (float)K_MULT);
99     case 'K':
100                 return (long)((num * (float)K_MULT) * sizeof(long));
101     case 'm':
102                 return (long)(num * (float)M_MULT);
103     case 'M':
104                 return (long)((num * (float)M_MULT) * sizeof(long));
105     case 'g':
106                 return (long)(num * (float)G_MULT);
107     case 'G':   
108                 return (long)((num * (float)G_MULT) * sizeof(long));
109     default:
110         return -1;
111     }
112 }
113
114 /*
115  * Force 64 bits number when compiled as a 32-bit binary.
116  * This allows for a number bigger than 2G.
117  */
118
119 long long
120 str_to_llbytes(s)
121 char    *s;
122 {
123     char    mult, junk;
124     long    nconv;
125     double  num;
126
127     nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
128     if (nconv == 0 || nconv == 3 )
129         return -1;
130
131     if (nconv == 1)
132         return (long long)num;
133
134     switch (mult) {
135     case 'b':
136                 return (long long)(num * (float)B_MULT);
137     case 'k':
138                 return (long long)(num * (float)K_MULT);
139     case 'K':
140                 return (long long)((num * (float)K_MULT) * sizeof(long long));
141     case 'm':
142                 return (long long)(num * (float)M_MULT);
143     case 'M':
144                 return (long long)((num * (float)M_MULT) * sizeof(long long));
145     case 'g':
146                 return (long long)(num * (float)G_MULT);
147     case 'G':   
148                 return (long long)((num * (float)G_MULT) * sizeof(long long));
149     default:
150         return -1;
151     }
152 }
153
154 #ifdef UNIT_TEST
155
156 main(int argc, char **argv)
157 {
158     int ind;
159
160     if (argc == 1 ) {
161         fprintf(stderr, "missing str_to_bytes() parameteres\n");
162         exit(1);
163     }
164    
165     for (ind=1; ind<argc; ind++) {
166
167         printf("str_to_bytes(%s) returned %d\n", 
168             argv[ind], str_to_bytes(argv[ind]));
169
170         printf("str_to_lbytes(%s) returned %ld\n", 
171             argv[ind], str_to_lbytes(argv[ind]));
172
173         printf("str_to_llbytes(%s) returned %lld\n", 
174             argv[ind], str_to_llbytes(argv[ind]));
175     }
176 }
177
178 #endif