Index of Functions: A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X 
Index Page
locln

Table of contents
Procedure
Abstract
Required_Reading
Keywords
Declarations
Brief_I/O
Detailed_Input
Detailed_Output
Parameters
Exceptions
Files
Particulars
Examples
Restrictions
Literature_References
Author_and_Institution
Version

Procedure

     LOCLN ( Locate lines in a text file )

     SUBROUTINE LOCLN ( UNIT, BMARK, EMARK, LINE, BLINE, ELINE, FOUND )

Abstract

     Locate a group of lines in a text file delimited by markers.

Required_Reading

     None.

Keywords

     FILES
     TEXT

Declarations

     IMPLICIT NONE

     INTEGER               UNIT
     CHARACTER*(*)         BMARK
     CHARACTER*(*)         EMARK
     CHARACTER*(*)         LINE
     INTEGER               BLINE
     INTEGER               ELINE
     LOGICAL               FOUND

Brief_I/O

     VARIABLE  I/O  DESCRIPTION
     --------  ---  --------------------------------------------------
     UNIT       I   Logical unit connected to text file.
     BMARK      I   Begin marker.
     EMARK      I   End marker.
     LINE      I-O  Workspace.
     BLINE      O   Beginning line.
     ELINE      O   Ending line.
     FOUND      O   Markers found?

Detailed_Input

     UNIT     is a logical unit that has been connected to a
              text file by the calling program. Use the routine
              TXTOPR to open the file for read access and get its
              logical unit. The file pointer may be pointing to
              any line in the file due to previous read statements,
              for example, or due to previous calls to LOCLN.

     BMARK,
     EMARK    are markers that delimit some group of lines in
              the part of the file following the current position
              of the file pointer. The group begins with the
              first line equivalent to BMARK and ends with the
              next line equivalent to EMARK, ignoring leading
              and trailing blanks.

              If BMARK is blank, the group of lines begins with
              the first line following the current position of the
              file pointer; if EMARK is blank, the group of lines
              ends with the last line in the file.

      LINE       on input, is an arbitrary character string whose
              contents are ignored. LINE is used to read lines
              from the file connected to UNIT; its function
              is to determine the maximum length of the lines
              that can be read from the file. Lines longer
              than the declared length of LINE are truncated
              as they are read.

Detailed_Output

     LINE     on output, is undefined.

     BLINE,
     ELINE    are the line numbers of the first and last lines
              in the group delimited by BMARK and EMARK.

              By convention, the first line read by the routine
              is line 1; the second line is line 2; and so on.
              If BMARK is blank, BLINE will be 1.

     FOUND    is .TRUE. if a group of lines delimited by BMARK and
              EMARK is found, and is .FALSE. otherwise. ELINE is
              the last line read by LOCLN, so if FOUND is .TRUE.,
              the file pointer will be positioned on the line
              after ELINE.

Parameters

     None.

Exceptions

     1)  If FOUND is .FALSE., the values of BLINE and ELINE are not
         changed.

     2)  If an error occurs while reading from the input file,
         the error SPICE(FILEREADFAILED) is signaled.

     3)  Lines in the file that are longer than the declared length of
         LINE are truncated as they are read. If the truncation of
         line containing a marker causes truncation of that marker,
         it will not match the input value for that marker, so
         FOUND will be .FALSE.

Files

     See argument UNIT.

Particulars

     This routine locates delimited groups of lines in a text file.
     This allows files to be partitioned into sub-files; it also
     allows related inputs to be grouped together in a relatively
     free-format way.

