123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- /*====================================================================*
- *
- * uint64_t basespec (char const * string, unsigned base, unsigned size);
- *
- * number.h
- *
- * convert a character string to an equivalent unsigned integer and
- * return the result; terminate the program on failure;
- *
- * the base argument is the number base to be used for conversion;
- * base 0 permits the number base to be determined by the string
- * string prefix; 0b, 0d or 0x for binary, decimal or hex;
- *
- * this implementation accepts a minus sign in order to negate any
- * number in any base;
- *
- * the size argument is the maximum number of bytes permitted in the
- * result;
- *
- * Motley Tools by Charles Maier;
- * Copyright (c) 2001-2006 by Charles Maier Associates;
- * Licensed under the Internet Software Consortium License;
- *
- *--------------------------------------------------------------------*/
- #ifndef BASESPEC_SOURCE
- #define BASESPEC_SOURCE
- #include <stdlib.h>
- #include <ctype.h>
- #include "../tools/number.h"
- #include "../tools/error.h"
- uint64_t basespec (char const * string, unsigned base, unsigned size)
- {
- char const * number = string;
- unsigned radix = RADIX_DEC;
- signed scale = 1;
- uint64_t limit = 0;
- uint64_t value = 0;
- unsigned digit = 0;
- limit = ~limit;
- if (size < sizeof (limit))
- {
- limit <<= size << 3;
- limit = ~limit;
- }
- if (base)
- {
- radix = base;
- }
- if (* number == '=')
- {
- number++;
- }
- else if (* number == '+')
- {
- number++;
- }
- else if (* number == '-')
- {
- number++;
- scale = -1;
- }
- if (*number == '0')
- {
- number++;
- if ((*number == 'b') || (*number == 'B'))
- {
- radix = RADIX_BIN;
- number++;
- }
- else if ((*number == 'd') || (*number == 'D'))
- {
- radix = RADIX_DEC;
- number++;
- }
- else if ((*number == 'x') || (*number == 'X'))
- {
- radix = RADIX_HEX;
- number++;
- }
- }
- if ((base) && (base != radix))
- {
- error (1, EINVAL, "%s is not base %d notation", string, base);
- }
- while ((digit = todigit (*number)) < radix)
- {
- value *= radix;
- value += digit;
- if (value > limit)
- {
- error (1, ERANGE, "%s exceeds %d bits", string, (size << 3));
- }
- number++;
- }
- #ifdef WIN32
- while (isspace (*number))
- {
- number++;
- }
- #endif
- if (*number)
- {
- error (1, EINVAL, "%s is not base %d notation", string, radix);
- }
- return (scale * value);
- }
- #endif
|