xermsg.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /* xermsg.f -- translated by f2c (version 20100827).
  2. This file no longer depends on f2c.
  3. */
  4. #include "slatec-internal.hpp"
  5. /* Table of constant values */
  6. static integer const c__2 = 2;
  7. static integer const c__0 = 0;
  8. static logical c_false = FALSE_;
  9. static integer const c__4 = 4;
  10. static integer c_n1 = -1;
  11. static integer const c__72 = 72;
  12. static integer const c__1 = 1;
  13. static logical c_true = TRUE_;
  14. int xermsg_(char const *librar, char const *subrou, char const *messg,
  15. integer const *nerr, integer const *level,
  16. ftnlen const librar_len, ftnlen const subrou_len, ftnlen const messg_len)
  17. {
  18. /* System generated locals */
  19. address a__1[2];
  20. integer i__1, i__2, i__3[2];
  21. char ch__1[87];
  22. icilist ici__1;
  23. /* Local variables */
  24. integer i__, lerr;
  25. char temp[72];
  26. char xlibr[8];
  27. integer ltemp, kount;
  28. char xsubr[8];
  29. integer llevel, maxmes;
  30. char lfirst[20];
  31. integer lkntrl, kdummy;
  32. integer mkntrl;
  33. /* ***BEGIN PROLOGUE XERMSG */
  34. /* ***PURPOSE Process error messages for SLATEC and other libraries. */
  35. /* ***LIBRARY SLATEC (XERROR) */
  36. /* ***CATEGORY R3C */
  37. /* ***TYPE ALL (XERMSG-A) */
  38. /* ***KEYWORDS ERROR MESSAGE, XERROR */
  39. /* ***AUTHOR Fong, Kirby, (NMFECC at LLNL) */
  40. /* ***DESCRIPTION */
  41. /* XERMSG processes a diagnostic message in a manner determined by the */
  42. /* value of LEVEL and the current value of the library error control */
  43. /* flag, KONTRL. See subroutine XSETF for details. */
  44. /* LIBRAR A character constant (or character variable) with the name */
  45. /* of the library. This will be 'SLATEC' for the SLATEC */
  46. /* Common Math Library. The error handling package is */
  47. /* general enough to be used by many libraries */
  48. /* simultaneously, so it is desirable for the routine that */
  49. /* detects and reports an error to identify the library name */
  50. /* as well as the routine name. */
  51. /* SUBROU A character constant (or character variable) with the name */
  52. /* of the routine that detected the error. Usually it is the */
  53. /* name of the routine that is calling XERMSG. There are */
  54. /* some instances where a user callable library routine calls */
  55. /* lower level subsidiary routines where the error is */
  56. /* detected. In such cases it may be more informative to */
  57. /* supply the name of the routine the user called rather than */
  58. /* the name of the subsidiary routine that detected the */
  59. /* error. */
  60. /* MESSG A character constant (or character variable) with the text */
  61. /* of the error or warning message. In the example below, */
  62. /* the message is a character constant that contains a */
  63. /* generic message. */
  64. /* CALL XERMSG ('SLATEC', 'MMPY', */
  65. /* *'THE ORDER OF THE MATRIX EXCEEDS THE ROW DIMENSION', */
  66. /* *3, 1) */
  67. /* It is possible (and is sometimes desirable) to generate a */
  68. /* specific message--e.g., one that contains actual numeric */
  69. /* values. Specific numeric values can be converted into */
  70. /* character strings using formatted WRITE statements into */
  71. /* character variables. This is called standard Fortran */
  72. /* internal file I/O and is exemplified in the first three */
  73. /* lines of the following example. You can also catenate */
  74. /* substrings of characters to construct the error message. */
  75. /* Here is an example showing the use of both writing to */
  76. /* an internal file and catenating character strings. */
  77. /* CHARACTER*5 CHARN, CHARL */
  78. /* WRITE (CHARN,10) N */
  79. /* WRITE (CHARL,10) LDA */
  80. /* 10 FORMAT(I5) */
  81. /* CALL XERMSG ('SLATEC', 'MMPY', 'THE ORDER'//CHARN// */
  82. /* * ' OF THE MATRIX EXCEEDS ITS ROW DIMENSION OF'// */
  83. /* * CHARL, 3, 1) */
  84. /* There are two subtleties worth mentioning. One is that */
  85. /* the // for character catenation is used to construct the */
  86. /* error message so that no single character constant is */
  87. /* continued to the next line. This avoids confusion as to */
  88. /* whether there are trailing blanks at the end of the line. */
  89. /* The second is that by catenating the parts of the message */
  90. /* as an actual argument rather than encoding the entire */
  91. /* message into one large character variable, we avoid */
  92. /* having to know how long the message will be in order to */
  93. /* declare an adequate length for that large character */
  94. /* variable. XERMSG calls XERPRN to print the message using */
  95. /* multiple lines if necessary. If the message is very long, */
  96. /* XERPRN will break it into pieces of 72 characters (as */
  97. /* requested by XERMSG) for printing on multiple lines. */
  98. /* Also, XERMSG asks XERPRN to prefix each line with ' * ' */
  99. /* so that the total line length could be 76 characters. */
  100. /* Note also that XERPRN scans the error message backwards */
  101. /* to ignore trailing blanks. Another feature is that */
  102. /* the substring '$$' is treated as a new line sentinel */
  103. /* by XERPRN. If you want to construct a multiline */
  104. /* message without having to count out multiples of 72 */
  105. /* characters, just use '$$' as a separator. '$$' */
  106. /* obviously must occur within 72 characters of the */
  107. /* start of each line to have its intended effect since */
  108. /* XERPRN is asked to wrap around at 72 characters in */
  109. /* addition to looking for '$$'. */
  110. /* NERR An integer value that is chosen by the library routine's */
  111. /* author. It must be in the range -99 to 999 (three */
  112. /* printable digits). Each distinct error should have its */
  113. /* own error number. These error numbers should be described */
  114. /* in the machine readable documentation for the routine. */
  115. /* The error numbers need be unique only within each routine, */
  116. /* so it is reasonable for each routine to start enumerating */
  117. /* errors from 1 and proceeding to the next integer. */
  118. /* LEVEL An integer value in the range 0 to 2 that indicates the */
  119. /* level (severity) of the error. Their meanings are */
  120. /* -1 A warning message. This is used if it is not clear */
  121. /* that there really is an error, but the user's attention */
  122. /* may be needed. An attempt is made to only print this */
  123. /* message once. */
  124. /* 0 A warning message. This is used if it is not clear */
  125. /* that there really is an error, but the user's attention */
  126. /* may be needed. */
  127. /* 1 A recoverable error. This is used even if the error is */
  128. /* so serious that the routine cannot return any useful */
  129. /* answer. If the user has told the error package to */
  130. /* return after recoverable errors, then XERMSG will */
  131. /* return to the Library routine which can then return to */
  132. /* the user's routine. The user may also permit the error */
  133. /* package to terminate the program upon encountering a */
  134. /* recoverable error. */
  135. /* 2 A fatal error. XERMSG will not return to its caller */
  136. /* after it receives a fatal error. This level should */
  137. /* hardly ever be used; it is much better to allow the */
  138. /* user a chance to recover. An example of one of the few */
  139. /* cases in which it is permissible to declare a level 2 */
  140. /* error is a reverse communication Library routine that */
  141. /* is likely to be called repeatedly until it integrates */
  142. /* across some interval. If there is a serious error in */
  143. /* the input such that another step cannot be taken and */
  144. /* the Library routine is called again without the input */
  145. /* error having been corrected by the caller, the Library */
  146. /* routine will probably be called forever with improper */
  147. /* input. In this case, it is reasonable to declare the */
  148. /* error to be fatal. */
  149. /* Each of the arguments to XERMSG is input; none will be modified by */
  150. /* XERMSG. A routine may make multiple calls to XERMSG with warning */
  151. /* level messages; however, after a call to XERMSG with a recoverable */
  152. /* error, the routine should return to the user. Do not try to call */
  153. /* XERMSG with a second recoverable error after the first recoverable */
  154. /* error because the error package saves the error number. The user */
  155. /* can retrieve this error number by calling another entry point in */
  156. /* the error handling package and then clear the error number when */
  157. /* recovering from the error. Calling XERMSG in succession causes the */
  158. /* old error number to be overwritten by the latest error number. */
  159. /* This is considered harmless for error numbers associated with */
  160. /* warning messages but must not be done for error numbers of serious */
  161. /* errors. After a call to XERMSG with a recoverable error, the user */
  162. /* must be given a chance to call NUMXER or XERCLR to retrieve or */
  163. /* clear the error number. */
  164. /* ***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC */
  165. /* Error-handling Package, SAND82-0800, Sandia */
  166. /* Laboratories, 1982. */
  167. /* ***ROUTINES CALLED FDUMP, J4SAVE, XERCNT, XERHLT, XERPRN, XERSVE */
  168. /* ***REVISION HISTORY (YYMMDD) */
  169. /* 880101 DATE WRITTEN */
  170. /* 880621 REVISED AS DIRECTED AT SLATEC CML MEETING OF FEBRUARY 1988. */
  171. /* THERE ARE TWO BASIC CHANGES. */
  172. /* 1. A NEW ROUTINE, XERPRN, IS USED INSTEAD OF XERPRT TO */
  173. /* PRINT MESSAGES. THIS ROUTINE WILL BREAK LONG MESSAGES */
  174. /* INTO PIECES FOR PRINTING ON MULTIPLE LINES. '$$' IS */
  175. /* ACCEPTED AS A NEW LINE SENTINEL. A PREFIX CAN BE */
  176. /* ADDED TO EACH LINE TO BE PRINTED. XERMSG USES EITHER */
  177. /* ' ***' OR ' * ' AND LONG MESSAGES ARE BROKEN EVERY */
  178. /* 72 CHARACTERS (AT MOST) SO THAT THE MAXIMUM LINE */
  179. /* LENGTH OUTPUT CAN NOW BE AS GREAT AS 76. */
  180. /* 2. THE TEXT OF ALL MESSAGES IS NOW IN UPPER CASE SINCE THE */
  181. /* FORTRAN STANDARD DOCUMENT DOES NOT ADMIT THE EXISTENCE */
  182. /* OF LOWER CASE. */
  183. /* 880708 REVISED AFTER THE SLATEC CML MEETING OF JUNE 29 AND 30. */
  184. /* THE PRINCIPAL CHANGES ARE */
  185. /* 1. CLARIFY COMMENTS IN THE PROLOGUES */
  186. /* 2. RENAME XRPRNT TO XERPRN */
  187. /* 3. REWORK HANDLING OF '$$' IN XERPRN TO HANDLE BLANK LINES */
  188. /* SIMILAR TO THE WAY FORMAT STATEMENTS HANDLE THE / */
  189. /* CHARACTER FOR NEW RECORDS. */
  190. /* 890706 REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO */
  191. /* CLEAN UP THE CODING. */
  192. /* 890721 REVISED TO USE NEW FEATURE IN XERPRN TO COUNT CHARACTERS IN */
  193. /* PREFIX. */
  194. /* 891013 REVISED TO CORRECT COMMENTS. */
  195. /* 891214 Prologue converted to Version 4.0 format. (WRB) */
  196. /* 900510 Changed test on NERR to be -9999999 < NERR < 99999999, but */
  197. /* NERR .ne. 0, and on LEVEL to be -2 < LEVEL < 3. Added */
  198. /* LEVEL=-1 logic, changed calls to XERSAV to XERSVE, and */
  199. /* XERCTL to XERCNT. (RWC) */
  200. /* 920501 Reformatted the REFERENCES section. (WRB) */
  201. /* ***END PROLOGUE XERMSG */
  202. /* ***FIRST EXECUTABLE STATEMENT XERMSG */
  203. lkntrl = j4save_(&c__2, &c__0, &c_false);
  204. maxmes = j4save_(&c__4, &c__0, &c_false);
  205. /* LKNTRL IS A LOCAL COPY OF THE CONTROL FLAG KONTRL. */
  206. /* MAXMES IS THE MAXIMUM NUMBER OF TIMES ANY PARTICULAR MESSAGE */
  207. /* SHOULD BE PRINTED. */
  208. /* WE PRINT A FATAL ERROR MESSAGE AND TERMINATE FOR AN ERROR IN */
  209. /* CALLING XERMSG. THE ERROR NUMBER SHOULD BE POSITIVE, */
  210. /* AND THE LEVEL SHOULD BE BETWEEN 0 AND 2. */
  211. if (*nerr < -9999999 || *nerr > 99999999 || *nerr == 0 || *level < -1 || *
  212. level > 2) {
  213. xerprn_(" ***", &c_n1, "FATAL ERROR IN...$$ XERMSG -- INVALID ERROR \
  214. NUMBER OR LEVEL$$ JOB ABORT DUE TO FATAL ERROR.", &c__72, (ftnlen)4, (ftnlen)
  215. 91);
  216. xersve_(" ", " ", " ", &c__0, &c__0, &c__0, &kdummy, (ftnlen)1, (
  217. ftnlen)1, (ftnlen)1);
  218. xerhlt_(" ***XERMSG -- INVALID INPUT", (ftnlen)27);
  219. return 0;
  220. }
  221. /* RECORD THE MESSAGE. */
  222. i__ = j4save_(&c__1, nerr, &c_true);
  223. xersve_(librar, subrou, messg, &c__1, nerr, level, &kount, librar_len,
  224. subrou_len, messg_len);
  225. /* HANDLE PRINT-ONCE WARNING MESSAGES. */
  226. if (*level == -1 && kount > 1) {
  227. return 0;
  228. }
  229. /* ALLOW TEMPORARY USER OVERRIDE OF THE CONTROL FLAG. */
  230. f2c::s_copy(xlibr, librar, (ftnlen)8, librar_len);
  231. f2c::s_copy(xsubr, subrou, (ftnlen)8, subrou_len);
  232. f2c::s_copy(lfirst, messg, (ftnlen)20, messg_len);
  233. lerr = *nerr;
  234. llevel = *level;
  235. xercnt_(xlibr, xsubr, lfirst, &lerr, &llevel, &lkntrl, (ftnlen)8, (ftnlen)
  236. 8, (ftnlen)20);
  237. /* Computing MAX */
  238. i__1 = -2, i__2 = min(2,lkntrl);
  239. lkntrl = max(i__1,i__2);
  240. mkntrl = abs(lkntrl);
  241. /* SKIP PRINTING IF THE CONTROL FLAG VALUE AS RESET IN XERCNT IS */
  242. /* ZERO AND THE ERROR IS NOT FATAL. */
  243. if (*level < 2 && lkntrl == 0) {
  244. goto L30;
  245. }
  246. if (*level == 0 && kount > maxmes) {
  247. goto L30;
  248. }
  249. if (*level == 1 && kount > maxmes && mkntrl == 1) {
  250. goto L30;
  251. }
  252. if (*level == 2 && kount > max(1,maxmes)) {
  253. goto L30;
  254. }
  255. /* ANNOUNCE THE NAMES OF THE LIBRARY AND SUBROUTINE BY BUILDING A */
  256. /* MESSAGE IN CHARACTER VARIABLE TEMP (NOT EXCEEDING 66 CHARACTERS) */
  257. /* AND SENDING IT OUT VIA XERPRN. PRINT ONLY IF CONTROL FLAG */
  258. /* IS NOT ZERO. */
  259. if (lkntrl != 0) {
  260. f2c::s_copy(temp, "MESSAGE FROM ROUTINE ", (ftnlen)21, (ftnlen)21);
  261. /* Computing MIN */
  262. i__1 = f2c::i_len(subrou, subrou_len);
  263. i__ = min(i__1,16);
  264. f2c::s_copy(temp + 21, subrou, i__, i__);
  265. i__1 = i__ + 21;
  266. f2c::s_copy(temp + i__1, " IN LIBRARY ", i__ + 33 - i__1, (ftnlen)12);
  267. ltemp = i__ + 33;
  268. /* Computing MIN */
  269. i__1 = f2c::i_len(librar, librar_len);
  270. i__ = min(i__1,16);
  271. i__1 = ltemp;
  272. f2c::s_copy(temp + i__1, librar, ltemp + i__ - i__1, i__);
  273. i__1 = ltemp + i__;
  274. f2c::s_copy(temp + i__1, ".", ltemp + i__ + 1 - i__1, (ftnlen)1);
  275. ltemp = ltemp + i__ + 1;
  276. xerprn_(" ***", &c_n1, temp, &c__72, (ftnlen)4, ltemp);
  277. }
  278. /* IF LKNTRL IS POSITIVE, PRINT AN INTRODUCTORY LINE BEFORE */
  279. /* PRINTING THE MESSAGE. THE INTRODUCTORY LINE TELLS THE CHOICE */
  280. /* FROM EACH OF THE FOLLOWING THREE OPTIONS. */
  281. /* 1. LEVEL OF THE MESSAGE */
  282. /* 'INFORMATIVE MESSAGE' */
  283. /* 'POTENTIALLY RECOVERABLE ERROR' */
  284. /* 'FATAL ERROR' */
  285. /* 2. WHETHER CONTROL FLAG WILL ALLOW PROGRAM TO CONTINUE */
  286. /* 'PROG CONTINUES' */
  287. /* 'PROG ABORTED' */
  288. /* 3. WHETHER OR NOT A TRACEBACK WAS REQUESTED. (THE TRACEBACK */
  289. /* MAY NOT BE IMPLEMENTED AT SOME SITES, SO THIS ONLY TELLS */
  290. /* WHAT WAS REQUESTED, NOT WHAT WAS DELIVERED.) */
  291. /* 'TRACEBACK REQUESTED' */
  292. /* 'TRACEBACK NOT REQUESTED' */
  293. /* NOTICE THAT THE LINE INCLUDING FOUR PREFIX CHARACTERS WILL NOT */
  294. /* EXCEED 74 CHARACTERS. */
  295. /* WE SKIP THE NEXT BLOCK IF THE INTRODUCTORY LINE IS NOT NEEDED. */
  296. if (lkntrl > 0) {
  297. /* THE FIRST PART OF THE MESSAGE TELLS ABOUT THE LEVEL. */
  298. if (*level <= 0) {
  299. f2c::s_copy(temp, "INFORMATIVE MESSAGE,", (ftnlen)20, (ftnlen)20);
  300. ltemp = 20;
  301. } else if (*level == 1) {
  302. f2c::s_copy(temp, "POTENTIALLY RECOVERABLE ERROR,", (ftnlen)30, (
  303. ftnlen)30);
  304. ltemp = 30;
  305. } else {
  306. f2c::s_copy(temp, "FATAL ERROR,", (ftnlen)12, (ftnlen)12);
  307. ltemp = 12;
  308. }
  309. /* THEN WHETHER THE PROGRAM WILL CONTINUE. */
  310. if (mkntrl == 2 && *level >= 1 || mkntrl == 1 && *level == 2) {
  311. i__1 = ltemp;
  312. f2c::s_copy(temp + i__1, " PROG ABORTED,", ltemp + 14 - i__1, (ftnlen)
  313. 14);
  314. ltemp += 14;
  315. } else {
  316. i__1 = ltemp;
  317. f2c::s_copy(temp + i__1, " PROG CONTINUES,", ltemp + 16 - i__1, (
  318. ftnlen)16);
  319. ltemp += 16;
  320. }
  321. /* FINALLY TELL WHETHER THERE SHOULD BE A TRACEBACK. */
  322. if (lkntrl > 0) {
  323. i__1 = ltemp;
  324. f2c::s_copy(temp + i__1, " TRACEBACK REQUESTED", ltemp + 20 - i__1, (
  325. ftnlen)20);
  326. ltemp += 20;
  327. } else {
  328. i__1 = ltemp;
  329. f2c::s_copy(temp + i__1, " TRACEBACK NOT REQUESTED", ltemp + 24 - i__1,
  330. (ftnlen)24);
  331. ltemp += 24;
  332. }
  333. xerprn_(" ***", &c_n1, temp, &c__72, (ftnlen)4, ltemp);
  334. }
  335. /* NOW SEND OUT THE MESSAGE. */
  336. xerprn_(" * ", &c_n1, messg, &c__72, (ftnlen)4, messg_len);
  337. /* IF LKNTRL IS POSITIVE, WRITE THE ERROR NUMBER AND REQUEST A */
  338. /* TRACEBACK. */
  339. if (lkntrl > 0) {
  340. ici__1.icierr = 0;
  341. ici__1.icirnum = 1;
  342. ici__1.icirlen = 72;
  343. ici__1.iciunit = temp;
  344. ici__1.icifmt = "('ERROR NUMBER = ', I8)";
  345. f2c::s_wsfi(&ici__1);
  346. f2c::do_fio(&c__1, (char *)&(*nerr), (ftnlen)sizeof(integer));
  347. f2c::e_wsfi();
  348. for (i__ = 16; i__ <= 22; ++i__) {
  349. if (*(unsigned char *)&temp[i__ - 1] != ' ') {
  350. goto L20;
  351. }
  352. /* L10: */
  353. }
  354. L20:
  355. /* Writing concatenation */
  356. i__3[0] = 15, a__1[0] = temp;
  357. i__3[1] = 23 - (i__ - 1), a__1[1] = temp + (i__ - 1);
  358. f2c::s_cat(ch__1, a__1, i__3, &c__2, (ftnlen)87);
  359. xerprn_(" * ", &c_n1, ch__1, &c__72, (ftnlen)4, 23 - (i__ - 1) + 15);
  360. fdump_();
  361. }
  362. /* IF LKNTRL IS NOT ZERO, PRINT A BLANK LINE AND AN END OF MESSAGE. */
  363. if (lkntrl != 0) {
  364. xerprn_(" * ", &c_n1, " ", &c__72, (ftnlen)4, (ftnlen)1);
  365. xerprn_(" ***", &c_n1, "END OF MESSAGE", &c__72, (ftnlen)4, (ftnlen)
  366. 14);
  367. xerprn_(" ", &c__0, " ", &c__72, (ftnlen)4, (ftnlen)1);
  368. }
  369. /* IF THE ERROR IS NOT FATAL OR THE ERROR IS RECOVERABLE AND THE */
  370. /* CONTROL FLAG IS SET FOR RECOVERY, THEN RETURN. */
  371. L30:
  372. if (*level <= 0 || *level == 1 && mkntrl <= 1) {
  373. return 0;
  374. }
  375. /* THE PROGRAM WILL BE STOPPED DUE TO AN UNRECOVERED ERROR OR A */
  376. /* FATAL ERROR. PRINT THE REASON FOR THE ABORT AND THE ERROR */
  377. /* SUMMARY IF THE CONTROL FLAG AND THE MAXIMUM ERROR COUNT PERMIT. */
  378. if (lkntrl > 0 && kount < max(1,maxmes)) {
  379. if (*level == 1) {
  380. xerprn_(" ***", &c_n1, "JOB ABORT DUE TO UNRECOVERED ERROR.", &
  381. c__72, (ftnlen)4, (ftnlen)35);
  382. } else {
  383. xerprn_(" ***", &c_n1, "JOB ABORT DUE TO FATAL ERROR.", &c__72, (
  384. ftnlen)4, (ftnlen)29);
  385. }
  386. xersve_(" ", " ", " ", &c_n1, &c__0, &c__0, &kdummy, (ftnlen)1, (
  387. ftnlen)1, (ftnlen)1);
  388. xerhlt_(" ", (ftnlen)1);
  389. } else {
  390. xerhlt_(messg, messg_len);
  391. }
  392. return 0;
  393. } /* xermsg_ */