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