(md5_file): New function -- extracted from main.
[coreutils.git] / lib / xstrtol.c
blob42d3758a69159a7fe91e056fe3932cf8dc1492dd
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
5 #ifdef STDC_HEADERS
6 #include <stdlib.h>
7 #endif
9 #ifdef HAVE_STRING_H
10 # include <string.h>
11 #else
12 # include <strings.h>
13 # ifndef strchr
14 # define strchr index
15 # endif
16 #endif
18 #define NDEBUG
19 #include <assert.h>
21 #include <errno.h>
22 #ifndef errno
23 extern int errno;
24 #endif
26 #if HAVE_LIMITS_H
27 #include <limits.h>
28 #endif
30 #ifndef ULONG_MAX
31 #define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
32 #endif
34 #ifndef LONG_MAX
35 #define LONG_MAX ((long int) (ULONG_MAX >> 1))
36 #endif
38 #include "xstrtol.h"
40 #define BKM_SCALE(x, scale_factor, error_return) \
41 do \
42 { \
43 if ((x) > (double) __ZLONG_MAX / (scale_factor)) \
44 return (error_return); \
45 (x) *= (scale_factor); \
46 } \
47 while (0)
49 __unsigned long int __strtol ();
51 /* FIXME: comment. */
53 strtol_error
54 __xstrtol (s, ptr, base, val, valid_suffixes)
55 const char *s;
56 char **ptr;
57 int base;
58 __unsigned long int *val;
59 const char *valid_suffixes;
61 char *t_ptr;
62 char **p;
63 __unsigned long int tmp;
65 assert (0 <= base && base <= 36);
67 p = (ptr ? ptr : &t_ptr);
69 errno = 0;
70 tmp = __strtol (s, p, base);
71 if (errno != 0)
72 return LONGINT_OVERFLOW;
73 if (*p == s)
74 return LONGINT_INVALID;
75 if (!valid_suffixes)
77 if (**p == '\0')
79 *val = tmp;
80 return LONGINT_OK;
82 else
83 return LONGINT_INVALID_SUFFIX_CHAR;
86 if (**p != '\0' && strchr (valid_suffixes, **p))
88 switch (**p)
90 case 'b':
91 BKM_SCALE (tmp, 512, LONGINT_OVERFLOW);
92 ++(*p);
93 break;
95 case 'c':
96 ++(*p);
97 break;
99 case 'B':
100 case 'k':
101 BKM_SCALE (tmp, 1024, LONGINT_OVERFLOW);
102 ++(*p);
103 break;
105 case 'm':
106 BKM_SCALE (tmp, 1024 * 1024, LONGINT_OVERFLOW);
107 ++(*p);
108 break;
110 case 'w':
111 BKM_SCALE (tmp, 2, LONGINT_OVERFLOW);
112 ++(*p);
113 break;
115 default:
116 return LONGINT_INVALID_SUFFIX_CHAR;
117 break;
121 *val = tmp;
122 return LONGINT_OK;
125 #ifdef TESTING_XSTRTO
127 #include <stdio.h>
128 #include "error.h"
130 char *program_name;
133 main (int argc, char** argv)
135 strtol_error s_err;
136 int i;
138 program_name = argv[0];
139 for (i=1; i<argc; i++)
141 char *p;
142 __unsigned long int val;
144 s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
145 if (s_err == LONGINT_OK)
147 printf ("%s->%lu (%s)\n", argv[i], val, p);
149 else
151 STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
154 exit (0);
156 #endif /* TESTING_XSTRTO */