home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
contrib
/
menu
/
menu.S
< prev
next >
Wrap
Text File
|
1993-04-29
|
5KB
|
189 lines
#
# menu.icn
# copyright 1992 Ronald Florence
# @(#) version 1.1 (ron@mlfarm.com, 12 May 1992)
#
# See xmenu.icn for the X-Windows/X-Icon version.
#
# configuration:
# indexfile := full path of index file
# data_dir := recipe directory
# pager := optional external pager (instead of built-in pager)
# Print_cmd := pretty-printer and/or spooler (for OS with pipes)
# regexparser := (ms-dos only) findre <or> ReFind
# for ms-dos, use: link iolib, findre <or> link iolib, regexp
link iolib
global Pipes, Print_cmd
procedure main(arg)
local indexfile, data_dir, pager, zcat, hits, online, keys, pchar,
egrep, meta_keys, egrep_cmd, k, index, m, found, search, putout,
out, recipe, rpath, rf, regexparser
# configuration
indexfile := getenv("INDEXFILE") | "%INDEXFILE%"
data_dir := getenv("RECIPEDIR") | "%DATADIR%"
pager := getenv("PAGER") | "%PAGER%"
Print_cmd := "%PRINTCMD%"
regexparser :=
# end of configuration
(*arg > 0) | stop("usage: menu keyword [regexp,...]")
close(open(indexfile)) | stop("can't read index")
hits := []
online := []
keys := []
pchar := &ascii[32:127]
Pipes := "pipes" == &features
# If we have pipes and egrep (Unix),
# separate the keywords into those with
# metacharacters and those without. If
# there are none with metacharacters, pop
# one off the non-meta list to use with
# an egrep search.
if \Pipes & close(open("/bin/" | "/usr/bin/" | "/usr/ucb/" || "egrep"))
then {
meta_keys := []
egrep_cmd := "cat " || indexfile
regexparser := find
every k := !arg do put(if metas(k) then meta_keys else keys, map(k))
\meta_keys[1] | put(meta_keys, pop(keys))
every k := !meta_keys do egrep_cmd ||:= " | egrep -i '" || k || "'"
index := open(egrep_cmd || " 2>&1", "rp")
}
# Without pipes and egrep use findre
# or ReFind for the regular expression
# search. S-l-o-w.
else {
index := open(indexfile)
every put(keys, map(!arg))
}
# The search is a generator, breaking
# when the find or regexparser fails. We
# then put online recipes in one list
# and the reference recipes in another.
every !index ? {
\egrep_cmd & find("error"|"grep") & stop("search expression error")
m := map(&subject)
found := 1
every k := !keys do {
search := if /egrep & metas(k) then regexparser else find
search(k, m) | break found := &null
}
\found & {
put(if ="Comp-" then online else hits,
left(tab(many(pchar)), 20) || (tab(upto(pchar)), tab(many(pchar))))
tab(0)
}
}
*hits + *online = 0 & stop("No matching recipes.")
\hits[1] & more("RECIPES", hits)
\online[1] & repeat {
more("ON-LINE RECIPES", online)
writes("\nEnter recipe numbers(s): ")
read() ? {
(*&subject = 0) | upto('qQ') & exit(1)
# Print code for the built-in pager.
putout := if upto('pP') then print else more
while tab(upto(&digits)) do {
out := []
recipe := tab(many(&digits))
rpath := data_dir || recipe
if close(open(rpath)) then {
if *pager > 0 then system(pager || " " || rpath)
# Put the recipe in a list, so more
# will know how big it is.
else rf := open(rpath) & every put(out, !rf)
}
else if \Pipes then {
rpath ||:= ".Z"
if *pager > 0 then system("zcat " || rpath || " | " || pager)
else {
rf := open("zcat " || rpath, "rp")
every put(out, !rf)
close(rf)
} | write("Can't find " || rpath)
}
\out[1] & putout("RECIPE " || recipe, out, "End of Recipe " || recipe)
}
}
}
end
procedure print(recipe, head)
local prn, rp, mode
if \Print_cmd & \Pipes then {
Print_cmd ? {
prn := (\tab(find("%s")) || head) | tab(0)
move(2) & prn ||:= tab(0)
}
mode := "wp"
}
else if not "MS-DOS" == &features then
return write("Sorry, not configured to print.")
else {
mode := "w"
prn := "PRN"
}
rp := open(prn, "wp")
every write(rp, !recipe)
return close(rp)
end
# Procedured modified from R.Goerwitz
# to detect whether a keyword contains
# meta-characters, e.g., whether we
# need a regular expression search.
procedure metas(str)
str ? {
tab(many('*+?|'))
while tab(upto('\\*+()|?.$^[')) do {
if ="\\" then move(1) | stop("badly-formed search string")
else return .&pos
}
}
fail
end
# This is kluged to not clear the
# screen or show the percentage
# after -MORE- for the lists of recipes.
procedure more(header, what, footer)
static lines
local ans
initial {
writes(getval("cl"))
lines := 0
}
/footer | {
writes(getval("cl"))
lines := 0
}
\header & {
write(getval("md"|"so") || header || ":" || getval("me"|"se"))
lines +:= 1
}
every !what ? {
write(tab(0))
((lines +:= 1 + *&subject/getval("co")) % (getval("li") - 1) = 0) & {
writes(getval("so") || "-MORE-")
\footer & writes("(", (100 > (lines - 2)*100/*what) | 100, "%)")
writes(getval("se"))
ans := read() & writes(getval("up") || getval("ce"))
upto('nNqQ', ans) & fail
}
}
\footer & {
writes(getval("so") || footer || getval("se"))
read() & writes(getval("up") || getval("ce"))
}
end