NCEPLIBS-bufr  12.0.1
parutg.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Parse a mnemonic from a character string.
3 C>
4 C> @author Woollen @date 1994-01-06
5 
6 C> Parse a mnemonic from a character string.
7 C>
8 C> This subroutine parses a user-specified tag (mnemonic)
9 C> (UTG) that represents a value either being decoded from a bufr file
10 C> (if it is being read) or encoded into a bufr file (if it is being
11 C> written). This subroutine first checks to see if the tag contains
12 C> a condition character ('=', '!', '<', '>', '^' or '#'). If it does
13 C> not, nothing happens at this point. If it does, then the type of
14 C> condition character is noted and the tag is stripped of all
15 C> characters at and beyond the condition character. In either event,
16 C> the resultant tag is checked against those in the internal jump/
17 C> link subset table (in module tables). If found, the node
18 C> associated with the tag is returned (and it is either a "condition"
19 C> node or a "store" node depending of the presence or absence of a
20 C> condition character in UTG). Otherwise the node is returned as
21 C> zero. if the tag represents a condition node, then the condition
22 C> value (numeric characters beyond the condition character in the
23 C> user-specified tag input here) is returned.
24 C>
25 C> As an example of condition character usage, consider the following
26 C> example of a call to ufbint():
27 C>
28 C> @code
29 C> REAL*8 USR(4,50)
30 C> ....
31 C> ....
32 C> CALL UFBINT(LUNIN,USR,4,50,IRET,'PRLC<50000 TMDB WDIR WSPD')
33 C> @endcode
34 C>
35 C> Assuming that LUNIN points to a BUFR file open for input (reading),
36 C> then the USR array now contains IRET levels of data (up to a maximum
37 C> of 50) where the value of PRLC is/was less than 50000, along with
38 C> the corresponding values for TMDB, WDIR and WSPD at those levels.
39 C>
40 C> As another example, consider the following example of a call to
41 C> readlc() for a long character string:
42 C>
43 C> @code
44 C> CHARACTER*200 LCHR
45 C> ....
46 C> ....
47 C> CALL READLC(LUNIN,LCHR,'NUMID#3')
48 C> @endcode
49 C>
50 C> Assuming that LUNIN points to a BUFR file open for input (reading),
51 C> then the LCHR string now contains the value corresponding to the
52 C> third occurrence of NUMID within the current subset.
53 C>
54 C> Valid condition codes include:
55 C> - '<' - less than
56 C> - '>' - greater than
57 C> - '=' - equal to
58 C> - '!' - not equal to
59 C> - '#' - ordinal identifier for a particular occurrence of a long character string
60 C>
61 C> @param[in] LUN - integer: File ID.
62 C> @param[in] IO - integer: status indicator for BUFR file associated with LUN:
63 C> - 0 input file
64 C> - 1 output file
65 C> @param[in] UTG character*(*): user-supplied tag representing a value to be
66 C> encoded/decoded to/from BUFR file.
67 C> @param[out] NOD - integer: positional index in internal jump/link subset
68 C> table for TAG.
69 C> - 0 TAG not found in table
70 C> @param[out] KON - integer: indicator for type of condition character found in UTG:
71 C> - 0 no condition character found (NOD is a store node)
72 C> - 1 character '=' found (NOD is a condition node)
73 C> - 2 character '!' found (NOD is a condition node)
74 C> - 3 character '<' found (NOD is a condition node)
75 C> - 4 character '>' found (NOD is a condition node)
76 C> - 5 character '^' found (NOD is a condition node; specifically, a "bump" node)
77 C> - 6 character '#' found (NOD is a condition node)
78 C> @param[out] VAL - real: condition value associated with condition character found in utg:
79 C> - 0 = UTG does not have a condition character
80 C>
81 C> @author Woollen @date 1994-01-06
82  SUBROUTINE parutg(LUN,IO,UTG,NOD,KON,VAL)
83 
84  USE moda_msgcwd
85  USE moda_tables
86 
87  COMMON /utgprm/ picky
88 
89  CHARACTER*(*) UTG
90  CHARACTER*128 BORT_STR1,BORT_STR2
91  CHARACTER*20 ATAG
92  CHARACTER*3 ATYP,BTYP
93  CHARACTER*1 COND(6)
94  dimension btyp(8),iok(8)
95  LOGICAL PICKY
96 
97  DATA nchk / 8/
98  DATA btyp /'SUB','SEQ','REP','RPC','RPS','DRB','DRP','DRS'/
99  DATA iok / -1 , -1 , -1 , -1 , -1 , 0 , 0 , 0 /
100 
101 C----------------------------------------------------------------------
102 C For now, set PICKY (see below) to always be .FALSE.
103  picky = .false.
104  cond(1) = '='
105  cond(2) = '!'
106  cond(3) = '<'
107  cond(4) = '>'
108  cond(5) = '^'
109  cond(6) = '#'
110  ncond = 6
111 C----------------------------------------------------------------------
112 
113  atag = ' '
114  atyp = ' '
115  kon = 0
116  nod = 0
117  val = 0
118  ltg = min(20,len(utg))
119 
120 C PARSE UTG, SAVING INTO ATAG ONLY CHARACTERS PRIOR TO CONDITION CHAR.
121 C --------------------------------------------------------------------
122 
123 C But first, take care of the special case where UTG denotes the
124 C short (i.e. 1-bit) delayed replication of a Table D mnemonic.
125 C This will prevent confusion later on since '<' and '>' are each
126 C also valid as condition characters.
127 
128  IF((utg(1:1).EQ.'<').AND.(index(utg(3:),'>').NE.0)) THEN
129  atag = utg
130  GO TO 1
131  ENDIF
132 
133  DO i=1,ltg
134  IF(utg(i:i).EQ.' ') GOTO 1
135  DO j=1,ncond
136  IF(utg(i:i).EQ.cond(j)) THEN
137  kon = j
138  icv = i+1
139  GOTO 1
140  ENDIF
141  ENDDO
142  atag(i:i) = utg(i:i)
143  ENDDO
144 
145 C FIND THE NODE ASSOCIATED WITH ATAG IN THE SUBSET TABLE
146 C ------------------------------------------------------
147 
148 1 inod = inode(lun)
149  DO nod=inod,isc(inod)
150  IF(atag.EQ.tag(nod)) GOTO 2
151  ENDDO
152 
153 C ATAG NOT FOUND IN SUBSET TABLE
154 C ------------------------------
155 
156 C So what do we want to do? We could be "picky" and abort right
157 C here, or we could allow for the possibility that, e.g. a user
158 C application has been streamlined to always call UFBINT with the
159 C same STR, even though some of the mnemonics contained within that
160 C STR may not exist within the sequence definition of every
161 C possible type/subtype that is being written by the application.
162 C In such cases, by not being "picky", we could just allow BUFRLIB
163 C to subsequently (and quietly, if IPRT happened to be set to -1
164 C in COMMON /QUIET/!) not actually store the value corresponding
165 C to such mnemonics, rather than loudly complaining and aborting.
166 
167  IF(kon.EQ.0 .AND. (io.EQ.0.OR.atag.EQ.'NUL'.OR..NOT.picky)) THEN
168 C i.e. (if this tag does not contain any condition characters)
169 C .AND.
170 C ((either the file is open for input) .OR.
171 C (the tag consists of 'NUL') .OR.
172 C (we aren't being "picky"))
173  nod = 0
174  GOTO 100
175  ELSE
176 C abort...
177  GOTO 900
178  ENDIF
179 
180 C ATAG IS FOUND IN SUBSET TABLE, MAKE SURE IT HAS A VALID NODE TYPE
181 C -----------------------------------------------------------------
182 
183 2 IF(kon.EQ.5) THEN
184 c .... Cond. char "^" must be assoc. with a delayed replication
185 c sequence (this is a "bump" node) (Note: This is obsolete but
186 c remains for "old" programs using the BUFR ARCHIVE LIBRARY)
187  IF(typ(nod-1).NE.'DRP' .AND. typ(nod-1).NE.'DRS') GOTO 901
188  ELSEIF(kon.NE.6) THEN
189 C Allow reading (but not writing) of delayed replication factors.
190  atyp = typ(nod)
191  DO i=1,nchk
192  IF(atyp.EQ.btyp(i) .AND. io.GT.iok(i)) GOTO 902
193  ENDDO
194  ENDIF
195 
196 C IF CONDITION NODE, GET CONDITION VALUE WHICH IS A NUMBER FOLLOWING IT
197 C ---------------------------------------------------------------------
198 
199  IF(kon.NE.0) THEN
200  CALL strnum(utg(icv:ltg),num,ier)
201  IF(ier.LT.0) GOTO 903
202  val = num
203  ENDIF
204 
205 C EXITS
206 C -----
207 
208 100 RETURN
209 900 WRITE(bort_str1,'("BUFRLIB: PARUTG - TRYING TO WRITE A MNEMONIC'//
210  . ' (",A,") WHICH DOES NOT EXIST IN SUBSET TABLE")') atag
211  WRITE(bort_str2,'(18X,"(UPON INPUT, IT CONTAINED THE CONDITION '//
212  . 'CHARACTER ",A,")")') utg(icv-1:icv-1)
213  CALL bort2(bort_str1,bort_str2)
214 901 WRITE(bort_str1,'("BUFRLIB: PARUTG - BUMP NODE (MNEMONIC ",A,")'//
215  . ' MUST REFER TO A DELAYED REPLICATION SEQUENCE, HERE TYPE IS "'//
216  . ',A)') atag,typ(nod-1)
217  CALL bort(bort_str1)
218 902 WRITE(bort_str1,'("BUFRLIB: PARUTG - ILLEGAL NODE TYPE: ",A," '//
219  . 'FOR MNEMONIC ",A)') atyp,atag
220  CALL bort(bort_str1)
221 903 WRITE(bort_str1,'("BUFRLIB: PARUTG - CONDITION VALUE IN '//
222  . 'MNEMONIC ",A," ILLEGAL BECAUSE ALL OTHER CHARACTERS IN '//
223  . 'MNEMONIC MUST BE NUMERIC")') utg
224  CALL bort(bort_str1)
225  END
subroutine bort2(STR1, STR2)
Log two error messages and abort application program.
Definition: bort2.f:18
subroutine bort(STR)
Log one error message and abort application program.
Definition: bort.f:18
This module contains declarations for arrays used to store information about the current BUFR message...
integer, dimension(:), allocatable inode
Table A mnemonic for type of BUFR message.
This module contains array and variable declarations used to store the internal jump/link table.
integer, dimension(:), allocatable isc
Scale factors corresponding to tag and typ:
character *3, dimension(:), allocatable typ
Type indicators corresponding to tag:
character *10, dimension(:), allocatable tag
Mnemonics in the jump/link table.
subroutine parutg(LUN, IO, UTG, NOD, KON, VAL)
Parse a mnemonic from a character string.
Definition: parutg.f:83
recursive subroutine strnum(str, num, iret)
Decode an integer from a character string.
Definition: strnum.F90:24