xerprn.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* xerprn.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__4 = 4;
  7. static integer const c__1 = 1;
  8. int xerprn_(char const *prefix, integer const *npref, char const *messg,
  9. integer const *nwrap, ftnlen prefix_len, ftnlen messg_len)
  10. {
  11. /* System generated locals */
  12. integer i__1, i__2;
  13. cilist ci__1;
  14. /* Local variables */
  15. integer i__, n, iu[5];
  16. char cbuff[148];
  17. integer lpref, nextc, lwrap, nunit;
  18. integer lpiece, idelta, lenmsg;
  19. /* ***BEGIN PROLOGUE XERPRN */
  20. /* ***SUBSIDIARY */
  21. /* ***PURPOSE Print error messages processed by XERMSG. */
  22. /* ***LIBRARY SLATEC (XERROR) */
  23. /* ***CATEGORY R3C */
  24. /* ***TYPE ALL (XERPRN-A) */
  25. /* ***KEYWORDS ERROR MESSAGES, PRINTING, XERROR */
  26. /* ***AUTHOR Fong, Kirby, (NMFECC at LLNL) */
  27. /* ***DESCRIPTION */
  28. /* This routine sends one or more lines to each of the (up to five) */
  29. /* logical units to which error messages are to be sent. This routine */
  30. /* is called several times by XERMSG, sometimes with a single line to */
  31. /* print and sometimes with a (potentially very long) message that may */
  32. /* wrap around into multiple lines. */
  33. /* PREFIX Input argument of type CHARACTER. This argument contains */
  34. /* characters to be put at the beginning of each line before */
  35. /* the body of the message. No more than 16 characters of */
  36. /* PREFIX will be used. */
  37. /* NPREF Input argument of type INTEGER. This argument is the number */
  38. /* of characters to use from PREFIX. If it is negative, the */
  39. /* intrinsic function LEN is used to determine its length. If */
  40. /* it is zero, PREFIX is not used. If it exceeds 16 or if */
  41. /* LEN(PREFIX) exceeds 16, only the first 16 characters will be */
  42. /* used. If NPREF is positive and the length of PREFIX is less */
  43. /* than NPREF, a copy of PREFIX extended with blanks to length */
  44. /* NPREF will be used. */
  45. /* MESSG Input argument of type CHARACTER. This is the text of a */
  46. /* message to be printed. If it is a long message, it will be */
  47. /* broken into pieces for printing on multiple lines. Each line */
  48. /* will start with the appropriate prefix and be followed by a */
  49. /* piece of the message. NWRAP is the number of characters per */
  50. /* piece; that is, after each NWRAP characters, we break and */
  51. /* start a new line. In addition the characters '$$' embedded */
  52. /* in MESSG are a sentinel for a new line. The counting of */
  53. /* characters up to NWRAP starts over for each new line. The */
  54. /* value of NWRAP typically used by XERMSG is 72 since many */
  55. /* older error messages in the SLATEC Library are laid out to */
  56. /* rely on wrap-around every 72 characters. */
  57. /* NWRAP Input argument of type INTEGER. This gives the maximum size */
  58. /* piece into which to break MESSG for printing on multiple */
  59. /* lines. An embedded '$$' ends a line, and the count restarts */
  60. /* at the following character. If a line break does not occur */
  61. /* on a blank (it would split a word) that word is moved to the */
  62. /* next line. Values of NWRAP less than 16 will be treated as */
  63. /* 16. Values of NWRAP greater than 132 will be treated as 132. */
  64. /* The actual line length will be NPREF + NWRAP after NPREF has */
  65. /* been adjusted to fall between 0 and 16 and NWRAP has been */
  66. /* adjusted to fall between 16 and 132. */
  67. /* ***REFERENCES R. E. Jones and D. K. Kahaner, XERROR, the SLATEC */
  68. /* Error-handling Package, SAND82-0800, Sandia */
  69. /* Laboratories, 1982. */
  70. /* ***ROUTINES CALLED I1MACH, XGETUA */
  71. /* ***REVISION HISTORY (YYMMDD) */
  72. /* 880621 DATE WRITTEN */
  73. /* 880708 REVISED AFTER THE SLATEC CML SUBCOMMITTEE MEETING OF */
  74. /* JUNE 29 AND 30 TO CHANGE THE NAME TO XERPRN AND TO REWORK */
  75. /* THE HANDLING OF THE NEW LINE SENTINEL TO BEHAVE LIKE THE */
  76. /* SLASH CHARACTER IN FORMAT STATEMENTS. */
  77. /* 890706 REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO */
  78. /* STREAMLINE THE CODING AND FIX A BUG THAT CAUSED EXTRA BLANK */
  79. /* LINES TO BE PRINTED. */
  80. /* 890721 REVISED TO ADD A NEW FEATURE. A NEGATIVE VALUE OF NPREF */
  81. /* CAUSES LEN(PREFIX) TO BE USED AS THE LENGTH. */
  82. /* 891013 REVISED TO CORRECT ERROR IN CALCULATING PREFIX LENGTH. */
  83. /* 891214 Prologue converted to Version 4.0 format. (WRB) */
  84. /* 900510 Added code to break messages between words. (RWC) */
  85. /* 920501 Reformatted the REFERENCES section. (WRB) */
  86. /* ***END PROLOGUE XERPRN */
  87. /* ***FIRST EXECUTABLE STATEMENT XERPRN */
  88. xgetua_(iu, &nunit);
  89. /* A ZERO VALUE FOR A LOGICAL UNIT NUMBER MEANS TO USE THE STANDARD */
  90. /* ERROR MESSAGE UNIT INSTEAD. I1MACH(4) RETRIEVES THE STANDARD */
  91. /* ERROR MESSAGE UNIT. */
  92. n = i1mach_(4);
  93. i__1 = nunit;
  94. for (i__ = 1; i__ <= i__1; ++i__) {
  95. if (iu[i__ - 1] == 0) {
  96. iu[i__ - 1] = n;
  97. }
  98. /* L10: */
  99. }
  100. /* LPREF IS THE LENGTH OF THE PREFIX. THE PREFIX IS PLACED AT THE */
  101. /* BEGINNING OF CBUFF, THE CHARACTER BUFFER, AND KEPT THERE DURING */
  102. /* THE REST OF THIS ROUTINE. */
  103. if (*npref < 0) {
  104. lpref = f2c::i_len(prefix, prefix_len);
  105. } else {
  106. lpref = *npref;
  107. }
  108. lpref = min(16,lpref);
  109. if (lpref != 0) {
  110. f2c::s_copy(cbuff, prefix, lpref, prefix_len);
  111. }
  112. /* LWRAP IS THE MAXIMUM NUMBER OF CHARACTERS WE WANT TO TAKE AT ONE */
  113. /* TIME FROM MESSG TO PRINT ON ONE LINE. */
  114. /* Computing MAX */
  115. i__1 = 16, i__2 = min(132,*nwrap);
  116. lwrap = max(i__1,i__2);
  117. /* SET LENMSG TO THE LENGTH OF MESSG, IGNORE ANY TRAILING BLANKS. */
  118. lenmsg = f2c::i_len(messg, messg_len);
  119. n = lenmsg;
  120. i__1 = n;
  121. for (i__ = 1; i__ <= i__1; ++i__) {
  122. if (*(unsigned char *)&messg[lenmsg - 1] != ' ') {
  123. goto L30;
  124. }
  125. --lenmsg;
  126. /* L20: */
  127. }
  128. L30:
  129. /* IF THE MESSAGE IS ALL BLANKS, THEN PRINT ONE BLANK LINE. */
  130. if (lenmsg == 0) {
  131. i__1 = lpref;
  132. f2c::s_copy(cbuff + i__1, " ", lpref + 1 - i__1, (ftnlen)1);
  133. i__1 = nunit;
  134. for (i__ = 1; i__ <= i__1; ++i__) {
  135. ci__1.cierr = 0;
  136. ci__1.ciunit = iu[i__ - 1];
  137. ci__1.cifmt = "(A)";
  138. f2c::s_wsfe(&ci__1);
  139. f2c::do_fio(&c__1, cbuff, lpref + 1);
  140. f2c::e_wsfe();
  141. /* L40: */
  142. }
  143. return 0;
  144. }
  145. /* SET NEXTC TO THE POSITION IN MESSG WHERE THE NEXT SUBSTRING */
  146. /* STARTS. FROM THIS POSITION WE SCAN FOR THE NEW LINE SENTINEL. */
  147. /* WHEN NEXTC EXCEEDS LENMSG, THERE IS NO MORE TO PRINT. */
  148. /* WE LOOP BACK TO LABEL 50 UNTIL ALL PIECES HAVE BEEN PRINTED. */
  149. /* WE LOOK FOR THE NEXT OCCURRENCE OF THE NEW LINE SENTINEL. THE */
  150. /* INDEX INTRINSIC FUNCTION RETURNS ZERO IF THERE IS NO OCCURRENCE */
  151. /* OR IF THE LENGTH OF THE FIRST ARGUMENT IS LESS THAN THE LENGTH */
  152. /* OF THE SECOND ARGUMENT. */
  153. /* THERE ARE SEVERAL CASES WHICH SHOULD BE CHECKED FOR IN THE */
  154. /* FOLLOWING ORDER. WE ARE ATTEMPTING TO SET LPIECE TO THE NUMBER */
  155. /* OF CHARACTERS THAT SHOULD BE TAKEN FROM MESSG STARTING AT */
  156. /* POSITION NEXTC. */
  157. /* LPIECE .EQ. 0 THE NEW LINE SENTINEL DOES NOT OCCUR IN THE */
  158. /* REMAINDER OF THE CHARACTER STRING. LPIECE */
  159. /* SHOULD BE SET TO LWRAP OR LENMSG+1-NEXTC, */
  160. /* WHICHEVER IS LESS. */
  161. /* LPIECE .EQ. 1 THE NEW LINE SENTINEL STARTS AT MESSG(NEXTC: */
  162. /* NEXTC). LPIECE IS EFFECTIVELY ZERO, AND WE */
  163. /* PRINT NOTHING TO AVOID PRODUCING UNNECESSARY */
  164. /* BLANK LINES. THIS TAKES CARE OF THE SITUATION */
  165. /* WHERE THE LIBRARY ROUTINE HAS A MESSAGE OF */
  166. /* EXACTLY 72 CHARACTERS FOLLOWED BY A NEW LINE */
  167. /* SENTINEL FOLLOWED BY MORE CHARACTERS. NEXTC */
  168. /* SHOULD BE INCREMENTED BY 2. */
  169. /* LPIECE .GT. LWRAP+1 REDUCE LPIECE TO LWRAP. */
  170. /* ELSE THIS LAST CASE MEANS 2 .LE. LPIECE .LE. LWRAP+1 */
  171. /* RESET LPIECE = LPIECE-1. NOTE THAT THIS */
  172. /* PROPERLY HANDLES THE END CASE WHERE LPIECE .EQ. */
  173. /* LWRAP+1. THAT IS, THE SENTINEL FALLS EXACTLY */
  174. /* AT THE END OF A LINE. */
  175. nextc = 1;
  176. L50:
  177. lpiece = f2c::i_indx(messg + (nextc - 1), "$$", lenmsg - (nextc - 1), (ftnlen)
  178. 2);
  179. if (lpiece == 0) {
  180. /* THERE WAS NO NEW LINE SENTINEL FOUND. */
  181. idelta = 0;
  182. /* Computing MIN */
  183. i__1 = lwrap, i__2 = lenmsg + 1 - nextc;
  184. lpiece = min(i__1,i__2);
  185. if (lpiece < lenmsg + 1 - nextc) {
  186. for (i__ = lpiece + 1; i__ >= 2; --i__) {
  187. i__1 = nextc + i__ - 2;
  188. if (f2c::s_cmp(messg + i__1, " ", nextc + i__ - 1 - i__1, (ftnlen) 1) == 0) {
  189. lpiece = i__ - 1;
  190. idelta = 1;
  191. goto L54;
  192. }
  193. /* L52: */
  194. }
  195. }
  196. L54:
  197. i__1 = lpref;
  198. f2c::s_copy(cbuff + i__1, messg + (nextc - 1), lpref + lpiece - i__1,
  199. nextc + lpiece - 1 - (nextc - 1));
  200. nextc = nextc + lpiece + idelta;
  201. } else if (lpiece == 1) {
  202. /* WE HAVE A NEW LINE SENTINEL AT MESSG(NEXTC:NEXTC+1). */
  203. /* DON'T PRINT A BLANK LINE. */
  204. nextc += 2;
  205. goto L50;
  206. } else if (lpiece > lwrap + 1) {
  207. /* LPIECE SHOULD BE SET DOWN TO LWRAP. */
  208. idelta = 0;
  209. lpiece = lwrap;
  210. for (i__ = lpiece + 1; i__ >= 2; --i__) {
  211. i__1 = nextc + i__ - 2;
  212. if (f2c::s_cmp(messg + i__1, " ", nextc + i__ - 1 - i__1, (ftnlen)1) ==
  213. 0) {
  214. lpiece = i__ - 1;
  215. idelta = 1;
  216. goto L58;
  217. }
  218. /* L56: */
  219. }
  220. L58:
  221. i__1 = lpref;
  222. f2c::s_copy(cbuff + i__1, messg + (nextc - 1), lpref + lpiece - i__1,
  223. nextc + lpiece - 1 - (nextc - 1));
  224. nextc = nextc + lpiece + idelta;
  225. } else {
  226. /* IF WE ARRIVE HERE, IT MEANS 2 .LE. LPIECE .LE. LWRAP+1. */
  227. /* WE SHOULD DECREMENT LPIECE BY ONE. */
  228. --lpiece;
  229. i__1 = lpref;
  230. f2c::s_copy(cbuff + i__1, messg + (nextc - 1), lpref + lpiece - i__1,
  231. nextc + lpiece - 1 - (nextc - 1));
  232. nextc = nextc + lpiece + 2;
  233. }
  234. /* PRINT */
  235. i__1 = nunit;
  236. for (i__ = 1; i__ <= i__1; ++i__) {
  237. ci__1.cierr = 0;
  238. ci__1.ciunit = iu[i__ - 1];
  239. ci__1.cifmt = "(A)";
  240. f2c::s_wsfe(&ci__1);
  241. f2c::do_fio(&c__1, cbuff, lpref + lpiece);
  242. f2c::e_wsfe();
  243. /* L60: */
  244. }
  245. if (nextc <= lenmsg) {
  246. goto L50;
  247. }
  248. return 0;
  249. } /* xerprn_ */