[bug #68448] replace strtoull/strtoul with from_char in lex.ll

"Dmitri A. Sergatskov" <[email protected]> Sat, 13 Jun 2026 01:28:46 -0400 (EDT)
Newsgroups gmane.comp.gnu.octave.bugs
Message-ID <[email protected]>
Please use the bug tracker to post updates to a bug report.  The mailing list is intended as a read-only notification stream.  Info posted to this mailing list address won't appear in the tracker database where it is most useful.

URL:
  <https://savannah.gnu.org/bugs/?68448>

                 Summary: replace strtoull/strtoul with from_char in lex.ll
                   Group: GNU Octave
               Submitter: dasergatskov
               Submitted: Sat 13 Jun 2026 05:28:42 AM UTC
                Category: Octave Function
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: Performance
                  Status: None
             Assigned to: None
         Originator Name:
        Originator Email:
             Open/Closed: Open
         Discussion Lock: Unlocked
                 Release: dev
        Operating System: Any
           Fixed Release: None
         Planned Release: None


    _______________________________________________________

Follow-up Comments:


-------------------------------------------------------
Date: Sat 13 Jun 2026 05:28:42 AM UTC By: Dmitri A. Sergatskov <dasergatskov>
Code improvement rather than a bug.

I guess we missed some of the modernization the last round. 
It also addresses the "FIXME".

@@ -3152,21 +3160,25 @@
       return syntax_error (msg);
     }
 
-  // FIXME: is there a better way?  Can uintmax_t be anything other than
long
-  // or long long?  Should we just be using uint64_t instead of uintmax_t?
-
-  errno = 0;
-  char *end;
-  uintmax_t long_int_val;
-  if (sizeof (uintmax_t) == sizeof (unsigned long long))
-    long_int_val = strtoull (yytxt.c_str (), &end, 2);
-  else if (sizeof (uintmax_t) == sizeof (unsigned long))
-    long_int_val = strtoul (yytxt.c_str (), &end, 2);
-  else
-    error ("unexpected: size mismatch: uintmax_t vs unsigned long or unsigned
long long in base_lexer::handle_number<2> - please report this bug");
-
-  if (errno == ERANGE)
-    error ("unexpected: ERANGE error in base_lexer::handle_number<2> - please
report this bug");
+  uintmax_t long_int_val = 0;
+  const char *chars_start = yytxt.c_str ();
+  const char *chars_end = chars_start + yytxt.length ();
+  auto [ptr, ec] = std::from_chars (chars_start, chars_end, long_int_val,
2);
+  if (ec != std::errc{})
+    {
+      switch (ec)
+        {
+        case std::errc::invalid_argument:
+          fatal_error ("invalid binary format in base_lexer::handle_number<2>
- please report this bug");
+          break;
+        case std::errc::result_out_of_range:
+          fatal_error ("binary value out of range in
base_lexer::handle_number<2> - please report this bug");
+          break;
+        default:
+          fatal_error ("from_chars failed in base_lexer::handle_number<2> -
please report this bug");
+          break;
+        }
+    }
 
   octave_value ov = make_integer_value (long_int_val, unsigned_val, bytes);
 


Dmitri.
-- 








    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?68448>

_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
signature.asc (application/pgp-signature, 228 B)
-----BEGIN PGP SIGNATURE-----

iHUEABYIAB0WIQQk97aszIMMAvLLwm6qLAuaBUf3TgUCaizqjgAKCRCqLAuaBUf3
TjAbAQDvVMInamHzSEs8VkDlcMPUVgoDQLlSa/qF1EjQ49QboAD/Qopzqiyf6e7Z
PGb+lE/uqYxJU4qZtXjblFrCztEy5wg=
=ghXZ
-----END PGP SIGNATURE-----