"Fossies" - the Fresh Open Source Software Archive 
Member "xombrero-1.6.4/osx/osx.c" (17 Feb 2015, 8389 Bytes) of package /linux/www/old/xombrero-1.6.4.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "osx.c" see the
Fossies "Dox" file reference documentation.
1 /* $OpenBSD: fmt_scaled.c,v 1.10 2009/06/20 15:00:04 martynas Exp $ */
2
3 /*
4 * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * fmt_scaled: Format numbers scaled for human comprehension
31 * scan_scaled: Scan numbers in this format.
32 *
33 * "Human-readable" output uses 4 digits max, and puts a unit suffix at
34 * the end. Makes output compact and easy-to-read esp. on huge disks.
35 * Formatting code was originally in OpenBSD "df", converted to library routine.
36 * Scanning code written for OpenBSD libutil.
37 */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <string.h>
43 #include <ctype.h>
44 #include <limits.h>
45 #include <unistd.h>
46
47 #include "util.h"
48
49 typedef enum {
50 NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6
51 } unit_type;
52
53 /* These three arrays MUST be in sync! XXX make a struct */
54 static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };
55 static char scale_chars[] = "BKMGTPE";
56 static long long scale_factors[] = {
57 1LL,
58 1024LL,
59 1024LL*1024,
60 1024LL*1024*1024,
61 1024LL*1024*1024*1024,
62 1024LL*1024*1024*1024*1024,
63 1024LL*1024*1024*1024*1024*1024,
64 };
65 #define SCALE_LENGTH (sizeof(units)/sizeof(units[0]))
66
67 #define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */
68
69 /* Convert the given input string "scaled" into numeric in "result".
70 * Return 0 on success, -1 and errno set on error.
71 */
72 int
73 scan_scaled(char *scaled, long long *result)
74 {
75 char *p = scaled;
76 int sign = 0;
77 unsigned int i, ndigits = 0, fract_digits = 0;
78 long long scale_fact = 1, whole = 0, fpart = 0;
79
80 /* Skip leading whitespace */
81 while (isascii(*p) && isspace(*p))
82 ++p;
83
84 /* Then at most one leading + or - */
85 while (*p == '-' || *p == '+') {
86 if (*p == '-') {
87 if (sign) {
88 errno = EINVAL;
89 return -1;
90 }
91 sign = -1;
92 ++p;
93 } else if (*p == '+') {
94 if (sign) {
95 errno = EINVAL;
96 return -1;
97 }
98 sign = +1;
99 ++p;
100 }
101 }
102
103 /* Main loop: Scan digits, find decimal point, if present.
104 * We don't allow exponentials, so no scientific notation
105 * (but note that E for Exa might look like e to some!).
106 * Advance 'p' to end, to get scale factor.
107 */
108 for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) {
109 if (*p == '.') {
110 if (fract_digits > 0) { /* oops, more than one '.' */
111 errno = EINVAL;
112 return -1;
113 }
114 fract_digits = 1;
115 continue;
116 }
117
118 i = (*p) - '0'; /* whew! finally a digit we can use */
119 if (fract_digits > 0) {
120 if (fract_digits >= MAX_DIGITS-1)
121 /* ignore extra fractional digits */
122 continue;
123 fract_digits++; /* for later scaling */
124 fpart *= 10;
125 fpart += i;
126 } else { /* normal digit */
127 if (++ndigits >= MAX_DIGITS) {
128 errno = ERANGE;
129 return -1;
130 }
131 whole *= 10;
132 whole += i;
133 }
134 }
135
136 if (sign) {
137 whole *= sign;
138 fpart *= sign;
139 }
140
141 /* If no scale factor given, we're done. fraction is discarded. */
142 if (!*p) {
143 *result = whole;
144 return 0;
145 }
146
147 /* Validate scale factor, and scale whole and fraction by it. */
148 for (i = 0; i < SCALE_LENGTH; i++) {
149
150 /* Are we there yet? */
151 if (*p == scale_chars[i] ||
152 *p == tolower(scale_chars[i])) {
153
154 /* If it ends with alphanumerics after the scale char, bad. */
155 if (isalnum(*(p+1))) {
156 errno = EINVAL;
157 return -1;
158 }
159 scale_fact = scale_factors[i];
160
161 /* scale whole part */
162 whole *= scale_fact;
163
164 /* truncate fpart so it does't overflow.
165 * then scale fractional part.
166 */
167 while (fpart >= LLONG_MAX / scale_fact) {
168 fpart /= 10;
169 fract_digits--;
170 }
171 fpart *= scale_fact;
172 if (fract_digits > 0) {
173 for (i = 0; i < fract_digits -1; i++)
174 fpart /= 10;
175 }
176 whole += fpart;
177 *result = whole;
178 return 0;
179 }
180 }
181 errno = ERANGE;
182 return -1;
183 }
184
185 /* Format the given "number" into human-readable form in "result".
186 * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
187 * Return 0 on success, -1 and errno set if error.
188 */
189 int
190 fmt_scaled(long long number, char *result)
191 {
192 long long abval, fract = 0;
193 unsigned int i;
194 unit_type unit = NONE;
195
196 abval = llabs(number);
197
198 /* Not every negative long long has a positive representation.
199 * Also check for numbers that are just too darned big to format
200 */
201 if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {
202 errno = ERANGE;
203 return -1;
204 }
205
206 /* scale whole part; get unscaled fraction */
207 for (i = 0; i < SCALE_LENGTH; i++) {
208 if (abval/1024 < scale_factors[i]) {
209 unit = units[i];
210 fract = (i == 0) ? 0 : abval % scale_factors[i];
211 number /= scale_factors[i];
212 if (i > 0)
213 fract /= scale_factors[i - 1];
214 break;
215 }
216 }
217
218 fract = (10 * fract + 512) / 1024;
219 /* if the result would be >= 10, round main number */
220 if (fract == 10) {
221 if (number >= 0)
222 number++;
223 else
224 number--;
225 fract = 0;
226 }
227
228 if (number == 0)
229 strlcpy(result, "0B", FMT_SCALED_STRSIZE);
230 else if (unit == NONE || number >= 100 || number <= -100) {
231 if (fract >= 5) {
232 if (number >= 0)
233 number++;
234 else
235 number--;
236 }
237 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",
238 number, scale_chars[unit]);
239 } else
240 (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",
241 number, fract, scale_chars[unit]);
242
243 return 0;
244 }
245
246
247 /* --------------------------------------------------------------------------- */
248 /* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
249
250 /*
251 * Copyright (c) 2004 Ted Unangst and Todd Miller
252 * All rights reserved.
253 *
254 * Permission to use, copy, modify, and distribute this software for any
255 * purpose with or without fee is hereby granted, provided that the above
256 * copyright notice and this permission notice appear in all copies.
257 *
258 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
259 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
260 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
261 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
262 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
263 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
264 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
265 */
266
267 #define INVALID 1
268 #define TOOSMALL 2
269 #define TOOLARGE 3
270
271 long long
272 strtonum(const char *numstr, long long minval, long long maxval,
273 const char **errstrp)
274 {
275 long long ll = 0;
276 char *ep;
277 int error = 0;
278 struct errval {
279 const char *errstr;
280 int err;
281 } ev[4] = {
282 { NULL, 0 },
283 { "invalid", EINVAL },
284 { "too small", ERANGE },
285 { "too large", ERANGE },
286 };
287
288 ev[0].err = errno;
289 errno = 0;
290 if (minval > maxval)
291 error = INVALID;
292 else {
293 ll = strtoll(numstr, &ep, 10);
294 if (numstr == ep || *ep != '\0')
295 error = INVALID;
296 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
297 error = TOOSMALL;
298 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
299 error = TOOLARGE;
300 }
301 if (errstrp != NULL)
302 *errstrp = ev[error].errstr;
303 errno = ev[error].err;
304 if (error)
305 ll = 0;
306
307 return (ll);
308 }