aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/runtime
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gmail.com>2021-12-25 15:07:12 +0100
committerFrancois-Xavier Coudert <fxcoudert@gmail.com>2021-12-25 15:07:12 +0100
commit4ae906e46c4c173b79c9c60c6157ff68e05f7464 (patch)
tree30547d298d8ea29320e37d7e765c363ff22135ee /libgfortran/runtime
parentffb5418fb79e951e4a8cc818e2408106aa58b9a8 (diff)
downloadgcc-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.c1
-rw-r--r--libgfortran/runtime/error.c31
-rw-r--r--libgfortran/runtime/string.c39
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;
}