Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/stdlib/strtonum.c
| /*- | /*- | ||||
| * Copyright (c) 2004 Ted Unangst and Todd Miller | * Copyright (c) 2004 Ted Unangst and Todd Miller | ||||
| * All rights reserved. | * All rights reserved. | ||||
| * | * | ||||
| * Copyright 2023 Oxide Computer Company | |||||
ziaee: I'm not sure if it's necessary, but all our style guides use this. | |||||
Not Done Inline ActionsIt's not necessary and if it's not in upstream; let's omit it. It's kind of silly that "Copyright (c)" is so prevalent, it'd be like writing "and &" or "% percent" emaste: It's not necessary and if it's not in upstream; let's omit it. It's kind of silly that… | |||||
Done Inline ActionsIt's the copyright of the original change, not mine. I'm not sure it would be well received by them if I changed it here? rosenfeld_grumpf.hope-2000.org: It's the copyright of the original change, not mine. I'm not sure it would be well received by… | |||||
Not Done Inline ActionsI don't know either, so I asked them. Hopefully they will come comment. It's so small, but I wanna get this kinda stuff right during import. ziaee: I don't know either, so I asked them. Hopefully they will come comment. It's so small, but I… | |||||
| * | |||||
| * Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||||
| * purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||||
| * copyright notice and this permission notice appear in all copies. | * copyright notice and this permission notice appear in all copies. | ||||
| * | * | ||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
| * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
| * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
| * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
| * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
| * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
| * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
| * | * | ||||
| * $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ | * $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ | ||||
| */ | */ | ||||
| #include <errno.h> | #include <errno.h> | ||||
| #include <limits.h> | #include <limits.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #define INVALID 1 | #define INVALID 1 | ||||
| #define TOOSMALL 2 | #define TOOSMALL 2 | ||||
| #define TOOLARGE 3 | #define TOOLARGE 3 | ||||
| #define BADBASE 4 | |||||
| #define MBASE ('z' - 'a' + 1 + 10) | |||||
| long long | long long | ||||
| strtonum(const char *numstr, long long minval, long long maxval, | strtonumx(const char *numstr, long long minval, long long maxval, | ||||
| const char **errstrp) | const char **errstrp, int base) | ||||
| { | { | ||||
| long long ll = 0; | long long ll = 0; | ||||
| int error = 0; | int error = 0; | ||||
| char *ep; | char *ep; | ||||
| struct errval { | struct errval { | ||||
| const char *errstr; | const char *errstr; | ||||
| int err; | int err; | ||||
| } ev[4] = { | } ev[5] = { | ||||
| { NULL, 0 }, | { NULL, 0 }, | ||||
| { "invalid", EINVAL }, | { "invalid", EINVAL }, | ||||
| { "too small", ERANGE }, | { "too small", ERANGE }, | ||||
| { "too large", ERANGE }, | { "too large", ERANGE }, | ||||
| { "unparsable; invalid base specified", EINVAL }, | |||||
| }; | }; | ||||
| ev[0].err = errno; | ev[0].err = errno; | ||||
| errno = 0; | errno = 0; | ||||
| if (minval > maxval) { | if (minval > maxval) { | ||||
| error = INVALID; | error = INVALID; | ||||
| } else if (base < 0 || base > MBASE || base == 1) { | |||||
| error = BADBASE; | |||||
| } else { | } else { | ||||
| ll = strtoll(numstr, &ep, 10); | ll = strtoll(numstr, &ep, base); | ||||
| if (errno == EINVAL || numstr == ep || *ep != '\0') | if (numstr == ep || *ep != '\0') | ||||
| error = INVALID; | error = INVALID; | ||||
| else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) | ||||
| error = TOOSMALL; | error = TOOSMALL; | ||||
| else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) | else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) | ||||
| error = TOOLARGE; | error = TOOLARGE; | ||||
| } | } | ||||
| if (errstrp != NULL) | if (errstrp != NULL) | ||||
| *errstrp = ev[error].errstr; | *errstrp = ev[error].errstr; | ||||
| errno = ev[error].err; | errno = ev[error].err; | ||||
| if (error) | if (error != 0) | ||||
| ll = 0; | ll = 0; | ||||
| return (ll); | return (ll); | ||||
| } | |||||
| long long | |||||
| strtonum(const char *numstr, long long minval, long long maxval, | |||||
| const char **errstrp) | |||||
| { | |||||
| return (strtonumx(numstr, minval, maxval, errstrp, 10)); | |||||
| } | } | ||||
I'm not sure if it's necessary, but all our style guides use this.