Examples

     1) Let FILE.TXT be a text file that contains the following lines.
        (The lines are numbered for reference, but these numbers do
        not appear in the file).

           1    BEGIN POEM
           2       Oh snail,
           3       Climb Mount Fuji,
           4       But slowly, slowly!
           5    END POEM
           6
           7    BEGIN PROSE
           8       Lady, one of us has this book open
           9       to the wrong page.
           10   END PROSE
           11
           12   BEGIN POEM
           13      John Keats, John Keats,
           14      John,
           15      Put your scarf on.
           16   END POEM
           17
           18   BEGIN QUOTE
           19      That's not writing. That's typing.
           20
           21               (Truman Capote on Jack Kerouac)
           22   END QUOTE
           23
           24   BEGIN POEM
           25      Twice five syllables
           26      Plus seven isn't much, but
           27      That's haiku for you.
           28   BEGIN POEM
           29
           30   BEGIN EQUATION
           31            2
           32      e = mc
           33   END EQUATION

     Then the code fragment

           CALL TXTOPR ( 'FILE.TXT', UNIT )

           BMARK = 'BEGIN POEM'
           EMARK = 'END POEM'

           CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )

           DO WHILE ( FOUND )
              WRITE (*,*) 'Found poem between lines ', B, ' and ', E

              CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )
           END DO

     produces the following report:

           Found poem between lines   1 and   5
           Found poem between lines   7 and  11
           Found poem between lines   8 and  12

     Note that line numbers are returned relative to the position
     of the file pointer when LOCLN is called. The following code
     fragment generates the numbers relative to the start of the
     file.

           REWIND ( UNIT )

           OFFSET = 0
           CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )

           DO WHILE ( FOUND )
              WRITE (*,*) 'Found poem between lines ',
          .                OFFSET + B,
          .                ' and ',
          .                OFFSET + E

              OFFSET = OFFSET + E
              CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )
           END DO

           CLOSE ( UNIT )

     The following report is produced:

           Found poem between lines   1 and   5
           Found poem between lines  12 and  16
           Found poem between lines  24 and  28


     2) Given the same file, the code fragment

           CALL TXTOPR ( 'FILE.TXT', UNIT )

           CALL LOCLN ( UNIT,
          .             'begin poem',
          .             'end poem',
          .             LINE,
          .             B,
          .             E,
          .             FOUND )

           CLOSE ( UNIT )

     finds nothing because case is significant: FOUND is false,
     and B and E are unchanged.

     3) This code fragment

           CALL TXTOPR ( 'FILE.TXT', UNIT )

           CALL LOCLN ( UNIT,
          .             ' ',
          .             'BEGIN PROSE',
          .             LINE,
          .             B,
          .             E,
          .             FOUND )

           CLOSE ( UNIT )

     when executed on the same file returns B = 1 and E = 7.
     In effect, a blank begin marker "matches" the first line
     that is read.

     Similarly, a blank end marker "matches" the last line of
     the file, the code fragment

           CALL TXTOPR ( 'FILE.TXT', UNIT )

           CALL LOCLN ( UNIT,
          .             'BEGIN QUOTE',
          .             ' ',
          .             LINE,
          .             B,
          .             E,
          .             FOUND )

           CLOSE ( UNIT )

     when executed on the same file returns B = 18 and E = 33.
     If both markers are blank, LOCLN basically counts the lines
     in the file.

     4) The code fragment

           CALL TXTOPR ( 'FILE.TXT', UNIT )

           MARK = 'BEGIN POEM'

           CALL LOCLN ( UNIT, MARK, MARK, LINE, FIRST, SECOND, FOUND )

           CLOSE ( UNIT )

     returns FIRST = 1 and SECOND = 12 -- the first two lines that
     are equivalent to MARK.

     5) Nesting is not supported. That is, if UNIT is connected to
     a file containing the following lines (ignoring line numbers),

           1   Begin Object
           2     Begin Object
           3       Begin Object
           4         Just kidding!
           5       End Object
           6     End Object
           7   End Object

           REWIND ( UNIT )

           CALL LOCLN ( UNIT,
          .             'Begin Object'
          .             'End Object',
          .             LINE,
          .             B,
          .             E,
          .             FOUND )

     returns B = 1 and E = 5, not E = 7.

     6) Let UNIT be connected to a text file containing the
     following lines, again ignoring line numbers which are
     listed for easy reference.

           1    The first case tests the capability of ...
           2
           3    NEW CASE
           4       TARGET = JUPITER
           5       EPOCH  = 21 JUN 1992 13:04
           6    END CASE
           7
           8    The next case uses a different target and a slightly
           9    longer exposure time...
           10
           11   NEW CASE
           12      TARGET   = IO
           13      EPOCH    = 21 JUN 1992 13:04
           14      EXPOSURE = 2.44 SECONDS
           15   END CASE
           16
           17   The next case changes targets in order to...
           18
           19   NEW CASE
           20      TARGET   = EUROPA
           21      EPOCH    = 21 JUN 1992 13:04
           22      EXPOSURE = 2.44 SECONDS
           23   END CASE

     Then the code fragment

           REWIND ( UNIT )

           BMARK = 'NEW CASE'
           EMARK = 'END CASE'

           CASES  = 0
           OFFSET = 0
           CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )

           DO WHILE ( FOUND )
              CASES      = CASES  + 1
              BEG(CASES) = OFFSET + B
              END(CASES) = OFFSET + E

              OFFSET = OFFSET + E
              CALL LOCLN ( UNIT, BMARK, EMARK, LINE, B, E, FOUND )
           END DO

     saves the locations of the various input cases (skipping past
     the intervening commentary) in the arrays BEG and END. After
     running the code, CASES, BEG, and END have the following values:

           CASES = 3
           BEG   = 3,  11,  19
           END   = 6,  15,  23

     The following code fragment retrieves the i'th case.

           REWIND ( UNIT )

           DO J = 1, BEG(I) - 1
              READ (UNIT,FMT='(A)') LINE
           END DO

           DO J = BEG(I), END(I)
              READ (UNIT,FMT='(A)') LINE
               .
               .  Process the line
               .
           END DO

     While this isn't an incredibly efficient way to process
     large files, it can be effective for smaller files.

Restrictions

     None.

Literature_References

     None.

Author_and_Institution

     J. Diaz del Rio    (ODC Space)
     J.E. McLean        (JPL)
     W.L. Taber         (JPL)

Version

    SPICELIB Version 1.1.0, 12-AUG-2021 (JDR)

        Added IMPLICIT NONE statement.

        Edited the header to comply with NAIF standard.

    SPICELIB Version 1.0.1, 10-MAR-1992 (WLT)

        Comment section for permuted index source lines was added
        following the header.

    SPICELIB Version 1.0.0, 05-APR-1991 (JEM)
Fri Dec 31 18:36:32 2021