source: LMDZ6/trunk/libf/misc/xerprn.f90 @ 5444

Last change on this file since 5444 was 5246, checked in by abarral, 2 months ago

Convert fixed-form to free-form sources .F -> .{f,F}90
(WIP: some .F remain, will be handled in subsequent commits)

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 8.7 KB
Line 
1!DECK XERPRN
2SUBROUTINE XERPRN (PREFIX, NPREF, MESSG, NWRAP)
3  IMPLICIT NONE
4  !***BEGIN PROLOGUE  XERPRN
5  !***SUBSIDIARY
6  !***PURPOSE  Print error messages processed by XERMSG.
7  !***LIBRARY   SLATEC (XERROR)
8  !***CATEGORY  R3C
9  !***TYPE      ALL (XERPRN-A)
10  !***KEYWORDS  ERROR MESSAGES, PRINTING, XERROR
11  !***AUTHOR  Fong, Kirby, (NMFECC at LLNL)
12  !***DESCRIPTION
13  !
14  ! This routine sends one or more lines to each of the (up to five)
15  ! logical units to which error messages are to be sent.  This routine
16  ! is called several times by XERMSG, sometimes with a single line to
17  ! print and sometimes with a (potentially very long) message that may
18  ! wrap around into multiple lines.
19  !
20  ! PREFIX  Input argument of type CHARACTER.  This argument contains
21  !     characters to be put at the beginning of each line before
22  !     the body of the message.  No more than 16 characters of
23  !     PREFIX will be used.
24  !
25  ! NPREF   Input argument of type INTEGER.  This argument is the number
26  !     of characters to use from PREFIX.  If it is negative, the
27  !     intrinsic function LEN is used to determine its length.  If
28  !         it is zero, PREFIX is not used.  If it exceeds 16 or if
29  !     LEN(PREFIX) exceeds 16, only the first 16 characters will be
30  !     used.  If NPREF is positive and the length of PREFIX is less
31  !     than NPREF, a copy of PREFIX extended with blanks to length
32  !     NPREF will be used.
33  !
34  ! MESSG   Input argument of type CHARACTER.  This is the text of a
35  !     message to be printed.  If it is a long message, it will be
36  !     broken into pieces for printing on multiple lines.  Each line
37  !     will start with the appropriate prefix and be followed by a
38  !     piece of the message.  NWRAP is the number of characters per
39  !     piece; that is, after each NWRAP characters, we break and
40  !     start a new line.  In addition the characters '$$' embedded
41  !     in MESSG are a sentinel for a new line.  The counting of
42  !     characters up to NWRAP starts over for each new line.  The
43  !     value of NWRAP typically used by XERMSG is 72 since many
44  !     older error messages in the SLATEC Library are laid out to
45  !     rely on wrap-around every 72 characters.
46  !
47  ! NWRAP   Input argument of type INTEGER.  This gives the maximum size
48  !     piece into which to break MESSG for printing on multiple
49  !     lines.  An embedded '$$' ends a line, and the count restarts
50  !     at the following character.  If a line break does not occur
51  !     on a blank (it would split a word) that word is moved to the
52  !     next line.  Values of NWRAP less than 16 will be treated as
53  !     16.  Values of NWRAP greater than 132 will be treated as 132.
54  !     The actual line length will be NPREF + NWRAP after NPREF has
55  !     been adjusted to fall between 0 and 16 and NWRAP has been
56  !     adjusted to fall between 16 and 132.
57  !
58  !***REFERENCES  R. E. Jones and D. K. Kahaner, XERROR, the SLATEC
59  !             Error-handling Package, SAND82-0800, Sandia
60  !             Laboratories, 1982.
61  !***ROUTINES CALLED  I1MACH, XGETUA
62  !***REVISION HISTORY  (YYMMDD)
63  !   880621  DATE WRITTEN
64  !   880708  REVISED AFTER THE SLATEC CML SUBCOMMITTEE MEETING OF
65  !       JUNE 29 AND 30 TO CHANGE THE NAME TO XERPRN AND TO REWORK
66  !       THE HANDLING OF THE NEW LINE SENTINEL TO BEHAVE LIKE THE
67  !       SLASH CHARACTER IN FORMAT STATEMENTS.
68  !   890706  REVISED WITH THE HELP OF FRED FRITSCH AND REG CLEMENS TO
69  !       STREAMLINE THE CODING AND FIX A BUG THAT CAUSED EXTRA BLANK
70  !       LINES TO BE PRINTED.
71  !   890721  REVISED TO ADD A NEW FEATURE.  A NEGATIVE VALUE OF NPREF
72  !       CAUSES LEN(PREFIX) TO BE USED AS THE LENGTH.
73  !   891013  REVISED TO CORRECT ERROR IN CALCULATING PREFIX LENGTH.
74  !   891214  Prologue converted to Version 4.0 format.  (WRB)
75  !   900510  Added code to break messages between words.  (RWC)
76  !   920501  Reformatted the REFERENCES section.  (WRB)
77  !***END PROLOGUE  XERPRN
78  CHARACTER(len=*) :: PREFIX, MESSG
79  INTEGER :: NPREF, NWRAP
80  CHARACTER(len=148) :: CBUFF
81  INTEGER :: IU(5), NUNIT
82  CHARACTER(len=2) :: NEWLIN
83  PARAMETER (NEWLIN = '$$')
84  INTEGER :: N, I1MACH, I, LPREF, LWRAP, LENMSG, NEXTC
85  INTEGER :: LPIECE, IDELTA
86  !***FIRST EXECUTABLE STATEMENT  XERPRN
87  CALL XGETUA(IU,NUNIT)
88  !
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  !
93  N = I1MACH(4)
94  DO I=1,NUNIT
95     IF (IU(I) .EQ. 0) IU(I) = N
96  END DO
97  !
98  !   LPREF IS THE LENGTH OF THE PREFIX.  THE PREFIX IS PLACED AT THE
99  !   BEGINNING OF CBUFF, THE CHARACTER BUFFER, AND KEPT THERE DURING
100  !   THE REST OF THIS ROUTINE.
101  !
102  IF ( NPREF .LT. 0 ) THEN
103     LPREF = LEN(PREFIX)
104  ELSE
105     LPREF = NPREF
106  ENDIF
107  LPREF = MIN(16, LPREF)
108  IF (LPREF .NE. 0) CBUFF(1:LPREF) = PREFIX
109  !
110  !   LWRAP IS THE MAXIMUM NUMBER OF CHARACTERS WE WANT TO TAKE AT ONE
111  !   TIME FROM MESSG TO PRINT ON ONE LINE.
112  !
113  LWRAP = MAX(16, MIN(132, NWRAP))
114  !
115  !   SET LENMSG TO THE LENGTH OF MESSG, IGNORE ANY TRAILING BLANKS.
116  !
117  LENMSG = LEN(MESSG)
118  N = LENMSG
119  DO I=1,N
120     IF (MESSG(LENMSG:LENMSG) .NE. ' ') GO TO 30
121     LENMSG = LENMSG - 1
122  END DO
123   30   CONTINUE
124  !
125  !   IF THE MESSAGE IS ALL BLANKS, THEN PRINT ONE BLANK LINE.
126  !
127  IF (LENMSG .EQ. 0) THEN
128     CBUFF(LPREF+1:LPREF+1) = ' '
129     DO I=1,NUNIT
130        WRITE(IU(I), '(A)') CBUFF(1:LPREF+1)
131     END DO
132     RETURN
133  ENDIF
134  !
135  !   SET NEXTC TO THE POSITION IN MESSG WHERE THE NEXT SUBSTRING
136  !   STARTS.  FROM THIS POSITION WE SCAN FOR THE NEW LINE SENTINEL.
137  !   WHEN NEXTC EXCEEDS LENMSG, THERE IS NO MORE TO PRINT.
138  !   WE LOOP BACK TO LABEL 50 UNTIL ALL PIECES HAVE BEEN PRINTED.
139  !
140  !   WE LOOK FOR THE NEXT OCCURRENCE OF THE NEW LINE SENTINEL.  THE
141  !   INDEX INTRINSIC FUNCTION RETURNS ZERO IF THERE IS NO OCCURRENCE
142  !   OR IF THE LENGTH OF THE FIRST ARGUMENT IS LESS THAN THE LENGTH
143  !   OF THE SECOND ARGUMENT.
144  !
145  !   THERE ARE SEVERAL CASES WHICH SHOULD BE CHECKED FOR IN THE
146  !   FOLLOWING ORDER.  WE ARE ATTEMPTING TO SET LPIECE TO THE NUMBER
147  !   OF CHARACTERS THAT SHOULD BE TAKEN FROM MESSG STARTING AT
148  !   POSITION NEXTC.
149  !
150  !   LPIECE .EQ. 0   THE NEW LINE SENTINEL DOES NOT OCCUR IN THE
151  !                   REMAINDER OF THE CHARACTER STRING.  LPIECE
152  !                   SHOULD BE SET TO LWRAP OR LENMSG+1-NEXTC,
153  !                   WHICHEVER IS LESS.
154  !
155  !   LPIECE .EQ. 1   THE NEW LINE SENTINEL STARTS AT MESSG(NEXTC:
156  !                   NEXTC).  LPIECE IS EFFECTIVELY ZERO, AND WE
157  !                   PRINT NOTHING TO AVOID PRODUCING UNNECESSARY
158  !                   BLANK LINES.  THIS TAKES CARE OF THE SITUATION
159  !                   WHERE THE LIBRARY ROUTINE HAS A MESSAGE OF
160  !                   EXACTLY 72 CHARACTERS FOLLOWED BY A NEW LINE
161  !                   SENTINEL FOLLOWED BY MORE CHARACTERS.  NEXTC
162  !                   SHOULD BE INCREMENTED BY 2.
163  !
164  !   LPIECE .GT. LWRAP+1  REDUCE LPIECE TO LWRAP.
165  !
166  !   ELSE            THIS LAST CASE MEANS 2 .LE. LPIECE .LE. LWRAP+1
167  !                   RESET LPIECE = LPIECE-1.  NOTE THAT THIS
168  !                   PROPERLY HANDLES THE END CASE WHERE LPIECE .EQ.
169  !                   LWRAP+1.  THAT IS, THE SENTINEL FALLS EXACTLY
170  !                   AT THE END OF A LINE.
171  !
172  NEXTC = 1
173   50   LPIECE = INDEX(MESSG(NEXTC:LENMSG), NEWLIN)
174  IF (LPIECE .EQ. 0) THEN
175  !
176  !   THERE WAS NO NEW LINE SENTINEL FOUND.
177  !
178     IDELTA = 0
179     LPIECE = MIN(LWRAP, LENMSG+1-NEXTC)
180     IF (LPIECE .LT. LENMSG+1-NEXTC) THEN
181        DO I=LPIECE+1,2,-1
182           IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN
183              LPIECE = I-1
184              IDELTA = 1
185              GOTO 54
186           ENDIF
187        END DO
188     ENDIF
189   54   CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
190     NEXTC = NEXTC + LPIECE + IDELTA
191  ELSEIF (LPIECE .EQ. 1) THEN
192  !
193  !   WE HAVE A NEW LINE SENTINEL AT MESSG(NEXTC:NEXTC+1).
194  !   DON'T PRINT A BLANK LINE.
195  !
196     NEXTC = NEXTC + 2
197     GO TO 50
198  ELSEIF (LPIECE .GT. LWRAP+1) THEN
199  !
200  !   LPIECE SHOULD BE SET DOWN TO LWRAP.
201  !
202     IDELTA = 0
203     LPIECE = LWRAP
204     DO I=LPIECE+1,2,-1
205        IF (MESSG(NEXTC+I-1:NEXTC+I-1) .EQ. ' ') THEN
206           LPIECE = I-1
207           IDELTA = 1
208           GOTO 58
209        ENDIF
210     END DO
211   58   CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
212     NEXTC = NEXTC + LPIECE + IDELTA
213  ELSE
214  !
215  !   IF WE ARRIVE HERE, IT MEANS 2 .LE. LPIECE .LE. LWRAP+1.
216  !   WE SHOULD DECREMENT LPIECE BY ONE.
217  !
218     LPIECE = LPIECE - 1
219     CBUFF(LPREF+1:LPREF+LPIECE) = MESSG(NEXTC:NEXTC+LPIECE-1)
220     NEXTC  = NEXTC + LPIECE + 2
221  ENDIF
222  !
223  !   PRINT
224  !
225  DO I=1,NUNIT
226     WRITE(IU(I), '(A)') CBUFF(1:LPREF+LPIECE)
227  END DO
228  !
229  IF (NEXTC .LE. LENMSG) GO TO 50
230  RETURN
231END SUBROUTINE XERPRN
Note: See TracBrowser for help on using the repository browser.