Home | History | Annotate | Line # | Download | only in isc
      1  1.1  christos /*	$NetBSD: parseint.c,v 1.1 2024/02/18 20:57:49 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  1.1  christos  *
      6  1.1  christos  * SPDX-License-Identifier: MPL-2.0
      7  1.1  christos  *
      8  1.1  christos  * This Source Code Form is subject to the terms of the Mozilla Public
      9  1.1  christos  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  1.1  christos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  1.1  christos  *
     12  1.1  christos  * See the COPYRIGHT file distributed with this work for additional
     13  1.1  christos  * information regarding copyright ownership.
     14  1.1  christos  */
     15  1.1  christos 
     16  1.1  christos /*! \file */
     17  1.1  christos 
     18  1.1  christos #include <ctype.h>
     19  1.1  christos #include <errno.h>
     20  1.1  christos #include <inttypes.h>
     21  1.1  christos #include <limits.h>
     22  1.1  christos #include <stdlib.h>
     23  1.1  christos 
     24  1.1  christos #include <isc/parseint.h>
     25  1.1  christos #include <isc/result.h>
     26  1.1  christos 
     27  1.1  christos isc_result_t
     28  1.1  christos isc_parse_uint32(uint32_t *uip, const char *string, int base) {
     29  1.1  christos 	unsigned long n;
     30  1.1  christos 	uint32_t r;
     31  1.1  christos 	char *e;
     32  1.1  christos 	if (!isalnum((unsigned char)(string[0]))) {
     33  1.1  christos 		return (ISC_R_BADNUMBER);
     34  1.1  christos 	}
     35  1.1  christos 	errno = 0;
     36  1.1  christos 	n = strtoul(string, &e, base);
     37  1.1  christos 	if (*e != '\0') {
     38  1.1  christos 		return (ISC_R_BADNUMBER);
     39  1.1  christos 	}
     40  1.1  christos 	/*
     41  1.1  christos 	 * Where long is 64 bits we need to convert to 32 bits then test for
     42  1.1  christos 	 * equality.  This is a no-op on 32 bit machines and a good compiler
     43  1.1  christos 	 * will optimise it away.
     44  1.1  christos 	 */
     45  1.1  christos 	r = (uint32_t)n;
     46  1.1  christos 	if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) {
     47  1.1  christos 		return (ISC_R_RANGE);
     48  1.1  christos 	}
     49  1.1  christos 	*uip = r;
     50  1.1  christos 	return (ISC_R_SUCCESS);
     51  1.1  christos }
     52  1.1  christos 
     53  1.1  christos isc_result_t
     54  1.1  christos isc_parse_uint16(uint16_t *uip, const char *string, int base) {
     55  1.1  christos 	uint32_t val;
     56  1.1  christos 	isc_result_t result;
     57  1.1  christos 	result = isc_parse_uint32(&val, string, base);
     58  1.1  christos 	if (result != ISC_R_SUCCESS) {
     59  1.1  christos 		return (result);
     60  1.1  christos 	}
     61  1.1  christos 	if (val > 0xFFFF) {
     62  1.1  christos 		return (ISC_R_RANGE);
     63  1.1  christos 	}
     64  1.1  christos 	*uip = (uint16_t)val;
     65  1.1  christos 	return (ISC_R_SUCCESS);
     66  1.1  christos }
     67  1.1  christos 
     68  1.1  christos isc_result_t
     69  1.1  christos isc_parse_uint8(uint8_t *uip, const char *string, int base) {
     70  1.1  christos 	uint32_t val;
     71  1.1  christos 	isc_result_t result;
     72  1.1  christos 	result = isc_parse_uint32(&val, string, base);
     73  1.1  christos 	if (result != ISC_R_SUCCESS) {
     74  1.1  christos 		return (result);
     75  1.1  christos 	}
     76  1.1  christos 	if (val > 0xFF) {
     77  1.1  christos 		return (ISC_R_RANGE);
     78  1.1  christos 	}
     79  1.1  christos 	*uip = (uint8_t)val;
     80  1.1  christos 	return (ISC_R_SUCCESS);
     81  1.1  christos }
     82