timport strtonum(3) from OpenBSD - numtools - perform numerical operations on vectors and matrices in unix pipes
 (HTM) git clone git://src.adamsgaard.dk/numtools
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 76946865659abbf6fb22ab476a2c6075aed14a99
 (DIR) parent 817421dee16bed3f985a841c575be086cfb3254a
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Wed, 11 May 2022 11:21:18 +0200
       
       import strtonum(3) from OpenBSD
       
       Diffstat:
         M Makefile                            |       3 ++-
         A strtonum.c                          |      65 +++++++++++++++++++++++++++++++
         M util.h                              |       4 ++++
       
       3 files changed, 71 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/Makefile b/Makefile
       t@@ -28,8 +28,9 @@ SRC = \
                util.c \
        
        COMPATSRC = \
       -        strnlen.c \
                strlcpy.c \
       +        strnlen.c \
       +        strtonum.c \
                xreallocarray.c \
        
        COMPATOBJ = ${COMPATSRC:.c=.o}
 (DIR) diff --git a/strtonum.c b/strtonum.c
       t@@ -0,0 +1,65 @@
       +/*        $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $        */
       +
       +/*
       + * Copyright (c) 2004 Ted Unangst and Todd Miller
       + * All rights reserved.
       + *
       + * Permission to use, copy, modify, and distribute this software for any
       + * purpose with or without fee is hereby granted, provided that the above
       + * copyright notice and this permission notice appear in all copies.
       + *
       + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
       + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
       + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
       + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
       + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
       + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
       + */
       +
       +#include <errno.h>
       +#include <limits.h>
       +#include <stdlib.h>
       +
       +#define        INVALID                1
       +#define        TOOSMALL        2
       +#define        TOOLARGE        3
       +
       +long long
       +strtonum(const char *numstr, long long minval, long long maxval,
       +    const char **errstrp)
       +{
       +        long long ll = 0;
       +        int error = 0;
       +        char *ep;
       +        struct errval {
       +                const char *errstr;
       +                int err;
       +        } ev[4] = {
       +                { NULL,                0 },
       +                { "invalid",        EINVAL },
       +                { "too small",        ERANGE },
       +                { "too large",        ERANGE },
       +        };
       +
       +        ev[0].err = errno;
       +        errno = 0;
       +        if (minval > maxval) {
       +                error = INVALID;
       +        } else {
       +                ll = strtoll(numstr, &ep, 10);
       +                if (numstr == ep || *ep != '\0')
       +                        error = INVALID;
       +                else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
       +                        error = TOOSMALL;
       +                else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
       +                        error = TOOLARGE;
       +        }
       +        if (errstrp != NULL)
       +                *errstrp = ev[error].errstr;
       +        errno = ev[error].err;
       +        if (error)
       +                ll = 0;
       +
       +        return (ll);
       +}
 (DIR) diff --git a/util.h b/util.h
       t@@ -17,6 +17,10 @@ size_t strlcpy(char *dst, const char *src, size_t dsize);
        #undef strnlen
        size_t strnlen(const char *str, size_t maxlen);
        
       +#undef strtonum
       +long long strtonum(const char *numstr, long long minval, long long maxval,
       +    const char **errstrp);
       +
        void * xreallocarray(void *m, size_t n, size_t s);
        
        size_t allocarr(double **arr, const char *str, size_t maxlen);