"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 }