strtonum.c revision 1.1 1 1.1 christos /* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 2004 Ted Unangst and Todd Miller
5 1.1 christos * All rights reserved.
6 1.1 christos *
7 1.1 christos * Permission to use, copy, modify, and distribute this software for any
8 1.1 christos * purpose with or without fee is hereby granted, provided that the above
9 1.1 christos * copyright notice and this permission notice appear in all copies.
10 1.1 christos *
11 1.1 christos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 1.1 christos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 1.1 christos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 1.1 christos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 1.1 christos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 1.1 christos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 1.1 christos * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 1.1 christos */
19 1.1 christos
20 1.1 christos #include <errno.h>
21 1.1 christos #include <limits.h>
22 1.1 christos #include <stdlib.h>
23 1.1 christos
24 1.1 christos #define INVALID 1
25 1.1 christos #define TOOSMALL 2
26 1.1 christos #define TOOLARGE 3
27 1.1 christos
28 1.1 christos long long
29 1.1 christos strtonum(const char *numstr, long long minval, long long maxval,
30 1.1 christos const char **errstrp)
31 1.1 christos {
32 1.1 christos long long ll = 0;
33 1.1 christos char *ep;
34 1.1 christos int error = 0;
35 1.1 christos struct errval {
36 1.1 christos const char *errstr;
37 1.1 christos int err;
38 1.1 christos } ev[4] = {
39 1.1 christos { NULL, 0 },
40 1.1 christos { "invalid", EINVAL },
41 1.1 christos { "too small", ERANGE },
42 1.1 christos { "too large", ERANGE },
43 1.1 christos };
44 1.1 christos
45 1.1 christos ev[0].err = errno;
46 1.1 christos errno = 0;
47 1.1 christos if (minval > maxval)
48 1.1 christos error = INVALID;
49 1.1 christos else {
50 1.1 christos ll = strtoll(numstr, &ep, 10);
51 1.1 christos if (numstr == ep || *ep != '\0')
52 1.1 christos error = INVALID;
53 1.1 christos else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
54 1.1 christos error = TOOSMALL;
55 1.1 christos else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
56 1.1 christos error = TOOLARGE;
57 1.1 christos }
58 1.1 christos if (errstrp != NULL)
59 1.1 christos *errstrp = ev[error].errstr;
60 1.1 christos errno = ev[error].err;
61 1.1 christos if (error)
62 1.1 christos ll = 0;
63 1.1 christos
64 1.1 christos return (ll);
65 1.1 christos }
66 1.1 christos
67