AfanasevGad7

This is a task for our favourite professor
git clone git://git.stellar-nexus.ru/AfanasevGad7
Log | Files | Refs

commit df287f2e67cbd2671be31b95df12b8e5cdcf1bb6
parent 63553d7670317bbb9ec0b252d66c77593cc58058
Author: Plat <plat@stellar-nexus.ru>
Date:   Wed,  5 Nov 2025 22:41:59 +0000

Attempt numero 4

Diffstat:
Dlibutil/estrtod.c | 18------------------
Alibutil/strtonum.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrb.c | 7++++---
Mutil.h | 6+++++-
4 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/libutil/estrtod.c b/libutil/estrtod.c @@ -1,18 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> - -#include "../util.h" - -double -estrtod(const char *s) -{ - char *end; - double d; - - d = strtod(s, &end); - if (end == s || *end != '\0') - eprintf("%s: not a real number\n", s); - return d; -} diff --git a/libutil/strtonum.c b/libutil/strtonum.c @@ -0,0 +1,85 @@ +/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu 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> + +#include "../util.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); +} + +long long +enstrtonum(int status, const char *numstr, long long minval, long long maxval) +{ + const char *errstr; + long long ll; + + ll = strtonum(numstr, minval, maxval, &errstr); + if (errstr) + enprintf(status, "strtonum %s: %s\n", numstr, errstr); + return ll; +} + +long long +estrtonum(const char *numstr, long long minval, long long maxval) +{ + return enstrtonum(1, numstr, minval, maxval); +} diff --git a/rb.c b/rb.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <stdlib.h> +#include <limits.h> #include "tree.h" @@ -102,7 +103,7 @@ main(int argc, char *argv[]) argv0 = argv[0]; if (argc != 3) usage(); - unsigned int data_limit = estrtod(argv[1]); + unsigned int data_limit = estrtonum(argv[1], 1, UINT_MAX); Node *root = NULL; @@ -115,8 +116,8 @@ main(int argc, char *argv[]) int search_value, attempt; for (search_value = attempt = 0; search_value < 1 || search_value > data_limit; ++attempt) { if (attempt) - printf("Impossible value\n"); - search_value = estrtod(argv[2]); + eprintf("Impossible value\n"); + search_value = estrtonum(argv[2], 1, INT_MAX); } Node *s = search(root, search_value); diff --git a/util.h b/util.h @@ -21,4 +21,8 @@ void enprintf(int, const char *, ...); void eprintf(const char *, ...); void weprintf(const char *, ...); -double estrtod(const char *); +#undef strtonum +#define strtonum xstrtonum +long long strtonum(const char *, long long, long long, const char **); +long long enstrtonum(int, const char *, long long, long long); +long long estrtonum(const char *, long long, long long);