From: Marek Küthe Date: Fri, 14 Feb 2025 23:31:18 +0000 (+0000) Subject: Split the strtonum function into two parts to create a better structure X-Git-Tag: v0.96~9^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F525%2Fhead;p=thirdparty%2Fmtr.git Split the strtonum function into two parts to create a better structure This even saves some memory when converting signed integers, as no `long` is used. --- diff --git a/ui/mtr.c b/ui/mtr.c index d47e75c..447eced 100644 --- a/ui/mtr.c +++ b/ui/mtr.c @@ -439,19 +439,19 @@ static void parse_arg( case OPT_DISPLAYMODE: ctl->display_mode = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if ((DisplayModeMAX - 1) < ctl->display_mode) error(EXIT_FAILURE, 0, "value out of range (%d - %d): %s", DisplayModeDefault, (DisplayModeMAX - 1), optarg); break; case 'c': ctl->MaxPing = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); ctl->ForceMaxPing = 1; break; case 's': ctl->cpacketsize = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); break; case 'I': ctl->InterfaceName = optarg; @@ -476,7 +476,7 @@ static void parse_arg( } break; case 'f': - ctl->fstTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT); + ctl->fstTTL = strtoint_or_err(optarg, "invalid argument"); if (ctl->fstTTL < 1) { /* prevent 0 hop */ ctl->fstTTL = 1; } @@ -485,7 +485,7 @@ static void parse_arg( read_from_file(names, optarg); break; case 'm': - ctl->maxTTL = strtonum_or_err(optarg, "invalid argument", STRTO_INT); + ctl->maxTTL = strtoint_or_err(optarg, "invalid argument"); if (ctl->maxTTL > (MaxHost - 1)) { ctl->maxTTL = MaxHost - 1; } @@ -495,13 +495,13 @@ static void parse_arg( break; case 'U': ctl->maxUnknown = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->maxUnknown < 1) { ctl->maxUnknown = 1; } break; case 'E': - ctl->maxDisplayPath = strtonum_or_err(optarg, "invalid argument", STRTO_INT); + ctl->maxDisplayPath = strtoint_or_err(optarg, "invalid argument"); if (ctl->maxDisplayPath > MAX_PATH) { ctl->maxDisplayPath = MAX_PATH; } @@ -521,7 +521,7 @@ static void parse_arg( break; case 'B': ctl->bitpattern = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->bitpattern > 255) ctl->bitpattern = -1; break; @@ -533,7 +533,7 @@ static void parse_arg( break; case 'Q': ctl->tos = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->tos > 255 || ctl->tos < 0) { /* error message, should do more checking for valid values, * details in rfc2474 */ @@ -574,7 +574,7 @@ static void parse_arg( break; case 'P': ctl->remoteport = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->remoteport < 1 || MaxPort < ctl->remoteport) { error(EXIT_FAILURE, 0, "Illegal port number: %d", ctl->remoteport); @@ -582,7 +582,7 @@ static void parse_arg( break; case 'L': ctl->localport = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->localport < MinPort || MaxPort < ctl->localport) { error(EXIT_FAILURE, 0, "Illegal port number: %d", ctl->localport); @@ -590,7 +590,7 @@ static void parse_arg( break; case 'Z': ctl->probe_timeout = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); ctl->probe_timeout *= 1000000; break; case '4': @@ -604,7 +604,7 @@ static void parse_arg( #ifdef HAVE_IPINFO case 'y': ctl->ipinfo_no = - strtonum_or_err(optarg, "invalid argument", STRTO_INT); + strtoint_or_err(optarg, "invalid argument"); if (ctl->ipinfo_no < 0 || 4 < ctl->ipinfo_no) { error(EXIT_FAILURE, 0, "value %d out of range (0 - 4)", ctl->ipinfo_no); @@ -625,7 +625,7 @@ static void parse_arg( #ifdef SO_MARK case 'M': ctl->mark = - strtonum_or_err(optarg, "invalid argument", STRTO_U32INT); + strtoulong_or_err(optarg, "invalid argument"); break; #endif default: diff --git a/ui/utils.c b/ui/utils.c index 5754894..45dd47a 100644 --- a/ui/utils.c +++ b/ui/utils.c @@ -70,28 +70,37 @@ char *trim( } /* Parse string, and return positive signed int. */ -long int strtonum_or_err( +int strtoint_or_err( const char *str, - const char *errmesg, - const int type) + const char *errmesg) { - long int num; + int num; char *end = NULL; if (str != NULL && *str != '\0') { errno = 0; num = strtol(str, &end, 0); - if (errno == 0 && str != end && end != NULL && *end == '\0') { - switch (type) { - case STRTO_INT: - if (num < INT_MAX) - return num; - break; - case STRTO_U32INT: - if (num < UINT32_MAX) - return num; - break; - } + if (errno == 0 && str != end && end != NULL && *end == '\0' && num < INT_MAX) { + return num; + } + } + error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str); + return 0; +} + +/* Parse string, and return positive unsigned long int. */ +unsigned long strtoulong_or_err( + const char *str, + const char *errmesg) +{ + unsigned long int num; + char *end = NULL; + + if (str != NULL && *str != '\0') { + errno = 0; + num = strtoul(str, &end, 0); + if (errno == 0 && str != end && end != NULL && *end == '\0' && num < UINT32_MAX) { + return num; } } error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str); diff --git a/ui/utils.h b/ui/utils.h index 621e3d3..3aa7267 100644 --- a/ui/utils.h +++ b/ui/utils.h @@ -17,18 +17,15 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -enum { - STRTO_INT, - STRTO_U32INT -}; - extern char *trim( char *s, const char c); -extern long int strtonum_or_err( +extern int strtoint_or_err( + const char *str, + const char *errmesg); +extern unsigned long strtoulong_or_err( const char *str, - const char *errmesg, - const int type); + const char *errmesg); extern float strtofloat_or_err( const char *str, const char *errmesg);