############################################################################
#
#	File:     patfetch.icn
#
#	Subject:  Program to extract patterns from a file
#
#	Author:   Ralph E. Griswold
#
#	Date:     July 22, 1993
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#
#  This program accepts a list of integer specifications for patterns
#  as the appear in order in a file of patterns.  The selected patterns
#  are written to standard output, but not until the end of the input
#  specifications.  The name of the pattern file is specified on the
#  command line.
#
#  Each line of input can be a comma-separated string of either integers
#  or integer ranges.  Blanks after commas are tolerated.  An example of
#  input is:
#
#	1-3, 5
#	10
#	13-17
#	8
#
#  which specifies the patterns 1, 2, 3, 5, 8, 10, 13, 14, 15, 16, and 17.
#
#  Note that the integers need not be in order, although within a range,
#  the lower bound must precede the upper bound.
#
############################################################################
#
#  Links:  patutils
#
############################################################################

link patutils

procedure main(args)
   local file, input, i, hitlist, patlist, spec, lo, hi, subspec

   file := args[1] | stop("*** no pattern list specified")

   input := open(file) | stop(" *** cannot open input file")
 
   hitlist := set()			# construct set of indices to remove

   while spec := read() do {
      spec ? {
         while subspec := tab(upto(',') | 0) do {
            if insert(hitlist, integer(subspec)) then {		# integer
               move(1) | break
               tab(many(' '))
               }
            else {
               subspec ? {
                  lo := tab(many(&digits)) &
                  ="-" &
                  hi := tab(many(&digits)) &
                  lo <= hi &
                  pos(0) | write(&errout, "*** bad specification")
                  every insert(hitlist, 0 < integer(lo to hi))
                  }
               move(1) | break
               tab(many(' '))
               }
            }
         }
      }

   patlist := []			# read in list of patterns

   while put(patlist, readpatt(input))
   
   every i := !sort(hitlist) do {		# write out selected patterns
      write(patlist[i]) | write(&errout, "*** ", i, " out of bounds")
      }

end
