rts-slatec.c

     1  //!@file rts-slatec.c
     2  //!@author J. Marcel van der Veer
     3  //
     4  // !@section Copyright
     5  //
     6  // This file is part of VIF - vintage FORTRAN compiler.
     7  // Copyright 2020-2025 J. Marcel van der Veer <algol68g@xs4all.nl>.
     8  //
     9  //! @section License
    10  //
    11  // This program is free software; you can redistribute it and/or modify it 
    12  // under the terms of the GNU General Public License as published by the 
    13  // Free Software Foundation; either version 3 of the License, or 
    14  // (at your option) any later version.
    15  //
    16  // This program is distributed in the hope that it will be useful, but 
    17  // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
    18  // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
    19  // more details. You should have received a copy of the GNU General Public 
    20  // License along with this program. If not, see <http://www.gnu.org/licenses/>.
    21  
    22  //! @section Synopsis
    23  //!
    24  //! Runtime support for SLATEC subprograms.
    25  
    26  //!@brief SLATEC stubs for VIF, adapted to C.
    27  // SLATEC common mathematical library, version 4.1, July 1993.
    28  //
    29  // SLATEC was developed at US government research laboratories 
    30  // and is in the public domain.
    31  // Repository: http://www.netlib.org/slatec/
    32  
    33  #include <vif.h>
    34  
    35  // d1mach yields machine-dependent parameters for the 
    36  // local machine environment.
    37  //
    38  // d1mach(1) = b**(emin-1), the smallest positive magnitude. 
    39  // d1mach(2) = b**emax*(1 - b**(-t)), the largest magnitude. 
    40  // d1mach(3) = b**(-t), the smallest relative spacing. 
    41  // d1mach(4) = b**(1-t), the largest relative spacing. 
    42  // d1mach(5) = log10(b) 
    43  
    44  real_4 _r1mach (int_4 *i)
    45  {
    46    switch (*i) {
    47  //    r1mach(1) = b**(emin-1), the smallest positive magnitude. 
    48    case 1: return FLT_MIN;
    49  //    r1mach(2) = b**emax*(1 - b**(-t)), the largest magnitude. 
    50    case 2: return FLT_MAX;
    51  //    r1mach(3) = b**(-t), the smallest relative spacing. 
    52    case 3: return 0.5 * FLT_EPSILON;
    53  //    r1mach(4) = b**(1-t), the largest relative spacing. 
    54    case 4: return FLT_EPSILON;
    55  //    r1mach(5) = log10(b) 
    56    case 5: return M_LOG10_2;
    57  //
    58    default: return 0.0;
    59    }
    60  }
    61   
    62  real_8 _d1mach (int_4 *i)
    63  {
    64    switch (*i) {
    65  //    d1mach(1) = b**(emin-1), the smallest positive magnitude. 
    66    case 1: return DBL_MIN;
    67  //    d1mach(2) = b**emax*(1 - b**(-t)), the largest magnitude. 
    68    case 2: return DBL_MAX;
    69  //    d1mach(3) = b**(-t), the smallest relative spacing. 
    70    case 3: return 0.5 * DBL_EPSILON;
    71  //    d1mach(4) = b**(1-t), the largest relative spacing. 
    72    case 4: return DBL_EPSILON;
    73  //    d1mach(5) = log10(b) 
    74    case 5: return M_LOG10_2;
    75  //
    76    default: return 0.0;
    77    }
    78  }
    79  
    80  real_8 _dmach (int_4 *i)
    81  {
    82    return _d1mach (i);
    83  }
    84   
    85  // i1mach yields machine-dependent parameters for the 
    86  // local machine environment.
    87  //
    88  // i/o unit numbers: 
    89  //  i1mach(1) = the standard input unit. 
    90  //  i1mach(2) = the standard output unit. 
    91  //  i1mach(3) = the standard punch unit. 
    92  //  i1mach(4) = the standard error message unit. 
    93  //
    94  // words: 
    95  //  i1mach(5) = the number of bits per int_4 storage unit. 
    96  //  i1mach(6) = the number of characters per int_4 storage unit. 
    97  //
    98  // integers: 
    99  //  assume int_4s are represented in the s-digit, base-a form 
   100  //
   101  //             sign (x(s-1)*a**(s-1) + ... + x(1)*a + x(0) ) 
   102  //
   103  //             where 0 .le. x(i) .lt. a for i=0,...,s-1. 
   104  //  i1mach(7) = a, the base. 
   105  //  i1mach(8) = s, the number of base-a digits. 
   106  //  i1mach(9) = a**s - 1, the largest magnitude. 
   107  //
   108  // floating-point_4 numbers: 
   109  //  assume floating-point_4 numbers are represented in the t-digit, 
   110  //  base-b form 
   111  //             sign (b**e)*((x(1)/b) + ... + (x(t)/b**t) ) 
   112  //
   113  //             where 0 .le. x(i) .lt. b for i=1,...,t, 
   114  //             0 .lt. x(1), and emin .le. e .le. emax. 
   115  //  i1mach(10) = b, the base. 
   116  //
   117  // single-precision: 
   118  //  i1mach(11) = t, the number of base-b digits. 
   119  //  i1mach(12) = emin, the smallest exponent e. 
   120  //  i1mach(13) = emax, the largest exponent e. 
   121  //
   122  // double-precision: 
   123  //  i1mach(14) = t, the number of base-b digits. 
   124  //  i1mach(15) = emin, the smallest exponent e. 
   125  //  i1mach(16) = emax, the largest exponent e. 
   126  
   127  int_4 _i1mach (int_4 *i) 
   128  {
   129    switch(*i) {
   130  //  i1mach(1) = the standard input unit. 
   131  //  i1mach(2) = the standard output unit. 
   132  //  i1mach(3) = the standard punch unit. 
   133  //  i1mach(4) = the standard error message unit. 
   134    case  1: return STDF_IN;
   135    case  2: return STDF_OUT;
   136    case  3: return STDF_PUN;
   137    case  4: return STDF_ERR;
   138  //  i1mach(5) = the number of bits per int_4 storage unit. 
   139  //  i1mach(6) = the number of characters per int_4 storage unit. 
   140    case  5: return CHAR_BIT * sizeof (int_4);
   141    case  6: return sizeof (int_4);
   142  //  i1mach(7) = a, the base. 
   143  //  i1mach(8) = s, the number of base-a digits. 
   144  //  i1mach(9) = a**s - 1, the largest magnitude. 
   145    case  7: return 2;
   146    case  8: return CHAR_BIT * sizeof (int_4) - 1;
   147    case  9: return INT_MAX;
   148  //  i1mach(10) = b, the base. 
   149    case 10: return FLT_RADIX;
   150  //  i1mach(11) = t, the number of base-b digits. 
   151  //  i1mach(12) = emin, the smallest exponent e. 
   152  //  i1mach(13) = emax, the largest exponent e. 
   153    case 11: return FLT_MANT_DIG;
   154    case 12: return FLT_MIN_EXP;
   155    case 13: return FLT_MAX_EXP;
   156  //  i1mach(14) = t, the number of base-b digits. 
   157  //  i1mach(15) = emin, the smallest exponent e. 
   158  //  i1mach(16) = emax, the largest exponent e. 
   159    case 14: return DBL_MANT_DIG;
   160    case 15: return DBL_MIN_EXP;
   161    case 16: return DBL_MAX_EXP;
   162  //
   163    default: return 0;
   164    }
   165  }
   166  
   167  // amach yields machine-dependent parameters for the local environment.
   168  //
   169  // subroutine amach(mode, i, i1, r1, d1)
   170  
   171  int_4 _amach (int_4 _p_ mode_, int_4 _p_ i_, int_4 _p_ i1_, real_4 _p_ r1_, real_8 _p_ d1_)
   172  {
   173    if (*mode_ == 0) {
   174      *i1_ = _i1mach(i_);
   175    }
   176    else if (*mode_ == 1) {
   177      *r1_ = _r1mach(i_);
   178    }
   179    else {
   180      *d1_ = _d1mach(i_);
   181    }
   182    return 0;
   183  }
   184  
   185  // SLATEC message routine stubs.
   186  
   187  int_4 _j4save (int_4 _p_ iwhich, int_4 _p_ ivalue, logical_4 _p_ iset)
   188  {
   189  // J4SAVE saves and recalls several global variables needed
   190  // by the library error handling routines.
   191  //
   192  // Description of Parameters
   193  //      --Input--
   194  //        IWHICH - Index of item desired.
   195  //                = 1 Refers to current error number.
   196  //                = 2 Refers to current error control flag.
   197  //                = 3 Refers to current unit number to which error
   198  //                    messages are to be sent.  (0 means use standard.)
   199  //                = 4 Refers to the maximum number of times any
   200  //                     message is to be printed (as set by XERMAX).
   201  //                = 5 Refers to the total number of units to which
   202  //                     each error message is to be written.
   203  //                = 6 Refers to the 2nd unit for error messages
   204  //                = 7 Refers to the 3rd unit for error messages
   205  //                = 8 Refers to the 4th unit for error messages
   206  //                = 9 Refers to the 5th unit for error messages
   207  //        IVALUE - The value to be set for the IWHICH-th parameter,
   208  //                 if ISET is .TRUE. .
   209  //        ISET   - If ISET=.TRUE., the IWHICH-th parameter will BE
   210  //                 given the value, IVALUE.  If ISET=.FALSE., the
   211  //                 IWHICH-th parameter will be unchanged, and IVALUE
   212  //                 is a dummy parameter.
   213  //      --Output--
   214  //        The (old) value of the IWHICH-th parameter will be returned
   215  //        in the function value, J4SAVE.
   216  //
   217    static int_4 iparam[9] = {0, 2, 0, 10, 1, 0, 0, 0, 0};
   218    int_4 curr = iparam[*iwhich - 1];
   219    if (*iset) {
   220      iparam[*iwhich - 1] = *ivalue;
   221    }
   222    return curr;
   223  }
   224  
   225  static int_4 __kontrl__ = 0;
   226  
   227  int_4 _xerclr (void)
   228  {
   229  // This routine simply resets the current error number to zero.
   230  // This may be necessary in order to determine that a certain
   231  // error has occurred again since the last time NUMXER was
   232  // referenced.
   233    errno = 0;
   234    return 0;
   235  }
   236  
   237  int_4 _xerdmp (void)
   238  {
   239  // XERDMP prints the error tables, then clears them.
   240    return EXIT_SUCCESS;
   241  }
   242  
   243  int_4 _xermax (int_4 _p_ _max)
   244  {
   245  // XERMAX sets the maximum number of times any message is to be printed.
   246  // That is, non-fatal messages are not to be printed after they have occurred 
   247  // MAX times. Such non-fatal messages may be printed less than MAX times even
   248  // if they occur MAX times, if error suppression mode (KONTRL=0) is ever in 
   249  // MAX - the maximum number of times any one message is to be printed.
   250    (void) _max;
   251    return EXIT_SUCCESS;
   252  }
   253  
   254  int_4 _xgetf (int_4 _p_ kontrl)
   255  {
   256  // XGETF returns the current value of the error control flag
   257  // in KONTRL.  See subroutine XSETF for flag value meanings.
   258  // (KONTRL is an output parameter only.)
   259  //
   260    *kontrl = __kontrl__;
   261    return EXIT_SUCCESS;
   262  }
   263  
   264  int_4 _xsetf (int_4 _p_ kontrl)
   265  {
   266  // XSETF sets the error control flag value to KONTRL.
   267  // (KONTRL is an input parameter only.)
   268  // The following table shows how each message is treated,
   269  // depending on the values of KONTRL and LEVEL.  (See XERMSG
   270  // for description of LEVEL.)
   271  
   272  // If KONTRL is zero or negative, no information other than the
   273  // message itself (including numeric values, if any) will be
   274  // printed.  If KONTRL is positive, introductory messages,
   275  // trace-backs, etc., will be printed in addition to the message.
   276  
   277  //   ABS(KONTRL)
   278  // LEVEL        0              1              2
   279  // value
   280  //  2        fatal          fatal          fatal
   281  
   282  //  1     not printed      printed         fatal
   283  
   284  //  0     not printed      printed        printed
   285  
   286  // -1     not printed      printed        printed
   287  //                       only           only
   288  //                       once           once
   289    __kontrl__ = *kontrl;
   290    return 0;
   291  }
   292  
   293  int_4 _xgetun (int_4 _p_ iunit)
   294  {
   295  // XGETUN gets the (first) output file to which error messages
   296  // are being sent.  To find out if more than one file is being
   297  // used, one must use the XGETUA routine.
   298    (void) iunit;
   299    return EXIT_SUCCESS;
   300  }
   301  
   302  
   303  int_4 xsetun (int_4 _p_ iunit)
   304  {
   305  // XSETUN sets the output file to which error messages are to
   306  // be sent.  Only one file will be used.  See XSETUA for
   307  // how to declare more than one file.
   308    (void) iunit;
   309    return EXIT_SUCCESS;
   310  }
   311  
   312  int_4 xsetua (int_4 _p_ iunita, int_4 _p_ n)
   313  {
   314  // XSETUA may be called to declare a list of up to five
   315  // logical units, each of which is to receive a copy of
   316  // each error message processed by this package.
   317  // The purpose of XSETUA is to allow simultaneous printing
   318  // of each error message on, say, a main output file,
   319  // an interactive terminal, and other files such as graphics
   320  // communication files.
   321    (void) iunita;
   322    (void) n;
   323    return EXIT_SUCCESS;
   324  }
   325  
   326  int_4 _xgetua (int_4 _p_ iunita, int_4 _p_ n)
   327  {
   328  // XGETUA may be called to determine the unit number or numbers
   329  // to which error messages are being sent.
   330  // These unit numbers may have been set by a call to XSETUN,
   331  // or a call to XSETUA, or may be a default value.
   332    (void) iunita;
   333    (void) n;
   334    return EXIT_SUCCESS;
   335  }
   336  
   337  int_4 _xerprn (char _p_ prefix_, int_4 _p_ npref_, char _p_ messg_, int_4 _p_ nwrap_)
   338  {
   339  // This routine sends one or more lines to each of the (up to five)
   340  // logical units to which error messages are to be sent.  This routine
   341  // is called several times by XERMSG, sometimes with a single line to
   342  // print and sometimes with a (potentially very long) message that may
   343  // wrap around into multiple lines.
   344  //
   345  // PREFIX  Input argument of type CHARACTER.  This argument contains
   346  //         characters to be put at the beginning of each line before
   347  //         the body of the message.  No more than 16 characters of
   348  //         PREFIX will be used.
   349  //
   350  // NPREF   Input argument of type INTEGER.  This argument is the number
   351  //         of characters to use from PREFIX.  If it is negative, the
   352  //         intrinsic function LEN is used to determine its length.  If
   353  //         it is zero, PREFIX is not used.  If it exceeds 16 or if
   354  //         LEN(PREFIX) exceeds 16, only the first 16 characters will be
   355  //         used.  If NPREF is positive and the length of PREFIX is less
   356  //         than NPREF, a copy of PREFIX extended with blanks to length
   357  //         NPREF will be used.
   358  //
   359  // MESSG   Input argument of type CHARACTER.  This is the text of a
   360  //         message to be printed.  If it is a long message, it will be
   361  //         broken into pieces for printing on multiple lines.  Each line
   362  //         will start with the appropriate prefix and be followed by a
   363  //         piece of the message.  NWRAP is the number of characters per
   364  //         piece; that is, after each NWRAP characters, we break and
   365  //         start a new line.  In addition the characters '$$' embedded
   366  //         in MESSG are a sentinel for a new line.  The counting of
   367  //         characters up to NWRAP starts over for each new line.  The
   368  //         value of NWRAP typically used by XERMSG is 72 since many
   369  //         older error messages in the SLATEC Library are laid out to
   370  //         rely on wrap-around every 72 characters.
   371  //
   372  // NWRAP   Input argument of type INTEGER.  This gives the maximum size
   373  //         piece into which to break MESSG for printing on multiple
   374  //         lines.  An embedded '$$' ends a line, and the count restarts
   375  //         at the following character.  If a line break does not occur
   376  //         on a blank (it would split a word) that word is moved to the
   377  //         next line.  Values of NWRAP less than 16 will be treated as
   378  //         16.  Values of NWRAP greater than 132 will be treated as 132.
   379  //         The actual line length will be NPREF + NWRAP after NPREF has
   380  //         been adjusted to fall between 0 and 16 and NWRAP has been
   381  //         adjusted to fall between 16 and 132.
   382    (void) prefix_;
   383    (void) npref_;
   384    (void) messg_;
   385    (void) nwrap_;
   386    return EXIT_SUCCESS;
   387  }
   388  
   389  int_4 _xersve (char _p_ librar_, char _p_ subrou_, char _p_ messg_, int_4 _p_ kflag_, int_4 _p_ nerr_, int_4 _p_ level_, int_4 _p_ icount_)
   390  {
   391  // Record that an error has occurred and possibly dump and clear the tables.
   392    (void) librar_;
   393    (void) subrou_;
   394    (void) messg_;
   395    (void) kflag_;
   396    (void) nerr_;
   397    (void) level_;
   398    (void) icount_;
   399    return EXIT_SUCCESS;
   400  }
   401  
   402  int_4 _xermsg (char _p_ librar, char _p_ subrou, char _p_ messg, int_4 _p_ nerr, int_4 _p_ level)
   403  {
   404  // XERMSG processes a diagnostic message in a manner determined by the
   405  // value of LEVEL and the current value of the library error control
   406  // flag, KONTRL.  See subroutine XSETF for details.
   407  
   408  // LIBRAR   A character constant (or character variable) with the name
   409  //       of the library.  This will be 'SLATE' for the SLATEC
   410  //       ommon Math Library.  The error handling package is
   411  //       general enough to be used by many libraries
   412  //       simultaneously, so it is desirable for the routine that
   413  //       detects and reports an error to identify the library name
   414  //       as well as the routine name.
   415  
   416  // SUBROU   A character constant (or character variable) with the name
   417  //       of the routine that detected the error.  Usually it is the
   418  //       name of the routine that is calling XERMSG.  There are
   419  //       some instances where a user callable library routine calls
   420  //       lower level subsidiary routines where the error is
   421  //       detected.  In such cases it may be more informative to
   422  //       supply the name of the routine the user called rather than
   423  //       the name of the subsidiary routine that detected the
   424  //       error.
   425  
   426  // MESSG    A character constant (or character variable) with the text
   427  //       of the error or warning message.  In the example below,
   428  //       the message is a character constant that contains a
   429  //       generic message.
   430  
   431  //             ALL XERMSG ('SLATEC', 'MMPY',
   432  //            *'THE ORDER OF THE MATRIX EXEEDS THE ROW DIMENSION',
   433  //            *3, 1)
   434  
   435  //       It is possible (and is sometimes desirable) to generate a
   436  //       specific message--e.g., one that contains actual numeric
   437  //       values.  Specific numeric values can be converted into
   438  //       character strings using formatted WRITE statements into
   439  //       character variables.  This is called standard Fortran
   440  //       internal file I/O and is exemplified in the first three
   441  //       lines of the following example.  You can also catenate
   442  //       substrings of characters to construct the error message.
   443  //       Here is an example showing the use of both writing to
   444  //       an internal file and catenating character strings.
   445  
   446  //             CHARACTER*5 CHARN, CHARL
   447  //             WRITE (HARN,10) N
   448  //             WRITE (HARL,10) LDA
   449  //          10 FORMAT(I5)
   450  //             ALL XERMSG ('SLATEC', 'MMPY', 'THE ORDER'//CHARN//
   451  //            *   ' OF THE MATRIX EXEEDS ITS ROW DIMENSION OF'//
   452  //            *   HARL, 3, 1)
   453  
   454  //       There are two subtleties worth mentioning.  One is that
   455  //       the // for character catenation is used to construct the
   456  //       error message so that no single character constant is
   457  //       continued to the next line.  This avoids confusion as to
   458  //       whether there are trailing blanks at the end of the line.
   459  //       The second is that by catenating the parts of the message
   460  //       as an actual argument rather than encoding the entire
   461  //       message into one large character variable, we avoid
   462  //       having to know how long the message will be in order to
   463  //       declare an adequate length for that large character
   464  //       variable.  XERMSG calls XERPRN to print_4 the message using
   465  //       multiple lines if necessary.  If the message is very long,
   466  //       XERPRN will break it into pieces of 72 characters (as
   467  //       requested by XERMSG) for printing on multiple lines.
   468  //       Also, XERMSG asks XERPRN to prefix each line with ' *  '
   469  //       so that the total line length could be 76 characters.
   470  //       Note also that XERPRN scans the error message backwards
   471  //       to ignore trailing blanks.  Another feature is that
   472  //       the substring '$$' is treated as a new line sentinel
   473  //       by XERPRN.  If you want to construct a multiline
   474  //       message without having to count out multiples of 72
   475  //       characters, just use '$$' as a separator.  '$$'
   476  //       obviously must occur within 72 characters of the
   477  //       start of each line to have its intended effect since
   478  //       XERPRN is asked to wrap around at 72 characters in
   479  //       addition to looking for '$$'.
   480  
   481  // NERR     An integer value that is chosen by the library routine's
   482  //       author.  It must be in the range -99 to 999 (three
   483  //       printable digits).  Each distinct error should have its
   484  //       own error number.  These error numbers should be described
   485  //       in the machine readable documentation for the routine.
   486  //       The error numbers need be unique only within each routine,
   487  //       so it is reasonable for each routine to start enumerating
   488  //       errors from 1 and proceeding to the next integer.
   489  
   490  // LEVEL    An integer value in the range 0 to 2 that indicates the
   491  //       level (severity) of the error.  Their meanings are
   492  
   493  //      -1  A warning message.  This is used if it is not clear
   494  //          that there really is an error, but the user's attention
   495  //          may be needed.  An attempt is made to only print_4 this
   496  //          message once.
   497  
   498  //       0  A warning message.  This is used if it is not clear
   499  //          that there really is an error, but the user's attention
   500  //          may be needed.
   501  
   502  //       1  A recoverable error.  This is used even if the error is
   503  //          so serious that the routine cannot return any useful
   504  //          answer.  If the user has told the error package to
   505  //          return after recoverable errors, then XERMSG will
   506  //          return to the Library routine which can then return to
   507  //          the user's routine.  The user may also permit the error
   508  //          package to terminate the program upon encountering a
   509  //          recoverable error.
   510  
   511  //       2  A fatal error.  XERMSG will not return to its caller
   512  //          after it receives a fatal error.  This level should
   513  //          hardly ever be used; it is much better to allow the
   514  //          user a chance to recover.  An example of one of the few
   515  //          cases in which it is permissible to declare a level 2
   516  //          error is a reverse communication Library routine that
   517  //          is likely to be called repeatedly until it integrates
   518  //          across some interval.  If there is a serious error in
   519  //          the input such that another step cannot be taken and
   520  //          the Library routine is called again without the input
   521  //          error having been corrected by the caller, the Library
   522  //          routine will probably be called forever with improper
   523  //          input.  In this case, it is reasonable to declare the
   524  //          error to be fatal.
   525  
   526  // Each of the arguments to XERMSG is input; none will be modified by
   527  // XERMSG.  A routine may make multiple calls to XERMSG with warning
   528  // level messages; however, after a call to XERMSG with a recoverable
   529  // error, the routine should return to the user.  Do not try to call
   530  // XERMSG with a second recoverable error after the first recoverable
   531  // error because the error package saves the error number.  The user
   532  // can retrieve this error number by calling another entry point_4 in
   533  // the error handling package and then clear the error number when
   534  // recovering from the error. Calling XERMSG in succession causes the
   535  // old error number to be overwritten by the latest error number.
   536  // This is considered harmless for error numbers associated with
   537  // warning messages but must not be done for error numbers of serious
   538  // errors.  After a call to XERMSG with a recoverable error, the user
   539  // must be given a chance to call NUMXER or XERLR to retrieve or
   540  // clear the error number.
   541  //
   542  
   543  // Note that this stub ignores __kontrl__.
   544    fprintf (stderr, "** slatec     ** error: %s: %s: %s\n", _strlower (librar), _strlower (subrou), _strlower (messg));  
   545    errno = *nerr;
   546    if (*level == 2) {
   547      exit (EXIT_FAILURE);
   548    }
   549    return EXIT_FAILURE;
   550  }
   551  
   552  int_4 _xerbla(char _p_ srname, int_4 _p_ info)
   553  {
   554  //  XERBLA is called by Level 2 and 3 BLAS routines if an input parameter
   555  //  is invalid.
   556  //
   557  //  Parameters
   558  //  ==========
   559  //
   560  //  SRNAME - CHARACTER*6.
   561  //           On entry, SRNAME specifies the name of the routine which
   562  //           called XERBLA.
   563  //
   564  //  INFO   - INTEGER.
   565  //           On entry, INFO specifies the position of the invalid
   566  //           parameter in the parameter-list of the calling routine.
   567  //
   568      RECORD msg;
   569      _srecordf (msg, "** blas       ** %6s: invalid parameter #%2d\n", srname, *info);
   570      RTE ("xerbla", msg);
   571      return EXIT_FAILURE;
   572  }
   573  
   574  int_4 _xerabt(char _p_ msg, int_4 _p_ nmessg)
   575  {
   576  //
   577  //     Latest revision  -  January 24, 1990 (JRD)
   578  //
   579  //     ABSTRACT
   580  //        ***NOTE*** Machine dependent routine
   581  //        XERABT aborts the execution of the program.
   582  //        The error message causing the abort is given in the calling
   583  //        sequence in case one needs it for printing on a dayfile,
   584  //        for example.
   585  //
   586  //     DESCRIPTION OF PARAMETERS
   587  //        MESSG and NMESSG are as in xerror, except that nmessg may
   588  //        be zero, in which case no message is being supplied.
   589  //
   590  //     Written by Ron Jones, with SLATEC Common Math Library subcommittee
   591  //     latest revision ---  7 June 1978
   592  //
   593     if (*nmessg != 0) {
   594       RTE (NO_TEXT, msg); // Does not return.
   595     } else {
   596       RTE (NO_TEXT, NO_TEXT); // Does not return.
   597     }
   598     return EXIT_FAILURE;
   599  }
   600  


© 2002-2025 J.M. van der Veer (jmvdveer@xs4all.nl)