diff options
author | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-11-13 16:28:05 +0000 |
---|---|---|
committer | Sam Thursfield <sam.thursfield@codethink.co.uk> | 2017-11-13 16:29:09 +0000 |
commit | 03ac50856c9fc8c96b7a17239ee40a10397750a7 (patch) | |
tree | a648c6d3428e4757e003f6ed1748adb9613065db /libgfortran/runtime | |
parent | 34efdaf078b01a7387007c4e6bde6db86384c4b7 (diff) | |
download | gcc-tarball-03ac50856c9fc8c96b7a17239ee40a10397750a7.tar.gz |
gcc 7.2.0
This is imported manually due to a bug in the tarball import script.
See the baserock-dev mailing list archives (November 2017) for a
more detailed explaination of the issue.
Diffstat (limited to 'libgfortran/runtime')
-rw-r--r-- | libgfortran/runtime/backtrace.c | 179 | ||||
-rw-r--r-- | libgfortran/runtime/bounds.c | 271 | ||||
-rw-r--r-- | libgfortran/runtime/compile_options.c | 265 | ||||
-rw-r--r-- | libgfortran/runtime/convert_char.c | 66 | ||||
-rw-r--r-- | libgfortran/runtime/environ.c | 687 | ||||
-rw-r--r-- | libgfortran/runtime/error.c | 666 | ||||
-rw-r--r-- | libgfortran/runtime/fpu.c | 41 | ||||
-rw-r--r-- | libgfortran/runtime/in_pack_generic.c | 218 | ||||
-rw-r--r-- | libgfortran/runtime/in_unpack_generic.c | 239 | ||||
-rw-r--r-- | libgfortran/runtime/main.c | 114 | ||||
-rw-r--r-- | libgfortran/runtime/memory.c | 102 | ||||
-rw-r--r-- | libgfortran/runtime/minimal.c | 196 | ||||
-rw-r--r-- | libgfortran/runtime/pause.c | 74 | ||||
-rw-r--r-- | libgfortran/runtime/select.c | 46 | ||||
-rw-r--r-- | libgfortran/runtime/select_inc.c | 133 | ||||
-rw-r--r-- | libgfortran/runtime/stop.c | 143 | ||||
-rw-r--r-- | libgfortran/runtime/string.c | 214 |
17 files changed, 0 insertions, 3654 deletions
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c deleted file mode 100644 index 77dd4d5f0a..0000000000 --- a/libgfortran/runtime/backtrace.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (C) 2006-2017 Free Software Foundation, Inc. - Contributed by François-Xavier Coudert - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - -#include <gthr.h> - -#include <string.h> -#include <errno.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "backtrace-supported.h" -#include "backtrace.h" - - -/* Store our own state while backtracing. */ -struct mystate -{ - int frame; - bool try_simple; - bool in_signal_handler; -}; - - -/* Does a function name have "_gfortran_" or "_gfortrani_" prefix, possibly - with additional underscore(s) at the beginning? Cannot use strncmp() - because we might be called from a signal handler. */ - -static int -has_gfortran_prefix (const char *s) -{ - if (!s) - return 0; - - while (*s == '_') - s++; - - return (s[0] == 'g' && s[1] == 'f' && s[2] == 'o' && s[3] == 'r' - && s[4] == 't' && s[5] == 'r' && s[6] == 'a' && s[7] == 'n' - && (s[8] == '_' || (s[8] == 'i' && s[9] == '_'))); -} - -static void -error_callback (void *data, const char *msg, int errnum) -{ - struct mystate *state = (struct mystate *) data; -#define ERRHDR "\nCould not print backtrace: " - - if (errnum < 0) - { - state->try_simple = true; - return; - } - else if (errnum == 0) - { - estr_write (ERRHDR); - estr_write (msg); - estr_write ("\n"); - } - else - { - char errbuf[256]; - if (state->in_signal_handler) - { - estr_write (ERRHDR); - estr_write (msg); - estr_write (", errno: "); - const char *p = gfc_itoa (errnum, errbuf, sizeof (errbuf)); - estr_write (p); - estr_write ("\n"); - } - else - st_printf (ERRHDR "%s: %s\n", msg, - gf_strerror (errnum, errbuf, sizeof (errbuf))); - } -} - -static int -simple_callback (void *data, uintptr_t pc) -{ - struct mystate *state = (struct mystate *) data; - st_printf ("#%d 0x%lx\n", state->frame, (unsigned long) pc); - (state->frame)++; - return 0; -} - -static int -full_callback (void *data, uintptr_t pc, const char *filename, - int lineno, const char *function) -{ - struct mystate *state = (struct mystate *) data; - - if (has_gfortran_prefix (function)) - return 0; - - st_printf ("#%d 0x%lx in %s\n", state->frame, - (unsigned long) pc, function == NULL ? "???" : function); - if (filename || lineno != 0) - st_printf ("\tat %s:%d\n", filename == NULL ? "???" : filename, lineno); - (state->frame)++; - - if (function != NULL && strcmp (function, "main") == 0) - return 1; - - return 0; -} - - -/* Display the backtrace. */ - -void -show_backtrace (bool in_signal_handler) -{ - struct backtrace_state *lbstate; - struct mystate state = { 0, false, in_signal_handler }; - - lbstate = backtrace_create_state (NULL, __gthread_active_p (), - error_callback, NULL); - - if (lbstate == NULL) - return; - - if (!BACKTRACE_SUPPORTED || (in_signal_handler && BACKTRACE_USES_MALLOC)) - { - /* If symbolic backtrace is not supported on this target, or would - require malloc() and we are in a signal handler, go with a - simple backtrace. */ - - backtrace_simple (lbstate, 0, simple_callback, error_callback, &state); - } - else - { - /* libbacktrace uses mmap, which is safe to call from a signal handler - (in practice, if not in theory). Thus we can generate a symbolic - backtrace, if debug symbols are available. */ - - backtrace_full (lbstate, 0, full_callback, error_callback, &state); - if (state.try_simple) - backtrace_simple (lbstate, 0, simple_callback, error_callback, &state); - } -} - - - -/* Function called by the front-end translating the BACKTRACE intrinsic. */ - -extern void backtrace (void); -export_proto (backtrace); - -void -backtrace (void) -{ - show_backtrace (false); -} - diff --git a/libgfortran/runtime/bounds.c b/libgfortran/runtime/bounds.c deleted file mode 100644 index ffa09628b6..0000000000 --- a/libgfortran/runtime/bounds.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright (C) 2009-2017 Free Software Foundation, Inc. - Contributed by Thomas Koenig - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <assert.h> - -/* Auxiliary functions for bounds checking, mostly to reduce library size. */ - -/* Bounds checking for the return values of the iforeach functions (such - as maxloc and minloc). The extent of ret_array must - must match the rank of array. */ - -void -bounds_iforeach_return (array_t *retarray, array_t *array, const char *name) -{ - index_type rank; - index_type ret_rank; - index_type ret_extent; - - ret_rank = GFC_DESCRIPTOR_RANK (retarray); - - if (ret_rank != 1) - runtime_error ("Incorrect rank of return array in %s intrinsic:" - "is %ld, should be 1", name, (long int) ret_rank); - - rank = GFC_DESCRIPTOR_RANK (array); - ret_extent = GFC_DESCRIPTOR_EXTENT(retarray,0); - if (ret_extent != rank) - runtime_error ("Incorrect extent in return value of" - " %s intrinsic: is %ld, should be %ld", - name, (long int) ret_extent, (long int) rank); - -} - -/* Check the return of functions generated from ifunction.m4. - We check the array descriptor "a" against the extents precomputed - from ifunction.m4, and complain about the argument a_name in the - intrinsic function. */ - -void -bounds_ifunction_return (array_t * a, const index_type * extent, - const char * a_name, const char * intrinsic) -{ - int empty; - int n; - int rank; - index_type a_size; - - rank = GFC_DESCRIPTOR_RANK (a); - a_size = size0 (a); - - empty = 0; - for (n = 0; n < rank; n++) - { - if (extent[n] == 0) - empty = 1; - } - if (empty) - { - if (a_size != 0) - runtime_error ("Incorrect size in %s of %s" - " intrinsic: should be zero-sized", - a_name, intrinsic); - } - else - { - if (a_size == 0) - runtime_error ("Incorrect size of %s in %s" - " intrinsic: should not be zero-sized", - a_name, intrinsic); - - for (n = 0; n < rank; n++) - { - index_type a_extent; - a_extent = GFC_DESCRIPTOR_EXTENT(a, n); - if (a_extent != extent[n]) - runtime_error("Incorrect extent in %s of %s" - " intrinsic in dimension %ld: is %ld," - " should be %ld", a_name, intrinsic, (long int) n + 1, - (long int) a_extent, (long int) extent[n]); - - } - } -} - -/* Check that two arrays have equal extents, or are both zero-sized. Abort - with a runtime error if this is not the case. Complain that a has the - wrong size. */ - -void -bounds_equal_extents (array_t *a, array_t *b, const char *a_name, - const char *intrinsic) -{ - index_type a_size, b_size, n; - - assert (GFC_DESCRIPTOR_RANK(a) == GFC_DESCRIPTOR_RANK(b)); - - a_size = size0 (a); - b_size = size0 (b); - - if (b_size == 0) - { - if (a_size != 0) - runtime_error ("Incorrect size of %s in %s" - " intrinsic: should be zero-sized", - a_name, intrinsic); - } - else - { - if (a_size == 0) - runtime_error ("Incorrect size of %s of %s" - " intrinsic: Should not be zero-sized", - a_name, intrinsic); - - for (n = 0; n < GFC_DESCRIPTOR_RANK (b); n++) - { - index_type a_extent, b_extent; - - a_extent = GFC_DESCRIPTOR_EXTENT(a, n); - b_extent = GFC_DESCRIPTOR_EXTENT(b, n); - if (a_extent != b_extent) - runtime_error("Incorrect extent in %s of %s" - " intrinsic in dimension %ld: is %ld," - " should be %ld", a_name, intrinsic, (long int) n + 1, - (long int) a_extent, (long int) b_extent); - } - } -} - -/* Check that the extents of a and b agree, except that a has a missing - dimension in argument which. Complain about a if anything is wrong. */ - -void -bounds_reduced_extents (array_t *a, array_t *b, int which, const char *a_name, - const char *intrinsic) -{ - - index_type i, n, a_size, b_size; - - assert (GFC_DESCRIPTOR_RANK(a) == GFC_DESCRIPTOR_RANK(b) - 1); - - a_size = size0 (a); - b_size = size0 (b); - - if (b_size == 0) - { - if (a_size != 0) - runtime_error ("Incorrect size in %s of %s" - " intrinsic: should not be zero-sized", - a_name, intrinsic); - } - else - { - if (a_size == 0) - runtime_error ("Incorrect size of %s of %s" - " intrinsic: should be zero-sized", - a_name, intrinsic); - - i = 0; - for (n = 0; n < GFC_DESCRIPTOR_RANK (b); n++) - { - index_type a_extent, b_extent; - - if (n != which) - { - a_extent = GFC_DESCRIPTOR_EXTENT(a, i); - b_extent = GFC_DESCRIPTOR_EXTENT(b, n); - if (a_extent != b_extent) - runtime_error("Incorrect extent in %s of %s" - " intrinsic in dimension %ld: is %ld," - " should be %ld", a_name, intrinsic, (long int) i + 1, - (long int) a_extent, (long int) b_extent); - i++; - } - } - } -} - -/* count_0 - count all the true elements in an array. The front - end usually inlines this, we need this for bounds checking - for unpack. */ - -index_type count_0 (const gfc_array_l1 * array) -{ - const GFC_LOGICAL_1 * restrict base; - index_type rank; - int kind; - int continue_loop; - index_type count[GFC_MAX_DIMENSIONS]; - index_type extent[GFC_MAX_DIMENSIONS]; - index_type sstride[GFC_MAX_DIMENSIONS]; - index_type result; - index_type n; - - rank = GFC_DESCRIPTOR_RANK (array); - kind = GFC_DESCRIPTOR_SIZE (array); - - base = array->base_addr; - - if (kind == 1 || kind == 2 || kind == 4 || kind == 8 -#ifdef HAVE_GFC_LOGICAL_16 - || kind == 16 -#endif - ) - { - if (base) - base = GFOR_POINTER_TO_L1 (base, kind); - } - else - internal_error (NULL, "Funny sized logical array in count_0"); - - for (n = 0; n < rank; n++) - { - sstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(array,n); - extent[n] = GFC_DESCRIPTOR_EXTENT(array,n); - count[n] = 0; - - if (extent[n] <= 0) - return 0; - } - - result = 0; - continue_loop = 1; - while (continue_loop) - { - if (*base) - result ++; - - count[0]++; - base += sstride[0]; - n = 0; - while (count[n] == extent[n]) - { - count[n] = 0; - base -= sstride[n] * extent[n]; - n++; - if (n == rank) - { - continue_loop = 0; - break; - } - else - { - count[n]++; - base += sstride[n]; - } - } - } - return result; -} diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c deleted file mode 100644 index b572c88153..0000000000 --- a/libgfortran/runtime/compile_options.c +++ /dev/null @@ -1,265 +0,0 @@ -/* Handling of compile-time options that influence the library. - Copyright (C) 2005-2017 Free Software Foundation, Inc. - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <signal.h> - - -/* Useful compile-time options will be stored in here. */ -compile_options_t compile_options; - -#ifndef LIBGFOR_MINIMAL -static volatile sig_atomic_t fatal_error_in_progress = 0; - - -/* Helper function for backtrace_handler to write information about the - received signal to stderr before actually giving the backtrace. */ -static void -show_signal (int signum) -{ - const char * name = NULL, * desc = NULL; - - switch (signum) - { -#if defined(SIGQUIT) - case SIGQUIT: - name = "SIGQUIT"; - desc = "Terminal quit signal"; - break; -#endif - - /* The following 4 signals are defined by C89. */ - case SIGILL: - name = "SIGILL"; - desc = "Illegal instruction"; - break; - - case SIGABRT: - name = "SIGABRT"; - desc = "Process abort signal"; - break; - - case SIGFPE: - name = "SIGFPE"; - desc = "Floating-point exception - erroneous arithmetic operation"; - break; - - case SIGSEGV: - name = "SIGSEGV"; - desc = "Segmentation fault - invalid memory reference"; - break; - -#if defined(SIGBUS) - case SIGBUS: - name = "SIGBUS"; - desc = "Access to an undefined portion of a memory object"; - break; -#endif - -#if defined(SIGSYS) - case SIGSYS: - name = "SIGSYS"; - desc = "Bad system call"; - break; -#endif - -#if defined(SIGTRAP) - case SIGTRAP: - name = "SIGTRAP"; - desc = "Trace/breakpoint trap"; - break; -#endif - -#if defined(SIGXCPU) - case SIGXCPU: - name = "SIGXCPU"; - desc = "CPU time limit exceeded"; - break; -#endif - -#if defined(SIGXFSZ) - case SIGXFSZ: - name = "SIGXFSZ"; - desc = "File size limit exceeded"; - break; -#endif - } - - if (name) - st_printf ("\nProgram received signal %s: %s.\n", name, desc); - else - st_printf ("\nProgram received signal %d.\n", signum); -} - - -/* A signal handler to allow us to output a backtrace. */ -void -backtrace_handler (int signum) -{ - /* Since this handler is established for more than one kind of signal, - it might still get invoked recursively by delivery of some other kind - of signal. Use a static variable to keep track of that. */ - if (fatal_error_in_progress) - raise (signum); - fatal_error_in_progress = 1; - - show_signal (signum); - estr_write ("\nBacktrace for this error:\n"); - show_backtrace (true); - - /* Now reraise the signal. We reactivate the signal's - default handling, which is to terminate the process. - We could just call exit or abort, - but reraising the signal sets the return status - from the process correctly. */ - signal (signum, SIG_DFL); - raise (signum); -} -#endif - -/* Set the usual compile-time options. */ -extern void set_options (int , int []); -export_proto(set_options); - -void -set_options (int num, int options[]) -{ - if (num >= 1) - compile_options.warn_std = options[0]; - if (num >= 2) - compile_options.allow_std = options[1]; - if (num >= 3) - compile_options.pedantic = options[2]; - if (num >= 4) - compile_options.backtrace = options[3]; - if (num >= 5) - compile_options.sign_zero = options[4]; - if (num >= 6) - compile_options.bounds_check = options[5]; - if (num >= 7) - compile_options.fpe_summary = options[6]; - -#ifndef LIBGFOR_MINIMAL - /* If backtrace is required, we set signal handlers on the POSIX - 2001 signals with core action. */ - if (compile_options.backtrace) - { -#if defined(SIGQUIT) - signal (SIGQUIT, backtrace_handler); -#endif - - /* The following 4 signals are defined by C89. */ - signal (SIGILL, backtrace_handler); - signal (SIGABRT, backtrace_handler); - signal (SIGFPE, backtrace_handler); - signal (SIGSEGV, backtrace_handler); - -#if defined(SIGBUS) - signal (SIGBUS, backtrace_handler); -#endif - -#if defined(SIGSYS) - signal (SIGSYS, backtrace_handler); -#endif - -#if defined(SIGTRAP) - signal (SIGTRAP, backtrace_handler); -#endif - -#if defined(SIGXCPU) - signal (SIGXCPU, backtrace_handler); -#endif - -#if defined(SIGXFSZ) - signal (SIGXFSZ, backtrace_handler); -#endif - } -#endif -} - - -/* Default values for the compile-time options. Keep in sync with - gcc/fortran/options.c (gfc_init_options). */ -void -init_compile_options (void) -{ - compile_options.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY; - compile_options.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL - | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 - | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY; - compile_options.pedantic = 0; - compile_options.backtrace = 0; - compile_options.sign_zero = 1; - compile_options.fpe_summary = 0; -} - -/* Function called by the front-end to tell us the - default for unformatted data conversion. */ - -extern void set_convert (int); -export_proto (set_convert); - -void -set_convert (int conv) -{ - compile_options.convert = conv; -} - -extern void set_record_marker (int); -export_proto (set_record_marker); - - -void -set_record_marker (int val) -{ - - switch(val) - { - case 4: - compile_options.record_marker = sizeof (GFC_INTEGER_4); - break; - - case 8: - compile_options.record_marker = sizeof (GFC_INTEGER_8); - break; - - default: - runtime_error ("Invalid value for record marker"); - break; - } -} - -extern void set_max_subrecord_length (int); -export_proto (set_max_subrecord_length); - -void set_max_subrecord_length(int val) -{ - if (val > GFC_MAX_SUBRECORD_LENGTH || val < 1) - { - runtime_error ("Invalid value for maximum subrecord length"); - return; - } - - compile_options.max_subrecord_length = val; -} diff --git a/libgfortran/runtime/convert_char.c b/libgfortran/runtime/convert_char.c deleted file mode 100644 index 8e228f2b77..0000000000 --- a/libgfortran/runtime/convert_char.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Runtime conversion of strings from one character kind to another. - Copyright (C) 2008-2017 Free Software Foundation, Inc. - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - - -extern void convert_char1_to_char4 (gfc_char4_t **, gfc_charlen_type, - const unsigned char *); -export_proto(convert_char1_to_char4); - -extern void convert_char4_to_char1 (unsigned char **, gfc_charlen_type, - const gfc_char4_t *); -export_proto(convert_char4_to_char1); - - -void -convert_char1_to_char4 (gfc_char4_t **dst, gfc_charlen_type len, - const unsigned char *src) -{ - gfc_charlen_type i, l; - - l = len > 0 ? len : 0; - *dst = xmallocarray ((l + 1), sizeof (gfc_char4_t)); - - for (i = 0; i < l; i++) - (*dst)[i] = src[i]; - - (*dst)[l] = '\0'; -} - - -void -convert_char4_to_char1 (unsigned char **dst, gfc_charlen_type len, - const gfc_char4_t *src) -{ - gfc_charlen_type i, l; - - l = len > 0 ? len : 0; - *dst = xmalloc (l + 1); - - for (i = 0; i < l; i++) - (*dst)[i] = src[i]; - - (*dst)[l] = '\0'; -} diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c deleted file mode 100644 index bf02188ede..0000000000 --- a/libgfortran/runtime/environ.c +++ /dev/null @@ -1,687 +0,0 @@ -/* Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Andy Vaught - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - -#include <string.h> -#include <strings.h> -#include <ctype.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - - -/* Implementation of secure_getenv() for targets where it is not - provided. */ - -#ifdef FALLBACK_SECURE_GETENV -char * -secure_getenv (const char *name) -{ - if ((getuid () == geteuid ()) && (getgid () == getegid ())) - return getenv (name); - else - return NULL; -} -#endif - - - -/* Examine the environment for controlling aspects of the program's - execution. Our philosophy here that the environment should not prevent - the program from running, so any invalid value will be ignored. */ - - -options_t options; - -typedef struct variable -{ - const char *name; - int default_value; - int *var; - void (*init) (struct variable *); -} -variable; - -static void init_unformatted (variable *); - - -/* Initialize an integer environment variable. */ - -static void -init_integer (variable * v) -{ - char *p, *q; - - p = getenv (v->name); - if (p == NULL) - return; - - for (q = p; *q; q++) - if (!isdigit (*q) && (p != q || *q != '-')) - return; - - *v->var = atoi (p); -} - - -/* Initialize an integer environment variable which has to be positive. */ - -static void -init_unsigned_integer (variable * v) -{ - char *p, *q; - - p = getenv (v->name); - if (p == NULL) - return; - - for (q = p; *q; q++) - if (!isdigit (*q)) - return; - - *v->var = atoi (p); -} - - -/* Initialize a boolean environment variable. We only look at the first - letter of the value. */ - -static void -init_boolean (variable * v) -{ - char *p; - - p = getenv (v->name); - if (p == NULL) - return; - - if (*p == '1' || *p == 'Y' || *p == 'y') - *v->var = 1; - else if (*p == '0' || *p == 'N' || *p == 'n') - *v->var = 0; -} - - -/* Initialize a list output separator. It may contain any number of spaces - and at most one comma. */ - -static void -init_sep (variable * v) -{ - int seen_comma; - char *p; - - p = getenv (v->name); - if (p == NULL) - goto set_default; - - options.separator = p; - options.separator_len = strlen (p); - - /* Make sure the separator is valid */ - - if (options.separator_len == 0) - goto set_default; - seen_comma = 0; - - while (*p) - { - if (*p == ',') - { - if (seen_comma) - goto set_default; - seen_comma = 1; - p++; - continue; - } - - if (*p++ != ' ') - goto set_default; - } - - return; - -set_default: - options.separator = " "; - options.separator_len = 1; -} - - -static variable variable_table[] = { - - /* Unit number that will be preconnected to standard input */ - { "GFORTRAN_STDIN_UNIT", GFC_STDIN_UNIT_NUMBER, &options.stdin_unit, - init_integer }, - - /* Unit number that will be preconnected to standard output */ - { "GFORTRAN_STDOUT_UNIT", GFC_STDOUT_UNIT_NUMBER, &options.stdout_unit, - init_integer }, - - /* Unit number that will be preconnected to standard error */ - { "GFORTRAN_STDERR_UNIT", GFC_STDERR_UNIT_NUMBER, &options.stderr_unit, - init_integer }, - - /* If TRUE, all output will be unbuffered */ - { "GFORTRAN_UNBUFFERED_ALL", 0, &options.all_unbuffered, init_boolean }, - - /* If TRUE, output to preconnected units will be unbuffered */ - { "GFORTRAN_UNBUFFERED_PRECONNECTED", 0, &options.unbuffered_preconnected, - init_boolean }, - - /* Whether to print filename and line number on runtime error */ - { "GFORTRAN_SHOW_LOCUS", 1, &options.locus, init_boolean }, - - /* Print optional plus signs in numbers where permitted */ - { "GFORTRAN_OPTIONAL_PLUS", 0, &options.optional_plus, init_boolean }, - - /* Default maximum record length for sequential files */ - { "GFORTRAN_DEFAULT_RECL", DEFAULT_RECL, &options.default_recl, - init_unsigned_integer }, - - /* Separator to use when writing list output */ - { "GFORTRAN_LIST_SEPARATOR", 0, NULL, init_sep }, - - /* Set the default data conversion for unformatted I/O */ - { "GFORTRAN_CONVERT_UNIT", 0, 0, init_unformatted }, - - /* Print out a backtrace if possible on runtime error */ - { "GFORTRAN_ERROR_BACKTRACE", -1, &options.backtrace, init_boolean }, - - { NULL, 0, NULL, NULL } -}; - - -/* Initialize most runtime variables from - * environment variables. */ - -void -init_variables (void) -{ - variable *v; - - for (v = variable_table; v->name; v++) - { - if (v->var) - *v->var = v->default_value; - v->init (v); - } -} - - -/* This is the handling of the GFORTRAN_CONVERT_UNITS environment variable. - It is called from environ.c to parse this variable, and from - open.c to determine if the user specified a default for an - unformatted file. - The syntax of the environment variable is, in bison grammar: - - GFORTRAN_CONVERT_UNITS: mode | mode ';' exception ; - mode: 'native' | 'swap' | 'big_endian' | 'little_endian' ; - exception: mode ':' unit_list | unit_list ; - unit_list: unit_spec | unit_list unit_spec ; - unit_spec: INTEGER | INTEGER '-' INTEGER ; -*/ - -/* Defines for the tokens. Other valid tokens are ',', ':', '-'. */ - - -#define NATIVE 257 -#define SWAP 258 -#define BIG 259 -#define LITTLE 260 -/* Some space for additional tokens later. */ -#define INTEGER 273 -#define END (-1) -#define ILLEGAL (-2) - -typedef struct -{ - int unit; - unit_convert conv; -} exception_t; - - -static char *p; /* Main character pointer for parsing. */ -static char *lastpos; /* Auxiliary pointer, for backing up. */ -static int unit_num; /* The last unit number read. */ -static int unit_count; /* The number of units found. */ -static int do_count; /* Parsing is done twice - first to count the number - of units, then to fill in the table. This - variable controls what to do. */ -static exception_t *elist; /* The list of exceptions to the default. This is - sorted according to unit number. */ -static int n_elist; /* Number of exceptions to the default. */ - -static unit_convert endian; /* Current endianness. */ - -static unit_convert def; /* Default as specified (if any). */ - -/* Search for a unit number, using a binary search. The - first argument is the unit number to search for. The second argument - is a pointer to an index. - If the unit number is found, the function returns 1, and the index - is that of the element. - If the unit number is not found, the function returns 0, and the - index is the one where the element would be inserted. */ - -static int -search_unit (int unit, int *ip) -{ - int low, high, mid; - - if (n_elist == 0) - { - *ip = 0; - return 0; - } - - low = 0; - high = n_elist - 1; - - do - { - mid = (low + high) / 2; - if (unit == elist[mid].unit) - { - *ip = mid; - return 1; - } - else if (unit > elist[mid].unit) - low = mid + 1; - else - high = mid - 1; - } while (low <= high); - - if (unit > elist[mid].unit) - *ip = mid + 1; - else - *ip = mid; - - return 0; -} - -/* This matches a keyword. If it is found, return the token supplied, - otherwise return ILLEGAL. */ - -static int -match_word (const char *word, int tok) -{ - int res; - - if (strncasecmp (p, word, strlen (word)) == 0) - { - p += strlen (word); - res = tok; - } - else - res = ILLEGAL; - return res; -} - -/* Match an integer and store its value in unit_num. This only works - if p actually points to the start of an integer. The caller has - to ensure this. */ - -static int -match_integer (void) -{ - unit_num = 0; - while (isdigit (*p)) - unit_num = unit_num * 10 + (*p++ - '0'); - return INTEGER; -} - -/* This reads the next token from the GFORTRAN_CONVERT_UNITS variable. - Returned values are the different tokens. */ - -static int -next_token (void) -{ - int result; - - lastpos = p; - switch (*p) - { - case '\0': - result = END; - break; - - case ':': - case ',': - case '-': - case ';': - result = *p; - p++; - break; - - case 'b': - case 'B': - result = match_word ("big_endian", BIG); - break; - - case 'l': - case 'L': - result = match_word ("little_endian", LITTLE); - break; - - case 'n': - case 'N': - result = match_word ("native", NATIVE); - break; - - case 's': - case 'S': - result = match_word ("swap", SWAP); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - result = match_integer (); - break; - - default: - result = ILLEGAL; - break; - } - return result; -} - -/* Back up the last token by setting back the character pointer. */ - -static void -push_token (void) -{ - p = lastpos; -} - -/* This is called when a unit is identified. If do_count is nonzero, - increment the number of units by one. If do_count is zero, - put the unit into the table. */ - -static void -mark_single (int unit) -{ - int i,j; - - if (do_count) - { - unit_count++; - return; - } - if (search_unit (unit, &i)) - { - elist[i].conv = endian; - } - else - { - for (j=n_elist-1; j>=i; j--) - elist[j+1] = elist[j]; - - n_elist += 1; - elist[i].unit = unit; - elist[i].conv = endian; - } -} - -/* This is called when a unit range is identified. If do_count is - nonzero, increase the number of units. If do_count is zero, - put the unit into the table. */ - -static void -mark_range (int unit1, int unit2) -{ - int i; - if (do_count) - unit_count += abs (unit2 - unit1) + 1; - else - { - if (unit2 < unit1) - for (i=unit2; i<=unit1; i++) - mark_single (i); - else - for (i=unit1; i<=unit2; i++) - mark_single (i); - } -} - -/* Parse the GFORTRAN_CONVERT_UNITS variable. This is called - twice, once to count the units and once to actually mark them in - the table. When counting, we don't check for double occurrences - of units. */ - -static int -do_parse (void) -{ - int tok; - int unit1; - int continue_ulist; - char *start; - - unit_count = 0; - - start = p; - - /* Parse the string. First, let's look for a default. */ - tok = next_token (); - switch (tok) - { - case NATIVE: - endian = GFC_CONVERT_NATIVE; - break; - - case SWAP: - endian = GFC_CONVERT_SWAP; - break; - - case BIG: - endian = GFC_CONVERT_BIG; - break; - - case LITTLE: - endian = GFC_CONVERT_LITTLE; - break; - - case INTEGER: - /* A leading digit means that we are looking at an exception. - Reset the position to the beginning, and continue processing - at the exception list. */ - p = start; - goto exceptions; - break; - - case END: - goto end; - break; - - default: - goto error; - break; - } - - tok = next_token (); - switch (tok) - { - case ';': - def = endian; - break; - - case ':': - /* This isn't a default after all. Reset the position to the - beginning, and continue processing at the exception list. */ - p = start; - goto exceptions; - break; - - case END: - def = endian; - goto end; - break; - - default: - goto error; - break; - } - - exceptions: - - /* Loop over all exceptions. */ - while(1) - { - tok = next_token (); - switch (tok) - { - case NATIVE: - if (next_token () != ':') - goto error; - endian = GFC_CONVERT_NATIVE; - break; - - case SWAP: - if (next_token () != ':') - goto error; - endian = GFC_CONVERT_SWAP; - break; - - case LITTLE: - if (next_token () != ':') - goto error; - endian = GFC_CONVERT_LITTLE; - break; - - case BIG: - if (next_token () != ':') - goto error; - endian = GFC_CONVERT_BIG; - break; - - case INTEGER: - push_token (); - break; - - case END: - goto end; - break; - - default: - goto error; - break; - } - /* We arrive here when we want to parse a list of - numbers. */ - continue_ulist = 1; - do - { - tok = next_token (); - if (tok != INTEGER) - goto error; - - unit1 = unit_num; - tok = next_token (); - /* The number can be followed by a - and another number, - which means that this is a unit range, a comma - or a semicolon. */ - if (tok == '-') - { - if (next_token () != INTEGER) - goto error; - - mark_range (unit1, unit_num); - tok = next_token (); - if (tok == END) - goto end; - else if (tok == ';') - continue_ulist = 0; - else if (tok != ',') - goto error; - } - else - { - mark_single (unit1); - switch (tok) - { - case ';': - continue_ulist = 0; - break; - - case ',': - break; - - case END: - goto end; - break; - - default: - goto error; - } - } - } while (continue_ulist); - } - end: - return 0; - error: - def = GFC_CONVERT_NONE; - return -1; -} - -void init_unformatted (variable * v) -{ - char *val; - val = getenv (v->name); - def = GFC_CONVERT_NONE; - n_elist = 0; - - if (val == NULL) - return; - do_count = 1; - p = val; - do_parse (); - if (do_count <= 0) - { - n_elist = 0; - elist = NULL; - } - else - { - elist = xmallocarray (unit_count, sizeof (exception_t)); - do_count = 0; - p = val; - do_parse (); - } -} - -/* Get the default conversion for for an unformatted unit. */ - -unit_convert -get_unformatted_convert (int unit) -{ - int i; - - if (elist == NULL) - return def; - else if (search_unit (unit, &i)) - return elist[i].conv; - else - return def; -} diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c deleted file mode 100644 index d2f879e84a..0000000000 --- a/libgfortran/runtime/error.c +++ /dev/null @@ -1,666 +0,0 @@ -/* Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Andy Vaught - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - - -#include "libgfortran.h" -#include <assert.h> -#include <string.h> -#include <errno.h> -#include <signal.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -/* <sys/time.h> has to be included before <sys/resource.h> to work - around PR 30518; otherwise, MacOS 10.3.9 headers are just broken. */ -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif - - -#include <locale.h> - -#ifdef HAVE_XLOCALE_H -#include <xlocale.h> -#endif - - -#ifdef __MINGW32__ -#define HAVE_GETPID 1 -#include <process.h> -#endif - - -/* Termination of a program: F2008 2.3.5 talks about "normal - termination" and "error termination". Normal termination occurs as - a result of e.g. executing the end program statement, and executing - the STOP statement. It includes the effect of the C exit() - function. - - Error termination is initiated when the ERROR STOP statement is - executed, when ALLOCATE/DEALLOCATE fails without STAT= being - specified, when some of the co-array synchronization statements - fail without STAT= being specified, and some I/O errors if - ERR/IOSTAT/END/EOR is not present, and finally EXECUTE_COMMAND_LINE - failure without CMDSTAT=. - - 2.3.5 also explains how co-images synchronize during termination. - - In libgfortran we have three ways of ending a program. exit(code) - is a normal exit; calling exit() also causes open units to be - closed. No backtrace or core dump is needed here. For error - termination, we have exit_error(status), which prints a backtrace - if backtracing is enabled, then exits. Finally, when something - goes terribly wrong, we have sys_abort() which tries to print the - backtrace if -fbacktrace is enabled, and then dumps core; whether a - core file is generated is system dependent. When aborting, we don't - flush and close open units, as program memory might be corrupted - and we'd rather risk losing dirty data in the buffers rather than - corrupting files on disk. - -*/ - -/* Error conditions. The tricky part here is printing a message when - * it is the I/O subsystem that is severely wounded. Our goal is to - * try and print something making the fewest assumptions possible, - * then try to clean up before actually exiting. - * - * The following exit conditions are defined: - * 0 Normal program exit. - * 1 Terminated because of operating system error. - * 2 Error in the runtime library - * 3 Internal error in runtime library - * - * Other error returns are reserved for the STOP statement with a numeric code. - */ - - -/* Write a null-terminated C string to standard error. This function - is async-signal-safe. */ - -ssize_t -estr_write (const char *str) -{ - return write (STDERR_FILENO, str, strlen (str)); -} - - -/* st_vprintf()-- vsnprintf-like function for error output. We use a - stack allocated buffer for formatting; since this function might be - called from within a signal handler, printing directly to stderr - with vfprintf is not safe since the stderr locking might lead to a - deadlock. */ - -#define ST_VPRINTF_SIZE 512 - -int -st_vprintf (const char *format, va_list ap) -{ - int written; - char buffer[ST_VPRINTF_SIZE]; - -#ifdef HAVE_VSNPRINTF - written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap); -#else - written = vsprintf(buffer, format, ap); - - if (written >= ST_VPRINTF_SIZE - 1) - { - /* The error message was longer than our buffer. Ouch. Because - we may have messed up things badly, report the error and - quit. */ -#define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n" - write (STDERR_FILENO, buffer, ST_VPRINTF_SIZE - 1); - write (STDERR_FILENO, ERROR_MESSAGE, strlen(ERROR_MESSAGE)); - sys_abort (); -#undef ERROR_MESSAGE - - } -#endif - - written = write (STDERR_FILENO, buffer, written); - return written; -} - - -int -st_printf (const char * format, ...) -{ - int written; - va_list ap; - va_start (ap, format); - written = st_vprintf (format, ap); - va_end (ap); - return written; -} - - -/* sys_abort()-- Terminate the program showing backtrace and dumping - core. */ - -void -sys_abort (void) -{ - /* If backtracing is enabled, print backtrace and disable signal - handler for ABRT. */ - if (options.backtrace == 1 - || (options.backtrace == -1 && compile_options.backtrace == 1)) - { - estr_write ("\nProgram aborted. Backtrace:\n"); - show_backtrace (false); - signal (SIGABRT, SIG_DFL); - } - - abort(); -} - - -/* Exit in case of error termination. If backtracing is enabled, print - backtrace, then exit. */ - -void -exit_error (int status) -{ - if (options.backtrace == 1 - || (options.backtrace == -1 && compile_options.backtrace == 1)) - { - estr_write ("\nError termination. Backtrace:\n"); - show_backtrace (false); - } - exit (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 * -gf_strerror (int errnum, - char * buf __attribute__((unused)), - size_t buflen __attribute__((unused))) -{ -#ifdef HAVE_STRERROR_L - locale_t myloc = newlocale (LC_CTYPE_MASK | LC_MESSAGES_MASK, "", - (locale_t) 0); - char *p; - if (myloc) - { - p = strerror_l (errnum, myloc); - freelocale (myloc); - } - else - /* newlocale might fail e.g. due to running out of memory, fall - back to the simpler strerror. */ - p = strerror (errnum); - return p; -#elif defined(HAVE_STRERROR_R) -#ifdef HAVE_USELOCALE - /* Some targets (Darwin at least) have the POSIX 2008 extended - locale functions, but not strerror_l. So reset the per-thread - locale here. */ - uselocale (LC_GLOBAL_LOCALE); -#endif - /* POSIX returns an "int", GNU a "char*". */ - return - __builtin_choose_expr (__builtin_classify_type (strerror_r (0, buf, 0)) - == 5, - /* GNU strerror_r() */ - strerror_r (errnum, buf, buflen), - /* POSIX strerror_r () */ - (strerror_r (errnum, buf, buflen), buf)); -#elif defined(HAVE_STRERROR_R_2ARGS) - strerror_r (errnum, buf); - return buf; -#else - /* strerror () is not necessarily thread-safe, but should at least - be available everywhere. */ - return strerror (errnum); -#endif -} - - -/* show_locus()-- Print a line number and filename describing where - * something went wrong */ - -void -show_locus (st_parameter_common *cmp) -{ - char *filename; - - if (!options.locus || cmp == NULL || cmp->filename == NULL) - return; - - if (cmp->unit > 0) - { - filename = filename_from_unit (cmp->unit); - - if (filename != NULL) - { - st_printf ("At line %d of file %s (unit = %d, file = '%s')\n", - (int) cmp->line, cmp->filename, (int) cmp->unit, filename); - free (filename); - } - else - { - st_printf ("At line %d of file %s (unit = %d)\n", - (int) cmp->line, cmp->filename, (int) cmp->unit); - } - return; - } - - st_printf ("At line %d of file %s\n", (int) cmp->line, cmp->filename); -} - - -/* recursion_check()-- It's possible for additional errors to occur - * during fatal error processing. We detect this condition here and - * exit with code 4 immediately. */ - -#define MAGIC 0x20DE8101 - -static void -recursion_check (void) -{ - static int magic = 0; - - /* Don't even try to print something at this point */ - if (magic == MAGIC) - sys_abort (); - - magic = MAGIC; -} - - -#define STRERR_MAXSZ 256 - -/* os_error()-- Operating system error. We get a message from the - * operating system, show it and leave. Some operating system errors - * are caught and processed by the library. If not, we come here. */ - -void -os_error (const char *message) -{ - char errmsg[STRERR_MAXSZ]; - recursion_check (); - estr_write ("Operating system error: "); - estr_write (gf_strerror (errno, errmsg, STRERR_MAXSZ)); - estr_write ("\n"); - estr_write (message); - estr_write ("\n"); - exit_error (1); -} -iexport(os_error); - - -/* void runtime_error()-- These are errors associated with an - * invalid fortran program. */ - -void -runtime_error (const char *message, ...) -{ - va_list ap; - - recursion_check (); - estr_write ("Fortran runtime error: "); - va_start (ap, message); - st_vprintf (message, ap); - va_end (ap); - estr_write ("\n"); - exit_error (2); -} -iexport(runtime_error); - -/* void runtime_error_at()-- These are errors associated with a - * run time error generated by the front end compiler. */ - -void -runtime_error_at (const char *where, const char *message, ...) -{ - va_list ap; - - recursion_check (); - estr_write (where); - estr_write ("\nFortran runtime error: "); - va_start (ap, message); - st_vprintf (message, ap); - va_end (ap); - estr_write ("\n"); - exit_error (2); -} -iexport(runtime_error_at); - - -void -runtime_warning_at (const char *where, const char *message, ...) -{ - va_list ap; - - estr_write (where); - estr_write ("\nFortran runtime warning: "); - va_start (ap, message); - st_vprintf (message, ap); - va_end (ap); - estr_write ("\n"); -} -iexport(runtime_warning_at); - - -/* void internal_error()-- These are this-can't-happen errors - * that indicate something deeply wrong. */ - -void -internal_error (st_parameter_common *cmp, const char *message) -{ - recursion_check (); - show_locus (cmp); - estr_write ("Internal Error: "); - estr_write (message); - estr_write ("\n"); - - /* This function call is here to get the main.o object file included - when linking statically. This works because error.o is supposed to - be always linked in (and the function call is in internal_error - because hopefully it doesn't happen too often). */ - stupid_function_name_for_static_linking(); - - exit_error (3); -} - - -/* translate_error()-- Given an integer error code, return a string - * describing the error. */ - -const char * -translate_error (int code) -{ - const char *p; - - switch (code) - { - case LIBERROR_EOR: - p = "End of record"; - break; - - case LIBERROR_END: - p = "End of file"; - break; - - case LIBERROR_OK: - p = "Successful return"; - break; - - case LIBERROR_OS: - p = "Operating system error"; - break; - - case LIBERROR_BAD_OPTION: - p = "Bad statement option"; - break; - - case LIBERROR_MISSING_OPTION: - p = "Missing statement option"; - break; - - case LIBERROR_OPTION_CONFLICT: - p = "Conflicting statement options"; - break; - - case LIBERROR_ALREADY_OPEN: - p = "File already opened in another unit"; - break; - - case LIBERROR_BAD_UNIT: - p = "Unattached unit"; - break; - - case LIBERROR_FORMAT: - p = "FORMAT error"; - break; - - case LIBERROR_BAD_ACTION: - p = "Incorrect ACTION specified"; - break; - - case LIBERROR_ENDFILE: - p = "Read past ENDFILE record"; - break; - - case LIBERROR_BAD_US: - p = "Corrupt unformatted sequential file"; - break; - - case LIBERROR_READ_VALUE: - p = "Bad value during read"; - break; - - case LIBERROR_READ_OVERFLOW: - p = "Numeric overflow on read"; - break; - - case LIBERROR_INTERNAL: - p = "Internal error in run-time library"; - break; - - case LIBERROR_INTERNAL_UNIT: - p = "Internal unit I/O error"; - break; - - case LIBERROR_DIRECT_EOR: - p = "Write exceeds length of DIRECT access record"; - break; - - case LIBERROR_SHORT_RECORD: - p = "I/O past end of record on unformatted file"; - break; - - case LIBERROR_CORRUPT_FILE: - p = "Unformatted file structure has been corrupted"; - break; - - case LIBERROR_INQUIRE_INTERNAL_UNIT: - p = "Inquire statement identifies an internal file"; - break; - - default: - p = "Unknown error code"; - break; - } - - return p; -} - - -/* generate_error()-- Come here when an error happens. This - * subroutine is called if it is possible to continue on after the error. - * If an IOSTAT or IOMSG variable exists, we set it. If IOSTAT or - * ERR labels are present, we return, otherwise we terminate the program - * after printing a message. The error code is always required but the - * message parameter can be NULL, in which case a string describing - * the most recent operating system error is used. */ - -void -generate_error (st_parameter_common *cmp, int family, const char *message) -{ - char errmsg[STRERR_MAXSZ]; - - /* If there was a previous error, don't mask it with another - error message, EOF or EOR condition. */ - - if ((cmp->flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_ERROR) - return; - - /* Set the error status. */ - if ((cmp->flags & IOPARM_HAS_IOSTAT)) - *cmp->iostat = (family == LIBERROR_OS) ? errno : family; - - if (message == NULL) - message = - (family == LIBERROR_OS) ? gf_strerror (errno, errmsg, STRERR_MAXSZ) : - translate_error (family); - - if (cmp->flags & IOPARM_HAS_IOMSG) - cf_strcpy (cmp->iomsg, cmp->iomsg_len, message); - - /* Report status back to the compiler. */ - cmp->flags &= ~IOPARM_LIBRETURN_MASK; - switch (family) - { - case LIBERROR_EOR: - cmp->flags |= IOPARM_LIBRETURN_EOR; - if ((cmp->flags & IOPARM_EOR)) - return; - break; - - case LIBERROR_END: - cmp->flags |= IOPARM_LIBRETURN_END; - if ((cmp->flags & IOPARM_END)) - return; - break; - - default: - cmp->flags |= IOPARM_LIBRETURN_ERROR; - if ((cmp->flags & IOPARM_ERR)) - return; - break; - } - - /* Return if the user supplied an iostat variable. */ - if ((cmp->flags & IOPARM_HAS_IOSTAT)) - return; - - /* Terminate the program */ - - recursion_check (); - show_locus (cmp); - estr_write ("Fortran runtime error: "); - estr_write (message); - estr_write ("\n"); - exit_error (2); -} -iexport(generate_error); - - -/* generate_warning()-- Similar to generate_error but just give a warning. */ - -void -generate_warning (st_parameter_common *cmp, const char *message) -{ - if (message == NULL) - message = " "; - - show_locus (cmp); - estr_write ("Fortran runtime warning: "); - estr_write (message); - estr_write ("\n"); -} - - -/* Whether, for a feature included in a given standard set (GFC_STD_*), - we should issue an error or a warning, or be quiet. */ - -notification -notification_std (int std) -{ - int warning; - - if (!compile_options.pedantic) - return NOTIFICATION_SILENT; - - warning = compile_options.warn_std & std; - if ((compile_options.allow_std & std) != 0 && !warning) - return NOTIFICATION_SILENT; - - return warning ? NOTIFICATION_WARNING : NOTIFICATION_ERROR; -} - - -/* Possibly issue a warning/error about use of a nonstandard (or deleted) - feature. An error/warning will be issued if the currently selected - standard does not contain the requested bits. */ - -bool -notify_std (st_parameter_common *cmp, int std, const char * message) -{ - int warning; - - if (!compile_options.pedantic) - return true; - - warning = compile_options.warn_std & std; - if ((compile_options.allow_std & std) != 0 && !warning) - return true; - - if (!warning) - { - recursion_check (); - show_locus (cmp); - estr_write ("Fortran runtime error: "); - estr_write (message); - estr_write ("\n"); - exit_error (2); - } - else - { - show_locus (cmp); - estr_write ("Fortran runtime warning: "); - estr_write (message); - estr_write ("\n"); - } - return false; -} diff --git a/libgfortran/runtime/fpu.c b/libgfortran/runtime/fpu.c deleted file mode 100644 index b00316f271..0000000000 --- a/libgfortran/runtime/fpu.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Set FPU mask. - Copyright (C) 2005-2017 Free Software Foundation, Inc. - Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - -/* We include the platform-dependent code. */ -#include "fpu-target.h" - -/* Function called by the front-end to tell us - when a FPE should be raised. */ -extern void set_fpe (int); -export_proto(set_fpe); - -void -set_fpe (int exceptions) -{ - options.fpe = exceptions; - set_fpu (); -} diff --git a/libgfortran/runtime/in_pack_generic.c b/libgfortran/runtime/in_pack_generic.c deleted file mode 100644 index c4b78e9210..0000000000 --- a/libgfortran/runtime/in_pack_generic.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Generic helper function for repacking arrays. - Copyright (C) 2003-2017 Free Software Foundation, Inc. - Contributed by Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <string.h> - -extern void *internal_pack (gfc_array_char *); -export_proto(internal_pack); - -void * -internal_pack (gfc_array_char * source) -{ - index_type count[GFC_MAX_DIMENSIONS]; - index_type extent[GFC_MAX_DIMENSIONS]; - index_type stride[GFC_MAX_DIMENSIONS]; - index_type stride0; - index_type dim; - index_type ssize; - const char *src; - char *dest; - void *destptr; - int n; - int packed; - index_type size; - index_type type_size; - - if (source->base_addr == NULL) - return NULL; - - type_size = GFC_DTYPE_TYPE_SIZE(source); - size = GFC_DESCRIPTOR_SIZE (source); - switch (type_size) - { - case GFC_DTYPE_INTEGER_1: - case GFC_DTYPE_LOGICAL_1: - case GFC_DTYPE_DERIVED_1: - return internal_pack_1 ((gfc_array_i1 *) source); - - case GFC_DTYPE_INTEGER_2: - case GFC_DTYPE_LOGICAL_2: - return internal_pack_2 ((gfc_array_i2 *) source); - - case GFC_DTYPE_INTEGER_4: - case GFC_DTYPE_LOGICAL_4: - return internal_pack_4 ((gfc_array_i4 *) source); - - case GFC_DTYPE_INTEGER_8: - case GFC_DTYPE_LOGICAL_8: - return internal_pack_8 ((gfc_array_i8 *) source); - -#if defined(HAVE_GFC_INTEGER_16) - case GFC_DTYPE_INTEGER_16: - case GFC_DTYPE_LOGICAL_16: - return internal_pack_16 ((gfc_array_i16 *) source); -#endif - case GFC_DTYPE_REAL_4: - return internal_pack_r4 ((gfc_array_r4 *) source); - - case GFC_DTYPE_REAL_8: - return internal_pack_r8 ((gfc_array_r8 *) source); - -/* FIXME: This here is a hack, which will have to be removed when - the array descriptor is reworked. Currently, we don't store the - kind value for the type, but only the size. Because on targets with - __float128, we have sizeof(logn double) == sizeof(__float128), - we cannot discriminate here and have to fall back to the generic - handling (which is suboptimal). */ -#if !defined(GFC_REAL_16_IS_FLOAT128) -# if defined (HAVE_GFC_REAL_10) - case GFC_DTYPE_REAL_10: - return internal_pack_r10 ((gfc_array_r10 *) source); -# endif - -# if defined (HAVE_GFC_REAL_16) - case GFC_DTYPE_REAL_16: - return internal_pack_r16 ((gfc_array_r16 *) source); -# endif -#endif - - case GFC_DTYPE_COMPLEX_4: - return internal_pack_c4 ((gfc_array_c4 *) source); - - case GFC_DTYPE_COMPLEX_8: - return internal_pack_c8 ((gfc_array_c8 *) source); - -/* FIXME: This here is a hack, which will have to be removed when - the array descriptor is reworked. Currently, we don't store the - kind value for the type, but only the size. Because on targets with - __float128, we have sizeof(logn double) == sizeof(__float128), - we cannot discriminate here and have to fall back to the generic - handling (which is suboptimal). */ -#if !defined(GFC_REAL_16_IS_FLOAT128) -# if defined (HAVE_GFC_COMPLEX_10) - case GFC_DTYPE_COMPLEX_10: - return internal_pack_c10 ((gfc_array_c10 *) source); -# endif - -# if defined (HAVE_GFC_COMPLEX_16) - case GFC_DTYPE_COMPLEX_16: - return internal_pack_c16 ((gfc_array_c16 *) source); -# endif -#endif - - case GFC_DTYPE_DERIVED_2: - if (GFC_UNALIGNED_2(source->base_addr)) - break; - else - return internal_pack_2 ((gfc_array_i2 *) source); - - case GFC_DTYPE_DERIVED_4: - if (GFC_UNALIGNED_4(source->base_addr)) - break; - else - return internal_pack_4 ((gfc_array_i4 *) source); - - case GFC_DTYPE_DERIVED_8: - if (GFC_UNALIGNED_8(source->base_addr)) - break; - else - return internal_pack_8 ((gfc_array_i8 *) source); - -#ifdef HAVE_GFC_INTEGER_16 - case GFC_DTYPE_DERIVED_16: - if (GFC_UNALIGNED_16(source->base_addr)) - break; - else - return internal_pack_16 ((gfc_array_i16 *) source); -#endif - - default: - break; - } - - dim = GFC_DESCRIPTOR_RANK (source); - ssize = 1; - packed = 1; - for (n = 0; n < dim; n++) - { - count[n] = 0; - stride[n] = GFC_DESCRIPTOR_STRIDE(source,n); - extent[n] = GFC_DESCRIPTOR_EXTENT(source,n); - if (extent[n] <= 0) - { - /* Do nothing. */ - packed = 1; - break; - } - - if (ssize != stride[n]) - packed = 0; - - ssize *= extent[n]; - } - - if (packed) - return source->base_addr; - - /* Allocate storage for the destination. */ - destptr = xmallocarray (ssize, size); - dest = (char *)destptr; - src = source->base_addr; - stride0 = stride[0] * size; - - while (src) - { - /* Copy the data. */ - memcpy(dest, src, size); - /* Advance to the next element. */ - dest += size; - src += stride0; - count[0]++; - /* Advance to the next source element. */ - n = 0; - while (count[n] == extent[n]) - { - /* When we get to the end of a dimension, reset it and increment - the next dimension. */ - count[n] = 0; - /* We could precalculate these products, but this is a less - frequently used path so probably not worth it. */ - src -= stride[n] * extent[n] * size; - n++; - if (n == dim) - { - src = NULL; - break; - } - else - { - count[n]++; - src += stride[n] * size; - } - } - } - return destptr; -} diff --git a/libgfortran/runtime/in_unpack_generic.c b/libgfortran/runtime/in_unpack_generic.c deleted file mode 100644 index 46b6dddb19..0000000000 --- a/libgfortran/runtime/in_unpack_generic.c +++ /dev/null @@ -1,239 +0,0 @@ -/* Generic helper function for repacking arrays. - Copyright (C) 2003-2017 Free Software Foundation, Inc. - Contributed by Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <string.h> - -extern void internal_unpack (gfc_array_char *, const void *); -export_proto(internal_unpack); - -void -internal_unpack (gfc_array_char * d, const void * s) -{ - index_type count[GFC_MAX_DIMENSIONS]; - index_type extent[GFC_MAX_DIMENSIONS]; - index_type stride[GFC_MAX_DIMENSIONS]; - index_type stride0; - index_type dim; - index_type dsize; - char *dest; - const char *src; - int n; - int size; - int type_size; - - dest = d->base_addr; - /* This check may be redundant, but do it anyway. */ - if (s == dest || !s) - return; - - type_size = GFC_DTYPE_TYPE_SIZE (d); - switch (type_size) - { - case GFC_DTYPE_INTEGER_1: - case GFC_DTYPE_LOGICAL_1: - case GFC_DTYPE_DERIVED_1: - internal_unpack_1 ((gfc_array_i1 *) d, (const GFC_INTEGER_1 *) s); - return; - - case GFC_DTYPE_INTEGER_2: - case GFC_DTYPE_LOGICAL_2: - internal_unpack_2 ((gfc_array_i2 *) d, (const GFC_INTEGER_2 *) s); - return; - - case GFC_DTYPE_INTEGER_4: - case GFC_DTYPE_LOGICAL_4: - internal_unpack_4 ((gfc_array_i4 *) d, (const GFC_INTEGER_4 *) s); - return; - - case GFC_DTYPE_INTEGER_8: - case GFC_DTYPE_LOGICAL_8: - internal_unpack_8 ((gfc_array_i8 *) d, (const GFC_INTEGER_8 *) s); - return; - -#if defined (HAVE_GFC_INTEGER_16) - case GFC_DTYPE_INTEGER_16: - case GFC_DTYPE_LOGICAL_16: - internal_unpack_16 ((gfc_array_i16 *) d, (const GFC_INTEGER_16 *) s); - return; -#endif - - case GFC_DTYPE_REAL_4: - internal_unpack_r4 ((gfc_array_r4 *) d, (const GFC_REAL_4 *) s); - return; - - case GFC_DTYPE_REAL_8: - internal_unpack_r8 ((gfc_array_r8 *) d, (const GFC_REAL_8 *) s); - return; - -/* FIXME: This here is a hack, which will have to be removed when - the array descriptor is reworked. Currently, we don't store the - kind value for the type, but only the size. Because on targets with - __float128, we have sizeof(logn double) == sizeof(__float128), - we cannot discriminate here and have to fall back to the generic - handling (which is suboptimal). */ -#if !defined(GFC_REAL_16_IS_FLOAT128) -# if defined(HAVE_GFC_REAL_10) - case GFC_DTYPE_REAL_10: - internal_unpack_r10 ((gfc_array_r10 *) d, (const GFC_REAL_10 *) s); - return; -# endif - -# if defined(HAVE_GFC_REAL_16) - case GFC_DTYPE_REAL_16: - internal_unpack_r16 ((gfc_array_r16 *) d, (const GFC_REAL_16 *) s); - return; -# endif -#endif - - case GFC_DTYPE_COMPLEX_4: - internal_unpack_c4 ((gfc_array_c4 *)d, (const GFC_COMPLEX_4 *)s); - return; - - case GFC_DTYPE_COMPLEX_8: - internal_unpack_c8 ((gfc_array_c8 *)d, (const GFC_COMPLEX_8 *)s); - return; - -/* FIXME: This here is a hack, which will have to be removed when - the array descriptor is reworked. Currently, we don't store the - kind value for the type, but only the size. Because on targets with - __float128, we have sizeof(logn double) == sizeof(__float128), - we cannot discriminate here and have to fall back to the generic - handling (which is suboptimal). */ -#if !defined(GFC_REAL_16_IS_FLOAT128) -# if defined(HAVE_GFC_COMPLEX_10) - case GFC_DTYPE_COMPLEX_10: - internal_unpack_c10 ((gfc_array_c10 *) d, (const GFC_COMPLEX_10 *) s); - return; -# endif - -# if defined(HAVE_GFC_COMPLEX_16) - case GFC_DTYPE_COMPLEX_16: - internal_unpack_c16 ((gfc_array_c16 *) d, (const GFC_COMPLEX_16 *) s); - return; -# endif -#endif - - case GFC_DTYPE_DERIVED_2: - if (GFC_UNALIGNED_2(d->base_addr) || GFC_UNALIGNED_2(s)) - break; - else - { - internal_unpack_2 ((gfc_array_i2 *) d, (const GFC_INTEGER_2 *) s); - return; - } - case GFC_DTYPE_DERIVED_4: - if (GFC_UNALIGNED_4(d->base_addr) || GFC_UNALIGNED_4(s)) - break; - else - { - internal_unpack_4 ((gfc_array_i4 *) d, (const GFC_INTEGER_4 *) s); - return; - } - - case GFC_DTYPE_DERIVED_8: - if (GFC_UNALIGNED_8(d->base_addr) || GFC_UNALIGNED_8(s)) - break; - else - { - internal_unpack_8 ((gfc_array_i8 *) d, (const GFC_INTEGER_8 *) s); - return; - } - -#ifdef HAVE_GFC_INTEGER_16 - case GFC_DTYPE_DERIVED_16: - if (GFC_UNALIGNED_16(d->base_addr) || GFC_UNALIGNED_16(s)) - break; - else - { - internal_unpack_16 ((gfc_array_i16 *) d, (const GFC_INTEGER_16 *) s); - return; - } -#endif - - default: - break; - } - - size = GFC_DESCRIPTOR_SIZE (d); - - dim = GFC_DESCRIPTOR_RANK (d); - dsize = 1; - for (n = 0; n < dim; n++) - { - count[n] = 0; - stride[n] = GFC_DESCRIPTOR_STRIDE(d,n); - extent[n] = GFC_DESCRIPTOR_EXTENT(d,n); - if (extent[n] <= 0) - return; - - if (dsize == stride[n]) - dsize *= extent[n]; - else - dsize = 0; - } - - src = s; - - if (dsize != 0) - { - memcpy (dest, src, dsize * size); - return; - } - - stride0 = stride[0] * size; - - while (dest) - { - /* Copy the data. */ - memcpy (dest, src, size); - /* Advance to the next element. */ - src += size; - dest += stride0; - count[0]++; - /* Advance to the next source element. */ - n = 0; - while (count[n] == extent[n]) - { - /* When we get to the end of a dimension, reset it and increment - the next dimension. */ - count[n] = 0; - /* We could precalculate these products, but this is a less - frequently used path so probably not worth it. */ - dest -= stride[n] * extent[n] * size; - n++; - if (n == dim) - { - dest = NULL; - break; - } - else - { - count[n]++; - dest += stride[n] * size; - } - } - } -} diff --git a/libgfortran/runtime/main.c b/libgfortran/runtime/main.c deleted file mode 100644 index 8d466d1bba..0000000000 --- a/libgfortran/runtime/main.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Andy Vaught and Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - - -/* Stupid function to be sure the constructor is always linked in, even - in the case of static linking. See PR libfortran/22298 for details. */ -void -stupid_function_name_for_static_linking (void) -{ - return; -} - -/* This will be 0 for little-endian - machines and 1 for big-endian machines. */ -int big_endian = 0; - - -/* Figure out endianness for this machine. */ - -static void -determine_endianness (void) -{ - union - { - GFC_LOGICAL_8 l8; - GFC_LOGICAL_4 l4[2]; - } u; - - u.l8 = 1; - if (u.l4[0]) - big_endian = 0; - else if (u.l4[1]) - big_endian = 1; - else - runtime_error ("Unable to determine machine endianness"); -} - - -static int argc_save; -static char **argv_save; - - -/* Set the saved values of the command line arguments. */ - -void -set_args (int argc, char **argv) -{ - argc_save = argc; - argv_save = argv; -} -iexport(set_args); - - -/* Retrieve the saved values of the command line arguments. */ - -void -get_args (int *argc, char ***argv) -{ - *argc = argc_save; - *argv = argv_save; -} - - -/* Initialize the runtime library. */ - -static void __attribute__((constructor)) -init (void) -{ - /* Figure out the machine endianness. */ - determine_endianness (); - - /* Must be first */ - init_variables (); - - init_units (); - - /* If (and only if) the user asked for it, set up the FPU state. */ - if (options.fpe != 0) - set_fpu (); - - init_compile_options (); -} - - -/* Cleanup the runtime library. */ - -static void __attribute__((destructor)) -cleanup (void) -{ - close_units (); -} diff --git a/libgfortran/runtime/memory.c b/libgfortran/runtime/memory.c deleted file mode 100644 index 98c59bb066..0000000000 --- a/libgfortran/runtime/memory.c +++ /dev/null @@ -1,102 +0,0 @@ -/* Memory management routines. - Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <errno.h> - -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)-1) -#endif - - -void * -xmalloc (size_t n) -{ - void *p; - - if (n == 0) - n = 1; - - p = malloc (n); - - if (p == NULL) - os_error ("Memory allocation failed"); - - return p; -} - - -void * -xmallocarray (size_t nmemb, size_t size) -{ - void *p; - - if (!nmemb || !size) - size = nmemb = 1; -#define HALF_SIZE_T (((size_t) 1) << (__CHAR_BIT__ * sizeof (size_t) / 2)) - else if (__builtin_expect ((nmemb | size) >= HALF_SIZE_T, 0) - && nmemb > SIZE_MAX / size) - { - errno = ENOMEM; - os_error ("Integer overflow in xmallocarray"); - } - - p = malloc (nmemb * size); - - if (!p) - os_error ("Memory allocation failed in xmallocarray"); - - return p; -} - - -/* calloc wrapper that aborts on error. */ - -void * -xcalloc (size_t nmemb, size_t size) -{ - if (!nmemb || !size) - nmemb = size = 1; - - void *p = calloc (nmemb, size); - if (!p) - os_error ("Allocating cleared memory failed"); - - return p; -} - - -void * -xrealloc (void *ptr, size_t size) -{ - if (size == 0) - size = 1; - - void *newp = realloc (ptr, size); - if (!newp) - os_error ("Memory allocation failure in xrealloc"); - - return newp; -} diff --git a/libgfortran/runtime/minimal.c b/libgfortran/runtime/minimal.c deleted file mode 100644 index 2ef4f15925..0000000000 --- a/libgfortran/runtime/minimal.c +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Andy Vaught and Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <string.h> - - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -/* Stupid function to be sure the constructor is always linked in, even - in the case of static linking. See PR libfortran/22298 for details. */ -void -stupid_function_name_for_static_linking (void) -{ - return; -} - -options_t options; - -/* This will be 0 for little-endian - machines and 1 for big-endian machines. - - Currently minimal libgfortran only runs on little-endian devices - which don't support constructors so this is just a constant. */ -int big_endian = 0; - -static int argc_save; -static char **argv_save; - -/* recursion_check()-- It's possible for additional errors to occur - * during fatal error processing. We detect this condition here and - * exit with code 4 immediately. */ - -#define MAGIC 0x20DE8101 - -static void -recursion_check (void) -{ - static int magic = 0; - - /* Don't even try to print something at this point */ - if (magic == MAGIC) - sys_abort (); - - magic = MAGIC; -} - - -/* os_error()-- Operating system error. We get a message from the - * operating system, show it and leave. Some operating system errors - * are caught and processed by the library. If not, we come here. */ - -void -os_error (const char *message) -{ - recursion_check (); - printf ("Operating system error: "); - printf ("%s\n", message); - exit (1); -} -iexport(os_error); - - -/* void runtime_error()-- These are errors associated with an - * invalid fortran program. */ - -void -runtime_error (const char *message, ...) -{ - va_list ap; - - recursion_check (); - printf ("Fortran runtime error: "); - va_start (ap, message); - vprintf (message, ap); - va_end (ap); - printf ("\n"); - exit (2); -} -iexport(runtime_error); - -/* void runtime_error_at()-- These are errors associated with a - * run time error generated by the front end compiler. */ - -void -runtime_error_at (const char *where, const char *message, ...) -{ - va_list ap; - - recursion_check (); - printf ("%s", where); - printf ("\nFortran runtime error: "); - va_start (ap, message); - vprintf (message, ap); - va_end (ap); - printf ("\n"); - exit (2); -} -iexport(runtime_error_at); - - -void -runtime_warning_at (const char *where, const char *message, ...) -{ - va_list ap; - - printf ("%s", where); - printf ("\nFortran runtime warning: "); - va_start (ap, message); - vprintf (message, ap); - va_end (ap); - printf ("\n"); -} -iexport(runtime_warning_at); - - -/* void internal_error()-- These are this-can't-happen errors - * that indicate something deeply wrong. */ - -void -internal_error (st_parameter_common *cmp, const char *message) -{ - recursion_check (); - printf ("Internal Error: "); - printf ("%s", message); - printf ("\n"); - - /* This function call is here to get the main.o object file included - when linking statically. This works because error.o is supposed to - be always linked in (and the function call is in internal_error - because hopefully it doesn't happen too often). */ - stupid_function_name_for_static_linking(); - - exit (3); -} - - -/* Set the saved values of the command line arguments. */ - -void -set_args (int argc, char **argv) -{ - argc_save = argc; - argv_save = argv; -} -iexport(set_args); - - -/* Retrieve the saved values of the command line arguments. */ - -void -get_args (int *argc, char ***argv) -{ - *argc = argc_save; - *argv = argv_save; -} - -/* sys_abort()-- Terminate the program showing backtrace and dumping - core. */ - -void -sys_abort (void) -{ - /* If backtracing is enabled, print backtrace and disable signal - handler for ABRT. */ - if (options.backtrace == 1 - || (options.backtrace == -1 && compile_options.backtrace == 1)) - { - printf ("\nProgram aborted.\n"); - } - - abort(); -} diff --git a/libgfortran/runtime/pause.c b/libgfortran/runtime/pause.c deleted file mode 100644 index 990d76f6c9..0000000000 --- a/libgfortran/runtime/pause.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Implementation of the PAUSE statement. - Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <string.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - - -static void -do_pause (void) -{ - char buff[4]; - estr_write ("To resume execution, type go. " - "Other input will terminate the job.\n"); - - fgets(buff, 4, stdin); - if (strncmp(buff, "go\n", 3) != 0) - stop_string ('\0', 0); - estr_write ("RESUMED\n"); -} - -/* A numeric PAUSE statement. */ - -extern void pause_numeric (GFC_INTEGER_4); -export_proto(pause_numeric); - -void -pause_numeric (GFC_INTEGER_4 code) -{ - st_printf ("PAUSE %d\n", (int) code); - do_pause (); -} - -/* A character string or blank PAUSE statement. */ - -extern void pause_string (char *string, GFC_INTEGER_4 len); -export_proto(pause_string); - -void -pause_string (char *string, GFC_INTEGER_4 len) -{ - estr_write ("PAUSE "); - ssize_t w = write (STDERR_FILENO, string, len); - (void) sizeof (w); /* Avoid compiler warning about not using write - return val. */ - estr_write ("\n"); - - do_pause (); -} diff --git a/libgfortran/runtime/select.c b/libgfortran/runtime/select.c deleted file mode 100644 index 6b421515a4..0000000000 --- a/libgfortran/runtime/select.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Implement the SELECT statement for character variables. - Copyright (C) 2008-2017 Free Software Foundation, Inc. - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - - -/* The string selection function is defined using a few generic macros - in select_inc.c, so we avoid code duplication between the various - character type kinds. */ - -#undef CHARTYPE -#define CHARTYPE char -#undef SUFFIX -#define SUFFIX(x) x - -#include "select_inc.c" - - -#undef CHARTYPE -#define CHARTYPE gfc_char4_t -#undef SUFFIX -#define SUFFIX(x) x ## _char4 - -#include "select_inc.c" - diff --git a/libgfortran/runtime/select_inc.c b/libgfortran/runtime/select_inc.c deleted file mode 100644 index 0a0880bf57..0000000000 --- a/libgfortran/runtime/select_inc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Implement the SELECT statement for character variables. - Copyright (C) 2008-2017 Free Software Foundation, Inc. - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#define select_string SUFFIX(select_string) -#define select_struct SUFFIX(select_struct) -#define compare_string SUFFIX(compare_string) - -typedef struct -{ - CHARTYPE *low; - gfc_charlen_type low_len; - CHARTYPE *high; - gfc_charlen_type high_len; - int address; -} -select_struct; - -extern int select_string (select_struct *table, int table_len, - const CHARTYPE *selector, - gfc_charlen_type selector_len); -export_proto(select_string); - - -/* select_string()-- Given a selector string and a table of - * select_struct structures, return the address to jump to. */ - -int -select_string (select_struct *table, int table_len, const CHARTYPE *selector, - gfc_charlen_type selector_len) -{ - select_struct *t; - int i, low, high, mid; - int default_jump = -1; - - if (table_len == 0) - return -1; - - /* Record the default address if present */ - - if (table->low == NULL && table->high == NULL) - { - default_jump = table->address; - - table++; - table_len--; - if (table_len == 0) - return default_jump; - } - - /* Try the high and low bounds if present. */ - - if (table->low == NULL) - { - if (compare_string (table->high_len, table->high, - selector_len, selector) >= 0) - return table->address; - - table++; - table_len--; - if (table_len == 0) - return default_jump; - } - - t = table + table_len - 1; - - if (t->high == NULL) - { - if (compare_string (t->low_len, t->low, selector_len, selector) <= 0) - return t->address; - - table_len--; - if (table_len == 0) - return default_jump; - } - - /* At this point, the only table entries are bounded entries. Find - the right entry with a binary chop. */ - - low = -1; - high = table_len; - - while (low + 1 < high) - { - mid = (low + high) / 2; - - t = table + mid; - i = compare_string (t->low_len, t->low, selector_len, selector); - - if (i == 0) - return t->address; - - if (i < 0) - low = mid; - else - high = mid; - } - - /* The string now lies between the low indeces of the now-adjacent - high and low entries. Because it is less than the low entry of - 'high', it can't be that one. If low is still -1, then no - entries match. Otherwise, we have to check the high entry of - 'low'. */ - - if (low == -1) - return default_jump; - - t = table + low; - if (compare_string (selector_len, selector, t->high_len, t->high) <= 0) - return t->address; - - return default_jump; -} diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c deleted file mode 100644 index 81f00d77a6..0000000000 --- a/libgfortran/runtime/stop.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Implementation of the STOP statement. - Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Paul Brook <paul@nowt.org> - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public -License as published by the Free Software Foundation; either -version 3 of the License, or (at your option) any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - - -/* Fortran 2008 demands: If any exception (14) is signaling on that image, the - processor shall issue a warning indicating which exceptions are signaling; - this warning shall be on the unit identified by the named constant - ERROR_UNIT (13.8.2.8). In line with other compilers, we do not report - inexact - and we optionally ignore underflow, cf. thread starting at - http://mailman.j3-fortran.org/pipermail/j3/2013-June/006452.html. */ - -static void -report_exception (void) -{ - int set_excepts; - - if (!compile_options.fpe_summary) - return; - - set_excepts = get_fpu_except_flags (); - if ((set_excepts & compile_options.fpe_summary) == 0) - return; - - estr_write ("Note: The following floating-point exceptions are signalling:"); - - if ((compile_options.fpe_summary & GFC_FPE_INVALID) - && (set_excepts & GFC_FPE_INVALID)) - estr_write (" IEEE_INVALID_FLAG"); - - if ((compile_options.fpe_summary & GFC_FPE_ZERO) - && (set_excepts & GFC_FPE_ZERO)) - estr_write (" IEEE_DIVIDE_BY_ZERO"); - - if ((compile_options.fpe_summary & GFC_FPE_OVERFLOW) - && (set_excepts & GFC_FPE_OVERFLOW)) - estr_write (" IEEE_OVERFLOW_FLAG"); - - if ((compile_options.fpe_summary & GFC_FPE_UNDERFLOW) - && (set_excepts & GFC_FPE_UNDERFLOW)) - estr_write (" IEEE_UNDERFLOW_FLAG"); - - if ((compile_options.fpe_summary & GFC_FPE_DENORMAL) - && (set_excepts & GFC_FPE_DENORMAL)) - estr_write (" IEEE_DENORMAL"); - - if ((compile_options.fpe_summary & GFC_FPE_INEXACT) - && (set_excepts & GFC_FPE_INEXACT)) - estr_write (" IEEE_INEXACT_FLAG"); - - estr_write ("\n"); -} - - -/* A numeric STOP statement. */ - -extern _Noreturn void stop_numeric (GFC_INTEGER_4); -export_proto(stop_numeric); - -void -stop_numeric (GFC_INTEGER_4 code) -{ - report_exception (); - st_printf ("STOP %d\n", (int)code); - exit (code); -} - - -/* A character string or blank STOP statement. */ - -void -stop_string (const char *string, GFC_INTEGER_4 len) -{ - report_exception (); - if (string) - { - estr_write ("STOP "); - (void) write (STDERR_FILENO, string, len); - estr_write ("\n"); - } - exit (0); -} - - -/* Per Fortran 2008, section 8.4: "Execution of a STOP statement initiates - normal termination of execution. Execution of an ERROR STOP statement - initiates error termination of execution." Thus, error_stop_string returns - a nonzero exit status code. */ - -extern _Noreturn void error_stop_string (const char *, GFC_INTEGER_4); -export_proto(error_stop_string); - -void -error_stop_string (const char *string, GFC_INTEGER_4 len) -{ - report_exception (); - estr_write ("ERROR STOP "); - (void) write (STDERR_FILENO, string, len); - estr_write ("\n"); - - exit_error (1); -} - - -/* A numeric ERROR STOP statement. */ - -extern _Noreturn void error_stop_numeric (GFC_INTEGER_4); -export_proto(error_stop_numeric); - -void -error_stop_numeric (GFC_INTEGER_4 code) -{ - report_exception (); - st_printf ("ERROR STOP %d\n", (int) code); - exit_error (code); -} diff --git a/libgfortran/runtime/string.c b/libgfortran/runtime/string.c deleted file mode 100644 index 332b42e682..0000000000 --- a/libgfortran/runtime/string.c +++ /dev/null @@ -1,214 +0,0 @@ -/* Copyright (C) 2002-2017 Free Software Foundation, Inc. - Contributed by Paul Brook - -This file is part of the GNU Fortran runtime library (libgfortran). - -Libgfortran is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -Libgfortran is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -#include "libgfortran.h" -#include <string.h> -#include <strings.h> - - -/* Given a fortran string, return its length exclusive of the trailing - spaces. */ - -gfc_charlen_type -fstrlen (const char *string, gfc_charlen_type len) -{ - for (; len > 0; len--) - if (string[len-1] != ' ') - break; - - return len; -} - - -/* Copy a Fortran string (not null-terminated, hence length arguments - for both source and destination strings. Returns the non-padded - length of the destination. */ - -gfc_charlen_type -fstrcpy (char *dest, gfc_charlen_type destlen, - const char *src, gfc_charlen_type srclen) -{ - if (srclen >= destlen) - { - /* This will truncate if too long. */ - memcpy (dest, src, destlen); - return destlen; - } - else - { - memcpy (dest, src, srclen); - /* Pad with spaces. */ - memset (&dest[srclen], ' ', destlen - srclen); - return srclen; - } -} - - -/* Copy a null-terminated C string to a non-null-terminated Fortran - string. Returns the non-padded length of the destination string. */ - -gfc_charlen_type -cf_strcpy (char *dest, gfc_charlen_type dest_len, const char *src) -{ - size_t src_len; - - src_len = strlen (src); - - if (src_len >= (size_t) dest_len) - { - /* This will truncate if too long. */ - memcpy (dest, src, dest_len); - return dest_len; - } - else - { - memcpy (dest, src, src_len); - /* Pad with spaces. */ - memset (&dest[src_len], ' ', dest_len - src_len); - return src_len; - } -} - - -#ifndef HAVE_STRNLEN -static size_t -strnlen (const char *s, size_t maxlen) -{ - for (size_t ii = 0; ii < maxlen; ii++) - { - if (s[ii] == '\0') - return ii; - } - return maxlen; -} -#endif - - -#ifndef HAVE_STRNDUP -static char * -strndup (const char *s, size_t n) -{ - size_t len = strnlen (s, n); - char *p = malloc (len + 1); - if (!p) - return NULL; - memcpy (p, s, len); - p[len] = '\0'; - return p; -} -#endif - - -/* Duplicate a non-null-terminated Fortran string to a malloced - null-terminated C string. */ - -char * -fc_strdup (const char *src, gfc_charlen_type src_len) -{ - gfc_charlen_type n = fstrlen (src, src_len); - char *p = strndup (src, n); - if (!p) - os_error ("Memory allocation failed in fc_strdup"); - return p; -} - - -/* Duplicate a non-null-terminated Fortran string to a malloced - null-terminated C string, without getting rid of trailing - blanks. */ - -char * -fc_strdup_notrim (const char *src, gfc_charlen_type src_len) -{ - char *p = strndup (src, src_len); - if (!p) - os_error ("Memory allocation failed in fc_strdup"); - return p; -} - - -/* Given a fortran string and an array of st_option structures, search through - the array to find a match. If the option is not found, we generate an error - if no default is provided. */ - -int -find_option (st_parameter_common *cmp, const char *s1, gfc_charlen_type s1_len, - const st_option * opts, const char *error_message) -{ - /* Strip trailing blanks from the Fortran string. */ - size_t len = (size_t) fstrlen (s1, s1_len); - - for (; opts->name; opts++) - if (len == strlen(opts->name) && strncasecmp (s1, opts->name, len) == 0) - return opts->value; - - generate_error (cmp, LIBERROR_BAD_OPTION, error_message); - - return -1; -} - - -/* 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. */ - -const char * -gfc_itoa (GFC_INTEGER_LARGEST n, char *buffer, size_t len) -{ - int negative; - char *p; - GFC_UINTEGER_LARGEST t; - - if (len < GFC_ITOA_BUF_SIZE) - sys_abort (); - - if (n == 0) - return "0"; - - negative = 0; - t = n; - if (n < 0) - { - negative = 1; - t = -n; /*must use unsigned to protect from overflow*/ - } - - p = buffer + GFC_ITOA_BUF_SIZE - 1; - *p = '\0'; - - while (t != 0) - { - *--p = '0' + (t % 10); - t /= 10; - } - - if (negative) - *--p = '-'; - return p; -} |