11 Character handling routines

A set of portable routines to perform tasks associated with character handling is available within ADAM. These routines have the prefix CHR, and a complete description of the specifications is given in SUN/40. Appendix E gives a list of all the routines together with their argument lists and a short description of their functions. The appendix also indicates whether each routine is implemented as a subroutine or a function. (Functions must be declared with the appropriate type in the programs using them.) The CHR library is automatically linked during the ALINK procedure. Several of the most useful CHR routines are considered below.

One set of routines can be characterised as having the form CHR_xTOy where x and y are each one of C, D, I, L & R corresponding to type CHARACTER, DOUBLE, INTEGER, LOGICAL & REAL respectively. For example the call below will encode the real number X as a string:

        CALL CHR_RTOC (X, STRING, NCHAR)

NCHAR is the number of characters in the returned STRING. Thus if X=1237.4, STRING is returned as ’1237.4’ and NCHAR becomes 6.

The example program REPDIM1 in Section 5 reported the dimensions of the input data array one after another. A tidier result can be achieved by building a string using a succession of CHR_PUTx calls, where as above, x can be any of C, D, I, L or R. These calls have the form:

        CALL CHR_PUTx (VALUE, STRING, NCHAR)

where VALUE is a value of appropriate type, STRING is a character string which has the encoded value appended, and NCHAR on entry contains the position in the STRING at which the encoded VALUE is inserted and contains the length of the new string on return. The code to report the array dimensions can be changed to:

  *   Report the dimensions.
        NCHAR = 0
        CALL CHR_PUTC (’Array dimensions are ’, STRING, NCHAR)
        DO  I = 1, NDIM
  *      Add a ‘x’ between the dimensions if there are more than one.
           IF (I.GT.1) CALL CHR_PUTC (’ x ’, STRING, NCHAR)
  *      Add the next dimension to the string.
           CALL CHR_PUTI (DIM(I), STRING, NCHAR)
        ENDDO
        CALL MSG_OUT (’  ’, STRING, STATUS)

ADAM_EXAMPLES:REPDIM2.FOR contains this modification. Running this program on the datafile IMAGE.SDF produces the output below:

  No. of dimensions is 2
  Array dimensions are 256 x 256

Another common use for the CHR routines is in the ‘cleaning’ and comparison of strings. The fragment of code below is used to remove blanks and determine if the units given in the two strings are the same.

        CHARACTER*(100) STRNG1, STRNG2
        LOGICAL YES
        LOGICAL CHR_SIMLR                   ! Logical external Function.
  *     ...
        STRNG1 = ’   ERGS / ( CM ** 2 * S )’
        STRNG2 = ’ergs/(cm**2*s)’
  
        CALL CHR_RMBLK (STRNG1)         ! Remove blanks from STRNG1
        CALL CHR_RMBLK (STRNG2)         ! Remove blanks from STRNG2
        YES =CHR_SIMLR (STRNG1, STRNG2) ! Determine if strings equal apart from case.

A more ambitious example taken from ADAM_EXAMPLES:GETEBV.FOR follows. The extract below compares an input object name, OBJECT, with star names in a text file (EBV.DAT) and if a match is found, the value (the EBV) associated with the star is reported. The text file format is:

  * E(B-V) calculated from intrinsic photometry. (Accurate to within 0.03.)
  *  HD#     E(B-V)
     HD886   0.02
    HD1337   0.18
     ..        ..

The code first tidies the input string OBJECT by removing blanks. The first character of OBJECT is then tested to see if it is a number. If only the number has been given, the string ’HD’ is added at the beginning. Each line in the text file is now read; blank lines and lines beginning with ‘*’ are ignored. Other lines are decoded into words. On each line the first word is the star name and the second is a string containing the EBV associated with that star. The star name on each line is compared with OBJECT. If a match is found the second word on that line is decoded into a real value and reported.

  *   Remove all blanks.
        CALL CHR_RMBLK (OBJECT)
  
  *   If only the number is given, prefix this with ’HD’.
        IF (CHR_ISDIG(OBJECT (1:1))) THEN
           NCHAR = CHR_LEN(OBJECT)
           OBJECT(1:NCHAR+2) = ’HD’//OBJECT(1:NCHAR)
        ENDIF
  
  *   Now work through list of objects, trying to find a matching name
        FOUND = .FALSE.
        IOSTAT = 0
        DO WHILE (.NOT.FOUND)
  
  *      Read a line from the file.
           READ (UNIT, ’ (A)’, IOSTAT=IOSTAT, END=998) LINE
           IF (IOSTAT.NE.0) GOTO 997
  
  *      Ignore blank lines or lines beginning with ‘*’.
           IF (.NOT.((CHR_LEN(LINE).EQ.0) .OR. (LINE(1:1).EQ.’*’))) THEN
  
  *         Decode line into words.
              CALL CHR_DCWRD (LINE, 2, NWRD, START, STOP, WORDS, LSTAT)
  
  *         See if first word (containing star name) matches OBJECT.
              SAME = CHR_SIMLR (WORDS (1), OBJECT)
  
              IF (SAME) THEN
                 FOUND = .TRUE.
  
  *            Second word contains EBV. Encode this string as a REAL.
                 CALL CHR_CTOR (WORDS (2), EBV, STATUS)
  
  *            Output the star name and the associated EBV.
                 CALL MSG_SETC (’OBJECT’, OBJECT)
                 CALL MSG_FMTR (’EBV’, ’(F4.2)’, EBV)
                 CALL MSG_OUT (’ ’,’Star ^OBJECT has E(B-V)=^EBV’, STATUS)
              END IF
           END IF
        END DO