Tag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#else
# include <strings.h>
# ifndef strchr
# define strchr index
# endif
#endif
#define NDEBUG
#include <assert.h>
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#ifndef ULONG_MAX
#define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
#endif
#ifndef LONG_MAX
#define LONG_MAX ((long int) (ULONG_MAX >> 1))
#endif
#include "xstrtol.h"
#define BKM_SCALE(x, scale_factor, error_return) \
do \
{ \
if ((x) > (double) __ZLONG_MAX / (scale_factor)) \
return (error_return); \
(x) *= (scale_factor); \
} \
while (0)
__unsigned long int __strtol ();
/* FIXME: comment. */
strtol_error
__xstrtol (s, ptr, base, val, valid_suffixes)
const char *s;
char **ptr;
int base;
__unsigned long int *val;
const char *valid_suffixes;
{
char *t_ptr;
char **p;
__unsigned long int tmp;
assert (0 <= base && base <= 36);
p = (ptr ? ptr : &t_ptr);
errno = 0;
tmp = __strtol (s, p, base);
if (errno != 0)
return LONGINT_OVERFLOW;
if (*p == s)
return LONGINT_INVALID;
if (!valid_suffixes)
{
if (**p == '\0')
{
*val = tmp;
return LONGINT_OK;
}
else
return LONGINT_INVALID_SUFFIX_CHAR;
}
if (**p != '\0' && strchr (valid_suffixes, **p))
{
switch (**p)
{
case 'b':
BKM_SCALE (tmp, 512, LONGINT_OVERFLOW);
++(*p);
break;
case 'c':
++(*p);
break;
case 'B':
case 'k':
BKM_SCALE (tmp, 1024, LONGINT_OVERFLOW);
++(*p);
break;
case 'm':
BKM_SCALE (tmp, 1024 * 1024, LONGINT_OVERFLOW);
++(*p);
break;
case 'w':
BKM_SCALE (tmp, 2, LONGINT_OVERFLOW);
++(*p);
break;
default:
return LONGINT_INVALID_SUFFIX_CHAR;
break;
}
}
*val = tmp;
return LONGINT_OK;
}
#ifdef TESTING_XSTRTO
#include <stdio.h>
#include "error.h"
char *program_name;
int
main (int argc, char** argv)
{
strtol_error s_err;
int i;
program_name = argv[0];
for (i=1; i<argc; i++)
{
char *p;
__unsigned long int val;
s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
if (s_err == LONGINT_OK)
{
printf ("%s->%lu (%s)\n", argv[i], val, p);
}
else
{
STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
}
}
exit (0);
}
#endif /* TESTING_XSTRTO */