aboutsummaryrefslogtreecommitdiff
path: root/src/interp/br-search.boot.pamphlet
diff options
context:
space:
mode:
Diffstat (limited to 'src/interp/br-search.boot.pamphlet')
-rw-r--r--src/interp/br-search.boot.pamphlet1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/src/interp/br-search.boot.pamphlet b/src/interp/br-search.boot.pamphlet
new file mode 100644
index 00000000..f886a96a
--- /dev/null
+++ b/src/interp/br-search.boot.pamphlet
@@ -0,0 +1,1040 @@
+\documentclass{article}
+\usepackage{axiom}
+
+\title{\File{src/interp/br-search.boot} Pamphlet}
+\author{The Axiom Team}
+
+\begin{document}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+
+\section{License}
+
+<<license>>=
+-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are
+-- met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+@
+<<*>>=
+<<license>>
+
+--====================> WAS b-search.boot <================================
+
+--=======================================================================
+-- Grepping Database libdb.text
+-- Redone 12/95 for Saturn; previous function grep renamed as grepFile
+-- This function now either returns a filename or a list of strings
+--=======================================================================
+grepConstruct(s,key,:options) == --key = a o c d p x k (all) . (aok) w (doc)
+--Called from genSearch with key = "." and "w"
+--key = "." means a o c d p x
+--option1 = true means return the result as a file
+--All searches of the database call this function to get relevant lines
+--from libdb.text. Returns either a list of lines (usual case) or else
+--an alist of the form ((kind . <list of lines for that kind>) ...)
+ $localLibdb : local := fnameExists? '"libdb.text" and '"libdb.text"
+ lines := grepConstruct1(s,key)
+ IFCAR options => grepSplit(lines,key = 'w) --leave now if a constructor
+ MEMQ(key,'(o a)) => dbScreenForDefaultFunctions lines --kill default lines if a/o
+ lines
+
+grepConstruct1(s,key) ==
+--returns the name of file (WITHOUT .text.$SPADNUM on the end)
+ $key : local := key
+ if key = 'k and --convert 'k to 'y if name contains an "&"
+ or/[s . i = char '_& for i in 0..MAXINDEX s] then key := 'y
+ filter := pmTransFilter STRINGIMAGE s --parses and-or-not form
+ filter is ['error,:.] => filter --exit on parser error
+ pattern := mkGrepPattern(filter,key) --create string to pass to "grep"
+ grepConstructDo(pattern, key) --do the "grep"---see b-saturn.boot
+
+grepConstructDo(x, key) ==
+ $orCount := 0
+--atom x => grepFile(x, key,'i)
+ $localLibdb =>
+ oldLines := purgeNewConstructorLines(grepf(x,key,false),$newConstructorList)
+ newLines := grepf(x,$localLibdb,false)
+ union(oldLines, newLines)
+ grepf(x,key,false)
+
+dbExposed?(line,kind) == -- does line come from an unexposed constructor?
+ conname := INTERN
+ kind = char 'a or kind = char 'o => dbNewConname line --get conname from middle
+ dbName line
+ isExposedConstructor conname
+
+dbScreenForDefaultFunctions lines == [x for x in lines | not isDefaultOpAtt x]
+
+isDefaultOpAtt x == x.(1 + dbTickIndex(x,4,0)) = char 'x
+
+grepForAbbrev(s,key) ==
+--checks that filter s is not * and is all uppercase; if so, look for abbrevs
+ u := HGET($lowerCaseConTb,s) => ['Abbreviations,u] --try cheap test first
+ s := STRINGIMAGE s
+ someLowerCaseChar := false
+ someUpperCaseChar := false
+ for i in 0..MAXINDEX s repeat
+ c := s . i
+ LOWER_-CASE_-P c => return (someLowerCaseChar := true)
+ UPPER_-CASE_-P c => someUpperCaseChar := true
+ someLowerCaseChar or not someUpperCaseChar => false
+ pattern := DOWNCASE s
+ ['Abbreviations ,:[GETDATABASE(x,'CONSTRUCTORFORM)
+ for x in allConstructors() | test]] where test ==
+ not $includeUnexposed? and not isExposedConstructor x => false
+ a := GETDATABASE(x,'ABBREVIATION)
+ match?(pattern,PNAME a) and not HGET($defaultPackageNamesHT,x)
+
+applyGrep(x,filename) == --OBSELETE with $saturn--> see applyGrepSaturn
+ atom x => grepFile(x,filename,'i)
+ $localLibdb =>
+ a := purgeNewConstructorLines(grepf(x,filename,false),$newConstructorList)
+ b := grepf(x,$localLibdb,false)
+ grepCombine(a,b)
+ grepf(x,filename,false)
+
+grepCombine(a,b) == MSORT union(a,b)
+
+grepf(pattern,s,not?) == --s=sourceFile or list of strings
+ pattern is [op,:argl] =>
+ op = "and" =>
+ while argl is [arg,:argl] repeat
+ s := grepf(arg,s,not?) -- filter by successive greps
+ s
+ op = "or" =>
+ targetStack := nil
+ "union"/[grepf(arg,s,not?) for arg in argl]
+ op = "not" =>
+ not? => grepf(first argl,s,false)
+ --could be the first time so have to get all of same $key
+ lines := grepf(mkGrepPattern('"*",$key),s,false)
+ grepf(first argl,lines,true)
+ systemError nil
+ option :=
+ not? => 'iv
+ 'i
+ source :=
+ LISTP s => dbWriteLines s
+ s
+ grepFile(pattern,source,option)
+
+pmTransFilter s ==
+--result is either a string or (op ..) where op= and,or,not and arg are results
+ if $browseMixedCase = true then s := DOWNCASE s
+ or/[isFilterDelimiter? s.i or s.i = $charUnderscore for i in 0..MAXINDEX s]
+ => (parse := pmParseFromString s) and checkPmParse parse or
+ ['error,'"Illegal search string",'"\vspace{3}\center{{\em Your search string} ",escapeSpecialChars s,'" {\em has incorrect syntax}}"]
+ or/[s . i = char '_* and s.(i + 1) = char '_*
+ and (i=0 or s . (i - 1) ^= char $charUnderscore) for i in 0..(MAXINDEX s - 1)]
+ => ['error,'"Illegal search string",'"\vspace{3}\center{Consecutive {\em *}'s are not allowed in search patterns}"]
+ s
+
+checkPmParse parse ==
+ STRINGP parse => parse
+ fn parse => parse where fn(u) ==
+ u is [op,:args] =>
+ MEMQ(op,'(and or not)) and and/[checkPmParse x for x in args]
+ STRINGP u => true
+ false
+ nil
+
+dnForm x ==
+ STRINGP x => x
+ x is ['not,argl] =>
+ argl is ['or,:orargs]=>
+ ['and, :[dnForm negate u for u in orargs]] where negate s ==
+ s is ['not,argx] => argx
+ ['not,s]
+ argl is ['and,:andargs]=>
+ ['or,:[dnForm negate u for u in andargs]]
+ argl is ['not,notargl]=>
+ dnForm notargl
+ x
+ x is ['or,:argl1] => ['or,:[dnForm u for u in argl1]]
+ x is ['and,:argl2] => ['and,:[dnForm u for u in argl2]]
+ x
+
+pmParseFromString s ==
+ u := ncParseFromString pmPreparse s
+ dnForm flatten u where flatten s ==
+ s is [op,:argl] =>
+ STRINGP op => STRCONC(op,"STRCONC"/[STRCONC('" ",x) for x in argl])
+ [op,:[flatten x for x in argl]]
+ s
+
+pmPreparse s == hn fn(s,0,#s) where--stupid insertion of chars to get correct parse
+ hn x == SUBLISLIS('(and or not),'("and" "or" "not"),x)
+ fn(s,n,siz) == --main function: s is string, n is origin
+ n = siz => '""
+ i := firstNonDelim(s,n) or return SUBSTRING(s,n,nil)
+ j := firstDelim(s,i + 1) or siz
+ t := gn(s,i,j - 1)
+ middle :=
+ member(t,'("and" "or" "not")) => t
+ --the following 2 lines make commutative("*") parse correctly!!!!
+ t.0 = char '_" => t
+ j < siz - 1 and s.j = char '_( => t
+ STRCONC(char '_",t,char '_")
+ STRCONC(SUBSTRING(s,n,i - n),middle,fn(s,j,siz))
+ gn(s,i,j) == --replace each underscore by 4 underscores!
+ n := or/[k for k in i..j | s.k = $charUnderscore] =>
+ STRCONC(SUBSTRING(s,i,n - i + 1),$charUnderscore,gn(s,n + 1,j))
+ SUBSTRING(s,i,j - i + 1)
+
+firstNonDelim(s,n) == or/[k for k in n..MAXINDEX s | not isFilterDelimiter? s.k]
+firstDelim(s,n) == or/[k for k in n..MAXINDEX s | isFilterDelimiter? s.k]
+
+isFilterDelimiter? c == MEMQ(c,$pmFilterDelimiters)
+
+grepSplit(lines,doc?) ==
+ if doc? then
+ instream2 := OPEN STRCONC(getEnv '"AXIOM",'"/algebra/libdb.text")
+ cons := atts := doms := nil
+ while lines is [line, :lines] repeat
+ if doc? then
+ N:=PARSE_-INTEGER dbPart(line,1,-1)
+ if NUMBERP N then
+ FILE_-POSITION(instream2,N)
+ line := READLINE instream2
+ kind := dbKind line
+ not $includeUnexposed? and not dbExposed?(line,kind) => 'skip
+ (kind = char 'a or kind = char 'o) and isDefaultOpAtt line => 'skip
+ PROGN
+ kind = char 'c => cats := insert(line,cats)
+ kind = char 'd => doms := insert(line,doms)
+ kind = char 'x => defs := insert(line,defs)
+ kind = char 'p => paks := insert(line,paks)
+ kind = char 'a => atts := insert(line,atts)
+ kind = char 'o => ops := insert(line,ops)
+ kind = char '_- => 'skip --for now
+ systemError 'kind
+ if doc? then CLOSE instream2
+ [['"attribute",:NREVERSE atts],
+ ['"operation",:NREVERSE ops],
+ ['"category",:NREVERSE cats],
+ ['"domain",:NREVERSE doms],
+ ['"package",:NREVERSE paks]
+-- ['"default_ package",:NREVERSE defs] -- drop defaults
+ ]
+
+mkUpDownPattern s == recurse(s,0,#s) where
+ recurse(s,i,n) ==
+ i = n => '""
+ STRCONC(fixchar(s.i),recurse(s,i + 1,n))
+ fixchar(c) ==
+ ALPHA_-CHAR_-P c =>
+ STRCONC(char '_[,CHAR_-UPCASE c,CHAR_-DOWNCASE c,char '_])
+ c
+
+mkGrepPattern(s,key) ==
+ --called by grepConstruct1 and grepf
+ atom s => mkGrepPattern1(s,key)
+ [first s,:[mkGrepPattern(x,key) for x in rest s]]
+
+mkGrepPattern1(x,:options) == --called by mkGrepPattern (and grepConstructName?)
+ $options : local := options
+ s := STRINGIMAGE x
+--s := DOWNCASE STRINGIMAGE x
+ addOptions remUnderscores addWilds split(g s,char '_*) where
+ addWilds sl == --add wild cards (sl is list of parts between *'s)
+ IFCAR sl = '"" => h(IFCDR sl,[$wild1])
+ h(sl,nil)
+ g s == --remove "*"s around pattern for text match
+ not MEMQ('w,$options) => s
+ if s.0 = char '_* then s := SUBSTRING(s,1,nil)
+ if s.(k := MAXINDEX s) = char '_* then s := SUBSTRING(s,0,k)
+ s
+ h(sl,res) == --helper for wild cards
+ sl is [s,:r] => h(r,[$wild1,s,:res])
+ res := rest res
+ if not MEMQ('w,$options) then
+ if first res ^= '"" then res := ['"`",:res]
+ else if res is [.,p,:r] and p = $wild1 then res := r
+ "STRCONC"/NREVERSE res
+ remUnderscores s ==
+ (k := charPosition(char $charUnderscore,s,0)) < MAXINDEX s =>
+ STRCONC(SUBSTRING(s,0,k),'"[",s.(k + 1),'"]",
+ remUnderscores(SUBSTRING(s,k + 2,nil)))
+ s
+ split(s,char) ==
+ max := MAXINDEX s + 1
+ f := -1
+ [SUBSTRING(s,i,f-i)
+ while ((i := f + 1) <= max) and (f := charPosition(char,s,i))]
+ charPosition(c,t,startpos) == --honors underscores
+ n := SIZE t
+ if startpos < 0 or startpos > n then error "index out of range"
+ k:= startpos
+ for i in startpos .. n-1 while c ^= ELT(t,i)
+ or i > startpos and ELT(t,i-1) = '__ repeat (k := k+1)
+ k
+ addOptions s == --add front anchor
+ --options a o c d p x denote standard items
+ --options w means comments
+ --option t means text
+ --option s means signature
+ --option n means number of arguments
+ --option i means predicate
+ --option none means NO PREFIX
+ one := ($options is [x,:$options] and x => x; '"[^x]")
+ tick := '"[^`]*`"
+ one = 'w => s
+ one = 'none => (s = '"`" => '"^."; STRCONC('"^",s))
+ prefix :=
+ one = 't => STRCONC(tick,tick,tick,tick,tick,".*")
+ one = 'n => tick
+ one = 'i => STRCONC(tick,tick,tick,tick)
+ one = 's => STRCONC(tick,tick,tick)
+-- true => '"" ----> never put on following prefixes
+ one = 'k => '"[cdp]"
+ one = 'y => '"[cdpx]"
+ STRINGIMAGE one
+ s = $wild1 => STRCONC('"^",prefix)
+ STRCONC('"^",prefix,s)
+
+conform2OutputForm(form) ==
+ [op,:args] := form
+ null args => form
+ cosig := rest GETDATABASE(op,'COSIG)
+ atypes := rest CDAR GETDATABASE(op,'CONSTRUCTORMODEMAP)
+ sargl := [fn for x in args for atype in atypes for pred in cosig] where fn ==
+ pp [x,atype,pred]
+ pred => conform2OutputForm x
+ typ := sublisFormal(args,atype)
+ if x is ['QUOTE,a] then x := a
+ algCoerceInteractive(x,typ,'(OutputForm))
+ [op,:sargl]
+
+oPage(a,:b) == --called by \spadfun{opname}
+ oSearch (IFCAR b or a) --always take slow path
+
+oPageFrom(opname,conname) == --called by \spadfunFrom{opname}{conname}
+ htPage := htInitPage(nil,nil) --create empty page and fill in needed properties
+ htpSetProperty(htPage,'conform,conform := getConstructorForm conname)
+ htpSetProperty(htPage,'kind,STRINGIMAGE GETDATABASE(conname,'CONSTRUCTORKIND))
+ itemlist := ASSOC(opname,koOps(conform,nil)) --all operations name "opname"
+ null itemlist => systemError [conform,'" has no operation named ",opname]
+ opAlist := [itemlist]
+ dbShowOperationsFromConform(htPage,'"operation",opAlist)
+
+aPage(a,:b) == --called by \spadatt{a}
+ $attributeArgs : local := nil
+ arg := IFCAR b or a
+ s := pmParseFromString STRINGIMAGE arg
+ searchOn :=
+ ATOM s => s
+ IFCAR s
+ $attributeArgs : local := IFCAR IFCDR s
+ aSearch searchOn
+--must recognize that not all attributes can be found in database
+--e.g. constant(deriv) is not but appears in a conditional in LODO
+
+spadType(x) == --called by \spadtype{x} from HyperDoc
+ s := PNAME x
+ form := ncParseFromString s or
+ systemError ['"Argument: ",s,'" to spadType won't parse"]
+ if atom form then form := [form]
+ op := opOf form
+ looksLikeDomainForm form => APPLY(function conPage,form)
+ conPage(op)
+
+looksLikeDomainForm x ==
+ entry := getCDTEntry(opOf x,true) or return false
+ coSig := LASSOC('coSig,CDDR entry)
+ k := #coSig
+ atom x => k = 1
+ k ^= #x => false
+ and/[p for key in rest coSig for arg in rest x] where
+ p ==
+ key => looksLikeDomainForm arg
+ not IDENTP arg
+
+spadSys(x) == --called by \spadsyscom{x}
+ s := PNAME x
+ if s.0 = char '_) then s := SUBSTRING(s,1,nil)
+ form := ncParseFromString s or
+ systemError ['"Argument: ",s,'" to spadType won't parse"]
+ htSystemCommands PNAME opOf form
+
+--=======================================================================
+-- Name and General Search
+--=======================================================================
+aokSearch filter == genSearch(filter,true) --"General" from HD (see man0.ht)
+--General search for constructs but NOT documentation
+
+genSearch(filter,:options) == --"Complete" from HD (see man0.ht) and aokSearch
+--General + documentation search
+ null (filter := checkFilter filter) => nil --in case of filter error
+ filter = '"*" => htErrorStar()
+ includeDoc? := not IFCAR options
+--give summaries for how many a o c d p x match filter
+ regSearchAlist := grepConstruct(STRINGIMAGE filter,".",true)
+ regSearchAlist is ['error,:.] => bcErrorPage regSearchAlist
+ key := removeSurroundingStars filter
+ if includeDoc? then
+ docSearchAlist := grepConstruct(key,'w,true)
+ docSearchAlist is ['error,:.] => bcErrorPage docSearchAlist
+ docSearchAlist := [x for x in docSearchAlist | x.0 ^= char 'x]--drop defaults
+ genSearch1(filter,genSearchTran regSearchAlist,genSearchTran docSearchAlist)
+
+genSearchTran alist == [[x,y,:y] for [x,:y] in alist]
+
+
+genSearch1(filter,reg,doc) ==
+ regSearchAlist := searchDropUnexposedLines reg
+ docSearchAlist := searchDropUnexposedLines doc
+ key := removeSurroundingStars filter
+ regCount := searchCount regSearchAlist
+ docCount := searchCount docSearchAlist
+ count := regCount + docCount
+ count = 0 => emptySearchPage('"entry",filter,true)
+ count = 1 =>
+ alist := (regCount = 1 => regSearchAlist; docSearchAlist)
+ showNamedConstruct(or/[x for x in alist | CADR x])
+ summarize? :=
+ docSearchAlist => true
+ nonEmpties := [pair for pair in regSearchAlist | #(CADR pair) > 0]
+ not(nonEmpties is [pair])
+ not summarize? => showNamedConstruct pair
+ -----------generate a summary page---------------------------
+ plural :=
+ $exposedOnlyIfTrue => '"exposed entries match"
+ '"entries match"
+ prefix := pluralSay(count,'"", plural)
+ emfilter := ['"{\em ",escapeSpecialChars STRINGIMAGE filter,'"}"]
+ header := [:prefix,'" ",:emfilter]
+ page := htInitPage(header,nil)
+ htpSetProperty(page,'regSearchAlist,regSearchAlist)
+ htpSetProperty(page,'docSearchAlist,docSearchAlist)
+ htpSetProperty(page,'filter,filter)
+ if docSearchAlist then
+ dbSayItems(['"{\bf Construct Summary:} ",regCount],'"name matches",'"names match")
+ for [kind,:pair] in regSearchAlist for i in 0.. | #(first pair) > 0 repeat
+ bcHt '"\newline{}"
+ htSayStandard '"\tab{2}"
+ genSearchSay(pair,summarize?,kind,i,'showConstruct)
+ if docSearchAlist then
+ htSaySaturn '"\bigskip{}"
+ dbSayItems(['"\newline{\bf Documentation Summary:} ",docCount],'"mention",'"mentions",'" of {\em ",key,'"}")
+ for [kind,:pair] in docSearchAlist for i in 0.. | #(first pair) > 0 repeat
+ bcHt "\newline{}"
+ htSayStandard '"\tab{2}"
+ genSearchSay(pair,true,kind,i,'showDoc)
+ htShowPageStar()
+searchDropUnexposedLines alist ==
+ [[op,[pred for line in lines | pred],:lines] for [op,.,:lines] in alist] where
+ pred ==
+ not $exposedOnlyIfTrue or dbExposed?(line,dbKind line) => line
+ nil
+
+htShowPageStar() ==
+------------> OBSELETE
+ htSayStandard '"\endscroll "
+ if $exposedOnlyIfTrue then
+ htMakePage [['bcLinks,['"Exposed",'" {\em only}",'repeatSearch,NIL]]]
+ else
+ htSay('"*{\em =}")
+ htMakePage [['bcLinks,['"unexposed",'"",'repeatSearch,'T]]]
+ htShowPageNoScroll()
+
+repeatSearch(htPage,newValue) ==
+ $exposedOnlyIfTrue := newValue
+ filter := htpProperty(htPage,'filter)
+ reg := htpProperty(htPage,'regSearchAlist)
+ doc := htpProperty(htPage,'docSearchAlist)
+ reg => genSearch1(filter,reg,doc)
+ docSearch1(filter,doc)
+
+searchCount u == +/[# y for [x,y,:.] in u]
+
+showDoc(htPage,count) ==
+ showIt(htPage,count,htpProperty(htPage,'docSearchAlist))
+
+showConstruct(htPage,count) ==
+ showIt(htPage,count,htpProperty(htPage,'regSearchAlist))
+
+showIt(htPage,index,searchAlist) ==
+ filter := htpProperty(htPage,'filter)
+ [relativeIndex,n] := DIVIDE(index,8)
+ relativeIndex = 0 => showNamedConstruct(searchAlist.n)
+ [kind,items,:.] := searchAlist . n
+ for j in 1.. while j < relativeIndex repeat items := rest items
+ firstName := dbName first items --select name then gather all of same name
+ lines := [line for line in items while dbName line = firstName]
+ showNamedConstruct [kind,nil,:lines]
+
+showNamedConstruct([kind,.,:lines]) == dbSearch(lines,kind,'"")
+
+genSearchSay(pair,summarize,kind,who,fn) ==
+ [u,:fullLineList] := pair
+ count := #u
+ uniqueCount := genSearchUniqueCount u
+ short := summarize and uniqueCount >= $browseCountThreshold
+ htMakePage
+ [['bcLinks,[menuButton(),'"",'genSearchSayJump,[fullLineList,kind]]]]
+ if count = 0 then htSay('"{\em No ",kind,'"} ")
+ else if count = 1 then
+ htSay('"{\em 1 ",kind,'"} ")
+ else
+ htSay('"{\em ",count,'" ",pluralize kind,'"} ")
+ short => 'done
+ if uniqueCount ^= 1 then
+ htSayStandard '"\indent{4}"
+ htSay '"\newline "
+ htBeginTable()
+ lastid := nil
+ groups := organizeByName u
+ i := 1
+ for group in groups repeat
+ id := dbGetName first group
+ if $includeUnexposed? then
+ exposed? := or/[dbExposed?(item,dbKind item) for item in group]
+ bcHt '"{"
+ if $includeUnexposed? then
+ exposed? => htBlank()
+ htSayUnexposed()
+ htMakePage [['bcLinks, [id,'"",fn,who + 8*i]]]
+ i := i + #group
+ bcHt '"}"
+ if uniqueCount ^= 1 then
+ htEndTable()
+ htSayStandard '"\indent{0}"
+
+organizeByName u ==
+ [[(u := rest u; x) while u and head = dbName (x := first u)]
+ while u and (head := dbName first u)]
+
+genSearchSayJump(htPage,[lines,kind]) ==
+ filter := htpProperty(htPage,'filter)
+ dbSearch(lines,kind,filter)
+
+genSearchUniqueCount(u) ==
+--count the unique number of items (if less than $browseCountThreshold)
+ count := 0
+ lastid := nil
+ for item in u while count < $browseCountThreshold repeat
+ id := dbGetName item
+ if id ^= lastid then
+ count := count + 1
+ lastid := id
+ count
+
+dbGetName line == SUBSTRING(line,1,charPosition($tick,line,1) - 1)
+
+pluralSay(count,singular,plural,:options) ==
+ item := (options is [x,:options] => x; '"")
+ colon := (IFCAR options => '":"; '"")
+ count = 0 => concat('"No ",singular,item)
+ count = 1 => concat('"1 ",singular,item,colon)
+ concat(count,'" ",plural,item,colon)
+
+
+--=======================================================================
+-- Documentation Search
+--=======================================================================
+docSearch filter == --"Documentation" from HD (see man0.ht)
+ null (filter := checkFilter filter) => nil --in case of filter error
+ filter = '"*" => htErrorStar()
+ key := removeSurroundingStars filter
+ docSearchAlist := grepConstruct(filter,'w,true)
+ docSearchAlist is ['error,:.] => bcErrorPage docSearchAlist
+ docSearchAlist := [x for x in docSearchAlist | x.0 ^= char 'x] --drop defaults
+ docSearch1(filter,genSearchTran docSearchAlist)
+
+docSearch1(filter,doc) ==
+ docSearchAlist := searchDropUnexposedLines doc
+ count := searchCount docSearchAlist
+ count = 0 => emptySearchPage('"entry",filter,true)
+ count = 1 => showNamedConstruct(or/[x for x in docSearchAlist | CADR x],1)
+ prefix := pluralSay(count,'"entry matches",'"entries match")
+ emfilter := ['"{\em ",escapeSpecialChars STRINGIMAGE filter,'"}"]
+ header := [:prefix,'" ",:emfilter]
+ page := htInitPage(header,nil)
+ htpSetProperty(page,'docSearchAlist,docSearchAlist)
+ htpSetProperty(page,'regSearchAlist,nil)
+ htpSetProperty(page,'filter,filter)
+ dbSayItems(['"\newline Documentation Summary: ",count],'"mention",'"mentions",'" of {\em ",filter,'"}")
+ for [kind,:pair] in docSearchAlist for i in 0.. | #(first pair) > 0 repeat
+ bcHt '"\newline{}"
+ htSayStandard '"\tab{2}"
+ genSearchSay(pair,true,kind,i,'showDoc)
+ htShowPageStar()
+
+removeSurroundingStars filter ==
+ key := STRINGIMAGE filter
+ if key.0 = char '_* then key := SUBSTRING(key,1,nil)
+ if key.(max := MAXINDEX key) = char '_* then key := SUBSTRING(key,0,max)
+ key
+
+showNamedDoc([kind,:lines],index) ==
+ dbGather(kind,lines,index - 1,true)
+
+sayDocMessage message ==
+ htSay('"{\em ")
+ if message is [leftEnd,left,middle,right,rightEnd] then
+ htSay(leftEnd,left,'"}")
+ if left ^= '"" and left.(MAXINDEX left) = $blank then htBlank()
+ htSay middle
+ if right ^= '"" and right.0 = $blank then htBlank()
+ htSay('"{\em ",right,rightEnd)
+ else
+ htSay message
+ htSay ('"}")
+
+stripOffSegments(s,n) ==
+ progress := true
+ while n > 0 and progress = true repeat
+ n := n - 1
+ k := charPosition(char '_`,s,0)
+ new := SUBSTRING(s,k + 1,nil)
+ #new < #s => s := new
+ progress := false
+ n = 0 => s
+ nil
+
+replaceTicksBySpaces s ==
+ n := -1
+ max := MAXINDEX s
+ while (n := charPosition(char '_`,s,n + 1)) <= max repeat SETELT(s,n,char '_ )
+ s
+
+checkFilter filter ==
+ filter := STRINGIMAGE filter
+ filter = '"" => '"*"
+ trimString filter
+
+aSearch filter == --called from HD (man0.ht): general attribute search
+ null (filter := checkFilter filter) => nil --in case of filter error
+ dbSearch(grepConstruct(filter,'a),'"attribute",filter)
+
+oSearch filter == -- called from HD (man0.ht): operation search
+ opAlist := opPageFastPath filter => opPageFast opAlist
+ key := 'o
+ null (filter := checkFilter filter) => nil --in case of filter error
+ filter = '"*" => grepSearchQuery('"operation",[filter,key,'"operation",'oSearchGrep])
+ oSearchGrep(filter,key,'"operation")
+
+oSearchGrep(filter,key,kind) == --called from grepSearchQuery/oSearch
+ dbSearch(grepConstruct(filter,'o),kind,filter)
+
+grepSearchQuery(kind,items) ==
+ page := htInitPage('"Query Page",nil)
+ htpSetProperty(page,'items,items)
+ htQuery(['"{\em Do you want a list of {\em all} ",pluralize kind,'"?\vspace{1}}"],'grepSearchJump,true)
+ htShowPage()
+
+cSearch filter == --called from HD (man0.ht): category search
+ constructorSearch(checkFilter filter,'c,'"category")
+
+dSearch filter == --called from HD (man0.ht): domain search
+ constructorSearch(checkFilter filter,'d,'"domain")
+
+pSearch filter == --called from HD (man0.ht): package search
+ constructorSearch(checkFilter filter,'p,'"package")
+
+xSearch filter == --called from HD (man0.ht): default package search
+ constructorSearch(checkFilter filter,'x,'"default package")
+
+kSearch filter == --called from HD (man0.ht): constructor search (no defaults)
+ constructorSearch(checkFilter filter,'k,'"constructor")
+
+ySearch filter == --called from conPage: like kSearch but defaults included
+ constructorSearch(checkFilter filter,'y,'"constructor")
+
+constructorSearch(filter,key,kind) ==
+ null filter => nil --in case of filter error
+ (parse := conSpecialString? filter) => conPage parse
+ pageName := LASSOC(DOWNCASE filter,'(("union" . DomainUnion)("record" . DomainRecord)("mapping" . DomainMapping) ("enumeration" . DomainEnumeration))) =>
+ downlink pageName
+ name := (STRINGP filter => INTERN filter; filter)
+ if u := HGET($lowerCaseConTb,name) then filter := STRINGIMAGE first u
+ line := conPageFastPath DOWNCASE filter =>
+ code := dbKind line
+ newkind :=
+ code = char 'p => '"package"
+ code = char 'd => '"domain"
+ code = char 'c => '"category"
+ nil
+ kind = '"constructor" or kind = newkind => kPage line
+ page := htInitPage('"Query Page",nil)
+ htpSetProperty(page,'line,line)
+ message :=
+ ['"{\em ",dbName line,'"} is not a {\em ",kind,'"} but a {\em ",
+ newkind,'"}. Would you like to view it?\vspace{1}"]
+ htQuery(message, 'grepConstructorSearch,true)
+ htShowPage()
+ filter = '"*" => grepSearchQuery(kind,[filter,key,kind,'constructorSearchGrep])
+ constructorSearchGrep(filter,key,kind)
+
+grepConstructorSearch(htPage,yes) == kPage htpProperty(htPage,'line)
+
+conSpecialString?(filter,:options) ==
+ secondTime := IFCAR options
+ parse :=
+ words := string2Words filter is [s] => ncParseFromString s
+ and/[not member(x,'("and" "or" "not")) for x in words] => ncParseFromString filter
+ false
+ null parse => nil
+ form := conLowerCaseConTran parse
+ MEMQ(KAR form,'(and or not)) or CONTAINED("*",form) => nil
+ filter = '"Mapping" =>nil
+ u := kisValidType form => u
+ secondTime => false
+ u := "STRCONC"/[string2Constructor x for x in dbString2Words filter]
+ conSpecialString?(u, true)
+
+dbString2Words l ==
+ i := 0
+ [w while dbWordFrom(l,i) is [w,i]]
+
+$dbDelimiters := [char " " , char "(", char ")"]
+
+dbWordFrom(l,i) ==
+ maxIndex := MAXINDEX l
+ while maxIndex >= i and l.i = char " " repeat i := i + 1
+ if maxIndex >= i and member(l.i, $dbDelimiters) then return [l.i, i + 1]
+ k := or/[j for j in i..maxIndex | not member(l.j, $dbDelimiters)] or return nil
+ buf := '""
+ while k <= maxIndex and not member(c := l.k, $dbDelimiters) repeat
+ ch :=
+ c = char '__ => l.(k := 1+k) --this may exceed bounds
+ c
+ buf := STRCONC(buf,ch)
+ k := k + 1
+ [buf,k]
+
+conLowerCaseConTran x ==
+ IDENTP x => IFCAR HGET($lowerCaseConTb, x) or x
+ atom x => x
+ [conLowerCaseConTran y for y in x]
+
+string2Constructor x ==
+ not STRINGP x => x
+ IFCAR HGET($lowerCaseConTb, INTERN DOWNCASE x) or x
+
+conLowerCaseConTranTryHarder x ==
+ IDENTP x => IFCAR HGET($lowerCaseConTb,DOWNCASE x) or x
+ atom x => x
+ [conLowerCaseConTranTryHarder y for y in x]
+
+constructorSearchGrep(filter,key,kind) ==
+ dbSearch(grepConstruct(filter,key),kind,filter)
+
+grepSearchJump(htPage,yes) ==
+ [filter,key,kind,fn] := htpProperty(htPage,'items)
+ FUNCALL(fn,filter,key,kind)
+
+--=======================================================================
+-- Branch Functions After Database Search
+--=======================================================================
+dbSearch(lines,kind,filter) == --called by attribute, operation, constructor search
+ lines is ['error,:.] => bcErrorPage lines
+ null filter => nil --means filter error
+ lines is ['Abbreviations,:r] => dbSearchAbbrev(lines,kind,filter)
+ if member(kind,'("attribute" "operation")) then --should not be necessary!!
+ lines := dbScreenForDefaultFunctions lines
+ count := #lines
+ count = 0 => emptySearchPage(kind,filter)
+ member(kind,'("attribute" "operation")) => dbShowOperationLines(kind,lines)
+ dbShowConstructorLines lines
+
+dbSearchAbbrev([.,:conlist],kind,filter) ==
+ null conlist => emptySearchPage('"abbreviation",filter)
+ kind := intern kind
+ if kind ^= 'constructor then
+ conlist := [x for x in conlist | LASSOC('kind,IFCDR IFCDR x) = kind]
+ conlist is [[nam,:.]] => conPage DOWNCASE nam
+ cAlist := [[con,:true] for con in conlist]
+ htPage := htInitPage('"",nil)
+ htpSetProperty(htPage,'cAlist,cAlist)
+ htpSetProperty(htPage,'thing,nil)
+ return dbShowCons(htPage,'names)
+ page := htInitPage([#conlist,
+ '" Abbreviations Match {\em ",STRINGIMAGE filter,'"}"],nil)
+ for [nam,abbr,:r] in conlist repeat
+ kind := LASSOC('kind,r)
+ htSay('"\newline{\em ",s := STRINGIMAGE abbr)
+ htSayStandard '"\tab{10}"
+ htSay '"}"
+ htSay kind
+ htSayStandard '"\tab{19}"
+ bcCon nam
+ htShowPage()
+
+--=======================================================================
+-- Selectable Search
+--=======================================================================
+detailedSearch(filter) ==
+ page := htInitPage('"Detailed Search with Options",nil)
+ filter := escapeSpecialChars PNAME filter
+ bcHt '"Select what you want to search for, then click on {\em Search} below"
+ bcHt '"\newline{\it Note:} Logical searches using {\em and}, {\em or}, and {\em not} are not permitted here."
+ htSayHrule()
+ htMakePage '(
+ (text . "\newline")
+ (bcRadioButtons which
+ ( "\tab{3}{\em Operations}"
+ ((text . "\newline\space{3}")
+ (text . "name") (bcStrings (14 "*" opname EM))
+ (text . " \#args") (bcStrings (1 "*" opnargs EM))
+ (text . " signature") (bcStrings (14 "*" opsig EM))
+ (text . "\vspace{1}\newline "))
+ ops)
+ ( "\tab{3}{\em Attributes}"
+ ((text . "\newline\space{3}")
+ (text . "name") (bcStrings (14 "*" attrname EM))
+ (text . " \#args ") (bcStrings (1 "*" attrnargs EM))
+ (text . " arguments ")(bcStrings (14 "*" attrargs EM))
+ (text . "\vspace{1}\newline "))
+ attrs)
+ ( "\tab{3}{\em Constructors}"
+ ((text . "\tab{17}")
+ (bcButtons (1 cats)) (text . " {\em categories} ")
+ (bcButtons (1 doms)) (text . " {\em domains} ")
+ (bcButtons (1 paks)) (text . " {\em packages} ")
+ (bcButtons (1 defs)) (text . " {\em defaults} ")
+ (text . "\newline\tab{3}")
+ (text . "name") (bcStrings (14 "*" conname EM))
+ (text . " \#args") (bcStrings (1 "*" connargs EM))
+ (text . "signature") (bcStrings (14 "*" consig EM))
+ (text . "\vspace{1}\newline "))
+ cons)
+-- ( "\tab{3}{\em Documentation}"
+-- ((text . "\tab{26}key")
+-- (bcStrings (28 "*" docfilter EM)))
+-- doc)
+ )
+ (text . "\vspace{1}\newline\center{ ")
+ (bcLinks ("\box{Search}" "" generalSearchDo NIL))
+ (text . "}"))
+ htShowPage()
+
+generalSearchDo(htPage,flag) ==
+--$exposedOnlyIfTrue := (flag => 'T; nil)
+ $htPage := htPage
+ alist := htpInputAreaAlist htPage
+ which := htpButtonValue(htPage,'which)
+ selectors :=
+ which = 'cons => '(conname connargs consig)
+ which = 'ops => '(opname opnargs opsig)
+ '(attrname attrnargs attrargs)
+ name := generalSearchString(htPage,selectors.0)
+ nargs:= generalSearchString(htPage,selectors.1)
+ npat := standardizeSignature generalSearchString(htPage,selectors.2)
+ kindCode :=
+ which = 'ops => char 'o
+ which = 'attrs => char 'a
+ acc := '""
+ if htButtonOn?(htPage,'cats) then acc := STRCONC(char 'c,acc)
+ if htButtonOn?(htPage,'doms) then acc := STRCONC(char 'd,acc)
+ if htButtonOn?(htPage,'paks) then acc := STRCONC(char 'p,acc)
+ if htButtonOn?(htPage,'defs) then acc := STRCONC(char 'x,acc)
+ n := #acc
+ n = 0 or n = 4 => '"[cdpx]"
+ n = 1 => acc
+ STRCONC(char '_[,acc,char '_])
+ form := mkDetailedGrepPattern(kindCode,name,nargs,npat)
+ lines := applyGrep(form,'libdb)
+--lines := dbReadLines resultFile
+ if MEMQ(which,'(ops attrs)) then lines := dbScreenForDefaultFunctions lines
+ kind :=
+ which = 'cons =>
+ n = 1 =>
+ htButtonOn?(htPage,'cats) => '"category"
+ htButtonOn?(htPage,'doms) => '"domain"
+ htButtonOn?(htPage,'paks) => '"package"
+ '"default package"
+ '"constructor"
+ which = 'ops => '"operation"
+ '"attribute"
+ null lines => emptySearchPage(kind,nil)
+ dbSearch(lines,kind,'"filter")
+
+generalSearchString(htPage,sel) ==
+ string := htpLabelInputString(htPage,sel)
+ string = '"" => '"*"
+ string
+
+htButtonOn?(htPage,key) ==
+ LASSOC(key,htpInputAreaAlist htPage) is [a,:.] and a = '" t"
+
+mkDetailedGrepPattern(kind,name,nargs,argOrSig) == main where
+ main ==
+ nottick := '"[^`]"
+ name := replaceGrepStar name
+ firstPart :=
+ $saturn => STRCONC(char '_^,name)
+ STRCONC(char '_^,kind,name)
+ nargsPart := replaceGrepStar nargs
+ exposedPart := char '_. --always get exposed/unexposed
+ patPart := replaceGrepStar argOrSig
+ simp STRCONC(conc(firstPart,conc(nargsPart,conc(exposedPart, patPart))),$tick)
+ conc(a,b) ==
+ b = '"[^`]*" or b = char '_. => a
+ STRCONC(a,$tick,b)
+ simp a ==
+ m := MAXINDEX a
+ m > 6 and a.(m-5) = char '_[ and a.(m-4) = char '_^
+ and a.(m-3) = $tick and a.(m-2) = char '_]
+ and a.(m-1) = char '_* and a.m = $tick
+ => simp SUBSTRING(a,0,m-5)
+ a
+
+replaceGrepStar s ==
+ s = "" => s
+ final := MAXINDEX s
+ i := charPosition(char '_*,s,0)
+ i > final => s
+ STRCONC(SUBSTRING(s,0,i),'"[^`]*",replaceGrepStar SUBSTRING(s,i + 1,nil))
+
+standardizeSignature(s) == underscoreDollars
+ s.0 = char '_( => s
+ k := STRPOS('"->",s,0,nil) or return s --will fail except perhaps on constants
+ s.(k - 1) = char '_) => STRCONC(char '_(,s)
+ STRCONC(char '_(,SUBSTRING(s,0,k),char '_),SUBSTRING(s,k,nil))
+
+underscoreDollars(s) == fn(s,0,MAXINDEX s) where
+ fn(s,i,n) ==
+ i > n => '""
+ (m := charPosition(char '_$,s,i)) > n => SUBSTRING(s,i,nil)
+ STRCONC(SUBSTRING(s,i,m - i),'"___$",fn(s,m + 1,n))
+
+--=======================================================================
+-- Code dependent on $saturn
+--=======================================================================
+
+obey x ==
+ $saturn and not $aixTestSaturn => nil
+ OBEY x
+
+--=======================================================================
+-- I/O Code
+--=======================================================================
+
+getTempPath kind ==
+ pathname := mkGrepFile kind
+ obey STRCONC('"rm -f ", pathname)
+ pathname
+
+dbWriteLines(s, :options) ==
+ pathname := IFCAR options or getTempPath 'source
+ $outStream: local := MAKE_-OUTSTREAM pathname
+ for x in s repeat writedb x
+ SHUT $outStream
+ pathname
+
+dbReadLines target == --AIX only--called by grepFile
+ instream := OPEN target
+ lines := [READLINE instream while not EOFP instream]
+ CLOSE instream
+ lines
+
+dbGetCommentOrigin line ==
+--Given a comment line in comdb, returns line in libdb pointing to it
+--Comment lines have format [dcpxoa]xxxxxx`ccccc... where
+--x's give pointer into libdb, c's are comments
+ firstPart := dbPart(line,1,-1)
+ key := INTERN SUBSTRING(firstPart,0,1) --extract this and throw away
+ address := SUBSTRING(firstPart, 1, nil) --address in libdb
+ instream := OPEN grepSource key --this always returns libdb now
+ FILE_-POSITION(instream,PARSE_-INTEGER address)
+ line := READLINE instream
+ CLOSE instream
+ line
+
+grepSource key ==
+ key = 'libdb => STRCONC($SPADROOT,'"/algebra/libdb.text")
+ key = 'gloss => STRCONC($SPADROOT,'"/algebra/glosskey.text")
+ key = $localLibdb => $localLibdb
+ mkGrepTextfile
+ MEMQ(key, '(_. a c d k o p x)) => 'libdb
+ 'comdb
+
+mkGrepTextfile s == STRCONC($SPADROOT,"/algebra/", STRINGIMAGE s, '".text")
+
+mkGrepFile s == --called to generate a path name for a temporary grep file
+ prefix :=
+ $standard or $aixTestSaturn => '"/tmp/"
+ STRCONC($SPADROOT,'"/algebra/")
+ suffix := getEnv '"SPADNUM"
+ STRCONC(prefix, PNAME s,'".txt.", suffix)
+
+--=======================================================================
+-- Grepping Code
+--=======================================================================
+
+grepFile(pattern,:options) ==
+ key := (x := IFCAR options => (options := rest options; x); nil)
+ source := grepSource key
+ lines :=
+ not PROBE_-FILE source => NIL
+ $standard or $aixTestSaturn =>
+ -----AIX Version----------
+ target := getTempPath 'target
+ casepart :=
+ MEMQ('iv,options)=> '"-vi"
+ '"-i"
+ command := STRCONC('"grep ",casepart,'" _'",pattern,'"_' ",source)
+ obey
+ member(key,'(a o c d p x)) =>
+ STRCONC(command, '" | sed 's/~/", STRINGIMAGE key, '"/' > ", target)
+ STRCONC(command, '" > ",target)
+ dbReadLines target
+ ----Windows Version------
+ invert? := MEMQ('iv, options)
+ GREP(source, pattern, false, not invert?)
+ dbUnpatchLines lines
+
+dbUnpatchLines lines == --concatenate long lines together, skip blank lines
+ dash := char '_-
+ acc := nil
+ while lines is [line, :lines] repeat
+ #line = 0 => 'skip --skip blank lines
+ acc :=
+ line.0 = dash and line.1 = dash =>
+ [STRCONC(first acc,SUBSTRING(line,2,nil)),:rest acc]
+ [line,:acc]
+ -- following call to NREVERSE needed to keep lines properly sorted
+ NREVERSE acc ------> added by BMT 12/95
+
+
+
+
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}