home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-19 | 32.2 KB | 1,141 lines |
- Newsgroups: comp.sources.misc
- From: goer@midway.uchicago.edu (Richard L. Goerwitz)
- Subject: v23i068: quranref - Holy Qur'an word and passage based retrievals, Part02/08
- Message-ID: <1991Oct19.022225.12778@sparky.imd.sterling.com>
- X-Md4-Signature: 6092c0a6f024eb5140db5e6976730af1
- Date: Sat, 19 Oct 1991 02:22:25 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: goer@midway.uchicago.edu (Richard L. Goerwitz)
- Posting-number: Volume 23, Issue 68
- Archive-name: quranref/part02
- Environment: Icon
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # this is quranref.02 (part 2 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file listutil.icn continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 2; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping listutil.icn'
- else
- echo 'x - continuing file listutil.icn'
- sed 's/^X//' << 'SHAR_EOF' >> 'listutil.icn' &&
- X # then clear lines until we reach it...
- X if i-1 ~= lines+1 then {
- X every j := i to lines do {
- X iputs(igoto(getval("cm"), 1, j))
- X normal(); iputs(getval("ce"))
- X }
- X }
- X # Display message on status line.
- X status_line("-- " || \msg || " --" | "", "", "c")
- X
- X # If we're to the end of the screen, and there's still more to
- X # display, then...
- X if *l > lines-1 & (offset+i) ~= (*l+1) then {
- X rsp := snarf_input("Press !/b/c/m/v (q = quit viewing): ")
- X case map(rsp) of {
- X "" : offset := (*l > (offset+1))
- X "!" : push_shell()
- X "b" : offset := (0 < offset-lines+1) | 0
- X "c" : next
- X "m" : (offset := (*l > (offset+i-1)))
- X "q" : break
- X "v" : {
- X rsp2 := snarf_input("View which list: ")
- X rsp2 == "q" & next
- X rsp2 == "" & rsp2 := \last_viewed
- X if last_viewed := integer(rsp2) then {
- X if 0 < last_viewed <= *l
- X then return last_viewed
- X else err_message("Out of range.")
- X }
- X else err_message("Invalid list number.")
- X }
- X default : {
- X err_message("Command invalid in this context.")
- X }
- X }
- X }
- X # ...otherwise, we've displayed everything.
- X else {
- X prompt := "c/v (q to go to previous menu): "
- X if *l <= lines
- X then rsp:= snarf_input("Press !/" || prompt) | next
- X else rsp := snarf_input("Press !/b/" || prompt) | next
- X case map(rsp) of {
- X "!" : push_shell()
- X "b" : offset := (0 < offset-lines+1) | 0
- X "c"|"" : next
- X "m" : next # no more to display; just stay were we are
- X "q" : break
- X "v" : {
- X rsp2 := snarf_input("View which list: ")
- X rsp2 == "q" & next
- X rsp2 == "" & rsp2 := \last_viewed
- X if last_viewed := integer(rsp2) then {
- X if 0 < last_viewed <= *l
- X then return last_viewed
- X else err_message("Out of range.")
- X }
- X else err_message("Invalid list number.")
- X }
- X default : {
- X err_message("Command invalid in this context.")
- X }
- X }
- X }
- X }
- X return
- X
- Xend
- X
- X
- X
- Xprocedure search_list(lst_rec, direction, lines)
- X
- X local resp, subscript, ltrs, last_ltrs
- X # global _subscripts
- X
- X direction == ("?"|"/") | fail
- X
- X if pos(0) then {
- X resp := snarf_input("Enter pattern (q to abort): ")
- X resp == (""|"q") & fail
- X }
- X else resp := tab(0)
- X
- X if direction == "/"
- X then _subscripts := create { lst_rec.pos+2 to *lst_rec.l }
- X else _subscripts := create { lst_rec.pos to 1 by -1 }
- X
- X message("Searching...")
- X
- X# A probably futile attempt at optimization....
- X# last_ltrs := {
- X# if resp ? (tab(any(&digits)) | &null, tab(many(&letters)), pos(0))
- X# then "" else &null
- X# }
- X
- X while subscript := @_subscripts do {
- X# See above on futile attempts....
- X# if \last_ltrs then {
- X# convertb(lst_rec.l[subscript],kjv_filename) ?
- X# ltrs := (tab(any(&digits)) | "") || tab(many(&letters))
- X# (last_ltrs ~==:= ltrs) | next
- X# }
- X if findre(resp, convertb(lst_rec.l[subscript],kjv_filename)) then {
- X message("Done.")
- X return subscript-1
- X }
- X }
- X err_message("Pattern not found.")
- X return lst_rec.pos
- X
- Xend
- SHAR_EOF
- echo 'File listutil.icn is complete' &&
- true || echo 'restore of listutil.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= passutil.icn ==============
- if test -f 'passutil.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping passutil.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting passutil.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'passutil.icn' &&
- X############################################################################
- X#
- X# Name: 1.20
- X#
- X# Title: utilities for displaying passages
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: passutil.icn
- X#
- X############################################################################
- X#
- X# Contains:
- X#
- X# display_passage(ref), which displays ref, but fails if ref
- X# either can't be converted to a bitmap or else can, but
- X# doesn't correspond to any text in the main file
- X#
- X# listpassage(l, msg, width), which displays the lines contained
- X# in list l, truncating them to width, and displaying msg
- X# both near the top of the screen and on the status line
- X#
- X# writepassage(l, msg, switch), which writes list l to a file
- X# (the name of which it prompts the user to enter); if switch
- X# is nonnull, then it appends l to the file the user enters,
- X# rather then overwriting it
- X#
- X# get_{next,prev}_passage(), which generates the bitmap for the
- X# next/previous reference in the KJV file
- X#
- X# push_shell(), which suspends bibleref, and starts up either
- X# /bin/sh, or the program named in the SHELL environment
- X# variable.
- X#
- X############################################################################
- X#
- X# Links: ./rewrap.icn
- X#
- X# See also: ./bibleref.icn
- X#
- X############################################################################
- X
- X
- Xprocedure display_passage(passage_ref)
- X
- X local msg, d_list, bitmap, text
- X static width
- X # global kjv_filename
- X initial {
- X # decide how long to make lines. The display procedures
- X # listpassage leaves a margin on the left (8 spaces). On
- X # a typical display, it looks nice to leave about nine
- X # spaces on the other side. This leaves getval("co")-17
- X # spaces left for text in between. The space left for
- X # text here is stored in the static variable "width."
- X width := (18 < getval("co")-17) |
- X quit("display_passage","your terminal is too narrow",98)
- X }
- X
- X # Try to convert passage_ref to a retrieve-format bitmap.
- X if type(passage_ref) == "string" then {
- X *passage_ref > 0 | fail
- X bitmap := ref_2_bitmap(passage_ref, kjv_filename) | fail
- X }
- X # If the passage_ref is not a string, the it's probably already
- X # been converted; try to use it as-is.
- X else bitmap := passage_ref
- X
- X repeat {
- X
- X message("Locating text in main file...")
- X # Now check to see if the passage is present in the indexed text.
- X text := bitmap_2_text(bitmap, kjv_filename) | {
- X err_message("No such passage in " || kjv_filename || ".")
- X fail
- X }
- X # Rewrap passage to width characters per line; put them into a list.
- X d_list := []
- X every put(d_list, rewrap(text, width-1))
- X put(d_list, rewrap(&null, width-1))
- X
- X # Get the name of the current passage, using standard abbrevs.
- X msg := convertb(bitmap, kjv_filename)
- X
- X # Display passage.
- X bitmap := listpassage(bitmap, d_list, msg, width) | fail
- X # If bitmap ends up null, then return.
- X if /bitmap then return
- X
- X }
- X
- Xend
- X
- X
- X
- Xprocedure listpassage(bitmap, l, msg, width)
- X
- X local offset, ss, done, i, j, n, rsp, result, prompt
- X static lines, top_margin
- X initial {
- X (lines := getval("li")-4) > 6 |
- X quit("listpassage", "your terminal isn't tall enough", 96)
- X top_margin := 3
- X }
- X
- X # "l" is a list of lines to print
- X # "msg" is the message to put on the status line
- X # "width" gives the length to which lines in l are truncated
- X
- X offset := 0
- X repeat {
- X
- X # Set up top margin.
- X every j := 1 to top_margin do {
- X iputs(igoto(getval("cm"), 1, j))
- X if j = 2 then {
- X writes(repl(" ",3))
- X underline()
- X writes(msg)
- X }
- X normal(); iputs(getval("ce"))
- X }
- X
- X i := 0
- X while *l >= (ss := offset + (lines > (i +:= 1))) do {
- X iputs(igoto(getval("cm"), 1, i+top_margin))
- X normal(); iputs(getval("ce"))
- X writes(repl(" ", 8), l[ss][1:\width|0])
- X }
- X
- X # If we haven't reached the end of the displayable screen,
- X # then clear lines until we reach it...
- X if i-1 ~= lines then {
- X every j := (i+top_margin) to lines+1 do {
- X iputs(igoto(getval("cm"), 1, j))
- X normal(); iputs(getval("ce"))
- X }
- X }
- X status_line("** " || \msg || " **" | "", "", "c")
- X
- X # If there's more to do, but we're at the end of the display,
- X # then...
- X if *l > lines-1 & (offset+i) ~= (*l+1) then {
- X rsp := snarf_input("Enter passage or !/a/b/c/m/w/+/- _
- X (q to quit viewing): ")
- X if result := display_passage(rsp) then {
- X return result
- X } else {
- X case map(rsp) of {
- X "" : offset := (*l > (offset+1))
- X "!" : push_shell()
- X "a" : write_passage(l, msg, "append")
- X "b" : offset := (0 < offset-lines+1) | 0
- X "c" : next
- X "m" : offset := (*l > (offset+i-1))
- X "+" : return get_next_bitmap(bitmap)
- X "-" : return get_prev_bitmap(bitmap)
- X "q" : return
- X "w" : write_passage(l, msg)
- X default : err_message("Command invalid in this context.")
- X }
- X }
- X }
- X # ...otherwise, we've displayed everything.
- X else {
- X prompt := "c/w/+/- (q to go to previous menu): "
- X if *l <= lines
- X then rsp:= snarf_input("Enter passage or !/a/" || prompt) | next
- X else rsp := snarf_input("Enter passage or !/a/b/" || prompt) | next
- X if result := display_passage(rsp) then {
- X return result
- X } else {
- X case map(rsp) of {
- X "!" : push_shell()
- X "a" : write_passage(l, msg, "append")
- X "b" : offset := (0 < offset-lines+1) | 0
- X "c"|"" : next
- X "m" : next
- X "+" : return get_next_bitmap(bitmap)
- X "-" : return get_prev_bitmap(bitmap)
- X "q" : return
- X "w" : write_passage(l, msg)
- X default : err_message("Command invalid in this context.")
- X }
- X }
- X }
- X }
- X
- Xend
- X
- X
- X
- Xprocedure write_passage(passage_list, msg, switch)
- X
- X local fname, outtext, firstchar
- X
- X # Get straight whether we are appending or clobbering.
- X (/switch := "w") | (switch := "a")
- X
- X until \outtext do {
- X fname := snarf_input("Enter filename (! for shell; q to quit): ")
- X fname ? {
- X firstchar := move(1) | ""
- X case firstchar of {
- X "" : fail
- X "!" : push_shell() & initialize_screen()
- X "q" : pos(0) & fail
- X default : {
- X outtext := open(fname, switch) | {
- X case switch of {
- X "a" : err_message("Can't append to "|| fname||".")
- X "w" : err_message("Cannot write to "|| fname||".")
- X default : quit("write_passage","internal error",80)
- X }
- X }
- X }
- X }
- X }
- X }
- X message("Writing.")
- X write(outtext, "::", msg)
- X every write(outtext,!passage_list)
- X close(outtext)
- X message("Done.")
- X return
- X
- Xend
- X
- X
- X
- Xprocedure get_next_bitmap(lastone)
- X
- X local next_bitmap
- X initial message("Reading limits file...")
- X
- X next_bitmap := NextBitmap(lastone, kjv_filename) | {
- X err_message(convertb(lastone, kjv_filename) || " has no successor.")
- X return lastone
- X }
- X return next_bitmap
- X
- Xend
- X
- X
- X
- Xprocedure get_prev_bitmap(lastone)
- X
- X local prev_bitmap
- X initial message("Reading limits file...")
- X
- X prev_bitmap := PrevBitmap(lastone, kjv_filename) | {
- X err_message(convertb(lastone, kjv_filename) || " has no predecessor.")
- X return lastone
- X }
- X return prev_bitmap
- X
- Xend
- X
- X
- X
- Xprocedure push_shell()
- X
- X local status
- X static shell
- X initial shell := getenv("SHELL") | "/bin/sh"
- X
- X tab(match("!"))
- X clear()
- X if pos(0)
- X then status := system(shell)
- X else {
- X status := system(shell || " -c '" || tab(0) || "'")
- X write("\n\n")
- X message("Please press return to re-enter Bibleref.")
- X read(&input)
- X }
- X clear()
- X
- X return status
- X
- Xend
- SHAR_EOF
- true || echo 'restore of passutil.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= readfile.icn ==============
- if test -f 'readfile.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping readfile.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting readfile.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'readfile.icn' &&
- X############################################################################
- X#
- X# Name: readfile.icn
- X#
- X# Title: read Bibleref files
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.3
- X#
- X############################################################################
- X#
- X# Contains readfile(), which reads a file from disk into memory.
- X# Detects automatically whether the file contains passages or only
- X# passage references. Converts both into Bibleref-format bitmap
- X# lists. Files may be in one of two formats: 1) ::key + text format
- X# (the format used when you write a passage to disk from within
- X# Bibleref), and 2) a list of references:
- X#
- X# 1. Gen 1:3
- X# 2. Exod 2:4
- X# 3. Lev 3:5
- X# etc.
- X#
- X# This is the format Bibleref uses when you write one of its
- X# internally generated passage lists to disk. The numbers+period
- X# are optional.
- X#
- X############################################################################
- X#
- X# Links: ./bibleref.icn ./ref2bmap.icn
- X#
- X# See also:
- X#
- X############################################################################
- X
- X
- Xprocedure readfile()
- X
- X local intext, fname, bitmap_list, firstline, line, firstchar
- X
- X until \intext do {
- X fname := snarf_input("Enter filename (! for shell; q to quit): ")
- X fname ? {
- X firstchar := move(1) | ""
- X case firstchar of {
- X "" : fail
- X "!" : push_shell() & initialize_screen()
- X "q" : pos(0) & fail
- X default : {
- X intext := open(fname) | {
- X err_message("Can't open " || fname || ".")
- X }
- X }
- X }
- X }
- X }
- X message("Reading.")
- X
- X bitmap_list := []
- X until firstline := ("" ~== trim(read(intext) | {
- X err_message("Empty file.")
- X fail
- X }))
- X firstline ? {
- X # If the first nonblank line shows the file to be in gettext
- X # format, then it was written by write_passage(), and we need
- X # only read in keys.
- X if ="::" & put(bitmap_list, ref_2_bitmap(tab(0), kjv_filename))
- X then {
- X while line := trim(read(intext)) do {
- X if ="::" then {
- X put(bitmap_list, ref_2_bitmap(tab(0), kjv_filename)) | {
- X err_message("Garbled ::key: "|| line ||".")
- X fail
- X }
- X } else next
- X }
- X # If the file is not in gettext format, then try reading it in as
- X # a pure list of passages.
- X } else {
- X tab(many(&digits ++ ' ')) & tab(match(".")) & tab(many(' '))
- X if put(bitmap_list, ref_2_bitmap(tab(0), kjv_filename)) then {
- X while line := trim("" ~== !intext) do {
- X line ? {
- X tab(many(&digits ++ ' ')) & ="." & tab(many(' '))
- X put(bitmap_list, ref_2_bitmap(tab(0), kjv_filename)) | {
- X err_message("Garbled line: "|| line ||".")
- X fail
- X }
- X }
- X }
- X } else {
- X err_message("Unrecognized file format. Aborting.")
- X fail
- X }
- X }
- X }
- X message("Done.")
- X
- X put(lists, lst(bitmap_list, 0, &null, "(read from disk)"))
- X return lists[-1]
- X
- Xend
- SHAR_EOF
- true || echo 'restore of readfile.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= srchutil.icn ==============
- if test -f 'srchutil.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping srchutil.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting srchutil.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'srchutil.icn' &&
- X############################################################################
- X#
- X# Name: srchutil.icn
- X#
- X# Title: search utilities for bibleref
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.14
- X#
- X############################################################################
- X#
- X# Contains:
- X#
- X# display_search(), which prompts the user, if necessary, for
- X# search strings and operators, performs the search, and
- X# then puts the results into the global list of lists,
- X#
- X# compose_search(), which compiles a little automaton which, when
- X# run via do_search(), returns a list of hits (i.e. retrieve-
- X# format bitmaps),
- X#
- X# do_search(), on which see above,
- X#
- X# various other utilities (e.g. compose_spaced_search())
- X#
- X############################################################################
- X#
- X# Links: ./complete.icn ./retrieve.icn, probably others
- X#
- X# See also: bibleref.icn
- X#
- X############################################################################
- X
- X# for debugging
- X# link ximage
- X
- Xprocedure search_database()
- X
- X #
- X # Search database for word or patterns matching whole words.
- X #
- X local search_machine, result, string_memb, tmp, excl
- X
- X search_machine := compose_search() | {
- X err_message("No search performed. Aborting.")
- X fail
- X }
- X
- X # for debugging purposes
- X # write(&errout, ximage(search_machine))
- X
- X if *search_machine > 4
- X then message("Executing complex search...")
- X else message("Executing search...")
- X *(result := do_search(search_machine)[1]) > 0 | {
- X err_message("No hits.")
- X fail
- X }
- X
- X #
- X # Nasty kludge to see what search strings were incorporated into the
- X # search_machine.
- X #
- X string_memb := "???"
- X tmp := search_machine[2]
- X excl := (\search_machine[4], "! ") | ""
- X repeat {
- X if type(tmp) == "string" then
- X string_memb := excl || tmp & break
- X else if type(tmp) == "list" then {
- X excl := (\tmp[4], "! ") | ""
- X tmp := tmp[2]
- X }
- X else break
- X }
- X if *search_machine > 4 then string_memb ||:= "..."
- X
- X if type(result) == "set" then result := sort(result)
- X put(lists, lst(result, 0, &null, string_memb))
- X message("Done.")
- X return lists[-1]
- X
- Xend
- X
- X
- X
- Xprocedure compose_search()
- X
- X #
- X # Put together a little search machine out of patterns specified by
- X # the user. Don't execute, though. Just return a list containing
- X # the user's directions to the calling procedure, and let it handle
- X # execution (via do_search()).
- X #
- X
- X local pattern, status, sense_of_search, rsp, result, u, r
- X static blanks
- X initial blanks := ' \t,'
- X
- X if pos(0)
- X then rsp := trim(snarf_input("Enter word (q to abort): "), blanks)
- X else return compose_spaced_search(blanks)
- X
- X rsp == (""|"q") & fail
- X if rsp ? (="!", pattern := tab(many(blanks)), tab(0)) then
- X sense_of_search := "inverted"
- X else pattern := rsp
- X
- X result := [retrieve, pattern, kjv_filename, sense_of_search]
- X repeat {
- X status := map(snarf_input("f to finish, or a/o/n (q aborts): "))
- X status == (""|"q") & fail
- X if upto(blanks, rsp) then
- X # And together all words in the input string.
- X return rsp ? compose_spaced_search(blanks)
- X if status == "f" then
- X return result
- X else if status == ("a"|"n"|"o") then {
- X if status ~== "o" then {
- X u := GetUnit() | next
- X r := GetRange() | next
- X }
- X return case status of {
- X "a" : [r_and, result, compose_search(), kjv_filename, u, r]
- X "o" : [r_or, result, compose_search(), kjv_filename, u, r]
- X "n" : [r_and_not, result, compose_search(), kjv_filename, u, r]
- X } | fail
- X }
- X else if status == (""|"q") then fail
- X else err_message("F = finish, a = and, o = or, n = and-not.")
- X }
- X
- Xend
- X
- X
- X
- Xprocedure GetUnit()
- X
- X local resp
- X
- X if filestats[kjv_filename].IS.no = 3 then
- X repeat {
- X resp := map(snarf_input("Enter unit (b/c/v): "))
- X case resp of {
- X "b" : return 1
- X "c" : return 2
- X "v" : return 3
- X "q"|"" : fail
- X default : {
- X err_message("Enter b (book), c (chapter), or v (verse).")
- X next
- X }
- X }
- X }
- X else if filestats[kjv_filename].IS.no = 2 then
- X repeat {
- X resp := map(snarf_input("Enter unit (c/v): "))
- X case resp of {
- X "c" : return 1
- X "v" : return 2
- X "q"|"" : fail
- X default : {
- X err_message("Enter c (chapter), or v (verse).")
- X next
- X }
- X }
- X }
- X else abort("GetUnit", "not configured for IS.no not = 2 or 3", 69)
- X
- Xend
- X
- X
- X
- Xprocedure GetRange()
- X
- X local resp
- X
- X repeat {
- X resp := map(snarf_input("Enter range: "))
- X if resp := integer(resp) then
- X return resp
- X else {
- X resp == ("q"|"") & fail
- X err_message("Enter an integer (usually 1 or 0).")
- X next
- X }
- X }
- X
- Xend
- X
- X
- X
- Xprocedure do_search(l)
- X
- X #
- X # Executes the little machine put together by compose_search().
- X #
- X
- X if *l = 0
- X then return l
- X
- X case type(l[1]) of {
- X "list" : return do_search(l[1]) ||| do_search(l[2:0])
- X "procedure" : return [l[1]!do_search(l[2:0])] | [[]]
- X default : return [l[1]] ||| do_search(l[2:0])
- X }
- X
- Xend
- X
- X
- X
- Xprocedure compose_spaced_search(blanks)
- X
- X #
- X # Try to turn searches with spaces in them (e.g. "sackcloth and ashes")
- X # into separate searches for each constituent word anded together.
- X # This routine is set up, though, to handle single words or patterns
- X # as well (e.g. "sackcloth").
- X #
- X
- X local token, sense_of_search, search_list
- X static wordchars
- X initial wordchars := ~blanks
- X
- X #
- X # Whoops, no string. This shouldn't happen, but just in case I screw
- X # up somewhere in the code, and forget to strip out superfluous blanks
- X # typed in by the user...
- X #
- X tab(upto(wordchars)) | {
- X err_message("No search string. Aborting.")
- X fail
- X }
- X if ="!" then {
- X sense_of_search := 1
- X tab(upto(wordchars))
- X }
- X token := tab(many(wordchars)) | {
- X err_message("Unexpected end of input. Aborting")
- X fail
- X }
- X
- X #
- X # Make sure tokens aren't just wildcard patterns! Also, warn the
- X # user about searches containing really common words.
- X #
- X upto(&letters, token) | {
- X err_message("Token "||token||" has no letters in it!")
- X fail
- X }
- X
- X #
- X # If we've reached the end of the search string, return what we
- X # have...
- X #
- X search_list := [retrieve, token, kjv_filename, sense_of_search]
- X pos(0) & (return search_list)
- X
- X #
- X # ...otherwise and this search string together with the next one,
- X #
- X return [r_and, search_list,
- X compose_spaced_search(blanks),
- X kjv_filename, filestats[kjv_filename].IS.no, 0]
- X
- Xend
- SHAR_EOF
- true || echo 'restore of srchutil.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= version.icn ==============
- if test -f 'version.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping version.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting version.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'version.icn' &&
- X############################################################################
- X#
- X# Name: version.icn
- X#
- X# Title: return Quranref version number
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.3
- X#
- X############################################################################
- X#
- X# See also: ./bibleref.icn
- X#
- X############################################################################
- X
- Xprocedure _version()
- X return "Quranref, version 1.0, patchlevel 1"
- Xend
- SHAR_EOF
- true || echo 'restore of version.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= complete.icn ==============
- if test -f 'complete.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping complete.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting complete.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'complete.icn' &&
- X############################################################################
- X#
- X# Name: complete.icn
- X#
- X# Title: complete partial input string
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.7
- X#
- X############################################################################
- X#
- X# This file contains a single procedure, complete(s,st), which
- X# completes a string (s) relative to a set or list of strings (st).
- X# Put differently, complete() lets you supply a partial string, s,
- X# and get back those strings in st that s is either equal to or a
- X# substring of.
- X#
- X# Lots of command interfaces allow completion of partial input.
- X# Complete() simply represents my personal sentiments about how this
- X# might best be done in Icon. If you strip away the profuse comments
- X# below, you end up with only about thirty lines of actual source
- X# code.
- X#
- X# I have arranged things so that only that portion of an automaton
- X# which is needed to complete a given string is actually created and
- X# stored. Storing automata for later use naturally makes complete()
- X# eat up more memory. The performance gains can make it worth the
- X# trouble, though. If, for some reason, there comes a time when it
- X# is advisable to reclaim the space occupied by complete's static
- X# structures, you can just call it without arguments. This
- X# "resets" complete() and forces an immediate garbage collection.
- X#
- X# Example code:
- X#
- X# commands := ["run","stop","quit","save","load","continue"]
- X# while line := read(&input) do {
- X# cmds := list()
- X# every put(cmds, complete(line, commands))
- X# case *cmds of {
- X# 0 : input_error(line)
- X# 1 : do_command(cmds[1])
- X# default : display_possible_completions(cmds)
- X# }
- X# etc...
- X#
- X# More Iconish methods might include displaying successive
- X# alternatives each time the user presses the tab key (this would,
- X# however, require using the nonportable getch() routine). Another
- X# method might be to use the first string suspended by complete().
- X#
- X# NOTE: This entire shebang could be replaced with a slightly slower
- X# and much smaller program suggested to me by Jerry Nowlin and Bob
- X# Alexander.
- X#
- X# procedure terscompl(s, st)
- X# suspend match(s, p := !st) & p
- X# end
- X#
- X# This program will work fine for lists with just a few members, and
- X# also for cases where s is fairly large. It will also use much less
- X# memory.
- X#
- X############################################################################
- X#
- X# Links: none
- X#
- X############################################################################
- X
- X
- X
- Xprocedure complete(s,st)
- X
- X local dfstn, c, l, old_chr, chr, newtbl, str, strset
- X static t
- X initial t := table()
- X
- X # No-arg invocation wipes out static structures & causes an
- X # immediate garbage collection.
- X if /s & /st then {
- X t := table()
- X collect() # do it NOW
- X fail
- X }
- X type(st) == ("list"|"set") |
- X stop("error (complete): list or set expected for arg2")
- X
- X # Seriously, all that's being done here is that possible states
- X # are being represented by sets containing possible completions of
- X # s relative to st. Each time a character is snarfed from s, we
- X # check to see what strings in st might represent possible
- X # completions, and store these in yet another set. At some
- X # point, we either run into a character in s that makes comple-
- X # tion impossible (fail), or we run out of characters in s (in
- X # which case we succeed, & suspend each of the possible
- X # completions).
- X
- X # Store any sets we have to create in a static structure for later
- X # re-use.
- X /t[st] := table()
- X
- X # We'll call the table entry for the current set dfstn. (It really
- X # does enable us to do things deterministically.)
- X dfstn := t[st]
- X
- X # Snarf one character at a time from s.
- X every c := !s do {
- X
- X # The state we're in is represented by the set of all possible
- X # completions before c was read. If we haven't yet seen char
- X # c in this state, run through the current-possible-completion
- X # set, popping off the first character of each possible
- X # completion, and then construct a table which uses these
- X # initial chars as keys, and makes the completions that are
- X # possible for each of these characters into the values for
- X # those keys.
- X if /dfstn[st] then {
- X
- X # To get strings that start with the same char together,
- X # sort the current string set (st).
- X l := sort(st)
- X newtbl := table()
- X old_chr := ""
- X # Now pop off each member of the sorted string set. Use
- X # first characters as keys, and then divvy up the full strings
- X # into sets of strings having the same initial letter.
- X every str := !l do {
- X str ? { chr := move(1) | next; str := tab(0) }
- X if old_chr ~==:= chr then {
- X strset := set([str])
- X insert(newtbl, chr, strset)
- X }
- X else insert(strset, str)
- X }
- X insert(dfstn, st, newtbl)
- X }
- X
- X # What we've done essentially is to create a table in which
- X # the keys represent labeled arcs out of the current state,
- X # and the values represent possible completion sets for those
- X # paths. What we need to do now is store that table in dfstn
- X # as the value of the current state-set (i.e. the current
- X # range of possible completions). Once stored, we can then
- X # see if there is any arc from the current state (dfstn[st])
- X # with the label c (dfstn[st][c]). If so, its value becomes
- X # the new current state (st), and we cycle around again for
- X # yet another c.
- X st := \dfstn[st][c] | fail
- X if *st = 1 & match(s,!st)
- X then break
- X }
- X
- X # Eventually we run out of characters in c. The current state
- X # (i.e. the set of possible completions) can simply be suspended
- X # one element at a time, with s prefixed to each element. If, for
- X # instance, st had contained ["hello","help","hear"] at the outset
- X # and s was equal to "hel", we would now be suspending "hel" ||
- X # !set(["lo","p"]).
- X suspend s || !st
- X
- Xend
- SHAR_EOF
- true || echo 'restore of complete.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= ipause.icn ==============
- if test -f 'ipause.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping ipause.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting ipause.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'ipause.icn' &&
- X############################################################################
- X#
- X# Name: ipause.icn
- X#
- X# Title: pause within an Icon program
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.2
- X#
- X############################################################################
- X#
- X# Ipause(i) - pause i milliseconds (accuracy depends on the resolution
- X# of the system clock). Would be nice if Icon had a nap() function, so
- X# that we didn't just have to loop. Of course, for operating systems
- X# that don't support all this multitasking nonsense, ipause() will do
- X# just fine.
- X#
- X############################################################################
- X
- X
- Xprocedure ipause(i)
- X
- X local T
- X T := &time
- X until &time >= (T + i)
- X return
- X
- Xend
- SHAR_EOF
- true || echo 'restore of ipause.icn failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= inbits.icn ==============
- if test -f 'inbits.icn' -a X"$1" != X"-c"; then
- echo 'x - skipping inbits.icn (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting inbits.icn (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'inbits.icn' &&
- X############################################################################
- X#
- X# Name: inbits.icn
- X#
- X# Title: read in variable length characters from a file
- X#
- X# Author: Richard L. Goerwitz
- X#
- X# Version: 1.2
- X#
- X############################################################################
- X#
- X# This procedure, inbits(), re-imports data converted into writable
- X# form by outbits(). See the file outbits.icn for all the whys and
- X# hows.
- X#
- X############################################################################
- X#
- X# Links: none
- X#
- X# See also: outbits.icn
- X#
- X############################################################################
- X
- X
- Xprocedure inbits(f, len)
- X
- X local i, byte, old_byte_mask
- X static old_byte, old_len, byte_length
- X initial {
- X old_byte := old_len := 0
- SHAR_EOF
- true || echo 'restore of inbits.icn failed'
- fi
- echo 'End of part 2'
- echo 'File inbits.icn is continued in part 3'
- echo 3 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-