From fcedfddf00b3f994e4f4e40332ac7fc192c63244 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 5 Oct 2025 21:56:51 +0700 Subject: claude is gud --- vere/ext/nasm/nasmlib/readnum.c | 179 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 vere/ext/nasm/nasmlib/readnum.c (limited to 'vere/ext/nasm/nasmlib/readnum.c') diff --git a/vere/ext/nasm/nasmlib/readnum.c b/vere/ext/nasm/nasmlib/readnum.c new file mode 100644 index 0000000..947bda5 --- /dev/null +++ b/vere/ext/nasm/nasmlib/readnum.c @@ -0,0 +1,179 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2016 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +/* + * nasmlib.c library routines for the Netwide Assembler + */ + +#include "compiler.h" + +#include "nctype.h" + +#include "nasmlib.h" +#include "error.h" +#include "nasm.h" /* For globalbits */ + +#define lib_isnumchar(c) (nasm_isalnum(c) || (c) == '$' || (c) == '_') + +static int radix_letter(char c) +{ + switch (c) { + case 'b': case 'B': + case 'y': case 'Y': + return 2; /* Binary */ + case 'o': case 'O': + case 'q': case 'Q': + return 8; /* Octal */ + case 'h': case 'H': + case 'x': case 'X': + return 16; /* Hexadecimal */ + case 'd': case 'D': + case 't': case 'T': + return 10; /* Decimal */ + default: + return 0; /* Not a known radix letter */ + } +} + +int64_t readnum(const char *str, bool *error) +{ + const char *r = str, *q; + int32_t pradix, sradix, radix; + int plen, slen, len; + uint64_t result, checklimit; + int digit, last; + bool warn = false; + int sign = 1; + + if (error) + *error = true; + + while (nasm_isspace(*r)) + r++; /* find start of number */ + + /* + * If the number came from make_tok_num (as a result of an %assign), it + * might have a '-' built into it (rather than in a preceding token). + */ + if (*r == '-') { + r++; + sign = -1; + } + + q = r; + + while (lib_isnumchar(*q)) + q++; /* find end of number */ + + len = q-r; + if (!len) { + /* Not numeric */ + return 0; + } + + /* + * Handle radix formats: + * + * 0 + * $ (hexadecimal) + * + */ + pradix = sradix = 0; + plen = slen = 0; + + if (len > 2 && *r == '0' && (pradix = radix_letter(r[1])) != 0) + plen = 2; + else if (len > 1 && *r == '$') + pradix = 16, plen = 1; + + if (len > 1 && (sradix = radix_letter(q[-1])) != 0) + slen = 1; + + if (pradix > sradix) { + radix = pradix; + r += plen; + } else if (sradix > pradix) { + radix = sradix; + q -= slen; + } else { + /* Either decimal, or invalid -- if invalid, we'll trip up + further down. */ + radix = 10; + } + + /* + * `checklimit' must be 2**64 / radix. We can't do that in + * 64-bit arithmetic, which we're (probably) using, so we + * cheat: since we know that all radices we use are even, we + * can divide 2**63 by radix/2 instead. + */ + checklimit = UINT64_C(0x8000000000000000) / (radix >> 1); + + /* + * Calculate the highest allowable value for the last digit of a + * 64-bit constant... in radix 10, it is 6, otherwise it is 0 + */ + last = (radix == 10 ? 6 : 0); + + result = 0; + while (*r && r < q) { + if (*r != '_') { + if (*r < '0' || (*r > '9' && *r < 'A') + || (digit = numvalue(*r)) >= radix) { + return 0; + } + if (result > checklimit || + (result == checklimit && digit >= last)) { + warn = true; + } + + result = radix * result + digit; + } + r++; + } + + if (warn) { + /*! + *!number-overflow [on] numeric constant does not fit + *! covers warnings about numeric constants which + *! don't fit in 64 bits. + */ + nasm_warn(WARN_NUMBER_OVERFLOW, + "numeric constant %s does not fit in 64 bits", + str); + } + + if (error) + *error = false; + return result * sign; +} -- cgit v1.2.3