diff options
author | Francois-Xavier Coudert <fxcoudert@gmail.com> | 2021-12-25 15:07:12 +0100 |
---|---|---|
committer | Francois-Xavier Coudert <fxcoudert@gmail.com> | 2021-12-25 15:07:12 +0100 |
commit | 4ae906e46c4c173b79c9c60c6157ff68e05f7464 (patch) | |
tree | 30547d298d8ea29320e37d7e765c363ff22135ee /libgfortran/runtime | |
parent | ffb5418fb79e951e4a8cc818e2408106aa58b9a8 (diff) | |
download | gcc-4ae906e46c4c173b79c9c60c6157ff68e05f7464.zip gcc-4ae906e46c4c173b79c9c60c6157ff68e05f7464.tar.gz gcc-4ae906e46c4c173b79c9c60c6157ff68e05f7464.tar.bz2 |
Fortran: simplify library code for integer-to-decimal conversion
libgfortran/ChangeLog:
PR libfortran/81986
PR libfortran/99191
* libgfortran.h: Remove gfc_xtoa(), adjust gfc_itoa() and
GFC_ITOA_BUF_SIZE.
* io/write.c (write_decimal): conversion parameter is always
gfc_itoa(), so remove it. Protect from overflow.
(xtoa): Move gfc_xtoa and update its name.
(xtoa_big): Renamed from ztoa_big for consistency.
(write_z): Adjust to new function names.
(write_i, write_integer): Remove last arg of write_decimal.
* runtime/backtrace.c (error_callback): Comment on the use of
gfc_itoa().
* runtime/error.c (gfc_xtoa): Move to io/write.c.
* runtime/string.c (gfc_itoa): Take an unsigned argument,
remove the handling of negative values.
Diffstat (limited to 'libgfortran/runtime')
-rw-r--r-- | libgfortran/runtime/backtrace.c | 1 | ||||
-rw-r--r-- | libgfortran/runtime/error.c | 31 | ||||
-rw-r--r-- | libgfortran/runtime/string.c | 39 |
3 files changed, 16 insertions, 55 deletions
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index 5ac0831..403c7c3 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -97,6 +97,7 @@ error_callback (void *data, const char *msg, int errnum) iov[1].iov_len = strlen (msg); iov[2].iov_base = (char*) ", errno: "; iov[2].iov_len = strlen (iov[2].iov_base); + /* Async-signal-safe function, errnum must be positive. */ const char *p = gfc_itoa (errnum, errbuf, sizeof (errbuf)); iov[3].iov_base = (char*) p; iov[3].iov_len = strlen (p); diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c index b9c7574..ba6ff86 100644 --- a/libgfortran/runtime/error.c +++ b/libgfortran/runtime/error.c @@ -219,37 +219,6 @@ exit_error (int status) } - -/* gfc_xtoa()-- Integer to hexadecimal conversion. */ - -const char * -gfc_xtoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len) -{ - int digit; - char *p; - - assert (len >= GFC_XTOA_BUF_SIZE); - - if (n == 0) - return "0"; - - p = buffer + GFC_XTOA_BUF_SIZE - 1; - *p = '\0'; - - while (n != 0) - { - digit = n & 0xF; - if (digit > 9) - digit += 'A' - '0' - 10; - - *--p = '0' + digit; - n >>= 4; - } - - return p; -} - - /* Hopefully thread-safe wrapper for a strerror() style function. */ char * diff --git a/libgfortran/runtime/string.c b/libgfortran/runtime/string.c index 536a9cd..835027a 100644 --- a/libgfortran/runtime/string.c +++ b/libgfortran/runtime/string.c @@ -169,21 +169,22 @@ find_option (st_parameter_common *cmp, const char *s1, gfc_charlen_type s1_len, } -/* gfc_itoa()-- Integer to decimal conversion. - The itoa function is a widespread non-standard extension to - standard C, often declared in <stdlib.h>. Even though the itoa - defined here is a static function we take care not to conflict with - any prior non-static declaration. Hence the 'gfc_' prefix, which - is normally reserved for functions with external linkage. Notably, - in contrast to the *printf() family of functions, this ought to be - async-signal-safe. */ +/* Integer to decimal conversion. + + This function is much more restricted than the widespread (but + non-standard) itoa() function. This version has the following + characteristics: + + - it takes only non-negative arguments + - it is async-signal-safe (we use it runtime/backtrace.c) + - it works in base 10 (see xtoa, otoa, btoa functions + in io/write.c for other radices) + */ const char * -gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len) +gfc_itoa (GFC_UINTEGER_LARGEST n, char *buffer, size_t len) { - int negative; char *p; - GFC_UINTEGER_LARGEST t; if (len < GFC_ITOA_BUF_SIZE) sys_abort (); @@ -191,24 +192,14 @@ gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len) if (n == 0) return "0"; - negative = 0; - t = n; - if (n < 0) - { - negative = 1; - t = -(GFC_UINTEGER_LARGEST) n; /* Must use unsigned to protect from overflow. */ - } - p = buffer + GFC_ITOA_BUF_SIZE - 1; *p = '\0'; - while (t != 0) + while (n != 0) { - *--p = '0' + (t % 10); - t /= 10; + *--p = '0' + (n % 10); + n /= 10; } - if (negative) - *--p = '-'; return p; } |