Before this patch, muon would use strtol() when converting a string
representing a 64-bit number. The C standard defines long to only be at
least 32 bits wide, but this doesn't cause issues on Unix-like systems
which use the LP64 data model where longs are 64 bits wide. On other
systems though, like 32-bit systems and Windows, longs are only 32 bits
wide, so it becomes impossible to parse strings containing 64-bit
numbers, even though muon pretended to always use 64-bit integers.
An example makes this pretty clear:
$ getconf LONG_BIT
32
$ cat long.meson
n = 9223372036854775807
$ muon-meson check long.meson
long.meson:1:5: error number out of representable range [-9223372036854775808,9223372036854775807]
1 | n = 9223372036854775807
^__________________
long.meson:2:24: error expected expression, got end of line
2 |
^
With this patch, muon now uses strtoll() when expecting 64-bit numbers,
since long long is always guaranteed to be at least 64 bits wide.
---
src/functions/compiler.c | 2 +-
src/lang/lexer.c | 2 +-
src/lang/string.c | 2 +-
src/options.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/functions/compiler.c b/src/functions/compiler.c
index d7518a95..c45ec9c1 100644
--- a/src/functions/compiler.c
+++ b/src/functions/compiler.c
@@ -405,7 +405,7 @@ compiler_check_parse_output_int(struct compiler_check_opts *opts)
{
char *endptr;
int64_t size;
- size = strtol(opts->cmd_ctx.out.buf, &endptr, 10);
+ size = strtoll(opts->cmd_ctx.out.buf, &endptr, 10);
if (*endptr) {
LOG_W("compiler check binary had malformed output '%s'", opts->cmd_ctx.out.buf);
return -1;
diff --git a/src/lang/lexer.c b/src/lang/lexer.c
index f50d55af..9bec3e3d 100644
--- a/src/lang/lexer.c
+++ b/src/lang/lexer.c
@@ -280,7 +280,7 @@ lex_number(struct lexer *lexer, struct token *token)
char *endptr = 0;
errno = 0;
- int64_t val = strtol(&lexer->src[lexer->i], &endptr, base);
+ int64_t val = strtoll(&lexer->src[lexer->i], &endptr, base);
assert(endptr);
if (endptr == &lexer->src[lexer->i]) {
diff --git a/src/lang/string.c b/src/lang/string.c
index 95038727..ac2f44e7 100644
--- a/src/lang/string.c
+++ b/src/lang/string.c
@@ -430,7 +430,7 @@ str_to_i(const struct str *ss, int64_t *res, bool strip)
}
}
- *res = strtol(start, &endptr, 10);
+ *res = strtoll(start, &endptr, 10);
if (strip) {
while (is_whitespace(*endptr)) {
diff --git a/src/options.c b/src/options.c
index f41a0b5b..264c54ed 100644
--- a/src/options.c
+++ b/src/options.c
@@ -325,7 +325,7 @@ coerce_option_override(struct workspace *wk, struct obj_option *opt, obj sval, o
case op_integer: {
int64_t num;
char *endptr;
- num = strtol(val->s, &endptr, 10);
+ num = strtoll(val->s, &endptr, 10);
if (!val->len || *endptr) {
vm_error(wk, "unable to coerce '%s' into a number", val->s);
--
2.43.0