aboutsummaryrefslogtreecommitdiff
path: root/pkg/system/help/xhelp
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /pkg/system/help/xhelp
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/system/help/xhelp')
-rw-r--r--pkg/system/help/xhelp/help.gui3027
-rw-r--r--pkg/system/help/xhelp/mkpkg28
-rw-r--r--pkg/system/help/xhelp/xhcmds.x185
-rw-r--r--pkg/system/help/xhelp/xhdir.x567
-rw-r--r--pkg/system/help/xhelp/xhelp.h89
-rw-r--r--pkg/system/help/xhelp/xhelp.x167
-rw-r--r--pkg/system/help/xhelp/xhfiles.x89
-rw-r--r--pkg/system/help/xhelp/xhhelp.x276
-rw-r--r--pkg/system/help/xhelp/xhinit.x77
-rw-r--r--pkg/system/help/xhelp/xhofile.x188
-rw-r--r--pkg/system/help/xhelp/xhpkg.x192
-rw-r--r--pkg/system/help/xhelp/xhprint.x151
-rw-r--r--pkg/system/help/xhelp/xhqref.x250
-rw-r--r--pkg/system/help/xhelp/xhroot.x73
-rw-r--r--pkg/system/help/xhelp/xhsave.x184
-rw-r--r--pkg/system/help/xhelp/xhsearch.x185
-rw-r--r--pkg/system/help/xhelp/xhsort.x223
-rw-r--r--pkg/system/help/xhelp/zzdebug.x59
18 files changed, 6010 insertions, 0 deletions
diff --git a/pkg/system/help/xhelp/help.gui b/pkg/system/help/xhelp/help.gui
new file mode 100644
index 00000000..b3f21c07
--- /dev/null
+++ b/pkg/system/help/xhelp/help.gui
@@ -0,0 +1,3027 @@
+# XHELP.GUI -- Graphics user interface for the IRAF help browser.
+
+reset-server
+appInitialize xhelp XHelp {
+
+XHelp*objects:\
+ toplevel Layout helpLayout\
+ helpLayout Group menubarGroup\
+ helpLayout Paned helpPanes\
+ menubarGroup Layout menubarLayout\
+ menubarLayout MenuButton fileButton\
+ menubarLayout MenuButton optionsButton\
+ menubarLayout Command printButton\
+ menubarLayout Command findButton\
+ menubarLayout Command searchButton\
+ menubarLayout MenuButton historyButton\
+ menubarLayout Command helpButton\
+ menubarLayout Command quitButton\
+\
+ helpPanes Group topicGroup\
+ topicGroup Layout topicLayout\
+ topicLayout Label topicLabel\
+ topicLayout Command reloadButton\
+ topicLayout Frame topicFrame\
+ topicFrame AsciiText topicEntry\
+ topicLayout Command topicClear\
+ topicLayout Frame listFrame\
+ listFrame Viewport listView\
+ listView List topicList\
+\
+ helpPanes Group outputGroup\
+ outputGroup Layout outputLayout\
+ outputLayout Command htbButton\
+ outputLayout Command htfButton\
+ outputLayout Command htuButton\
+ outputLayout Command hthButton\
+ outputLayout MenuButton secButton\
+ outputLayout MenuButton parButton\
+ outputLayout TextToggle hlpOpt\
+ outputLayout TextToggle srcOpt\
+ outputLayout TextToggle sysOpt\
+ outputLayout TextToggle filOpt\
+ outputLayout Frame helpFrame\
+ helpFrame HTML helpText\
+\
+\
+ toplevel TopLevelShell printShell\
+ printShell Layout prntLayout\
+ prntLayout Group printGroup\
+ prntLayout Group printCmdGroup\
+\
+ printGroup Layout printLayout\
+ printLayout Label toLabel\
+ printLayout TextToggle toPrinter\
+ printLayout TextToggle toFile\
+ printLayout Label printLabel\
+ printLayout Frame printFrame\
+ printFrame AsciiText printEntry\
+ printLayout Label pageLabel\
+ printLayout TextToggle pageLetter\
+ printLayout TextToggle pageLegal\
+ printLayout TextToggle pageA4\
+ printLayout TextToggle pageB5\
+\
+ printCmdGroup Layout printCmdLayout\
+ printCmdLayout Command printOkay\
+ printCmdLayout Command printDismiss\
+\
+\
+ toplevel TopLevelShell searchShell\
+ searchShell Group searchGroup\
+ searchGroup Layout searchLayout\
+ searchLayout Label resLabel\
+ searchLayout Frame resFrame\
+ resFrame HTML resList\
+ searchLayout Label searchLabel\
+ searchLayout Frame searchFrame\
+ searchFrame AsciiText searchEntry\
+ searchLayout Command searchClear\
+ searchLayout Command searchOkay\
+ searchLayout Label searchStatus\
+ searchLayout TextToggle exactMatch\
+ searchLayout Command searchHelp\
+ searchLayout Command searchDismiss\
+\
+\
+ toplevel TransientShell findShell\
+ findShell Layout fsLayout\
+ fsLayout Group findGroup\
+ fsLayout Group findCmdGroup\
+\
+ findGroup Layout findLayout\
+ findLayout Label findLabel\
+ findLayout Frame findFrame\
+ findFrame AsciiText findEntry\
+ findLayout TextToggle findDir\
+ findLayout TextToggle findCase\
+\
+ findCmdGroup Layout findCmdLayout\
+ findCmdLayout Command findOkay\
+ findCmdLayout Command findClear\
+ findCmdLayout Command findDismiss\
+\
+\
+ toplevel TopLevelShell fileShell\
+ fileShell Layout flist\
+ flist Group flGroup\
+ flGroup Layout flFrame\
+ flFrame Label flistLabel\
+ flFrame Frame flistFrame\
+ flistFrame AsciiText flistText\
+ flFrame Label flpkgLabel\
+ flFrame Label flpkgVal\
+ flFrame Command flDismiss\
+\
+\
+ toplevel TopLevelShell fileBrowser\
+ fileBrowser Layout fbLayout\
+ fbLayout Group fnavGroup\
+ fbLayout Group fbCmdGroup\
+ fbLayout Parameter directory\
+\
+ fnavGroup Layout fnavLayout\
+ fnavLayout Command fnavHome\
+ fnavLayout Command fnavUp\
+ fnavLayout Command fnavRoot\
+ fnavLayout Command fnavRescan\
+ fnavLayout Label filterLabel\
+ fnavLayout Frame filterFrame\
+ filterFrame AsciiText filterEntry\
+ fnavLayout Command filterClear\
+ fnavLayout Group dirGroup\
+ dirGroup Frame dirFrame\
+ dirFrame Viewport dirView\
+ dirView List dirList\
+ fnavLayout Group fileGroup\
+ fileGroup Frame fgFrame\
+ fgFrame Viewport fileView\
+ fileView List fileList\
+ fnavLayout Label curdirLabel\
+ fnavLayout Label curdirVal\
+ fnavLayout Label fnameLabel\
+ fnavLayout Frame fnameFrame\
+ fnameFrame AsciiText fnameEntry\
+ fnavLayout Command fnameClear\
+\
+ fnavLayout Group fmtGroup\
+ fmtGroup Layout fmtLayout\
+ fmtLayout Label fmtLabel\
+ fmtLayout TextToggle fmtSrc\
+ fmtLayout TextToggle fmtText\
+ fmtLayout TextToggle fmtHTML\
+ fmtLayout TextToggle fmtPS\
+ fmtLayout Label owLabel\
+ fmtLayout TextToggle overwrite\
+\
+ fbCmdGroup Layout fbCmdLayout\
+ fbCmdLayout Command fbcOkay\
+ fbCmdLayout Command fbcHelp\
+ fbCmdLayout Command fbcDismiss\
+\
+\
+ toplevel TopLevelShell doc_source\
+ doc_source Layout srcLayout\
+ srcLayout Frame srcMenuFrame\
+ srcMenuFrame Layout srcMenuBar\
+ srcMenuBar Command srcDismiss\
+ srcLayout Frame srcFrame\
+ srcFrame AsciiText srcText\
+\
+\
+ toplevel TopLevelShell hlpShell\
+ hlpShell Layout hlpLayout\
+ hlpLayout Group hlpMenuGroup\
+ hlpMenuGroup Layout hlpMenu\
+ hlpMenu Command hlpBack\
+ hlpMenu Command hlpForward\
+ hlpMenu Command hlpHome\
+ hlpMenu Command hlpTutorial\
+ hlpMenu Command hlpDismiss\
+ hlpLayout Frame hlpTextFrame\
+ hlpTextFrame HTML hlpText\
+ hlpLayout Label hfLabel\
+ hlpLayout Frame hfFrame\
+ hfFrame AsciiText hfEntry\
+ hlpLayout Command hfFind\
+ hlpLayout Command hfClear\
+ hlpLayout TextToggle hfDir\
+ hlpLayout TextToggle hfCase\
+ hlpShell Parameter help\
+\
+\
+ toplevel TransientShell warning\
+ warning Layout warn\
+ warn Frame warnFrame\
+ warnFrame Layout WFlayout\
+ WFlayout Icon warnIcon\
+ WFlayout TextBox warnText\
+ warn Frame warnBtnFrame\
+ warnBtnFrame Command warnDismiss\
+\
+\
+ toplevel TopLevelShell tclShell\
+ tclShell Layout tclLayout\
+ tclLayout Group tclCmdGroup\
+ tclCmdGroup Layout tclCmd\
+ tclCmd Command tclClear\
+ tclCmd Command tclExecute\
+ tclCmd Toggle tclLogging\
+ tclCmd Command tclDismiss\
+ tclLayout Frame tclFrame\
+ tclFrame AsciiText tclEntry\
+\
+\
+ toplevel Parameter xhelp\
+ xhelp Parameter textout\
+ xhelp Parameter alert\
+ xhelp Parameter apropos\
+ xhelp Parameter pkglist\
+ xhelp Parameter helpres\
+ xhelp Parameter helpfiles\
+ xhelp Parameter printer\
+ xhelp Parameter curpack\
+ xhelp Parameter curtask\
+ xhelp Parameter history\
+ xhelp Parameter showtype\
+ xhelp Parameter type
+
+
+
+ !-------------------------------------------------------
+ ! Define some global resources for the main menu panels.
+ !-------------------------------------------------------
+ *shadowWidth: 1
+ *background: gray75
+ *Arrow.width: 16
+ *Arrow.height: 25
+ *Text*height: 21
+ *Command.height: 21
+ *Command.highlightThickness: 1
+ *Command.internalHeight: 4
+ *MenuButton.height: 21
+ *MenuButton.highlightThickness: 1
+ *Label.borderWidth: 0
+ *Label.shadowWidth: 0
+ *TextButton.shadowWidth: 0
+ *TextButton.highlightThickness: 1
+ *TextToggle*borderWidth: 0
+ *TextToggle.highlightThickness: 0
+ *Toggle.highlightThickness: 1
+ *Group.shrinkToFit: True
+
+ *Arrow.foreground: gray72
+ *Arrow.background: gray72
+ *Text*background: gray72
+ *AsciiText*background: gray72
+ *TextBox.background: gray72
+ *MultiList*background: gray72
+ *List*background: gray72
+ *Slider2d*thumbColor: gray75
+
+
+ !-------------------------------------------------------------
+ ! Define resources to take advantage of the 3D scrollbar look.
+ !-------------------------------------------------------------
+ *Scrollbar*background: gray75
+ *Scrollbar*width: 15
+ *Scrollbar*height: 15
+ *Scrollbar*shadowWidth: 1
+ *Scrollbar*cursorName: top_left_arrow
+ *Scrollbar*pushThumb: true
+
+
+ !----------------------------------------
+ ! Menu resources giving a shadow effect.
+ !----------------------------------------
+ *SmeBSB.leftMargin: 10
+ *SmeBSB.rightMargin: 5
+ *SmeBSB.shadowWidth: 2
+ *SmeBSB*background: SteelBlue
+ *SimpleMenu*background: gray77
+ *SimpleMenu.borderWidth: 2
+ *SimpleMenu.borderColor: Black
+ *SimpleMenu.shadowWidth: 2
+ *SimpleMenu.line1.foreground: gray51
+ *SimpleMenu.line2.foreground: gray91
+ *SimpleMenu.line3.foreground: gray51
+ *SimpleMenu.line4.foreground: gray91
+ *SimpleMenu.line5.foreground: gray51
+ *SimpleMenu.line6.foreground: gray91
+ *SimpleMenu.line7.foreground: gray51
+ *SimpleMenu.line8.foreground: gray91
+ *SimpleMenu.line9.foreground: gray51
+ *SimpleMenu.line10.foreground: gray91
+ *SimpleMenu.line11.foreground: gray51
+ *SimpleMenu.line12.foreground: gray91
+ *SimpleMenu.line13.foreground: gray51
+ *SimpleMenu.line14.foreground: gray91
+ *SimpleMenu.line15.foreground: gray51
+ *SimpleMenu.line16.foreground: gray91
+ *SimpleMenu.line17.foreground: gray51
+ *SimpleMenu.line18.foreground: gray91
+ *SimpleMenu.line19.foreground: gray51
+ *SimpleMenu.line20.foreground: gray91
+ *SimpleMenu.line21.foreground: gray51
+ *SimpleMenu.line22.foreground: gray91
+ *SimpleMenu.line23.foreground: gray51
+ *SimpleMenu.line24.foreground: gray91
+ *SimpleMenu.line25.foreground: gray51
+ *SimpleMenu.line26.foreground: gray91
+ *SimpleMenu.line27.foreground: gray51
+ *SimpleMenu.line28.foreground: gray91
+ *SimpleMenu.line29.foreground: gray51
+ *SimpleMenu.line30.foreground: gray91
+
+
+ !----------------------------------------
+ ! Define the default fonts to be used.
+ !----------------------------------------
+ *font: -adobe-times-medium-r-normal-*-14-*-*-*
+ *Command.font: -adobe-times-bold-i-normal-*-12-*-*-*
+ *MenuButton.font: -adobe-times-bold-i-normal-*-12-*-*-*
+ *Toggle.font: -adobe-times-bold-i-normal-*-12-*-*-*
+ *Label.font: -adobe-times-bold-i-normal-*-12-*-*-*
+ *TextToggle.font: -adobe-times-bold-i-normal-*-12-*-*-*
+ *Group*SimpleMenu*font: 7x13
+ *HTML*SimpleMenu*font: 7x13
+
+ *HTML.plainFont: -*-fixed-medium-r-*-*-13-*-*-*
+ *HTML.listingFont: -*-fixed-medium-r-*-*-13-*-*-*
+ *HTML.font: -adobe-times-medium-r-normal-*-14-*-*-*
+ *HTML.boldFont: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.plainboldFont: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.fixedboldFont: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.header1Font: -adobe-times-bold-r-normal-*-18-*-*-*
+ *HTML.header2Font: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.header3Font: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.header4Font: -adobe-times-bold-r-normal-*-14-*-*-*
+ *HTML.header5Font: -adobe-times-medium-i-normal-*-12-*-*-*
+ *HTML.header6Font: -adobe-times-bold-r-normal-*-10-*-*-*
+ *HTML.anchorUnderlines: 0
+ *HTML.visitedAnchorUnderlines: 0
+ *HTML.anchorColor: blue
+ *HTML.visitedAnchorColor: red3
+ *HTML*background: gray72
+ *HTML*Scrollbar.background: gray75
+ *HTML*Scrollbar*width: 15
+ *HTML*Scrollbar*height: 15
+
+
+ !---------------------------
+ ! Set the default resources.
+ !---------------------------
+ *xhelp.title: IRAF Help Browser V1.0 - DEV
+ *xhelp.geometry: +0+0
+ *xhelp.width: 625
+ *xhelp.minWidth: 580
+ *xhelp.minheight: 450
+ *xhelp.height: 850
+
+ *helpLayout.geometry: 600x700+0+0
+ *helpLayout*borderWidth: 0
+ *helpLayout*Group.shrinkToFit: True
+ *helpLayout*Frame.frameType: sunken
+ *helpLayout*Frame.frameWidth: 1
+ *helpLayout*Command.internalHeight: 2
+ *helpLayout*MenuButton.internalHeight: 2
+ *helpLayout*Label*highlightThickness: 0
+ *helpLayout*List*shadeSurplus: False
+ *helpLayout*List.internalWidth: 10
+ *helpLayout*Viewport.allowVert: True
+ *helpLayout*Viewport.forceBars: True
+ *helpLayout.width: 600
+ *helpLayout.layout: vertical { \
+ menubarGroup < +inf -inf * > \
+ -1 \
+ horizontal { \
+ -1 \
+ helpPanes < +inf -inf * +inf -inf > \
+ -1 \
+ } \
+ -1 \
+ }
+ *helpLayout*SimpleMenu.shadowWidth: 2
+ *helpLayout*SimpleMenu.borderColor: Black
+ *helpLayout*SimpleMenu.borderWidth: 2
+
+ *menubarGroup.label:
+ *menubarGroup.outerOffset: 0
+ *menubarGroup.innerOffset: 5
+ *menubarGroup.frameType: raised
+ *menubarGroup.frameWidth: 2
+ *menubarGroup*Command.shadowWidth: 0
+ *menubarGroup*MenuButton.shadowWidth: 0
+ *menubarLayout.layout: horizontal { \
+ fileButton 5 \
+ optionsButton 5 \
+ printButton 5 \
+ findButton 5 \
+ searchButton 5 \
+ historyButton 5 \
+ 10 < +inf -inf > \
+ helpButton 5 \
+ quitButton \
+ }
+ *fileButton.label: File
+ *fileButton.menuName: fileMenu
+ *optionsButton.label: Options
+ *optionsButton.menuName: optsMenu
+ *printButton.label: Print
+ *findButton.label: Find
+ *searchButton.label: Search
+ *historyButton.label: History
+ *historyButton.menuName: historyMenu
+ *helpButton.label: Help
+ *quitButton.label: Quit
+
+ *topicGroup.label:
+ *topicGroup.outerOffset: 2
+ *topicGroup.innerOffset: 2
+ *topicGroup*frameType: chiseled
+ *topicGroup.frameWidth: 2
+ *topicGroup*Label.shadowWidth: 0
+ *topicGroup*Label.borderWidth: 1
+ *topicGroup*Label.highlightThickness: 1
+ *topicGroup*Viewport.useRight: True
+ *topicGroup*Viewport.useBottom: True
+ *topicLayout.layout: vertical { \
+ 2 < +2 -2 > \
+ horizontal { \
+ 3 < +3 -3 > \
+ topicLabel 2 topicFrame < +inf * > \
+ 2 \
+ topicClear 5 reloadButton \
+ 1 \
+ } \
+ 4 \
+ horizontal { \
+ vertical { \
+ -1 \
+ listFrame < +inf -inf * +inf -inf > \
+ -1 \
+ } \
+ } \
+ 2 < +2 -2 > \
+ }
+ *reloadButton.label: Reload
+ *topicLabel.label: Topic:
+ *topicLabel.justify: right
+ *topicEntry*width: 100
+ *topicEntry*editType: edit
+ *topicEntry*font: 7x13
+ *topicEntry*displayCaret: True
+ *topicClear.label: Clear
+
+ *topicList.font: 7x13
+ *topicList.width: 500
+ *topicList.height: 100
+ *topicList.columnSpacing: 20
+ *topicList.verticalList: True
+ !*topicList.defaultColumns: 6
+ !*topicList.forceColumns: True
+
+ *outputGroup.label:
+ *outputGroup.outerOffset: 2
+ *outputGroup.innerOffset: 2
+ *outputGroup*frameType: chiseled
+ *outputGroup.frameWidth: 2
+ *outputGrout*TextToggle*on: 0
+ *outputGroup*TextToggle.frameWidth: 2
+ *outputGroup*TextToggle.frameType: chiseled
+ *outputGroup*TextToggle.location: 0 0 65 25
+ *outputGroup*TextToggle.leftMargin: 4
+ *outputLayout.layout: vertical { \
+ 2 \
+ horizontal { \
+ 5 \
+ htbButton 2 htfButton 2 htuButton 2 hthButton 2 \
+ 10 < +inf -10 > \
+ secButton 2 parButton \
+ 10 < +inf -10 > \
+ hlpOpt -2 srcOpt -2 sysOpt 4 filOpt \
+ 5 \
+ } \
+ 2 \
+ horizontal { \
+ 2 \
+ helpFrame < +inf -inf * +inf -inf > \
+ 2 \
+ } \
+ }
+ *htbButton.label: Back
+ *htbButton.sensitive: False
+ *htfButton.label: Forward
+ *htfButton.sensitive: False
+ *htuButton.label: Up
+ *htuButton.sensitive: False
+ *hthButton.label: Home
+ *printButton.label: Print
+ *secButton.label: Sections
+ *secButton.menuName: secMenu
+ *parButton.label: Parameters
+ *parButton.menuName: parMenu
+ *hlpOpt*label: Help
+ *hlpOpt*on: 1
+ *hlpOpt*onIcon: diamond1s
+ *hlpOpt*offIcon: diamond0s
+ *hlpOpt*highlightColor: green
+ *srcOpt*label: Source
+ *srcOpt*on: 0
+ *srcOpt*onIcon: diamond1s
+ *srcOpt*offIcon: diamond0s
+ *srcOpt*highlightColor: green
+ *sysOpt*label: Sysdoc
+ *sysOpt*on: 0
+ *sysOpt*onIcon: diamond1s
+ *sysOpt*offIcon: diamond0s
+ *sysOpt*highlightColor: green
+ *filOpt*label: Files
+ *filOpt*on: 0
+ *filOpt*onIcon: square1s
+ *filOpt*offIcon: square0s
+ *filOpt*highlightColor: yellow
+
+ *helpText.width: 650
+ *helpText.height: 620
+ *helpText.anchorUnderlines: 1
+ *helpText.visitedAnchorUnderlines: 1
+ *helpText.verticalScrollOnRight: true
+ *helpText.translations: \
+ <Btn2Down>: popup(secMenu) \n\
+ <Btn2Up>: popdown(secMenu) \n\
+ <Btn3Down>: popup(navMenu) \n\
+ <Btn3Up>: popdown(navMenu) \n
+
+ *helpText*navMenu.foreground: Black
+ *helpText*navMenu.background: gray75
+ *helpText*secMenu.foreground: Black
+ *helpText*secMenu.background: gray75
+
+
+ !--------------------------+
+ ! Printer Shell resources. |
+ !--------------------------+
+ *printShell.title: Printer Selection
+ *printShell.width: 300
+ *printShell.height: 177
+ *printShell.minHeight: 177
+ *printShell.maxHeight: 177
+ *printShell*borderWidth: 0
+ *printShell*Group.frameType: chiseled
+ *printShell*Group.frameWidth: 2
+ *printShell*Group.innerOffset: 5
+ *printShell*Group.outerOffset: 2
+ *printShell*Command.internalheight: 4
+ *printShell*Text*editType: edit
+ *printShell*Text*height: 25
+ *printShell*TextToggle.frameWidth: 0
+ *printShell*Group.label:
+ *prntLayout.layout: vertical { \
+ printGroup < +inf -inf * > \
+ printCmdGroup < +inf -inf * > \
+ }
+
+ *printLayout*location: 0 0 70 25
+ *printLayout*offIcon: diamond0s
+ *printLayout*onIcon: diamond1s
+ *printLayout*highlightColor: yellow
+ *printLayout*Label.height: 35
+ *printLayout*Label.justify: right
+ *printLayout*TextToggle.frameWidth: 0
+ *printLayout*TextToggle.leftMargin: 8
+ *printLayout*TextToggle*highlightColor: yellow
+ *printLayout*TextToggle*onIcon: square1s
+ *printLayout*TextToggle*offIcon: square0s
+ *printLayout*TextToggle*alignment: left
+ *printLayout.layout: vertical { \
+ 0 < +0 >\
+ horizontal { toLabel 10 toPrinter 10 toFile 10 } \
+ 5 < +inf -5 > \
+ horizontal { \
+ printLabel 5 printFrame < +inf -inf * > -1 \
+ } \
+ 5 < +inf -5 > \
+ horizontal { \
+ vertical { pageLabel 10 } \
+ 12 \
+ horizontal { \
+ vertical { pageLetter -3 pageLegal } \
+ 10 \
+ vertical { pageA4 -3 pageB5 } \
+ } \
+ } \
+ 0 < +0 >\
+ }
+ *toLabel.label: Print to:
+ *toPrinter.label: Printer
+ *toPrinter.on: True
+ *toFile.label: File
+ *printLabel.label: Printer:
+ *printFrame.frameType: sunken
+ *printFrame.frameWidth: 1
+ *printEntry*string: printer
+ *pageLabel.label: Page Size:
+ *pageLetter.label: Letter
+ *pageLetter.on: 1
+ *pageLegal.label: Legal
+ *pageA4.label: A4
+ *pageB5.label: B5
+
+ *printCmdLayout.layout: horizontal { \
+ 3 \
+ printOkay 20 < +inf -20 > printDismiss \
+ 3 \
+ }
+ *printOkay.label: Print
+ *printDismiss.label: Dismiss
+
+
+ !-------------------------+
+ ! File Browser resources. |
+ !-------------------------+
+ *fileBrowser.width: 450
+ *fileBrowser.height: 375
+ *fileBrowser.title: Open a New File...
+ *fileBrowser*borderWidth: 0
+ *fileBrowser*Group.frameType: chiseled
+ *fileBrowser*Group.frameWidth: 2
+ *fileBrowser*Group.innerOffset: 3
+ *fileBrowser*Group.outerOffset: 3
+ *fileBrowser*Group.label:
+
+ *fbLayout.layout: vertical { \
+ 2 \
+ fnavGroup < +inf -inf * +inf -inf > \
+ -2 \
+ horizontal { \
+ -5 \
+ fbCmdGroup < +inf -inf * > \
+ -5 } \
+ -3 \
+ }
+
+ *fnavGroup*Frame.frameType: sunken
+ *fnavGroup*Frame.frameWidth: 1
+ *fnavGroup*Text*editType: edit
+ *fnavGroup*Text*height: 25
+ *fnavGroup*Text*font: 7x13
+ *fnavGroup*List.verticalList: True
+ *fnavGroup*List.defaultColumns: 1
+ *fnavGroup*List.forceColumns: True
+ *fnavGroup*List.font: 7x13
+ *fnavGroup*Label.justify: left
+ *fnavGroup*Viewport.allowVert: True
+ *fnavGroup*Viewport.allowHoriz: False
+ *fnavGroup*Viewport.forceBars: True
+ *fnavGroup*Viewport.useRight: True
+ *fnavGroup*Group.outerOffset: 7
+ *fnavGroup*Group.innerOffset: 3
+ *fnavLayout.layout: vertical { \
+ 5 \
+ vertical { \
+ -1 \
+ horizontal { \
+ 5 \
+ fnavHome < +inf -inf * > 2 \
+ fnavUp < +inf -inf * > 2 \
+ fnavRoot < +inf -inf * > 2 \
+ fnavRescan < +inf -inf * > \
+ 10 \
+ filterLabel 2 filterFrame < +inf -inf * > \
+ 2 \
+ filterClear \
+ 5 \
+ } \
+ 3 \
+ } \
+ 5 \
+ horizontal { \
+ -5 \
+ dirGroup < +inf -inf * +inf - inf > \
+ -8 \
+ fileGroup < +inf -inf * +inf - inf > \
+ -5 \
+ } \
+ -3 \
+ horizontal { \
+ curdirLabel 5 curdirVal < +inf -inf * > 5 } \
+ 5 \
+ horizontal { \
+ fnameLabel 2 fnameFrame < +inf -inf * > 2 fnameClear 5\
+ } \
+ 7 \
+ fmtGroup < +inf -inf * > \
+ -3 \
+ }
+ *fileBrowser*fnavGroup*dirGroup.label: Directories
+ *fileBrowser*fnavGroup*fileGroup.label: Files
+ *fileBrowser*fnavGroup*dirGroup.innerOffset: 3
+ *fileBrowser*fnavGroup*fileGroup.innerOffset: 3
+ *fileBrowser*fnavGroup*dirGroup.outerOffset: 7
+ *fileBrowser*fnavGroup*fileGroup.outerOffset: 7
+ *fileBrowser*fnavGroup*dirGroup.font: 7x13bold
+ *fileBrowser*fnavGroup*fileGroup.font: 7x13bold
+
+ *filterLabel.label: Filter
+ *filterClear.label: Clear
+ *curdirLabel.label: Directory:
+ *curdirVal.label:
+ *curdirVal.font: 7x13
+ *fnameLabel.label: Selection\ \
+ *fnameClear.label: Clear
+ *fnavHome.label: Home
+ *fnavUp.label: Up
+ *fnavRoot.label: Root
+ *fnavRescan.label: Rescan
+
+ *fmtGroup*Group.outerOffset: 3
+ *fmtGroup*Group.innerOffset: 3
+ *fmtLayout*TextToggle.frameWidth: 0
+ *fmtLayout*TextToggle.leftMargin: 4
+ *fmtLayout*TextToggle.alignment: left
+ *fmtLayout*TextToggle*highlightColor: yellow
+ *fmtLayout*TextToggle*onIcon: square1s
+ *fmtLayout*TextToggle*offIcon: square0s
+ *fmtLayout.layout: vertical { \
+ horizontal { 5 fmtLabel 10 fmtSrc 3 fmtText 3 fmtHTML 3 fmtPS 5 } \
+ horizontal { 50 owLabel 10 overwrite 5 < +inf > } \
+ }
+ *fmtLabel.label: Save As Format:
+ *fmtSrc.label: Source
+ *fmtSrc.on: 1
+ *fmtSrc.location: 0 0 65 22
+ *fmtText.label: Text
+ *fmtText.location: 0 0 65 22
+ *fmtHTML.label: HTML
+ *fmtHTML.location: 0 0 65 22
+ *fmtPS.label: PostScript
+ *fmtPS.location: 0 0 100 22
+ *owLabel.label: Options:
+ *overwrite.label: Allow overwrite of existing files?
+ *overwrite.location: 0 0 200 22
+
+ *fbCmdLayout.outerOffset: 0
+ *fbCmdLayout.layout: horizontal { \
+ 5 \
+ vertical { 2 fbcOkay 2 } \
+ 20 < +inf -20 > \
+ vertical { 2 fbcHelp 2 } \
+ 2 \
+ vertical { 2 fbcDismiss 2 } \
+ 5 \
+ }
+ *fbcOkay.label: Okay
+ *fbcHelp.label: Help
+ *fbcDismiss.label: Dismiss
+
+
+ !-----------------------+
+ ! Find Shell resources. |
+ !-----------------------+
+ *findShell.title: Find within a document...
+ *findShell.width: 365
+ *findShell.height: 130
+ *findShell*borderWidth: 0
+ *findShell*Group.frameType: chiseled
+ *findShell*Group.frameWidth: 2
+ *findShell*Group.innerOffset: 5
+ *findShell*Group.outerOffset: 2
+ *findShell*Command.internalheight: 4
+ *findShell*Text*editType: edit
+ *findShell*Text*height: 25
+ *findShell*TextToggle.frameWidth: 0
+ *findShell*Group.label:
+ *fsLayout.layout: vertical { \
+ findGroup < +inf -inf * > \
+ findCmdGroup < +inf -inf * > \
+ }
+
+ *findLayout*location: 0 0 120 25
+ *findLayout*offIcon: diamond0s
+ *findLayout*onIcon: diamond1s
+ *findLayout*highlightColor: yellow
+ *findLayout*Label.height: 35
+ *findLayout*Label.justify: right
+ *findLayout*TextToggle.frameWidth: 0
+ *findLayout*TextToggle.leftMargin: 4
+ *findLayout*TextToggle*highlightColor: yellow
+ *findLayout*TextToggle*onIcon: square1s
+ *findLayout*TextToggle*offIcon: square0s
+ *findLayout.layout: vertical { \
+ 5 \
+ horizontal { \
+ findLabel 7 findFrame < +inf -inf * > -1 \
+ } \
+ 5 \
+ horizontal { \
+ 20 < +inf -20 > \
+ findDir 10 findCase \
+ 20 < +inf -20 > \
+ } \
+ }
+ *findLabel.label: Find:
+ *findFrame.frameType: sunken
+ *findFrame.frameWidth: 1
+ *findEntry*string:
+ *findDir.label: Find Backwards
+ *findCase.label: Case Sensitive
+
+ *findCmdLayout.layout: horizontal { \
+ 3 \
+ findOkay \
+ 20 < +inf -20 > \
+ findClear \
+ 20 < +inf -20 > \
+ findDismiss \
+ 3 \
+ }
+ *findOkay.label: Find
+ *findClear.label: Clear
+ *findDismiss.label: Dismiss
+
+
+ !-------------------------------------------+
+ ! Set the document source viewer resources. |
+ !-------------------------------------------+
+ *doc_source.title: Page source
+ *doc_source.width: 575
+ *doc_source.height: 450
+ *srcLayout*borderWidth: 0
+ *srcLayout.layout: vertical { \
+ srcMenuFrame < +inf -inf * > \
+ -2 \
+ srcFrame < +inf -inf * +inf -inf > \
+ -2 \
+ }
+
+ *srcMenuBar.layout: horizontal { 50 < +inf -inf > srcDismiss 5 }
+ *srcMenuFrame.height: 40
+ *srcMenuFrame.outerOffset: 0
+ *srcMenuFrame.innerOffset: 5
+ *srcMenuFrame.frameType: chiseled
+ *srcMenuFrame.frameWidth: 2
+ *srcFrame.frameType: sunken
+ *srcFrame.frameWidth: 1
+ *srcFrame.outerOffset: 5
+ *srcText*scrollVertical: always
+ *srcText*scrollHorizontal: always
+ *srcText*Scrollbar.width: 15
+ *srcText*Scrollbar.height: 15
+ *srcText*background: gray75
+ *srcText*font: 7x13
+ *srcText*editType: read
+ *srcText*displayCaret: False
+ *srcDismiss.label: Dismiss
+ *srcDismiss.width: 150
+
+
+ !-------------------------+
+ ! Search Shell resources. |
+ !-------------------------+
+ *searchShell.title: Search for a topic...
+ *searchShell.width: 600
+ *searchShell.height: 250
+ *searchShell*borderWidth: 0
+ *searchShell*Viewport.allowVert: True
+ *searchShell*Viewport.allowHoriz: True
+ *searchShell*Viewport.useBottom: True
+ *searchShell*Viewport.useRight: False
+ *searchShell*Viewport.forceBars: True
+ *searchGroup.frameType: chiseled
+ *searchGroup.frameWidth: 2
+ *searchGroup.innerOffset: 7
+ *searchGroup.outerOffset: 7
+ *searchGroup.highlightThickness: 0
+ *searchGroup.label:
+ *searchLayout.layout: vertical { \
+ horizontal { \
+ 45 < +45 -45 > \
+ resLabel < +inf -inf * > \
+ 5 < +inf -inf > \
+ exactMatch \
+ } \
+ 2 < +2 - 2 > \
+ resFrame < +inf -inf * +inf -inf > \
+ 5 < +5 - 5 > \
+ horizontal { \
+ searchLabel 5 searchFrame \
+ 5 \
+ searchClear 2 searchOkay \
+ 5 < +inf -inf > \
+ searchStatus \
+ 5 < +inf -inf > \
+ searchHelp 2 searchDismiss \
+ } \
+ }
+ *resLabel.label: Task Package Description
+ *resLabel.justify: left
+ *resFrame.frameType: sunken
+ *resFrame.frameWidth: 1
+ *resList.font: 7x13
+ *resList.width: 100
+ *resList.height: 100
+ *resList.marginWidth: 5
+ *resList.marginHeight: 5
+
+ *searchLabel.label: Topic:
+ *searchFrame.frameType: sunken
+ *searchFrame.frameWidth: 1
+ *searchEntry*font: 7x13
+ *searchEntry*displayCaret: True
+ *searchEntry*editType: edit
+ *searchEntry*height: 25
+ *searchEntry*width: 150
+ *searchClear.label: Clear
+ *searchOkay.label: Search
+ *searchStatus.label:
+ *exactMatch.label: Require Exact Match
+ *exactMatch*on: 1
+ *exactMatch*onIcon: diamond1s
+ *exactMatch*offIcon: diamond0s
+ *exactMatch*highlightColor: green
+ *exactMatch.frameWidth: 2
+ *exactMatch.frameType: chiseled
+ *exactMatch.location: 0 0 150 25
+ *exactMatch.leftMargin: 4
+ *searchHelp.label: Help
+ *searchDismiss.label: Dismiss
+
+
+ !----------------
+ ! Help Window.
+ !----------------
+ *hlpShell.title: Help
+ *hlpShell.width: 500
+ *hlpShell.height: 620
+ *hlpLayout*borderWidth: 0
+ *hlpLayout*Frame*frameType: sunken
+ *hlpLayout*Frame*frameWidth: 1
+
+ *hlpMenuGroup.label:
+ *hlpMenuGroup.outerOffset: 0
+ *hlpMenuGroup.innerOffset: 0
+ *hlpLayout.layout: vertical { \
+ hlpMenuGroup < +inf -inf * > \
+ -3 \
+ hlpTextFrame < +inf -inf * +inf -inf > \
+ horizontal { \
+ 5 \
+ hfLabel 5 hfFrame < +inf -inf *> \
+ 2 \
+ hfFind 2 hfClear 5 hfDir 5 hfCase \
+ 5 \
+ } \
+ 2 \
+ }
+ *hlpLayout*TextToggle*location: 0 0 90 25
+ *hlpLayout*TextToggle*offIcon: diamond0s
+ *hlpLayout*TextToggle*onIcon: diamond1s
+ *hlpLayout*TextToggle*highlightColor: yellow
+ *hlpLayout*TextToggle*frameType: chiseled
+ *hlpLayout*TextToggle*frameWidth: 2
+ *hfEntry*editType: edit
+ *hfEntry*font: 7x13
+ *hfEntry*displayCaret: True
+ *hfLabel.label: Find:
+ *hfFind.label: Find
+ *hfClear.label: Clear
+ *hfDir.label: Backwards
+ *hfCase.label: Caseless
+ *hfCase.on: true
+
+ *hlpMenu*Command.internalHeight: 4
+ *hlpMenu*Command.highlightThickness: 1
+ *hlpMenu*Command.height: 20
+ *hlpMenu.layout: vertical { \
+ 5 \
+ horizontal { \
+ 5 \
+ hlpBack 2 hlpForward 2 hlpHome 2 hlpTutorial \
+ 20 < +inf -20 > \
+ hlpDismiss \
+ 5 \
+ } \
+ 5 \
+ }
+ *hlpBack.label: Back
+ *hlpBack.sensitive: False
+ *hlpForward.label: Forward
+ *hlpHome.label: Home
+ *hlpTutorial.label: Tutorial
+ *hlpTutorial.sensitive: false
+ *hlpDismiss.label: Dismiss
+
+ *hlpTextFrame.outerOffset: 2
+ *hlpText.width: 500
+ *hlpText.height: 500
+ *hlpText.anchorUnderlines: 1
+ *hlpText.visitedAnchorUnderlines: 1
+ *hlpText.verticalScrollOnRight: true
+
+
+ !------------------+
+ ! File List dialog.
+ !------------------+
+ *fileShell.title: Help Files
+ *fileShell.geometry: 500x165
+ *fileShell*borderWidth: 0
+ *fileShell*Command.width: 90
+ *fileShell*Command.height: 30
+ *fileShell*Frame.frameType: sunken
+ *fileShell*Frame.frameWidth: 1
+ *fileShell*Frame.innerOffset: 1
+ *fileShell*Text*font: 7x13
+ *flist.layout: vertical { \
+ 1 \
+ horizontal { 1 flGroup < +inf -inf * +inf -inf> 1 } \
+ 1 \
+ }
+
+ *flGroup.frameType: chiseled
+ *flGroup.frameWidth: 2
+ *flGroup.innerOffset: 5
+ *flGroup.outerOffset: 5
+ *flGroup.label:
+ *flFrame.layout: vertical { \
+ 5 \
+ horizontal { \
+ 13 \
+ flistLabel < +inf -inf * > \
+ 5 < +inf -5 > \
+ } \
+ 2 \
+ horizontal { 1 flistFrame < +inf -inf * +inf -inf > 1 } \
+ 7 \
+ horizontal { \
+ 5 \
+ flpkgLabel 2 flpkgVal < +inf -inf * > \
+ 5 < +inf -5 > \
+ flDismiss \
+ 5 \
+ } \
+ }
+ *flDismiss.label: Dismiss
+ *flistLabel.label: Option Status Filename
+ *flistLabel.justify: left
+ *flpkgLabel.label: Task:
+ *flpkgLabel.justify: left
+ *flpkgVal.label: (Undefined)
+ *flpkgVal.justify: left
+ *flpkgVal*font: 7x13
+ *flistText.label:
+ *flistText.scrollVertical: Never
+ *flistText.scrollHorizontal: whenNeeded
+ *flistText*displayCaret: False
+ *flistText*editType: edit
+
+
+ !----------------+
+ ! WARNING dialog.
+ !----------------+
+ *warning.geometry: +400+300
+ *warning*borderWidth: 0
+ *warning*TextBox.frameWidth: 0
+ *warning*Command.width: 90
+ *warning*Command.height: 30
+ *warning*Frame.frameType: sunken
+ *warning*Frame.frameWidth: 1
+ *warning*Frame.innerOffset: 3
+ *warn.layout: vertical { \
+ 5 \
+ horizontal { \
+ 5 \
+ warnFrame < +inf * +inf > \
+ 5 \
+ } \
+ 5 \
+ horizontal { \
+ 5 < +inf -5 > \
+ warnBtnFrame \
+ 5 < +inf -5 > \
+ } \
+ 5 \
+ }
+
+ *WFlayout.layout: horizontal { \
+ 5 \
+ vertical { \
+ 5 < +inf -5 > \
+ warnIcon \
+ 5 < +inf -5 > \
+ } \
+ 5 \
+ warnText < +inf -inf * +inf -inf > \
+ 5 \
+ }
+ *warnIcon.location: 0 0 40 40
+ *warnIcon.image: WARNING
+ *warnText.label: generic warning text
+ *warnText.width: 270
+ *warnText.height: 60
+ *warnText*background: gray75
+ *warnDismiss.label: Dismiss
+
+ !--------------------------
+ ! Define a Debug Tcl shell.
+ !--------------------------
+ *tclShell.width: 550
+ *tclShell.height: 180
+ *tclShell.title: TCL Command Entry Shell
+ *tclLayout*borderWidth: 0
+ *tclLayout*Frame.frameType: sunken
+ *tclLayout*Frame.frameWidth: 1
+ *tclLayout.layout: vertical { \
+ tclCmdGroup < +inf -inf * > \
+ tclFrame < +inf -inf * +inf -inf> \
+ }
+ *tclEntry*editType: edit
+ *tclEntry*type: string
+ *tclEntry*scrollVertical: Always
+ *tclEntry*scrollHorizontal: whenNeeded
+
+ *tclCmdGroup.label:
+ *tclCmdGroup.outerOffset: 0
+ *tclCmdGroup.innerOffset: 0
+ *tclCmd.layout: vertical { \
+ 5 \
+ horizontal { \
+ 5 \
+ tclClear 3 tclExecute \
+ 10 < +inf -10> \
+ tclLogging 3 tclDismiss \
+ 5 \
+ } \
+ 5 \
+ }
+ *tclClear.label: Clear
+ *tclExecute.label: Execute
+ *tclLogging.label: Enable Logging
+ *tclDismiss.label: Dismiss
+}
+
+
+
+################################################################################
+
+createObjects
+
+# Define Bitmaps and Pixmaps to be used.
+createBitmap null 16 16 {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+createBitmap check 16 16 {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x60,
+ 0x00, 0x30, 0x00, 0x18, 0x00, 0x0c, 0x08, 0x06, 0x18, 0x03, 0xb0, 0x01,
+ 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+createBitmap arrow 16 16 {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x14, 0xf8, 0x27,
+ 0x08, 0x40, 0xf8, 0x27, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+activate
+
+################################################################################
+
+
+################################################################################
+# Global variables. |
+################################################################################
+set version "IRAF Help GUI V1.0" ;# version string
+set curpack "" ;# current values
+set curtask ""
+set helpType "package" ;# type of help to get
+set helpOption "help" ;# help option param
+set fileManaged 0 ;# is fileShell mapped?
+set pkgList { }
+set visited(0) empty
+
+set listOrient 1 ;# options
+set showType 0
+set showFiles 1
+set exactMatch 1
+
+set MAX_MENU_SIZE 40 ;# what it says it is
+
+# History array initialization.
+set HPkg(0) {Home} ;# package
+set HOpt(0) {help} ;# option
+set HTask(0) {Home} ;# task
+set HUrl(0) {} ;# url
+set HType(0) {task} ;# type (task|package|file)
+set HFile(0) {} ;# filename
+set htop 0 ;# top of array
+set hcurrent 0 ;# current page
+
+# Panel mapping flags.
+set search_mapped 0 ;# searchShell mapped?
+
+
+################################################################################
+# Utility Callbacks
+################################################################################
+
+# Procedures for sending client cursor commands.
+proc GKey { key args } { send client gkey $key }
+proc GCmd { args } { send client gcmd $args }
+
+# Procedures to test True/False strings in resources.
+proc true { v } \
+ { expr { $v=="true" || $v=="True" || $v=="TRUE" || $v==1 || $v=="yes" } }
+proc false { v } \
+ { expr { $v=="false" || $v=="False" || $v=="FALSE" || $v==0 || $v=="no" } }
+
+# No-op procedure for text widgets with no callbacks to swallow newline.
+proc noop { args } { }
+
+# Common functions.
+proc min { a b } { expr {($a < $b) ? $a : $b} }
+proc max { a b } { expr {($a > $b) ? $a : $b} }
+
+
+#--------------------+
+# Debugging options. |
+#--------------------+
+set debug 0 ;# debug flag
+send tclLogging set state [min 1 $debug]
+
+
+################################################################################
+# Initialize. |
+################################################################################
+proc Init args {
+ global history curpack curtask debug
+ global secMenuDescription parMenuDescription
+ global HPkg HTask HUrl HOpt HFile HType
+
+ if {$debug == 1} { send tclShell map }
+
+ # Reinitialize global vars in case of a restart.
+ set curpack ""
+ set curtask ""
+ set helpType "package"
+ set helpOption "help"
+
+ # Initialize the entry strings.
+ send printEntry set string ""
+ send topicEntry set string ""
+
+ # Initialize the various lists.
+ send topicList setList "{ }" resize
+
+ send secButton set sensitive False
+ send parButton set sensitive False
+ editMenu secMenu secButton $secMenuDescription
+ editMenu parMenu parButton $parMenuDescription
+
+} ; #send server postActivateCallback Init
+
+
+
+# Create the Navigation Menu.
+set navMenuDescription {
+ { "Back " f.exec { Back }
+ sensitive {([send htbButton isSensitive]==1) ? "true" : "false" }
+ }
+ { "Forward " f.exec { Forward }
+ sensitive {([send htfButton isSensitive]==1) ? "true" : "false" }
+ }
+ { "Up " f.exec { Up }
+ sensitive {([send htuButton isSensitive]==1) ? "true" : "false" }
+ }
+ { "Home " f.exec { Home } }
+ { f.dblline }
+ { "Reload " f.exec { Reload } }
+ { "Open File... " f.exec { Open } }
+ { "Save As... " f.exec { SaveAs } }
+ { "View Page Source " f.exec { srcOpen } }
+ { f.dblline }
+ { "Find... " f.exec { Find } }
+ { "Search... " f.exec { Search } }
+ { "Print... " f.exec { Print } }
+} ; createMenu navMenu helpText $navMenuDescription
+
+# Create the default Section Menu.
+set secMenuDescription {
+ { " Top of Page " f.exec { send helpText gotoId 0 } }
+ { f.dblline }
+ { " " f.exec { noop } }
+ { " No Sections Found " f.exec { noop } }
+ { " " f.exec { noop } }
+} ; createMenu secMenu secButton $secMenuDescription
+
+# Create the default Parameter Menu.
+set parMenuDescription {
+ { " No Parameters Found" f.exec { noop } }
+} ; createMenu parMenu parButton $parMenuDescription
+
+
+# Initialize.
+Init
+
+
+################################################################################
+# Menubar command callbacks.
+################################################################################
+
+# File Menu
+set fileMenuDescription {
+ { " Open File... " f.exec { Open } }
+ { " Save As... " f.exec { SaveAs } }
+ { " Print... " f.exec { Print } }
+ { f.dblline }
+ { " Reload... " f.exec { Reload } }
+ { " View Page Source " f.exec { srcOpen } }
+ { " Search... " f.exec { Search } }
+ { " Find... " f.exec { Find } }
+ { f.dblline }
+ { " Help " f.exec { Help } }
+ { " Quit " f.exec { Quit } }
+} ; createMenu fileMenu fileButton $fileMenuDescription
+
+
+# History Menu
+set historyMenuDescription {
+ { " Back " f.exec { Back }
+ sensitive {([send htbButton isSensitive]==1) ? "true" : "false" }
+ }
+ { " Forward " f.exec { Forward }
+ sensitive {([send htfButton isSensitive]==1) ? "true" : "false" }
+ }
+ { " Up " f.exec { Up }
+ sensitive {([send htuButton isSensitive]==1) ? "true" : "false" }
+ }
+ { " Home " f.exec { Home } }
+ { f.dblline }
+ { " Clear History" f.exec { histClear } }
+ { f.dblline }
+} ; createMenu historyMenu historyButton $historyMenuDescription
+
+
+# Options Menu
+set optsMenuDescription {
+ { " Show task type " f.exec { setOpts showType }
+ bitmap {($showType==1)? "check" : "null"} }
+ { " Show missing files " f.exec { setOpts showFiles }
+ bitmap {($showFiles==1)? "check" : "null"} }
+ { f.dblline }
+ { " Vertical task listing " f.exec { setOpts verticalList True }
+ bitmap {($listOrient==1)? "check" : "null"}
+ }
+ { " Horizontal task listing " f.exec { setOpts verticalList False }
+ bitmap {($listOrient==0)? "check" : "null"}
+ }
+ { f.dblline }
+ { " Tcl Command Shell " f.exec { tclOpen } }
+} ; createMenu optsMenu optionsButton $optsMenuDescription
+
+
+proc setOpts { opt args } {
+ global optsMenuDescription
+ global listOrient showType showFiles
+ global HTask HPkg HOpt hcurrent
+
+ switch $opt {
+ showType { set showType [expr { ($showType == 1) ? 0 : 1 } ]
+ GCmd type $showType
+ set h $hcurrent
+ GCmd help $HTask($h) $HPkg($h) $HOpt($h)
+ }
+ showFiles { set showFiles [expr { ($showFiles == 1) ? 0 : 1 } ]
+ }
+ verticalList { set listOrient [expr { ($args == "False") ? 0 : 1 } ]
+ send topicList set verticalList $args
+ }
+ }
+ editMenu optsMenu optionsButton $optsMenuDescription
+}
+
+proc Print args {
+ send printShell map
+} ; send printButton addCallback Print
+
+proc Find { args } {
+ send findShell popup
+} ; send findButton addCallback Find
+
+proc Search { args } {
+ global search_mapped
+
+ send searchShell map
+ set search_mapped 1
+} ; send searchButton addCallback Search
+
+proc Reload args {
+ global HPkg HType HUrl HOpt HTask HFile hcurrent
+
+ if { $HType($hcurrent) == "file"} {
+ if {[info exists HFile($hcurrent)] == 1} {
+ GCmd directory open $HFile($hcurrent)
+ } else {
+ setAlert param old [format "HFile param at %d not found" $hcurrent]
+ }
+ } else {
+ loadHistItem $hcurrent $HPkg($hcurrent) $HTask($hcurrent) \
+ $HOpt($hcurrent) $HType($hcurrent) $HUrl($hcurrent)
+ }
+} ; send reloadButton addCallback Reload
+
+proc Help args {
+ send hlpShell map
+} ; send helpButton addCallback Help
+
+proc Open args {
+ send fmtGroup unmap
+ send fmtGroup set height 0
+ send fbcOkay set label Load
+ send fileBrowser map
+}
+
+proc SaveAs args {
+ global format
+
+ # Reset the default format every time we open.
+ send $format set on 0
+ set format fmtSrc
+ send $format set on 1
+
+ # If there's no filename specified set one as a default.
+ setDefaultFname
+
+ send fmtGroup map
+ send fmtGroup set height 65
+ send fbcOkay set label Save
+ send fileBrowser map
+}
+
+proc Quit args {
+ GCmd quit
+ deactivate unmap
+}; send quitButton addCallback Quit
+
+
+
+################################################################################
+# Callbacks for client state variables (UI parameter objects). When the
+# client's state changes it updates a UI parameter to reflect the change.
+# This produces a callback to one or more of the callbacks defined below,
+# used to update the GUI to reflect the changing state of the client.
+################################################################################
+
+proc setShowType { param old new } {
+ global showType listOrient showFiles optsMenuDescription
+ set showType $new
+ editMenu optsMenu optionsButton $optsMenuDescription
+}; send showtype addCallback setShowType
+
+proc setTopics { param old new } {
+ global pkgList
+ set pkgList $new
+ send topicList setList $new resize
+}; send pkglist addCallback setTopics
+
+proc appendHist { param old new } {
+ global helpType helpOption curtask curpack
+
+ if {$new == "package"} {
+ #addHistRecord $curpack $curpack "" $helpOption "" $helpType
+ addHistRecord $curpack $curpack "" $helpOption "" "package"
+ } elseif {$new == "append"} {
+ # We've got a result of some kind and all of the values have been
+ # set, so create a history record.
+ if {$curpack != "" && $curtask != ""} {
+ addHistRecord $curpack $curtask "" $helpOption "" $helpType
+ }
+ }
+}; send history addCallback appendHist
+
+proc setCurpack { param old new } {
+ global curpack
+
+ if { $new != [getPkgName $curpack] } {
+ if { $curpack != "" && \
+ $curpack != "clpackage" && \
+ [string match "root*" $new] != 1} {
+ set curpack [ format "%s.%s" $curpack $new]
+ send htuButton set sensitive true
+ } else {
+ set curpack $new
+ }
+ }
+}; send curpack addCallback setCurpack
+
+
+proc setCurtask { param old new } {
+ global curtask curpack helpType
+
+ if {$helpType == "package"} {
+ send topicEntry set string $curpack
+ } else {
+ send topicEntry set string [ format "%s.%s" $curpack $new ]
+ }
+
+ # Update the printer dialog so the filename defaults to the curtask.
+ if { [send toFile get on] } {
+ if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} {
+ send printEntry set string [format "%s" [fileSource] ]
+ } else {
+ send printEntry set string [format "%s.ps" $new]
+ }
+ } else {
+ send printEntry set string "printer"
+ }
+ set curtask $new
+}; send curtask addCallback setCurtask
+
+
+proc getPkgName { pkg } {
+ set last [ string last "." $pkg ]
+ if { $last > -1 } {
+ return [ string range $pkg [incr last] end ]
+ } else {
+ return $pkg
+ }
+}
+
+proc getParentName { pkg } {
+ set last [ string last "." $pkg ]
+ if { $last > -1 } {
+ set root [ string range $pkg 0 [incr last -1] ]
+ } else {
+ set root $pkg
+ }
+ return [getPkgName $root]
+}
+
+
+# Topic list selection callback.
+proc topicSelect { widget event args } {
+ global htop hcurrent curpack curtask helpOption helpType
+ global visited
+
+ # If we're currently positioned somewhere in the middle of the
+ # history menu, push the current page to the history list before
+ # getting the next result.
+ if {$htop != $hcurrent} {
+ addHistRecord $curpack $curtask "" $helpOption "" $helpType
+ send htbButton set sensitive True
+ send htuButton set sensitive True
+ }
+
+ set item [string trimright [send topicList getItem itemno] "."]
+ send topicList getItem itemno
+ if { $itemno != "none" } {
+ GCmd help $item $curpack $helpOption
+ set visited($item) 1
+ }
+} ; send topicList addEventHandler topicSelect buttonReleaseMask
+
+proc listViewResize { args } {
+ global pkglist
+ send topicList setList $pkglist resize
+} ; send listView addEventHandler listViewResize ResizeRedirectMask
+
+
+# Get help for a specific topic from the topic entry widget.
+proc getTopicHelp { widget mode topic args } {
+ global curpack helpOption
+
+ if { [string match "*\.*" $topic] == 1} {
+ set pkglist [ split $topic "." ]
+ set pack [lindex $pkglist [expr {[llength $pkglist] - 2}] ]
+ set task [lindex $pkglist [expr {[llength $pkglist] - 1}] ]
+ set curpack $pack
+ GCmd help $task $curpack $helpOption
+ } else {
+ set curtask ""
+ set curpack ""
+ GCmd help $topic $curpack $helpOption
+ }
+} ; send topicEntry addCallback getTopicHelp
+
+proc topicClear { args } {
+ send topicEntry set string ""
+} ; send topicClear addCallback topicClear
+
+
+
+################################################################################
+# Help text and HTML processing procedures.
+################################################################################
+
+proc setHelpResult { param old new } {
+ global helpType helpOption curtask curpack
+ global secMenuDescription parMenuDescription
+ global pkgList debug
+
+ # Debug status
+ if {$debug == 1} {
+ send tclEntry append \
+ [format "helpres: type=%1.1s opt=%4.4s curtask=%s curpack=%s\n" \
+ $helpType $helpOption $curtask $curpack ]
+ print [format "helpres: type=%1.1s opt=%4.4s curtask=%s curpack=%s\n" \
+ $helpType $helpOption $curtask $curpack ]
+ }
+
+ if { [string match "*<HTML>*" $new] == 1} {
+ # Strip the header table.
+ if {[ string match "*TABLE*" $new] == 1 } {
+ set new_start [expr [string first "</TABLE>" $new] + 12]
+ set text [ filterBraces [string range $new $new_start end] ]
+ } else {
+ set text [ filterBraces $new ]
+ }
+
+ # Got HTML directly from the client.
+ send helpText setText [format "<HTML><BODY>\n%s" $text ]
+
+ # Save the source for the viewer
+ set docSrc \
+ [ format "<HTML><BODY>\n%s\n</BODY></HTML>\n" $text]
+
+ # Parse the file for menu items.
+ setSectionMenu $new
+ setParameterMenu $new
+
+ } else {
+ # Disable help page content buttons for plain text.
+ send parButton set sensitive False
+ send secButton set sensitive False
+ editMenu secMenu secButton $secMenuDescription
+ editMenu parMenu parButton $parMenuDescription
+
+ # Filter plaintext .men files into something with links, otherwise
+ # unescape the curly braces used to pass the text through Tcl.
+ if {$helpType == "package"} {
+ set str [ filterLinks [ filterTcl $new ] ]
+ } else {
+ set str [ filterTcl $new ]
+ }
+
+ # Load the results
+ send helpText setText "<HTML><BODY><PRE>\n$str\n</PRE></BODY></HTML>"
+
+ # Save the source for the viewer
+ set docSrc \
+ [ format "<HTML><BODY><PRE>\n%s\n</PRE></BODY></HTML>\n" $str]
+ }
+ send helpText retestAnchors
+ send srcText set string $docSrc
+
+ # See which files associated with this topic are available. We turn off
+ # the option toggles first so they can be reset as needed by the client.
+ if {$helpOption != "sysdoc"} {send sysOpt "set sensitive False ; set on 0" }
+ if {$helpOption != "source"} {send srcOpt "set sensitive False ; set on 0" }
+
+ if {$helpType == "package"} {
+ set parent [getParentName $curpack]
+ if {$parent == "clpackage" || [string match "root*" $parent] == 1} {
+ GCmd files $curtask "clpackage"
+ } else {
+ GCmd files $curtask $parent
+ }
+ } else {
+ GCmd files $curtask [string range $curpack \
+ [expr {[string last "." $curpack ] + 1}] end]
+ }
+
+ # Highlight the package list item.
+ for {set i 0} {$i < [llength $pkgList]} {incr i} {
+ if {[lindex $pkgList $i] == $curtask } {
+ send topicList highlight $i
+ break
+ }
+ }
+ printHistStack "helpres "
+
+}; send helpres addCallback setHelpResult
+
+
+# Set an arbitrary TextToggle widget highlight color.
+proc setOptColor { widget color args } {
+ send $widget "set on 1 ; \
+ set offIcon diamond0s ; \
+ set highlightColor $color ; \
+ set background gray75 ; \
+ set onIcon diamond1s ; \
+ set highlightColor $color ; \
+ set background gray75"
+}
+
+
+# Set the file options for the files that were found to be valid (i.e.
+# they're listed in the files output and actually exist).
+proc setHelpFileOpts { param old new } {
+ global helpType helpOption curtask curpack
+ global showFiles
+
+ set opt [lindex $new 0]
+ set val [lindex $new 1]
+ if {$opt != "file"} { set stat [lindex $new 2] }
+
+ # Set the option toggles according to valid files.
+ if {$opt == "sys" && $stat == 0} {
+ send sysOpt set sensitive True
+ } elseif {$opt == "sys" && $stat == 1 && $showFiles == 1} {
+ setOptColor sysOpt yellow
+ }
+ if {$opt == "src" && $stat == 0} {
+ send srcOpt set sensitive True
+ } elseif {$opt == "src" && $stat == 1 && $showFiles == 1} {
+ setOptColor srcOpt yellow
+ }
+
+ # Update the help files panel text.
+ if {$opt == "file"} {
+ set pkg [ string trimright $val ":"]
+ send flpkgVal set label [ format "%s" $pkg ]
+ send toplevel set title [format "XHelp: %s" $pkg ]
+ send flistText set string ""
+ } else {
+ send flistText append [ format " %5.5s %-7.7s %s\n" \
+ $opt \
+ [ expr { ($stat == 0) ? "Okay" : "Error" }] \
+ $val]
+ }
+
+} ; send helpfiles addCallback setHelpFileOpts
+
+
+# Process an HREF link selection. URLs are assumed to be of the form
+#
+# <pkgname>.<task>
+# <task>
+# '#'<hname>
+#
+# If an internal link is found as in the last case we ignore any defined
+# package/task given, otherwise load the selected page.
+
+proc textAnchorSelected {widget cbtype event text href args} {
+ global HPkg HType HUrl HOpt HTask HFile hcurrent htop
+ global curpack helpOption visited
+
+ set visited($href) 1
+ send helpText retestAnchors
+
+ if {[string match "*#*" $href] == 1} {
+ set link [string range $href [expr [string first "#" $href] + 1] end ]
+ set HUrl($hcurrent) $link
+ send helpText gotoId [ send helpText anchorToId $link ]
+ } else {
+ if { [string match "*\.*" $href] == 1} {
+ set pack [lindex [split $href "."] 0]
+ set task [lindex [split $href "."] 1]
+ set curpack $pack
+ GCmd help $task $curpack $helpOption
+
+ } else {
+ GCmd help $href $curpack $helpOption
+ }
+ }
+
+ if {$hcurrent <= $htop} {
+ set h $hcurrent
+ addHistRecord $HPkg($h) $HTask($h) $HUrl($h) $HOpt($h) \
+ HFile($h) $HType($h)
+ }
+
+}; send helpText addCallback textAnchorSelected anchor
+
+
+# Remove only the escaped curly braces. Used to filter HTML text passed to
+# the GUI with escapes in it.
+
+proc filterBraces { istr args } {
+ if {$istr != ""} {
+ regsub -all {(\\\{)} $istr "\{" v1
+ regsub -all {(\\\})} $v1 "\}" results
+ return $results
+ }
+}
+
+# Remove the backslash escapes from source files, escape special chars for
+# presentation on an HTML widget.
+
+proc filterTcl { istr args } {
+ if {$istr != ""} {
+ regsub -all {(\\\{)} $istr "\{" v1
+ regsub -all {(\\\})} $v1 "\}" v2
+ regsub -all {(\<)} $v2 "\\&lt;" v3
+ regsub -all {(\>)} $v3 "\\&gt;" results
+ return $results
+ }
+}
+
+
+# Scan a plaintext doc to see if maybe this is a package help menu. We use
+# some assumption that most of the lines will be of the form "task '-' desc"
+# then parse the file resetting all of the 'task' names as HREFs for other
+# tasks.
+
+proc filterLinks { istr args } {
+
+ set lines [split $istr "\n"]
+ set blank " "
+ set results { }
+ lappend results ""
+ foreach i $lines {
+ set line [string trimleft [detab $i] ]
+ if {[regexp {(^[a-zA-Z0-9\ \_\(\)]+[\+|\-]*)} $line arg] == 1 &&
+ ([string match "*\-*" $arg] == 1 ||
+ [string first "\*" $line] > 0 ||
+ [string match "*\+*" $arg] == 1) } {
+
+ set task [string trim [string trimright $arg "-+"] ]
+ set l [string first "-" $line]
+ if {$l == -1} {
+ set l [string first "+" $line]
+ if {$l == -1} {
+ set l [string first "\*" $line]
+ }
+ }
+ set desc [ string range $line $l end ]
+
+ # We now have the task name and the description string, format
+ # on output with the HREF defined.
+ set nblanks [expr 13 - [string length $task] ]
+ set fmtstr [format "%%%ds<A HREF=\"%%s\">%%s</A> %%s\n" $nblanks ]
+ set ostr [format $fmtstr $blank $task $task $desc]
+
+ lappend results $ostr
+
+ } elseif {[regexp {(^[a-zA-Z0-9\_]+\.[a-zA-Z0-9\_]+\:$)} $i val] == 1} {
+
+ # Break out the task and package names.
+ regsub -all {[\.:]} $i " " val
+ scan $val "%s %s" parent child
+
+ # Format a URL and append the results.
+ if { [ string match "*root*" $parent] == 0} {
+ set ref [format "<A HREF=\"%s\">%s</A>.<A HREF=\"%s\">%s</A>:\n"\
+ $parent $parent $child $child ]
+ } else {
+ set ref [format "%s.<A HREF=\"%s\">%s</A>:\n"\
+ $parent $child $child ]
+ }
+ lappend results $ref
+
+ } else {
+ set nblanks [expr [string length $i] - [string length $line] ]
+ set fmtstr [format "%%%ds%%s\n" $nblanks ]
+ lappend results [format $fmtstr $blank $line ]
+ }
+ }
+ return [ join $results ]
+}
+
+
+# Generated a list of the lines and create the section menu.
+
+proc setSectionMenu { text args } {
+ global secMenuDescription
+
+ # Break out the table of contents from the string. Note we're hard-
+ # wired here into the form of the comment string used to contain the
+ # section name.
+ set l [expr [string first "<! Contents: " $text] + 12]
+ if {$l == 0} { return }
+ set s [string range $text $l end]
+ set r [expr [string first ">" $s] - 4]
+ set t [string range $s 0 $r]
+ set lst [split $t '\'']
+
+ # Now take the list generated and create the menu.
+ set items { }
+ lappend items " \"Top of Page\" f.exec \{ send helpText gotoId 0 \}"
+ lappend items " f.dblline "
+ foreach i $lst {
+ if {$i != " "} {
+ set i [ string trimright $i ]
+ regsub -all {[ ,.():;]} [string tolower $i] _ url
+ lappend items " \" $i \" f.exec \{ jumpToName #s_$url \}"
+ }
+ }
+
+ if { [llength $items] == 3 } {
+ send secButton set sensitive False
+ editMenu secMenu secButton $secMenuDescription
+ } else {
+ editMenu secMenu secButton $items
+ send secButton set sensitive True
+ }
+}
+
+
+# Generated a list of the lines and create the parameter menu.
+proc setParameterMenu { text args } {
+ global parMenuDescription
+ set items { }
+ foreach i [split $text "\n"] {
+ if {[string match "\<\! Sec*PARAMETERS*Level=0*" $i] == 1} {
+ set l [expr [string first "Line='" $i] + 6]
+ set s [string range $i $l end]
+ set r [expr [string first "\'" $s] - 1]
+ set t [string range $s 0 $r]
+ regsub -all {[\ ]} $t " " d ;# remove tabs
+ regsub -all {[\"]} $d "\\\"" entry
+
+ set l [expr [string first "Label='" $i] + 7]
+ set s [string range $i $l end]
+ set r [expr [string first "\'" $s] - 1]
+ set t [string range $s 0 $r]
+
+ lappend items " \"$entry\" f.exec \{ jumpToName #l_$t \}"
+ }
+ }
+
+ if { [llength $items] == 0 } {
+ send parButton set sensitive False
+ editMenu parMenu parButton $parMenuDescription
+ } else {
+ editMenu parMenu parButton $items
+ send parButton set sensitive True
+ }
+}
+
+
+# Position the page to the requested href name.
+proc jumpToName { name } {
+ global curtask curpack helpType helpOption
+
+ send helpText gotoId [send helpText anchorToId $name]
+ send helpText retestAnchors
+
+ # Now add a history record for the jump
+ addHistRecord $curpack $curtask $name $helpOption "" $helpType
+}
+
+
+# Utility routine to 'detab' a line and preserve format.
+proc detab {str {tablen 8}} {
+ set a 0
+ set i [string first "\t" $str]
+ while {$i != -1} {
+ set m { }
+ set j $i
+ while {[incr j] % $tablen} { append m { } }
+ set str [string range $str $a \
+ [expr {$i-1}]]$m[string range $str [incr i] end]
+ set i [string first "\t" $str]
+ }
+ return $str
+}
+
+
+################################################################################
+# Navigation and History Callbacks
+################################################################################
+
+# Go back one page.
+proc Back args {
+ global curtask curpack helpType helpOption
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+
+ incr hcurrent -1
+ if {$hcurrent >= 0} {
+ set item $HTask($hcurrent)
+ set pkg $HPkg($hcurrent)
+ set type $HType($hcurrent)
+ set h $hcurrent
+
+ if { $item == "Home" } {
+ loadHomePage
+ } else {
+ if { $HType($h) == "file"} {
+ if {[info exists HFile($h)] == 1} {
+ loadHistItem $h pkg $HFile($h) help file
+ } else {
+ setAlert param old \
+ [format "HFile param at %d not found" $hcurrent]
+ }
+ } else {
+ loadHistItem $h $HPkg($h) $HTask($h) $HOpt($h) \
+ $HType($h) $HUrl($h)
+ }
+ }
+
+ if {$hcurrent == 0} {
+ send htbButton set sensitive False
+ send htuButton set sensitive False
+ }
+ if {$hcurrent >= 0} {
+ send htfButton set sensitive True
+ send htuButton set sensitive True
+ }
+ } else {
+ set hcurrent 0
+ }
+ editHistoryMenu
+ printHistStack "Back "
+} ; send htbButton addCallback Back
+
+
+# Go forward one page.
+proc Forward args {
+ global curtask curpack helpType helpOption
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+
+ incr hcurrent
+ if {$hcurrent <= $htop} {
+ set item $HTask($hcurrent)
+ set pkg $HPkg($hcurrent)
+ set type $HType($hcurrent)
+ set h $hcurrent
+
+ if { $item == "Home" } {
+ loadHomePage
+ } else {
+ if { $HType($h) == "file"} {
+ if {[info exists HFile($h)] == 1} {
+ loadHistItem $h pkg $HFile($h) help file
+ } else {
+ setAlert param old \
+ [format "HFile param at %d not found" $hcurrent]
+ }
+ } else {
+ loadHistItem $h $HPkg($h) $HTask($h) $HOpt($h) \
+ $HType($h) $HUrl($h)
+ }
+ }
+
+ if {$hcurrent == $htop } {
+ send htfButton set sensitive False
+ send htbButton set sensitive True
+ } else {
+ send htbButton set sensitive True
+ }
+ } else {
+ incr hcurrent -1
+ }
+ editHistoryMenu
+ printHistStack "Forward "
+} ; send htfButton addCallback Forward
+
+
+# Go up to previous package, skipping over pages inbetween.
+proc Up args {
+ global curtask curpack helpType helpOption
+ global HPkg HType HUrl HOpt HTask htop hcurrent
+
+ # From the current page go back until we find a package
+ if {$HType($hcurrent) == "package"} {
+ set i [expr {$hcurrent-1} ]
+ } else {
+ set i $hcurrent
+ }
+ while {$HType($i) != "package" && $i >= 0} {
+ incr i -1
+ }
+
+ # Found package, go get it.
+ set hcurrent $i
+ if {$i == 0} {
+ loadHomePage ;# push a history record??
+ } else {
+ GCmd load $HTask($i) [getPkgName $HPkg($i)] $HOpt($i)
+ }
+
+ set curtask $HTask($hcurrent) ;# update the state of things
+ set curpack $HPkg($hcurrent)
+ set helpOption $HOpt($hcurrent)
+ set helpType $HType($hcurrent)
+
+ send topicEntry set string $curpack ;# update topic entry string
+
+ if {$hcurrent == 0} { ;# adjust navigation buttons
+ send htbButton set sensitive False
+ send htuButton set sensitive False
+ }
+ if {$hcurrent >= 0} {
+ send htfButton set sensitive True
+ send htuButton set sensitive True
+ }
+ editHistoryMenu
+ printHistStack "Forward "
+} ; send htuButton addCallback Up
+
+
+# Go straight to the homepage.
+proc Home args {
+ global curtask curpack helpType helpOption
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+
+ # Load the homepage.
+ loadHomePage
+
+ # A Home command jumps over everything in the history list but we
+ # need to push a history record for it anyway.
+ addHistRecord $HPkg(0) $HTask(0) $HUrl(0) $HOpt(0) $HFile(0) $HType(0)
+
+ send topicEntry set string ""
+ set curtask ""
+ set curpack ""
+ set helpType "package"
+ set helpType "help"
+} ; send hthButton addCallback Home
+
+
+# Load the homepage.
+proc loadHomePage { args } {
+ global curtask curpack version showType
+
+ GCmd help Home
+
+ # Clean up.
+ set curtask ""
+ set curpack ""
+ send topicEntry set string ""
+ send toplevel set title $version
+}
+
+# Clear all the history information.
+proc histClear args {
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+ global visited
+
+ # Clear the visited anchors list.
+ foreach i [array names visited] {
+ unset visited($i)
+ }
+
+ # Clear the history stack.
+ for { set i [expr {$htop -1}] } { $i >= 0 } { incr i -1 } {
+ catch {
+ unset HType($i)
+ unset HOpt($i)
+ unset HTask($i)
+ unset HPkg($i)
+ unset HUrl($i)
+ unset HFile($i)
+ }
+ }
+
+ # Reinitialize, but save the current page as the new history stack.
+ catch {
+ set HPkg(0) $HPkg($htop) ;# package
+ set HOpt(0) $HOpt($htop) ;# option
+ set HTask(0) $HTask($htop) ;# task
+ set HUrl(0) $HUrl($htop) ;# url
+ set HType(0) $HType($htop) ;# type
+ set HFile(0) $HFile($htop) ;# filename
+ }
+ set htop 0
+ set hcurrent 0
+
+ # Update navigation options and history menu.
+ send htbButton set sensitive False
+ send htfButton set sensitive False
+ send htuButton set sensitive False
+ editHistoryMenu
+}
+
+
+# Push an item on the history stack.
+proc addHistRecord { pkg task url opt file type } {
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+ global helpType helpOption
+ global historyMenuDescription
+
+ # Push a new history record to the top of the stack and make that the
+ # current record.
+ incr htop
+ set HPkg($htop) $pkg
+ set HTask($htop) $task
+ set HUrl($htop) $url
+ set HOpt($htop) $opt
+ set HFile($htop) [ expr {($file == "") ? "none" : $file } ]
+ set HType($htop) $type
+ set hcurrent $htop
+
+ # Activate the Back button.
+ if {$hcurrent == 1} {
+ send htbButton set sensitive True
+ if {$type == "package"} {
+ send htuButton set sensitive True
+ }
+ }
+
+ # Edit the history menu.
+ editHistoryMenu
+ printHistStack "addHistRecord"
+}
+
+
+# Edit the history menu to reflect the current state.
+proc editHistoryMenu { args } {
+ global HPkg HType HUrl HOpt HTask htop hcurrent
+ global helpType helpOption
+ global historyMenuDescription
+ global navMenuDescription
+ global MAX_MENU_SIZE
+
+ set items $historyMenuDescription
+ set nitems 0
+ if {$htop > $MAX_MENU_SIZE} {
+ set nstart [ min $htop [expr {$hcurrent + 3}] ]
+ } else {
+ set nstart $htop
+ }
+ for { set i $nstart } { $i >= 0 } { incr i -1 } {
+ set pkg $HPkg($i)
+ set task $HTask($i)
+ set type $HType($i)
+ set opt $HOpt($i)
+ set url $HUrl($i)
+ if {$pkg != "" || $type == "file"} {
+ if {$type == "task"} {
+ if {$url == ""} {
+ set entry [format "%-22.22s %4s" $task \
+ [menuItemType $type $url $opt ] ]
+ } else {
+ set entry [format "%-22.22s %4s" \
+ [ format "%s (%s)" $task [string trimleft $url "#"] ] \
+ [menuItemType $type $url $opt ] ]
+ }
+ } elseif {$type == "package"} {
+ set entry [format "%-22.22s %4s" [getPkgName $pkg] \
+ [menuItemType $type $url $opt ] ]
+ } elseif {$type == "file"} {
+ upvar #0 HFile file
+ set entry [format "%s" $file($i) ]
+ } else {
+ setAlert param old [format "Unknown help type: %s" $type]
+ }
+
+ if {$type == "file"} {
+ lappend items " \" $entry \" f.exec \{ \
+ loadHistItem $i pkg $entry help file \} \
+ bitmap \{\($i==$hcurrent\) ? \"arrow\" : \"null\" \} "
+ } else {
+ lappend items " \" $entry \" f.exec \{ \
+ loadHistItem $i [getPkgName $pkg] $task $opt $type $url \} \
+ bitmap \{\($i==$hcurrent\) ? \"arrow\" : \"null\" \} "
+ }
+ }
+
+ incr nitems 1
+ if {$nitems > $MAX_MENU_SIZE} {
+ lappend items "f.dblline"
+ lappend items " \" History truncated... \" f.exec \{ \} "
+ break
+ }
+ }
+ editMenu historyMenu historyButton $items
+
+ # Edit the navigation menu to get the sensitivities right for
+ # the current state.
+ editMenu navMenu helpText $navMenuDescription
+}
+
+
+# Utility routine to set the history item entry type.
+proc menuItemType { type url opt } {
+ if {$url != ""} {
+ return [format "Link"]
+ }
+
+ switch $opt {
+ "help" { return [format "%s" [expr {($type=="task")?"Task":"Pkg"} ]] }
+ "source" { return [format "(src)"] }
+ "sysdoc" { return [format "(sys)"] }
+ }
+}
+
+
+# Load a particular page/link from the history list.
+proc loadHistItem { itemno pkg task opt type args } {
+ global HPkg HType HUrl HOpt HTask htop hcurrent
+ global curtask curpack helpType helpOption hcurrent
+ global version
+
+ # Load the requested page. Check whether we just need to jump to
+ # the current page.
+ if {$task == "Home"} {
+ loadHomePage
+
+ } elseif {$type == "file"} {
+ GCmd directory open $task
+
+ } elseif {$itemno == $hcurrent || \
+ ($pkg != $curpack || \
+ $task != $curtask || \
+ $type != $helpType || \
+ $opt != $helpOption) } {
+ GCmd load $task $pkg $opt
+ }
+
+ # If the history item included an internal link, jump to it. The
+ # 'args' value will either be the URL or an empty string.
+ if {$args != ""} {
+ send helpText gotoId [send helpText anchorToId $args]
+ send helpText retestAnchors
+ }
+
+ # Update the topic entry string.
+ if { $type == "task" } {
+ send topicEntry set string [ format "%s.%s" $pkg $task ]
+ } elseif { $type == "file" } {
+ send topicEntry set string $task
+ } else {
+ send topicEntry set string $pkg
+ }
+
+ # Change the options button if needed.
+ if {$HOpt($itemno) != $helpOption} {
+ send [ getOptWidget $helpOption ] set on 0
+ setOptColor [ getOptWidget $HOpt($itemno) ] green
+ }
+
+ # Update the current entry.
+ set hcurrent $itemno
+
+ if { $type != "file" } {
+ set curtask $HTask($hcurrent)
+ set curpack $HPkg($hcurrent)
+ set helpOption $HOpt($hcurrent)
+ set helpType $HType($hcurrent)
+ } else {
+ set helpOption "help"
+ set helpType "file"
+ }
+
+ # Tweak the navigation buttons.
+ if {$hcurrent == 0} {
+ send htbButton set sensitive False
+ send htuButton set sensitive False
+ }
+ if {$hcurrent >= 0} {
+ send htfButton set sensitive True
+ send htuButton set sensitive True
+ }
+ if {$hcurrent == $htop } {
+ send htfButton set sensitive False
+ send htbButton set sensitive True
+ }
+
+ # Edit the history menu.
+ editHistoryMenu
+}
+
+# Initialize the history menu.
+editHistoryMenu
+
+# Given the option type return the widget name.
+proc getOptWidget { opt } {
+ switch $opt {
+ "help" { return "hlpOpt" }
+ "source" { return "srcOpt" }
+ "sysdoc" { return "sysOpt" }
+ }
+}
+
+# Debug utility to print the history stack.
+proc printHistStack { where args } {
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+ global debug
+
+ # Print the stack...
+ if {$debug > 0} {
+ print "_______________________________________________________________"
+ print $where
+ for { set i $htop } { $i >= 0 } { incr i -1 } {
+ if {$HType($i) == "file"} {
+ upvar #0 HFile file
+ print [format "%3s%d: type=%1.1s file=%s\n"\
+ [ expr {($i==$hcurrent) ? ">>>" : "---"} ] \
+ $i $HType($i) $file($i) ]
+ } else {
+ print [format "%3s%d: type=%1.1s opt=%4.4s task=%s pack=%s\n"\
+ [ expr {($i==$hcurrent) ? ">>>" : "---"} ] \
+ $i $HType($i) $HOpt($i) $HTask($i) $HPkg($i) $HUrl($i) ]
+ }
+ }
+ }
+}
+
+# Test whether an anchor has been visited.
+proc testAnchor {widget cbtype href} {
+ global visited
+ return [info exists visited($href)]
+}
+send hlpText addCallback testAnchor testAnchor
+send helpText addCallback testAnchor testAnchor
+send resList addCallback testAnchor testAnchor
+
+
+################################################################################
+# Options Menu
+################################################################################
+
+proc setType { param old new } {
+ global helpType
+ set helpType [string tolower $new ]
+} ; send type addCallback setType
+
+proc selectOption { widget type value args } {
+ global curtask curpack helpOption
+
+ if { $curtask != "" } {
+ foreach i { hlpOpt srcOpt sysOpt } { send $i set on 0 }
+ setOptColor $widget green
+ send $widget set on 1
+ switch $widget {
+ hlpOpt { set helpOption help
+ send fmtText setSensitive true
+ send fmtPS setSensitive true
+ }
+ srcOpt { set helpOption source
+ send fmtText setSensitive false
+ send fmtPS setSensitive false
+ }
+ sysOpt { set helpOption sysdoc
+ send fmtText setSensitive true
+ send fmtPS setSensitive true
+ }
+ }
+ GCmd help $curtask [getParentName $curpack] $helpOption
+ }
+}; foreach i {hlpOpt srcOpt sysOpt } { send $i addCallback selectOption }
+
+proc toggleFileOption { args } {
+ if { [ send filOpt get on] == 1 } {
+ send fileShell map
+ } else {
+ send fileShell unmap
+ }
+} ; send filOpt addCallback toggleFileOption
+
+send flDismiss addCallback "send fileShell unmap ; send filOpt set on 0"
+
+
+################################################################################
+# Procedure used by the printer prompt box.
+################################################################################
+
+proc setPrinterName { param old new } {
+ send printEntry set string $new
+}; send printer addCallback setPrinterName
+
+set page_size pageLetter
+
+proc pageRadio { widget type state args } {
+ global page_size
+
+ if {$state == 0} {
+ # Don't allow a button to be turned off.
+ send $widget set on 1
+ } else {
+ send $page_size set on 0
+ set page_size $widget
+ }
+}
+foreach w {pageLetter pageLegal pageA4 pageB5} { send $w addCallback pageRadio }
+
+proc toPrinterToggle args {
+ global curtask HType hcurrent
+ if { [send toPrinter get on] } {
+ send toFile set on False
+ send printLabel set label "Printer: "
+ send printEntry set string "printer"
+ } else {
+ send toFile set on True
+ send printLabel set label "File Name: "
+ if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} {
+ send printEntry set string [format "%s" [fileSource] ]
+ } else {
+ send printEntry set string [format "%s.ps" $curtask]
+ }
+ }
+} ; send toPrinter addCallback toPrinterToggle
+
+proc toFileToggle args {
+ global curtask HType hcurrent
+ if { [send toFile get on] } {
+ send toPrinter set on False
+ send printLabel set label "File Name: "
+ if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} {
+ send printEntry set string [format "%s" [fileSource] ]
+ } else {
+ send printEntry set string [format "%s.ps" $curtask]
+ }
+ } else {
+ send toPrinter set on True
+ send printLabel set label "Printer: "
+ send printEntry set string "printer"
+ }
+} ; send toFile addCallback toFileToggle
+
+proc doPrintOkay { args } {
+ global curtask curpack HType hcurrent
+
+ set device [ send printEntry get string ]
+ if { [send toPrinter get on] } {
+ GCmd print $curtask $curpack $device
+ } else {
+ if {$HType($hcurrent) == "file" || [send srcOpt get on] == 1} {
+ GCmd directory save [fileSource] $fname 1 source
+ } else {
+ GCmd directory save [fileSource] $fname 1 postscript
+ }
+ }
+ send printShell unmap
+}
+send printOkay addCallback doPrintOkay
+send printEntry addCallback doPrintOkay
+
+send printDismiss addCallback "send printShell unmap "
+
+
+################################################################################
+# Procedures used by the fileBrowser.
+################################################################################
+
+# File browsing globals
+set curdir "" ;# current directory
+set pattern "*" ;# filename template
+set format "fmtSrc" ;# SaveAs format
+
+
+# Browser selection callback.
+proc browserSelect { widget event args } {
+ global curdir helpOption
+
+ set opt [expr {$widget == "dirList" ? "dirlist" : "loadfile"}]
+ set item [send $widget getItem itemno]
+ send $widget getItem itemno
+ set mode [send fbcOkay get label]
+
+ if { $itemno != "none" } {
+ if { $mode == "Load"} {
+ if {$opt != "dirlist"} {
+ addHistRecord "" "" "" help [format "%s%s" $curdir $item] "file"
+ }
+ GCmd directory $opt $item
+ send flistText set string [format " file Okay %s%s\n" \
+ $curdir $item]
+ } else {
+ if {$opt == "dirlist"} {
+ GCmd directory $opt $item
+ } else {
+ send fnameEntry set string [format "%s%s" $curdir $item]
+ }
+ }
+ }
+}
+send dirList addEventHandler browserSelect buttonReleaseMask
+send fileList addEventHandler browserSelect buttonReleaseMask
+
+
+# Client callback.
+proc browserListing { param old new } {
+ global curdir pattern
+
+ set option [ lindex $new 0 ]
+ switch $option {
+ dirlist { set list [lindex $new 1]
+ send dirList setList $list resize
+ }
+ filelist { set list [lindex $new 1]
+ send fileList setList $list resize
+ }
+ template { set pattern [lindex $new 1]
+ send filterEntry set string $pattern
+ }
+ curdir { set curdir [lindex $new 1]
+ send curdirVal set label $curdir
+ }
+ selection { send fnameEntry set string [lindex $new 1] }
+ }
+} ; send directory addCallback browserListing
+
+
+# Set the filename matching template.
+proc setTemplate { widget mode pattern args } {
+ GCmd directory template $pattern
+} ; send filterEntry addCallback setTemplate
+
+
+# get the filename of the currently displayed page.
+proc fileSource { args } {
+ global helpOption
+
+ set str [ send flistText get string ]
+
+ set fname ""
+ for {set i 0} {$i < [llength $str]} {incr i 3} {
+ set j [expr {$i + 2} ]
+ if {($helpOption == "source" && [lindex $str $i] == "src") ||
+ ($helpOption == "sysdoc" && [lindex $str $i] == "sys") ||
+ ($helpOption == "help" && [lindex $str $i] == "hlp") ||
+ ($helpOption == "file" && [lindex $str $i] == "file")} {
+ set fname [lindex $str $j]
+ break
+ }
+ }
+ return $fname
+}
+
+# Open a specific file, either to load a new page or save the current page.
+proc openFile { widget args } {
+ global curdir helpOption
+
+ set fname [send fnameEntry get string]
+
+ if {$fname == ""} {
+ setAlert param old "No filename specified"
+ } else {
+ if { [send fbcOkay get label] == "Load"} {
+ addHistRecord "" "" "" "" [format "%s%s" $curdir $fname] "file"
+ GCmd directory open $fname
+ send flistText set string [format " file Okay %s\n" $fname]
+ } else {
+ set page [fileSource]
+ set ow [send overwrite get on]
+ if {[send fmtSrc get on] == 1} {
+ GCmd directory save $page $fname $ow source
+ } elseif {[send fmtText get on] == 1} {
+ GCmd directory save $page $fname $ow text
+ } elseif {[send fmtHTML get on] == 1} {
+ GCmd directory save $page $fname $ow html
+ } elseif {[send fmtPS get on] == 1} {
+ GCmd directory save $page $fname $ow postscript
+ }
+ }
+ }
+} ; send fbcOkay addCallback openFile
+
+
+# Make the SaveAs formats a radio box.
+proc fmtRadio { widget type state args } {
+ global format
+
+ if {$state == 0} {
+ # Don't allow a button to be turned off.
+ send $widget set on 1
+ } else {
+ send $format set on 0
+ set format $widget
+ }
+
+ # If there's no filename specified set one as a default.
+ setDefaultFname
+
+} ; foreach w {fmtSrc fmtText fmtHTML fmtPS} { send $w addCallback fmtRadio }
+
+
+# Set a default filename based on the selected format and task name
+proc setDefaultFname args {
+ global format curtask curdir
+
+ set fname [send fnameEntry get string]
+ if {$curtask != ""} {
+ switch $format {
+ fmtSrc { send fnameEntry \
+ set string [format "%s%s" $curdir $curtask] }
+ fmtText { send fnameEntry \
+ set string [format "%s%s.txt" $curdir $curtask] }
+ fmtHTML { send fnameEntry \
+ set string [format "%s%s.html" $curdir $curtask] }
+ fmtPS { send fnameEntry \
+ set string [format "%s%s.ps" $curdir $curtask] }
+ }
+ }
+}
+
+proc browserHelp args {
+ if { [send fbcOkay get label] == "Load"} {
+ showHelp lfiles
+ } else {
+ showHelp sfiles
+ }
+} ; send fbcHelp addCallback browserHelp
+
+send fnavHome addCallback "GCmd directory home"
+send fnavUp addCallback "GCmd directory up"
+send fnavRoot addCallback "GCmd directory root"
+send fnavRescan addCallback "GCmd directory rescan"
+send fnameClear addCallback "send fnameEntry set string \"\""
+send filterClear addCallback "send filterEntry set string \"\""
+send fbcDismiss addCallback "send fileBrowser unmap"
+
+
+
+################################################################################
+# Procedures used by the find box.
+################################################################################
+
+proc doFindOkay args {
+ set dir forward
+ set case caseless
+ set phrase [send findEntry get string]
+
+ if { $phrase != "" } {
+ if { [send findDir get on] } { set dir backward }
+ if { [send findCase get on] } { set case caseSensitive }
+
+ if { [send helpText searchText $phrase start end $dir $case] > 0 } {
+ set elid [lindex [lindex $start 0] 0]
+ set id [max 1 [expr $elid - 10] ]
+
+ send helpText gotoId $id
+ send helpText setSelection $start $end
+ } else {
+ send warnText set label "Search string not found."
+ send warning map
+ }
+ } else {
+ send warnText set label "Warning: No search phrase entered."
+ send warning map
+ }
+} ; foreach w { findOkay findEntry } { send $w addCallback doFindOkay }
+
+send findClear addCallback { send findEntry set string "" }
+send findDismiss addCallback { send findShell popdown }
+
+
+################################################################################
+# Procedures used by the apropos prompt box.
+################################################################################
+
+proc doSearchOkay args {
+ set phrase [send searchEntry get string]
+ if { $phrase != "" } {
+ send searchStatus set label "Searching..."
+ GCmd search [send exactMatch get on] $phrase
+ } else {
+ send warnText set label "Warning: No search phrase entered."
+ send warning map
+ }
+} ; foreach w { searchOkay searchEntry } { send $w addCallback doSearchOkay }
+
+proc searchResults { param old new } {
+ global search_mapped
+
+ if {$search_mapped == 0} {
+ Search
+ }
+ send resList setText $new
+ send resList retestAnchors
+ send searchStatus set label ""
+} ; send apropos addCallback searchResults
+
+# Selection callback.
+proc searchAnchorSelected {widget cbtype event text href args} {
+ global helpOption helpType curpack curtask
+ global visited
+
+ # Break out the task and package names.
+ set pack [lindex [split $href "."] 0]
+ set task [lindex [split $href "."] 1]
+
+ # Set the state and load the page.
+ if {$helpOption != "help"} {
+ send [getOptWidget $helpOption] set on 0
+ setOptColor hlpOpt green
+ }
+ set curtask $task
+ set curpack $pack
+ set helpOption "help"
+ set helpType [expr {($pack == $task) ? "package" : "task"}]
+ GCmd load $curtask $curpack $helpOption
+
+ # Add the history record, one for the package and one for the task.
+ addHistRecord $curpack $curpack "" $helpOption "" "package"
+ if {$pack != $task} {
+ addHistRecord $curpack $curtask "" $helpOption "" "task"
+ }
+ send htbButton set sensitive True
+ send htuButton set sensitive True
+ editHistoryMenu
+ printHistStack "searchAnchorSelected"
+
+ # Update the topic entry string.
+ if { $task == $pack } {
+ send topicEntry set string $pack
+ } else {
+ send topicEntry set string [ format "%s.%s" $pack $task ]
+ }
+
+ set visited($href) 1
+ send resList retestAnchors
+
+} ; send resList addCallback searchAnchorSelected anchor
+
+proc doSearchClear args {
+ send searchEntry set string ""
+} ; send searchClear addCallback doSearchClear
+
+proc doSearchDismiss args {
+ global search_mapped
+
+ set search_mapped 0
+ send searchShell unmap
+} ; send searchDismiss addCallback doSearchDismiss
+
+send searchHelp addCallback { showHelp search }
+
+
+################################################################################
+# Define procedures for the help panel
+################################################################################
+
+# Stuff for keeping track of visited anchors.
+set h_links { 0 }
+set h_linkIndex 0
+
+proc getHelpText { param old new } {
+ send hlpText setText $new
+}; send help addCallback getHelpText
+
+proc anchorSelected {widget cbtype event text href args} {
+ global visited h_links h_linkIndex
+ set anchID [send hlpText anchorToId $href]
+ set visited($href) 1
+ if {$h_linkIndex == 0} {
+ send hlpBack set sensitive True
+ if {[lindex $h_links 1] != $anchID} {
+ set h_links { 0 }
+ send hlpForward set sensitive False
+ }
+ }
+ if {$h_linkIndex > 0 && \
+ [lindex $h_links [expr $h_linkIndex + 1]] != $anchID} {
+ #set h_links [lrange $h_links 0 $h_linkIndex]
+ set pos [send hlpText positionToId 0 0]
+ set h_links [lreplace $h_links $h_linkIndex end $pos]
+ }
+ if {[lindex $h_links [expr $h_linkIndex + 1]] != $anchID} {
+ lappend h_links $anchID
+ incr h_linkIndex
+ } else {
+ send hlpForward set sensitive False
+ incr h_linkIndex
+ }
+ if {$h_linkIndex == [expr [llength $h_links] - 1]} {
+ send hlpForward set sensitive False
+ }
+ send hlpText gotoId $anchID
+ send hlpText retestAnchors
+}; send hlpText addCallback anchorSelected anchor
+
+
+# Callbacks to position forwards and backwards in link list.
+proc hlpForward args {
+ global h_links h_linkIndex
+ incr h_linkIndex
+ if {$h_linkIndex <= [llength $h_links]} {
+ set anchID [lindex $h_links $h_linkIndex]
+ send hlpText gotoId $anchID
+ send hlpText retestAnchors
+ if {$h_linkIndex == [expr [llength $h_links] - 1]} {
+ send hlpForward set sensitive False
+ send hlpBack set sensitive True
+ } else {
+ send hlpBack set sensitive True
+ }
+ } else {
+ incr h_linkIndex -1
+ }
+}; send hlpForward addCallback hlpForward
+
+proc hlpBack args {
+ global h_links h_linkIndex
+ incr h_linkIndex -1
+ if {$h_linkIndex >= 0} {
+ set anchID [lindex $h_links $h_linkIndex]
+ send hlpText gotoId $anchID
+ send hlpText retestAnchors
+ if {$h_linkIndex == 0} { send hlpBack set sensitive False }
+ if {$h_linkIndex >= 0} { send hlpForward set sensitive True }
+ } else {
+ incr h_linkIndex 1
+ }
+}; send hlpBack addCallback hlpBack
+
+proc hlpHome args {
+ global h_links h_linkIndex
+ set h_links { 0 }
+ set h_linkIndex 0
+ send hlpText gotoId 0
+ send hlpForward set sensitive False
+ send hlpBack set sensitive False
+}; send hlpHome addCallback hlpHome
+
+proc hlpTutorial args {
+ showHelp tutorial
+}; send hlpTutorial addCallback hlpTutorial
+send hlpTutorial unmap ;# NO TUTORIAL AT THE MOMENT
+
+proc showHelp {name args} {
+ anchorSelected widget cbtype event text #$name
+ send hlpShell map
+}
+
+proc hlpFind args {
+ set phrase [send hfEntry get string]
+ set dir forward
+ set case caseless
+
+ if { $phrase != "" } {
+ if { [send hfDir get on] } { set dir backward }
+ if { [send hfCase get on] } { set case caseSensitive }
+ if {[send hlpText searchText $phrase start end $dir $case ] > 0} {
+ set elid [lindex [lindex $start 0] 0]
+ set id [max 1 [expr $elid - 10] ]
+ send hlpText gotoId $id
+ send hlpText setSelection $start $end
+ } else {
+ send warnText set label "Search string not found."
+ send warning map
+ }
+ } else {
+ send warnText set label "Warning: No search phrase entered."
+ send warning map
+ }
+} ; foreach w { hfEntry hfFind } { send $w addCallback hlpFind }
+
+send hfClear addCallback { send hfEntry set string "" }
+
+send hlpDismiss addCallback "send hlpShell unmap"
+
+
+################################################################################
+# Document source viewer procedures.
+################################################################################
+
+proc srcOpen { args } { send doc_source map }
+send srcDismiss addCallback "send doc_source unmap"
+
+
+################################################################################
+# Define some TCL debug procedures
+################################################################################
+
+proc tclOpen {} { send tclShell map }
+
+proc tclCommandClear { widget args } {
+ send tclEntry set string ""
+} ; send tclClear addCallback tclCommandClear
+
+proc tclCommandExecute { widget args } { \
+ send server [send tclEntry {get string}]
+} ; send tclExecute addCallback tclCommandExecute
+
+proc tclCommand { widget mode command args } {
+ send server $command
+} ; send tclEntry addCallback tclCommand
+
+proc tclToggleLogging args {
+ global debug
+ if { [ send tclLogging get state] } {
+ set debug 1
+ send tclLogging set label "Disable Logging"
+ } else {
+ set debug 0
+ send tclLogging set label "Enable Logging"
+ }
+} ; tclToggleLogging
+send tclLogging addCallback tclToggleLogging
+
+send tclDismiss addCallback "send tclShell unmap"
+
+# Connect the 'textout' parameter so it appends messages from
+# the client to the Tcl text window.
+proc tclLogMessages { param old new } {
+ global debug
+ if {$debug == 1} { send tclEntry append [format "%s\n" $new ] }
+} ; send textout addCallback tclLogMessages
+
+
+################################################################################
+# Warning dialog. This pops up a dialog box with the given warning message.
+################################################################################
+
+proc warnOkay {widget args} {
+ global curpack curtask
+
+ set label [send warnText get label]
+ if {[string match "No*" $label ] == 1} {
+ set topic [send topicEntry get string]
+ set last [string last "." $topic ]
+ send topicEntry set string [ string range $topic 0 [ incr last -1 ] ]
+ }
+ send warning unmap
+}; send warnDismiss addCallback warnOkay
+
+
+# The parameter "alert" is used to forward alerts from the client. The
+# special 'dismiss' value can be used to shut down the alert from the
+# client, the special "pop" value pops the last history elements from the
+# stack (used in case of an error loading a file).
+
+proc setAlert {param old new} {
+ global HPkg HType HUrl HOpt HTask HFile htop hcurrent
+
+ if {$new == "dismiss"} {
+ send warning unmap
+ } elseif {$new == "pop"} {
+ catch {
+ unset HType($hcurrent)
+ unset HOpt($hcurrent)
+ unset HTask($hcurrent)
+ unset HPkg($hcurrent)
+ unset HUrl($hcurrent)
+ unset HFile($hcurrent)
+ }
+ incr hcurrent -1
+ } else {
+ send searchStatus set label ""
+ send warnText set label $new
+ send warning map
+ }
+}; send alert addCallback setAlert
+
+
diff --git a/pkg/system/help/xhelp/mkpkg b/pkg/system/help/xhelp/mkpkg
new file mode 100644
index 00000000..a12b2788
--- /dev/null
+++ b/pkg/system/help/xhelp/mkpkg
@@ -0,0 +1,28 @@
+# Make the GUI part of the HELP task.
+
+$checkout libpkg.a ../
+$update libpkg.a
+$checkin libpkg.a ../
+$exit
+
+zzdebug:
+ $omake zzdebug.x
+ $link zzdebug.o -l xtools
+ ;
+
+libpkg.a:
+ xhelp.x ../help.h xhelp.h
+ xhcmds.x ../help.h xhelp.h
+ xhdir.x xhelp.h <ctype.h> <diropen.h> <finfo.h>
+ xhfiles.x ../help.h xhelp.h <ctype.h> <fset.h>
+ xhhelp.x ../help.h xhelp.h <error.h> <finfo.h> <fset.h>
+ xhinit.x xhelp.h
+ xhofile.x xhelp.h <fset.h>
+ xhpkg.x <error.h> <fset.h> ../helpdir.h ../help.h xhelp.h
+ xhprint.x xhelp.h ../help.h <ctype.h> <error.h> <ttyset.h>
+ xhqref.x ../help.h xhelp.h <ctype.h> <finfo.h>
+ xhroot.x xhelp.h
+ xhsave.x ../help.h xhelp.h <ctype.h>
+ xhsearch.x xhelp.h <ctype.h> <fset.h>
+ xhsort.x xhelp.h <ctype.h>
+ ;
diff --git a/pkg/system/help/xhelp/xhcmds.x b/pkg/system/help/xhelp/xhcmds.x
new file mode 100644
index 00000000..2c98af79
--- /dev/null
+++ b/pkg/system/help/xhelp/xhcmds.x
@@ -0,0 +1,185 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include "../help.h"
+include "xhelp.h"
+
+
+# XHELP callback commands.
+define XC_COMMANDS "|help|load|print|quit|search|files|directory|type|package|"
+define CMD_HELP 1
+define CMD_LOAD 2
+define CMD_PRINT 3
+define CMD_QUIT 4
+define CMD_SEARCH 5
+define CMD_FILES 6
+define CMD_DIRECTORY 7
+define CMD_TYPE 8
+define CMD_PACKAGE 9
+
+
+# XH_COMMAND_LOOP -- Process the GUI command loop.
+
+procedure xh_command_loop (xh)
+
+pointer xh #I task descriptor
+
+pointer sp, cmd, name, pkg, pat, opt, dev
+real x, y
+int wcs, key, exact_match
+char str[SZ_FNAME]
+
+bool streq()
+int strdic(), clgcur()
+int xh_pkglist()
+
+begin
+ call smark (sp)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+ call salloc (pkg, SZ_FNAME, TY_CHAR)
+ call salloc (opt, SZ_FNAME, TY_CHAR)
+ call salloc (dev, SZ_FNAME, TY_CHAR)
+ call salloc (cmd, SZ_FNAME, TY_CHAR)
+ call salloc (pat, SZ_FNAME, TY_CHAR)
+
+
+ # Enter the command loop.
+ while (clgcur ("coords", x, y, wcs, key, str, SZ_FNAME) != EOF) {
+
+ # Skip any non-colon commands.
+ if (key != ':')
+ next
+
+ # Get the colon command string.
+ call sscan (str)
+ call gargwrd (Memc[cmd], SZ_FNAME)
+
+ switch (strdic (Memc[cmd], Memc[cmd], SZ_FNAME, XC_COMMANDS)) {
+ case CMD_HELP:
+ call gargwrd (Memc[name], SZ_FNAME)
+
+ # Get help on the requested topic, updates package list
+ # if necesary.
+ if (streq(Memc[name],"Home")) {
+ call xh_init (xh, NO, YES)
+ } else {
+ call gargwrd (Memc[pkg], SZ_FNAME) # curpack
+ call gargwrd (Memc[opt], SZ_FNAME) # option
+ call xh_cmd_help (xh, Memc[name], Memc[pkg], Memc[opt])
+ }
+
+ case CMD_FILES:
+ call gargwrd (Memc[name], SZ_FNAME) # task name
+ call gargwrd (Memc[pkg], SZ_FNAME) # parent package
+ call xh_files (xh, Memc[name], Memc[pkg])
+
+ case CMD_LOAD:
+ # Load a requested page from the history.
+ call gargwrd (Memc[name], SZ_FNAME) # task name
+ call gargwrd (Memc[pkg], SZ_FNAME) # curpack
+ call gargwrd (Memc[opt], SZ_FNAME) # help option
+ if (xh_pkglist (xh, Memc[name], HELPDB(xh), LIST(xh)) != 0)
+ call gmsg (XH_GP(xh), "pkglist", LIST(xh))
+ call xh_help (xh, Memc[name], Memc[pkg], Memc[opt])
+
+ case CMD_PRINT:
+ # Print the current results.
+ call gargwrd (Memc[name], SZ_FNAME) # task name
+ call gargwrd (Memc[pkg], SZ_FNAME) # curpack
+ call gargwrd (Memc[dev], SZ_FNAME) # printer name
+ call xh_print_help (xh, Memc[name], Memc[pkg], Memc[dev])
+
+ case CMD_QUIT:
+ # Quit the task.
+ break
+
+ case CMD_SEARCH:
+ # Get the results of the keyword search.
+ call gargi (exact_match)
+ call gargstr (Memc[pat], SZ_FNAME)
+ call xh_search (xh, exact_match, Memc[pat])
+
+ case CMD_DIRECTORY:
+ # Process the directory browsing command.
+ call gargwrd (Memc[opt], SZ_FNAME)
+ call xh_directory (xh, Memc[opt])
+
+ case CMD_TYPE:
+ # Get the showtype value from the GUI
+ call gargi (XH_SHOWTYPE(xh))
+
+ case CMD_PACKAGE:
+ # For the given item return the package in which it
+ # was found. [DEBUG ROUTINE.]
+ call gargwrd (Memc[name], SZ_FNAME)
+ call xh_pkgpath (xh, Memc[name], CURPACK(xh), Memc[pkg])
+ call printf ("%s => %s\n")
+ call pargstr (Memc[name])
+ call pargstr (Memc[pkg])
+ call flush(STDOUT)
+ }
+ }
+
+ call sfree (sp)
+end
+
+
+# XH_CMD_HELP -- Process a help command.
+
+procedure xh_cmd_help (xh, topic, curpack, option)
+
+pointer xh # task descriptor
+char topic[ARB] # requested topic
+char curpack[ARB] # current package
+char option[ARB] # option (help|source|sysdoc)
+
+int len
+
+bool streq()
+int strncmp()
+int xh_pkgname(), xh_pkglist()
+
+begin
+ if (streq (option, "help")) {
+ # No package name given, find one and load it.
+ if (streq (curpack, "{}")) {
+ curpack[1] = EOS
+ len = 0
+ if (xh_pkgname (xh, topic, curpack) == OK)
+ len = xh_pkglist (xh, curpack, HELPDB(xh), LIST(xh))
+
+ if (len != 0 &&
+ strncmp(curpack, "root", 4) != 0 &&
+ strncmp(curpack, "clpack", 6) != 0) {
+ call gmsg (XH_GP(xh), "pkglist", LIST(xh))
+ call strcpy (curpack, CURPACK(xh), SZ_FNAME)
+ call gmsg (XH_GP(xh), "curpack", curpack)
+ call gmsg (XH_GP(xh), "history", "package")
+ }
+ }
+
+ if (xh_pkglist (xh, topic, HELPDB(xh), LIST(xh)) != 0) {
+ # Got a package listing....
+ call gmsg (XH_GP(xh), "pkglist", LIST(xh))
+ call strcpy (topic, CURPACK(xh), SZ_FNAME)
+ call gmsg (XH_GP(xh), "curpack", topic)
+ }
+ }
+
+ if (streq (topic, CURPACK(xh))) {
+ call gmsg (XH_GP(xh), "type", "package")
+ call gmsg (XH_GP(xh), "curtask", topic)
+ if (streq (option, "help"))
+ call xh_help (xh, "", CURPACK(xh), option)
+ else
+ call xh_help (xh, topic, curpack, option)
+ call strcpy (CURPACK(xh), CURTASK(xh), SZ_FNAME)
+
+ } else {
+ call gmsg (XH_GP(xh), "type", "task")
+ call gmsg (XH_GP(xh), "curtask", topic)
+ call xh_help (xh, topic, CURPACK(xh), option)
+ call strcpy (topic, CURTASK(xh), SZ_FNAME)
+ }
+ call gmsg (XH_GP(xh), "history", "append")
+end
diff --git a/pkg/system/help/xhelp/xhdir.x b/pkg/system/help/xhelp/xhdir.x
new file mode 100644
index 00000000..3c951afa
--- /dev/null
+++ b/pkg/system/help/xhelp/xhdir.x
@@ -0,0 +1,567 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <diropen.h>
+include <ctype.h>
+include <finfo.h>
+
+include "xhelp.h"
+
+
+# Pattern matching definitions.
+define PATCHARS "*?["
+
+# Browsing command dictionary.
+define DIR_CMDS "|dirlist|loadfile|open|template|home|up|root|rescan|save|"
+define DIRLIST 1 # get the directory listing
+define LOADFILE 2 # load the requested file
+define OPEN 3 # load the requested file
+define TEMPLATE 4 # filename matching template
+define HOME 5 # goto the user's home$
+define UP 6 # go up one directory
+define ROOT 7 # go to the root directory
+define RESCAN 8 # rescan current directory
+define SAVE 9 # save to the requested file
+
+
+# XH_DIRECTORY -- Process the directory browsing command.
+
+procedure xh_directory (xh, command)
+
+pointer xh #i task descriptor
+char command[ARB] #i command option
+
+pointer sp, dir, file, pattern, path, fmt
+pointer task, pkg, opt, type
+int ncmd, overwrite
+int strdic(), strcmp(), envgets()
+
+begin
+ # Allocate working space and clear it.
+ call smark (sp)
+ call salloc (dir, SZ_PATHNAME, TY_CHAR)
+ call salloc (path, SZ_PATHNAME, TY_CHAR)
+ call salloc (file, SZ_FNAME, TY_CHAR)
+ call salloc (pattern, SZ_FNAME, TY_CHAR)
+ call salloc (fmt, SZ_FNAME, TY_CHAR)
+ call salloc (task, SZ_FNAME, TY_CHAR)
+ call salloc (pkg, SZ_FNAME, TY_CHAR)
+ call salloc (opt, SZ_FNAME, TY_CHAR)
+ call salloc (type, SZ_FNAME, TY_CHAR)
+
+ call aclrc (Memc[dir], SZ_FNAME)
+ call aclrc (Memc[path], SZ_FNAME)
+ call aclrc (Memc[file], SZ_FNAME)
+ call aclrc (Memc[fmt], SZ_FNAME)
+ call aclrc (Memc[pattern], SZ_FNAME)
+ call aclrc (Memc[task], SZ_FNAME)
+ call aclrc (Memc[pkg], SZ_FNAME)
+ call aclrc (Memc[opt], SZ_FNAME)
+ call aclrc (Memc[type], SZ_FNAME)
+
+ ncmd = strdic (command, command, SZ_LINE, DIR_CMDS)
+ switch (ncmd) {
+ case DIRLIST:
+ call gargwrd (Memc[dir], SZ_PATHNAME) # get the dirname
+ if (strcmp ("../", Memc[dir]) == 0) {
+ call xh_updir (xh)
+ } else {
+ call sprintf (Memc[path], SZ_PATHNAME, "%s%s")
+ call pargstr (CURDIR(xh))
+ call pargstr (Memc[dir])
+ call xh_set_curdir (xh, Memc[path])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+ call xh_selection (xh, CURDIR(xh))
+ }
+
+ case LOADFILE:
+ call gargwrd (Memc[file], SZ_FNAME) # get the filename
+ call sprintf (Memc[path], SZ_PATHNAME, "%s%s")
+ call pargstr (CURDIR(xh))
+ call pargstr (Memc[file])
+ call xh_open_file (xh, "helpres", Memc[path], YES, YES)
+ call xh_selection (xh, Memc[path])
+
+ case OPEN:
+ call gargwrd (Memc[file], SZ_FNAME) # get the filename
+ call xh_ldfile (xh, Memc[file])
+
+ case TEMPLATE:
+ call gargwrd (Memc[pattern], SZ_FNAME) # set the template
+ call xh_set_pattern (xh, Memc[pattern])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+
+ case HOME:
+ if (envgets ("home", Memc[dir], SZ_PATHNAME) != EOF) {
+ call xh_set_curdir (xh, Memc[dir])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+ }
+
+ case UP:
+ call xh_updir (xh)
+
+ case ROOT:
+ call xh_set_curdir (xh, "/")
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+
+ case RESCAN:
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+
+ case SAVE:
+ call gargwrd (Memc[path], SZ_FNAME) # get the filename
+ call gargwrd (Memc[file], SZ_FNAME) # get the output fname
+ call gargi (overwrite) # get the overwrite flag
+ call gargwrd (Memc[fmt], SZ_FNAME) # get the save format
+ call xh_save_file (xh, Memc[path], Memc[file], Memc[fmt],
+ overwrite)
+ }
+
+ call sfree (sp)
+end
+
+
+# XH_DIRLIST -- Given the directory name and a file template return the
+# directory contents.
+
+procedure xh_dirlist (xh, directory, pattern)
+
+pointer xh #i task descriptor
+char directory[ARB] #i directory to read
+char pattern[ARB] #i matching template
+
+pointer sp, path, fname, patbuf
+pointer dp, fp, ip, op, ep, sym
+bool match_extension
+int dd, n, patlen
+int nfiles, ndirs, lastch
+
+pointer stopen(), stenter()
+int diropen(), xh_isdir(), strncmp(), stridxs()
+int patmake(), patmatch(), strlen(), getline()
+
+begin
+ call smark (sp)
+ call salloc (path, SZ_PATHNAME, TY_CHAR)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (patbuf, SZ_LINE, TY_CHAR)
+
+ call aclrc (Memc[patbuf], SZ_LINE)
+
+ # If this isn't a directory just return silently.
+ if (xh_isdir (directory, Memc[path], SZ_PATHNAME) == 0) {
+ call sfree (sp)
+ return
+ }
+
+ # Open the requested directory
+ dd = diropen (directory, PASS_HIDDEN_FILES)
+
+ # Set up the pattern matching code. We recognize selecting all files
+ # with a particular extension as a special case, since this case is
+ # very common and can be done much more efficiently if we don't use
+ # the general pattern matching code. If we have no pattern set the
+ # length to zero to indicate that everything will match.
+
+ if (pattern[1] == EOS) {
+ patlen = 0
+ } else {
+ match_extension = (strncmp (pattern, "*.", 2) == 0 &&
+ stridxs (PATCHARS, pattern[3]) <= 0)
+ if (match_extension)
+ patlen = strlen (pattern)
+ else {
+ # Convert file matching pattern into general pattern string.
+ Memc[fname] = '^'
+ op = fname + 1
+ lastch = 0
+ for (ip=1; pattern[ip] != EOS; ip=ip+1) {
+ if (pattern[ip] == '*' && lastch != '?' && lastch != ']') {
+ Memc[op] = '?'
+ op = op + 1
+ }
+ lastch = pattern[ip]
+ Memc[op] = lastch
+ op = op + 1
+ }
+ Memc[op] = '$'
+ op = op + 1
+ Memc[op] = EOS
+
+ # Compile the pattern.
+ patlen = patmake (pattern, Memc[patbuf], SZ_LINE)
+ }
+ }
+
+ # Initialize counters.
+ ndirs = 0
+ nfiles = 0
+ dp = NULL
+ fp = NULL
+
+ # Accumulate the contents into the directory and files lists. We
+ # match files against the given template, all directories are
+ # matched regardless.
+ for (n=0; n != EOF; ) {
+ n = getline (dd, Memc[fname])
+ if (n < 1)
+ break
+ n = n - 1
+ Memc[fname+n] = EOS # stomp the newline
+
+ # See if this is a directory.
+ call sprintf (Memc[path], SZ_PATHNAME, "%s%s")
+ call pargstr (CURDIR(xh))
+ call pargstr (Memc[fname])
+ if (xh_isdir (Memc[path], Memc[path], SZ_PATHNAME) > 0) {
+ ndirs = ndirs + 1
+
+ # If this is the first directory initialize the symbol table.
+ if (ndirs == 1)
+ dp = stopen ("dirlist", LEN_INDEX, LEN_STAB, SZ_SBUF)
+
+ # Enter the directory name into the symbol table.
+ call strcat ("/", Memc[fname], SZ_FNAME)
+ sym = stenter (dp, Memc[fname], strlen(Memc[fname])+1)
+
+ } else {
+ # Check if the file matches the given pattern.
+ if (patlen > 0) {
+ if (match_extension) {
+ if (n < patlen)
+ next
+ ep = fname + n - 1
+ for (ip=patlen; ip > 2; ip=ip-1) {
+ if (Memc[ep] != pattern[ip])
+ break
+ ep = ep - 1
+ }
+ if (pattern[ip] != '.' || Memc[ep] != '.')
+ next
+ } else if (patmatch (Memc[fname], Memc[patbuf]) <= 0)
+ next
+ }
+
+ # We have a match.
+ nfiles = nfiles + 1
+
+ # If this is the first file initialize the symbol table.
+ if (nfiles == 1)
+ fp = stopen ("filelist", LEN_INDEX, LEN_STAB, SZ_SBUF)
+
+ # Enter the directory name into the symbol table.
+ sym = stenter (fp, Memc[fname], strlen(Memc[fname])+1)
+ }
+ }
+
+ # Send the results to the GUI.
+ call xh_putlist (xh, dp, "directory", "dirlist")
+ call xh_putlist (xh, fp, "directory", "filelist")
+
+ # Clean up.
+ if (dp != NULL)
+ call stclose (dp)
+ if (fp != NULL)
+ call stclose (fp)
+ call close (dd)
+ call sfree (sp)
+end
+
+
+# XH_PUTLIST -- Given the symtab for the directory contents construct a
+# list suitable for a message to the GUI. The 'arg' parameter is passed
+# to indicate which type of list this is.
+
+procedure xh_putlist (xh, stp, param, arg)
+
+pointer xh #i task descriptor
+pointer stp #i symtab ptr for list
+char param[ARB] #i GUI param to notify
+char arg[ARB] #i GUI param arg
+
+pointer sp, list, msg, sym, name, ip
+int nchars
+
+pointer sthead(), stnext(), stname()
+int stsize(), gstrcpy(), strcmp(), strlen()
+
+begin
+ # Return if there is no symtab information.
+ if (stp == NULL) {
+ call smark (sp)
+ call salloc (msg, SZ_FNAME , TY_CHAR)
+ call sprintf (Memc[msg], SZ_FNAME, "%s { }")
+ call pargstr (arg)
+
+ call gmsg (XH_GP(xh), param, Memc[msg]) # send it to the GUI
+ call gflush (XH_GP(xh))
+ call sfree (sp)
+ return
+ }
+
+ # Allocate space for the list.
+ nchars = stsize (stp) + 1
+
+ call smark (sp)
+ call salloc (list, nchars , TY_CHAR)
+ call aclrc (Memc[list], nchars)
+ ip = list
+
+ # Build the list from the symtab.
+ for (sym = sthead (stp); sym != NULL; sym = stnext (stp,sym)) {
+ name = stname(stp,sym)
+ if (strcmp (Memc[name], "./") != 0) {
+ ip = ip + gstrcpy (Memc[name], Memc[ip], SZ_FNAME)
+ ip = ip + gstrcpy (" ", Memc[ip], SZ_FNAME)
+ }
+ }
+
+ # Sort the list.
+ call xh_sort_list (Memc[list])
+
+ # Allocate space for the message buffer. The "+ 6" is space for
+ # the brackets around the list in the message created below.
+ nchars = nchars + strlen (arg) + 6
+ call salloc (msg, nchars, TY_CHAR)
+ call aclrc (Memc[msg], nchars)
+ ip = msg
+
+ # Begin the message by adding the arg and make a Tcl list of the
+ # contents.
+ call sprintf (Memc[msg], nchars, "%s { ")
+ call pargstr (arg)
+ call strcat (Memc[list], Memc[msg], nchars)
+ call strcat (" }", Memc[msg], nchars)
+
+ # Finally, send it to the GUI.
+ call gmsg (XH_GP(xh), param, Memc[msg])
+ call gflush (XH_GP(xh))
+
+ call sfree (sp)
+end
+
+
+# XH_LDFILE -- Load the requested file. If this is a file display it's
+# contents and update the browser with it's directory, otherwise if it's
+# a directory jump the browser to that directory.
+
+procedure xh_ldfile (xh, file)
+
+pointer xh #i task descriptor
+char file[ARB] #i requested file/dir
+
+pointer sp, ip, dir, parent, path
+int nchars
+int access(), strlen(), xh_isdir()
+
+begin
+ call smark (sp)
+ call salloc (dir, SZ_PATHNAME, TY_CHAR)
+ call salloc (path, SZ_PATHNAME, TY_CHAR)
+ call salloc (parent, SZ_PATHNAME, TY_CHAR)
+
+ # Expand the current directory to a host path.
+ call fdirname (file, Memc[dir], SZ_PATHNAME)
+
+ if (xh_isdir (Memc[dir], Memc[path], SZ_PATHNAME) > 0) {
+ # Set the curdir and load it's contents.
+ call xh_set_curdir (xh, Memc[path])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+ call xh_selection (xh, Memc[path])
+ }
+
+ if (access(file,0,0) == YES &&
+ xh_isdir (file, Memc[path], SZ_PATHNAME) == 0) {
+ # Work backwards to the parent '/', be sure to skip the trailing
+ # backslash already in the dirname.
+ ip = dir + strlen (Memc[dir]) - 2
+ while (Memc[ip] != '/' && ip > dir)
+ ip = ip - 1
+
+ nchars = ip - dir
+ if (nchars > 0)
+ call strcpy (Memc[dir], Memc[parent], nchars)
+ else
+ call strcpy ("/", Memc[parent], nchars)
+
+ # Set the parent dir and load it's contents.
+ call xh_set_curdir (xh, Memc[parent])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+
+ # Now load the file itself.
+ call xh_open_file (xh, "helpres", file, YES, YES)
+ call xh_selection (xh, file)
+ }
+
+ call sfree (sp)
+end
+
+
+# XH_UPDIR -- Go up to the parent directory and return contents.
+
+procedure xh_updir (xh)
+
+pointer xh #i task descriptor
+
+pointer sp, ip, dir, parent
+int nchars, strlen()
+
+begin
+ call smark (sp)
+ call salloc (dir, SZ_PATHNAME, TY_CHAR)
+ call salloc (parent, SZ_PATHNAME, TY_CHAR)
+
+ # Expand the current directory to a host path.
+ call fdirname (CURDIR(xh), Memc[dir], SZ_PATHNAME)
+
+ # Work backwards to the parent '/', be sure to skip the trailing
+ # backslash already in the dirname.
+ ip = dir + strlen (Memc[dir]) - 2
+ while (Memc[ip] != '/' && ip > dir)
+ ip = ip - 1
+
+ nchars = ip - dir
+ if (nchars > 0)
+ call strcpy (Memc[dir], Memc[parent], nchars)
+ else
+ call strcpy ("/", Memc[parent], nchars)
+
+ # Set the parent dir and load it's contents.
+ call xh_set_curdir (xh, Memc[parent])
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+ call xh_selection (xh, CURDIR(xh))
+
+ call sfree (sp)
+end
+
+
+# XH_SET_CURDIR -- Set the filename matching template pattern.
+
+procedure xh_set_curdir (xh, dir)
+
+pointer xh #i task descriptor
+char dir[ARB] #i current directory
+
+pointer sp, dirbuf
+int strlen()
+
+begin
+ call smark (sp)
+ call salloc (dirbuf, SZ_PATHNAME, TY_CHAR)
+
+ call strcpy (dir, CURDIR(xh), SZ_PATHNAME)
+ if (dir[strlen(dir)] != '/')
+ call strcat ("/", CURDIR(xh), SZ_PATHNAME)
+
+ call sprintf (Memc[dirbuf], SZ_PATHNAME, "curdir %s")
+ call pargstr (CURDIR(xh))
+
+ call gmsg (XH_GP(xh), "directory", Memc[dirbuf])
+ call gflush (XH_GP(xh))
+
+ call sfree (sp)
+end
+
+
+# XH_SET_PATTERN -- Set the filename matching template pattern.
+
+procedure xh_set_pattern (xh, pattern)
+
+pointer xh #i task descriptor
+char pattern[ARB] #i template pattern
+
+pointer sp, patbuf
+
+begin
+ call smark (sp)
+ call salloc (patbuf, SZ_FNAME, TY_CHAR)
+
+ call sprintf (Memc[patbuf], SZ_FNAME, "template %s")
+ call pargstr (pattern)
+
+ call strcpy (pattern, PATTERN(xh), SZ_FNAME)
+ call gmsg (XH_GP(xh), "directory", Memc[patbuf])
+ call gflush (XH_GP(xh))
+
+ call sfree (sp)
+end
+
+
+# XH_SELECTION -- Set the selected filename.
+
+procedure xh_selection (xh, selection)
+
+pointer xh #i task descriptor
+char selection[ARB] #i selection
+
+pointer sp, buf
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_FNAME, TY_CHAR)
+
+ call sprintf (Memc[buf], SZ_FNAME, "selection %s")
+ call pargstr (selection)
+
+ call gmsg (XH_GP(xh), "directory", Memc[buf])
+ call gflush (XH_GP(xh))
+ call sfree (sp)
+end
+
+
+# XH_ISDIR -- Test whether the named file is a directory. Check first to
+# see if it is a subdirectory of the current directory. If VFN is a directory,
+# return the OS pathname of the directory in pathname, and the number of
+# chars in the pathname as the function value. Otherwise return 0.
+
+int procedure xh_isdir (vfn, pathname, maxch)
+
+char vfn[ARB] # name to be tested
+char pathname[ARB] # receives path of directory
+int maxch # max chars out
+
+bool isdir
+pointer sp, fname, op
+int ip, fd, nchars, ch
+long file_info[LEN_FINFO]
+int finfo(), diropen(), gstrcpy(), strlen()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_PATHNAME, TY_CHAR)
+
+ # Copy the VFN string, minus any whitespace on either end.
+ op = fname
+ for (ip=1; vfn[ip] != EOS; ip=ip+1) {
+ ch = vfn[ip]
+ if (!IS_WHITE (ch)) {
+ Memc[op] = ch
+ op = op + 1
+ }
+ }
+ Memc[op] = EOS
+
+ isdir = false
+ if (finfo (Memc[fname], file_info) != ERR) {
+ isdir = (FI_TYPE(file_info) == FI_DIRECTORY)
+
+ if (isdir) {
+ call fdirname (Memc[fname], pathname, maxch)
+ nchars = strlen (pathname)
+ }
+
+ } else {
+ # If we get here, the VFN is the name of a new file.
+ ifnoerr (fd = diropen (Memc[fname], 0)) {
+ call close (fd)
+ isdir = true
+ }
+ nchars = gstrcpy (Memc[fname], pathname, maxch)
+ }
+
+ call sfree (sp)
+ if (isdir)
+ return (nchars)
+ else {
+ pathname[1] = EOS
+ return (0)
+ }
+end
diff --git a/pkg/system/help/xhelp/xhelp.h b/pkg/system/help/xhelp/xhelp.h
new file mode 100644
index 00000000..24bffc71
--- /dev/null
+++ b/pkg/system/help/xhelp/xhelp.h
@@ -0,0 +1,89 @@
+# XHELP.H -- Include file for the XHELP GUI task.
+
+# Help database header structure. Stored at the beginning of a help
+# database file. This information is taken from the help$helpdb.x source.
+
+define LEN_HDBHEADER 14
+define HDB_MAGICVAL 110104B
+
+define HDB_MAGIC Memi[$1] # helpdb file type code
+define HDB_RAW Memi[$1+1] # access compiled or raw database
+define HDB_RHD Memi[$1+2] # if raw, HP of root help directory
+define HDB_INDEX Memi[$1+3] # index of root help directory
+define HDB_CRDATE Meml[$1+4] # creation date
+define HDB_NENTRIES Memi[$1+5] # number of help directories in db
+define HDB_MAXENTRIES Memi[$1+6] # maximum no. of help directories in db
+define HDB_NMODULES Memi[$1+7] # count of the total number of modules
+define HDB_INDEXOFFSET Meml[$1+8] # file offset of index, chars
+define HDB_INDEXPTR Memi[$1+9] # pointer to loaded index, ty_struct
+define HDB_INDEXLEN Memi[$1+10] # length of index structure, su
+define HDB_DATAOFFSET Meml[$1+11] # file offset of data area, chars
+define HDB_DATAPTR Memi[$1+12] # pointer to loaded data area, ty_struct
+define HDB_DATALEN Memi[$1+13] # length of data area, struct units
+
+# Index structure. Identifies the contents of the database and tells where
+# they are stored. There is one index entry for each help directory, i.e.,
+# for each package.
+
+define LEN_HDBINDEX 34
+define SZ_DBIKEY 63
+define LEN_DBIDATA 2
+
+define DBI_KEY Memc[P2C($1)] # entry name
+define DBI_OFFSET Memi[$1+32] # offset of entry into data area, su
+define DBI_MTIME Meml[$1+33] # modification date of entry
+
+define MAX_ENTRIES 100 # initial max db entries
+define INC_ENTRIES 50 # increment if overflow
+define MAX_DEPTH 20 # max nesting of packages
+define MAX_MENUSIZE 500 # max modules in a table
+define MAX_NAMELEN 20 # max chars in a module name in table
+
+
+# XHELP Macro definitions.
+define SZ_HELPLIST 20480
+define SZ_XHELPSTRUCT 45
+
+define XH_GP Memi[$1] # graphics descriptor
+define XH_LPTR Memi[$1+1] # ptr for pkg list
+define XH_TEMPLATE Memi[$1+2] # initial help topic
+define XH_OPTION Memi[$1+3] # help option
+define XH_PRINTER Memi[$1+4] # printer name
+define XH_CURTASK Memi[$1+5] # current task name
+define XH_CURPACK Memi[$1+6] # current package name
+define XH_QUICKREF Memi[$1+7] # quick-reference filen
+define XH_HOMEPAGE Memi[$1+8] # startup page
+define XH_CURDIR Memi[$1+9] # current directory
+define XH_PATTERN Memi[$1+10] # current filename template
+define XH_HELPDB Memi[$1+11] # help database string
+define XH_SHOWTYPE Memi[$1+12] # indicate packages in list
+define XH_STP Memi[$1+13] # package list symtab ptr
+
+# Helpful macros
+define LIST Memc[XH_LPTR($1)]
+define TEMPLATE Memc[XH_TEMPLATE($1)]
+define OPTION Memc[XH_OPTION($1)]
+define PRINTER Memc[XH_PRINTER($1)]
+define CURTASK Memc[XH_CURTASK($1)]
+define CURPACK Memc[XH_CURPACK($1)]
+define QUICKREF Memc[XH_QUICKREF($1)]
+define HOMEPAGE Memc[XH_HOMEPAGE($1)]
+define CURDIR Memc[XH_CURDIR($1)]
+define PATTERN Memc[XH_PATTERN($1)]
+define HELPDB Memc[XH_HELPDB($1)]
+
+define WIDE_PAGE 100 # needed by the print routines
+define SZ_DDSTR 256
+
+
+# Filenames.
+define HELP "lib$scr/help.html" # default help file
+define PKGFILE "uparm$help.pkgs" # default package list symtab
+define QREFFILE "uparm$quick.ref" # default references file
+
+
+# Symbol table definitions.
+define LEN_INDEX 10 # length of symtab index
+define LEN_STAB 32 # initial length of symtab
+define SZ_SBUF 32 # initial size of symtab string buffer
+
diff --git a/pkg/system/help/xhelp/xhelp.x b/pkg/system/help/xhelp/xhelp.x
new file mode 100644
index 00000000..95a2f250
--- /dev/null
+++ b/pkg/system/help/xhelp/xhelp.x
@@ -0,0 +1,167 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include "../help.h"
+include "xhelp.h"
+
+
+# XHELP -- The main task procedure. XHELP is a GUI client program for
+# browsing the IRAF help system. As much as possible it uses the existing
+# help database code but provides a friendlier interface, allowing users to
+# browse packages for help pages in the same way they would browse packages
+# in the CL. It provides an HTML converter for LROFF sources for better
+# presentation in the GUI, as well as Postscript generation for better
+# looking hardcopy. XHelp acts as a server for the help system, merely
+# returning any output that the GUI has requested. Navigation is done in
+# the GUI code, this program maintains just the state of the last page
+# returned and knows nothing about how it got there. See the xhelp.hlp for
+# detailed documentation.
+
+procedure xhelp (topic)
+
+char topic[ARB] #I help template
+
+pointer xh
+char uifname[SZ_FNAME]
+int search, template
+
+pointer xh_open(), gopenui()
+bool clgetb()
+int btoi()
+
+begin
+ # Open structure and allocate pointers.
+ xh = xh_open ()
+ call strcpy (topic, TEMPLATE(xh), SZ_FNAME)
+
+ # Load the task parameters.
+ call clgstr ("option", OPTION(xh), SZ_FNAME)
+ call clgstr ("printer", PRINTER(xh), SZ_FNAME)
+ call clgstr ("quickref", QUICKREF(xh), SZ_FNAME)
+ XH_SHOWTYPE(xh) = btoi (clgetb("showtype"))
+ search = btoi (clgetb("search"))
+ template = btoi (clgetb("file_template"))
+
+ # Fetch the name of the help database.
+ call xh_ghelpdb (xh)
+
+ # Open the GUI.
+ call clgstr ("uifname", uifname, SZ_FNAME)
+ XH_GP(xh) = gopenui ("stdgraph", NEW_FILE, uifname, STDGRAPH)
+ call gflush (XH_GP(xh))
+
+ # Initialize the task and send topic list to the GUI.
+ call xh_init (xh, template, search)
+
+ # Initialize the task and send topic list to the GUI.
+ call xh_command_loop (xh)
+
+ # Clean up.
+ call gclose (XH_GP(xh))
+ call xh_close (xh)
+end
+
+
+# XH_OPEN -- Open and allocate the XHELP task structure.
+
+pointer procedure xh_open ()
+
+pointer xh # task descriptor
+errchk calloc
+
+begin
+ iferr (call calloc (xh, SZ_XHELPSTRUCT, TY_STRUCT))
+ call error (0, "Error opening task structure.")
+
+ iferr {
+ call calloc (XH_LPTR(xh), SZ_HELPLIST, TY_CHAR)
+ call calloc (XH_TEMPLATE(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_OPTION(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_PRINTER(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_CURTASK(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_CURPACK(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_QUICKREF(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_HOMEPAGE(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_CURDIR(xh), SZ_PATHNAME, TY_CHAR)
+ call calloc (XH_PATTERN(xh), SZ_FNAME, TY_CHAR)
+ call calloc (XH_HELPDB(xh), SZ_HELPDB, TY_CHAR)
+ } then
+ call error (0, "Error allocating structure pointers.")
+
+ return (xh)
+end
+
+
+# XH_CLOSE -- Close the XHELP task structure.
+
+procedure xh_close (xh)
+
+pointer xh # task descriptor
+
+begin
+ call mfree (XH_TEMPLATE(xh), TY_CHAR)
+ call mfree (XH_OPTION(xh), TY_CHAR)
+ call mfree (XH_PRINTER(xh), TY_CHAR)
+ call mfree (XH_CURTASK(xh), TY_CHAR)
+ call mfree (XH_CURPACK(xh), TY_CHAR)
+ call mfree (XH_QUICKREF(xh), TY_CHAR)
+ call mfree (XH_HOMEPAGE(xh), TY_CHAR)
+ call mfree (XH_CURDIR(xh), TY_CHAR)
+ call mfree (XH_PATTERN(xh), TY_CHAR)
+ call mfree (XH_HELPDB(xh), TY_CHAR)
+ call mfree (XH_LPTR(xh), TY_CHAR)
+
+ call mfree (xh, TY_STRUCT)
+end
+
+
+# XH_GHELPDB -- Fetch the name of the help database, i.e., "helpdb",
+# "helpdir", or the name of a file. If the helpdb string is a list check
+# for the existance of each file in the list to ensure the final list
+# contains only valid help databases.
+
+procedure xh_ghelpdb (xh)
+
+pointer xh # task descriptor
+
+pointer sp, hdb, hdbstr, name
+int list
+int fntopnb(), fntgfnb()
+int access(), envgets()
+bool streq()
+
+begin
+ call smark (sp)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+ call salloc (hdb, SZ_HELPDB, TY_CHAR)
+ call salloc (hdbstr, SZ_HELPDB, TY_CHAR)
+
+ # Clear the working memory.
+ call aclrc (Memc[name], SZ_FNAME)
+ call aclrc (Memc[hdb], SZ_HELPDB)
+ call aclrc (Memc[hdbstr], SZ_HELPDB)
+
+ # Get the parameter value.
+ call clgstr ("helpdb", Memc[hdbstr], SZ_HELPDB)
+ if (streq (Memc[hdbstr], "helpdb"))
+ if (envgets ("helpdb", Memc[hdbstr], SZ_HELPDB) <= 0)
+ call syserrs (SYS_ENVNF, "helpdb")
+
+ # Open the list.
+ list = fntopnb (Memc[hdbstr], YES)
+
+ # Copy each of the existing files in the list to the output database
+ # string to be used by the task.
+ while (fntgfnb(list, Memc[name], SZ_FNAME) != EOF) {
+ if (access (Memc[name], 0, 0) == YES) {
+ if (Memc[hdb] != EOS)
+ call strcat (",", Memc[hdb], SZ_HELPDB)
+ call strcat (Memc[name], Memc[hdb], SZ_HELPDB)
+ }
+ }
+ call strcpy (Memc[hdb], HELPDB(xh), SZ_HELPDB)
+
+ # Clean up.
+ call fntclsb (list)
+ call sfree (sp)
+end
diff --git a/pkg/system/help/xhelp/xhfiles.x b/pkg/system/help/xhelp/xhfiles.x
new file mode 100644
index 00000000..53597eda
--- /dev/null
+++ b/pkg/system/help/xhelp/xhfiles.x
@@ -0,0 +1,89 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <fset.h>
+include <ctype.h>
+include "../help.h"
+include "xhelp.h"
+
+
+# XH_FILES -- Get the files associated with the requested help topic,
+# i.e. do a "help <topic> opt=files" request.
+
+procedure xh_files (xh, topic, curpack)
+
+pointer xh #i task struct pointer
+char topic[ARB] #i help topic
+char curpack[ARB] #i current package
+
+pointer sp, bp, buf
+pointer opt, val, line
+int fd
+long fsize
+char fname[SZ_FNAME]
+
+long fstatl()
+int getline(), access(), open(), stridxs(), strlen()
+
+begin
+ if (topic[1] == EOS && curpack[1] == EOS)
+ return
+
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (buf, SZ_FNAME, TY_CHAR)
+ call salloc (opt, SZ_FNAME, TY_CHAR)
+ call salloc (val, SZ_FNAME, TY_CHAR)
+
+ # Get a temp file name.
+ call mktemp ("tmp$xhelpi", fname, SZ_FNAME)
+
+ # Open a temp file with the help information found.
+ fd = open (fname, NEW_FILE, TEXT_FILE)
+ call xh_get_help (fd, topic, curpack, "", HF_HTML, HELPDB(xh),
+ "all", "files")
+ call close (fd)
+
+ # Open the results file for reading.
+ fd = open (fname, READ_ONLY, TEXT_FILE)
+ fsize = fstatl (fd, F_FILESIZE)
+
+ # If we got a result parse the lines for "opt=file" information.
+ if (fsize != 0) {
+
+ while (getline (fd, Memc[line]) != EOF) {
+
+ # Stomp the newline.
+ Memc[line+strlen(Memc[line])-1] = EOS
+
+ # Extract the option type and filename.
+ if (stridxs ("=", Memc[line]) > 0) {
+ for (bp=line; IS_WHITE(Memc[bp]); bp=bp+1)
+ ;
+ call strcpy (Memc[bp], Memc[opt], 3)
+ for (; Memc[bp] != '='; bp=bp+1)
+ ;
+ call strcpy (Memc[bp+1], Memc[val], SZ_FNAME)
+
+ # See if the file exists.
+ call sprintf (Memc[buf], SZ_FNAME, "%s %s \0")
+ call pargstr (Memc[opt])
+ call pargstr (Memc[val])
+ if (access (Memc[val],0,0) == YES)
+ call strcat (" 0", Memc[buf], SZ_FNAME)
+ else
+ call strcat (" 1", Memc[buf], SZ_FNAME)
+ call gmsg (XH_GP(xh), "helpfiles", Memc[buf])
+
+ } else if (stridxs (":", Memc[line]) > 0) {
+ call xh_pkgpath (xh, topic, curpack, Memc[line])
+ call sprintf (Memc[buf], SZ_FNAME, "file %s")
+ call pargstr (Memc[line])
+ call gmsg (XH_GP(xh), "helpfiles", Memc[buf])
+ }
+ }
+ }
+
+ call close (fd) # clean up
+ call delete (fname)
+ call sfree (sp)
+end
diff --git a/pkg/system/help/xhelp/xhhelp.x b/pkg/system/help/xhelp/xhhelp.x
new file mode 100644
index 00000000..708a00ce
--- /dev/null
+++ b/pkg/system/help/xhelp/xhhelp.x
@@ -0,0 +1,276 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <fset.h>
+include <finfo.h>
+include <error.h>
+include "../help.h"
+include "xhelp.h"
+
+
+# XH_HELP -- Get the requested help topic and send the result to the GUI.
+
+procedure xh_help (xh, topic, curpack, opt)
+
+pointer xh #i task struct pointer
+char topic[ARB] #i help topic
+char curpack[ARB] #i current package
+char opt[ARB] #i help option
+
+pointer helpstr
+int ip, fdi
+long fsize
+char ch, fname[SZ_FNAME], err[SZ_LINE]
+
+long fstatl()
+char getc()
+int open()
+bool strne()
+
+begin
+ # Get a temp file name.
+ call mktemp ("tmp$xhelpi", fname, SZ_FNAME)
+
+ # Open a temp file with the help information found.
+ fdi = open (fname, NEW_FILE, TEXT_FILE)
+ call xh_get_help (fdi, topic, curpack, "", HF_HTML, HELPDB(xh),
+ "all", opt)
+ call close (fdi)
+
+ # Open the results file for reading.
+ fdi = open (fname, READ_ONLY, TEXT_FILE)
+ fsize = fstatl (fdi, F_FILESIZE)
+
+ # If no results try using the topic name as a curpack param.
+ if (fsize == 0) {
+ call close (fdi) # clean up from before
+ call delete (fname)
+
+ # Open a temp file with the help information found.
+ fdi = open (fname, NEW_FILE, TEXT_FILE)
+ call xh_get_help (fdi, topic, topic, "", HF_HTML, HELPDB(xh),
+ "all", opt)
+ call close (fdi)
+
+ # Open the results file for reading.
+ fdi = open (fname, READ_ONLY, TEXT_FILE)
+ fsize = fstatl (fdi, F_FILESIZE)
+
+ # If we still have nothing then punt...
+ if (fsize == 0 && topic[1] != EOS) {
+ if (strne (opt, "help")) {
+ call sprintf (err, SZ_LINE,
+ "No '%s' option help available\n for `%s'.")
+ call pargstr (opt)
+ call pargstr (topic)
+ } else {
+ call sprintf (err, SZ_LINE, "No help available for\n`%s'.")
+ call pargstr (topic)
+ }
+ call gmsg (XH_GP(xh), "alert", err)
+ call close (fdi)
+ call delete (fname)
+ return
+ }
+ }
+
+ # Now filter the file to escape the curly braces so they pass thru
+ # to the Tcl cleanly. Put the result in the string sent to the GUI.
+ call calloc (helpstr, fsize + SZ_LINE, TY_CHAR)
+ ip = helpstr
+ repeat {
+ ch = getc (fdi, ch)
+ if (ch == '{' || ch == '}') {
+ Memc[ip] = '\\'
+ ip = ip + 1
+ }
+ Memc[ip] = ch
+ ip = ip + 1
+ } until (ch == EOF)
+ Memc[ip-1] = EOS
+
+ # Clean up.
+ call close (fdi)
+ call delete (fname)
+
+ # Send the help text to the GUI who will display it.
+ call gmsg (XH_GP(xh), "helpres", Memc[helpstr])
+ call mfree (helpstr, TY_CHAR)
+end
+
+
+# XH_GET_HELP -- The main work procedure, i.e. a rip-off of the t_help()
+# procedure. Decode the option string, set up the control structure, and
+# finally call process_template to expand the module template and process
+# the help text for each module. The output is written to a temp file
+# opened by the calling procedure which may optionally sort it or display
+# it as is.
+
+procedure xh_get_help (fd, topic, curpack, file, format, helpdb, section, opt)
+
+int fd #i file descriptor of result
+char topic[ARB] #i topic
+char curpack[ARB] #i current package
+char file[ARB] #i file template
+int format #i output format (text|html|ps)
+char helpdb[ARB] #i help database
+char section[ARB] #i section on which to get help
+char opt[ARB] #i type of help
+
+int list
+long fi[LEN_FINFO], db_ctime
+pointer sp, ctrl, optn, db, fname
+
+long clktime()
+pointer hdb_open()
+bool strne(), streq()
+int stridxs(), finfo(), fntopnb(), fntgfnb(), get_option()
+
+errchk hdb_open
+
+data db_ctime /0/
+define forms_ 91
+
+begin
+ call smark (sp)
+ call salloc (ctrl, LEN_CTRLSTRUCT, TY_STRUCT)
+ call salloc (optn, SZ_FNAME, TY_CHAR)
+ call salloc (fname, SZ_PATHNAME, TY_CHAR)
+
+ # If we were called without any arguments, do not query for the
+ # template, just set it to null and help will be given for the
+ # current package.
+
+ call aclri (Memi[ctrl], LEN_CTRLSTRUCT)
+ if (topic[1] == EOS) {
+ if (file[1] == EOS) {
+ H_OPTION(ctrl) = O_MENU
+ H_TEMPLATE(ctrl) = EOS
+ H_PARNAME(ctrl) = EOS
+ H_SECNAME(ctrl) = EOS
+ } else
+ call strcpy (file, H_TEMPLATE(ctrl), SZ_LINE)
+ } else {
+ call strcpy (topic, H_TEMPLATE(ctrl), SZ_LINE)
+ }
+
+
+ # Check to see if any of the files in the list are newer than the
+ # time of the last hdb_open. The first time the process runs we open
+ # and read in the database. The database remains in memory between
+ # calls to HELP, provided the process does not shutdown, provided
+ # the name of the database to be used does not change, and provided
+ # a new help database is not created.
+
+ if (db_ctime > 0) {
+ list = fntopnb (helpdb, YES)
+ while (fntgfnb (list, Memc[fname], SZ_PATHNAME) != EOF) {
+ if (finfo (Memc[fname], fi) != ERR) {
+ if (db != NULL && FI_CTIME(fi) > db_ctime) {
+ call hdb_close (db)
+ db = NULL
+ break
+ }
+ }
+ }
+ call fntclsb (list)
+ } else
+ db = NULL
+
+ # Reopen the help database if in-core copy is out of date.
+ if (db == NULL) {
+ db = hdb_open (helpdb)
+ db_ctime = clktime (long(0))
+ }
+
+ # Fetch the value of the ALL switch. This determines whether help
+ # will stop after processing the first module matching the template,
+ # or process all modules in the database which match the template.
+ # Explicit use of a pattern matching character anywhere in the template
+ # enable allmodoules.
+
+ if (stridxs ("*?[],", H_TEMPLATE(ctrl)) > 0)
+ H_ALLMODULES(ctrl) = YES
+ else
+ H_ALLMODULES(ctrl) = NO
+
+ # If the FILTER_INPUT flag is set, only part of the input text will be
+ # processed. Filtering is only done if printing a single section or
+ # parameter.
+
+ H_FILTER_INPUT(ctrl) = NO
+
+ # Determine whether or not text for a single section or parameter
+ # is to be output. If the value of one of these strings is "all",
+ # all sections or all parameters are to be output. If the "all"
+ # default is in effect, null the string as a flag to lower level
+ # code that all help text is to be processed.
+
+ if (H_OPTION(ctrl) == NULL) {
+ call strcpy (section, H_SECNAME(ctrl), SZ_SECNAME)
+ if (streq (H_SECNAME(ctrl), "all")) {
+ H_SECNAME(ctrl) = EOS
+ H_PARNAME(ctrl) = EOS
+ }
+ if (H_SECNAME(ctrl) != EOS || H_PARNAME(ctrl) != EOS)
+ H_FILTER_INPUT(ctrl) = YES
+ }
+
+ # Fetch and decode option string; abbreviations are permitted.
+ if (H_OPTION(ctrl) != O_MENU) {
+ call strcpy (opt, Memc[optn], SZ_FNAME)
+ call strlwr (Memc[optn])
+ iferr (H_OPTION(ctrl) = get_option (Memc[optn])) {
+ H_OPTION(ctrl) = O_HELP
+ call erract (EA_WARN)
+ }
+ }
+
+forms_
+ # Pause between screens of output text only if the standard output
+ # is not redirected, and if enabled by the user.
+
+ H_IN(ctrl) = ERR
+ H_OUT(ctrl) = fd
+ H_NLINES(ctrl) = -1
+ H_STATE(ctrl) = BOF
+ H_EOF(ctrl) = NO
+ H_QUIT(ctrl) = NO
+
+ # If the standard output is not redirected, i.e., if writing to the
+ # terminal, determine whether or not output is to be paginated (pause
+ # between pages). If output is redirected, the pagination flag
+ # and help option controls whether or not manpage style output is
+ # enabled. Manpage output formatting is desirable only when formatting
+ # help text or printing named files.
+
+ H_RAWOUT(ctrl) = YES
+ H_MANPAGE(ctrl) = NO
+ H_PAGINATE(ctrl) = NO
+ H_SOFLAG(ctrl) = NO
+ H_FORMAT(ctrl) = format
+
+ # We don't produce output to a screen so shut off the tty.
+
+ H_TTY(ctrl) = NULL
+
+ # Set left and right margins for output text format.
+
+ H_LMARGIN(ctrl) = 1
+ H_RMARGIN(ctrl) = 72
+
+ # Copy the current package to the control struct.
+ if (strne(curpack,"Home") && strne(curpack,""))
+ call strcpy (curpack, H_CURPACK(ctrl), SZ_CURPACK)
+
+ # Initialization is completed, control structure is completed.
+ # Format and output the help text. If we have a module name template
+ # process the template against the help database, otherwise work
+ # directly out of the named files.
+
+ if (file[1] == EOS)
+ call do_module_template (db, H_TEMPLATE(ctrl), ctrl)
+ else
+ call do_file_template (H_TEMPLATE(ctrl), ctrl)
+
+ call sfree (sp)
+end
diff --git a/pkg/system/help/xhelp/xhinit.x b/pkg/system/help/xhelp/xhinit.x
new file mode 100644
index 00000000..41ff5b65
--- /dev/null
+++ b/pkg/system/help/xhelp/xhinit.x
@@ -0,0 +1,77 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include "xhelp.h"
+
+
+# XH_INIT -- Initialize the task and the GUI.
+
+procedure xh_init (xh, file_template, search)
+
+pointer xh #i task struct pointer
+int file_template #i is topic a file template?
+int search #i doing a search?
+
+char curdir[SZ_FNAME]
+int fd
+
+pointer strestore()
+int envgets(), open()
+bool streq()
+errchk open
+
+begin
+ # Update the quickref file.
+ call xh_updt_quickref (xh)
+
+ # If starting up with a search, get that information first.
+ if (search == YES && TEMPLATE(xh) != EOS) {
+ call xh_search (xh, NO, TEMPLATE(xh))
+ call strcpy ("", TEMPLATE(xh), SZ_FNAME)
+ call strcpy ("", LIST(xh), SZ_LINE)
+ }
+
+ # Create the root package and send the results to the GUI.
+ call xh_root_pkg (xh)
+ call gmsg (XH_GP(xh), "pkglist", LIST(xh))
+
+ # Initialize the package list symtab.
+ iferr (fd = open (PKGFILE, READ_ONLY, BINARY_FILE))
+ call error (0, "Cannot open package list symtab")
+ XH_STP(xh) = strestore (fd)
+ call close (fd)
+ call gmsgi (XH_GP(xh), "showtype", XH_SHOWTYPE(xh))
+
+
+ if (TEMPLATE(xh) != EOS && file_template == NO) {
+ # If we're given an initial help topic, get the page and load it.
+ #call xh_help (xh, TEMPLATE(xh), TEMPLATE(xh), OPTION(xh))
+ call xh_cmd_help (xh, TEMPLATE(xh), "{}", OPTION(xh))
+ call strcpy ("", TEMPLATE(xh), SZ_FNAME)
+
+ } else if (TEMPLATE(xh) != EOS && file_template == YES) {
+ # Load a user defined page.
+ call xh_open_file (xh, "helpres", TEMPLATE(xh), YES, YES)
+ call strcpy ("", TEMPLATE(xh), SZ_FNAME)
+
+ } else {
+ # Load either a user defined homepage or the task help.
+ call clgstr ("home", HOMEPAGE(xh), SZ_FNAME)
+ if (streq ("", HOMEPAGE(xh)))
+ call strcpy (HELP, HOMEPAGE(xh), SZ_FNAME)
+ call xh_open_file (xh, "helpres", HOMEPAGE(xh), NO, YES)
+ }
+
+ # Set the printer to be used.
+ call gmsg (XH_GP(xh), "printer", PRINTER(xh))
+
+ # Initialize the online help doc.
+ call xh_open_file (xh, "help", HELP, NO, YES)
+
+ # Initialize the file browsing parameters. Since we can't
+ # get the current directory for the session use home$.
+ if (envgets ("home", curdir, SZ_FNAME) != EOF) {
+ call xh_set_pattern (xh, "*")
+ call xh_set_curdir (xh, curdir)
+ call xh_dirlist (xh, CURDIR(xh), PATTERN(xh))
+ }
+end
diff --git a/pkg/system/help/xhelp/xhofile.x b/pkg/system/help/xhelp/xhofile.x
new file mode 100644
index 00000000..c12ea7d3
--- /dev/null
+++ b/pkg/system/help/xhelp/xhofile.x
@@ -0,0 +1,188 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <fset.h>
+include "xhelp.h"
+
+
+# XH_OPEN_FILE -- Open the named file and send it to the GUI. If this is
+# a help document (i.e. it contains a ".help" block) we first convert it
+# to HTML, otherwise send it as is.
+
+procedure xh_open_file (xh, parameter, filename, check_for_help, warn)
+
+pointer xh # task descriptor
+char parameter[ARB] # GUI parameter to notify
+char filename[ARB] # file to open
+int check_for_help # check file for help block?
+int warn # warn if not present?
+
+pointer sp, ip, buf, out, text
+int fdi, fdo
+long fsize
+bool has_help
+
+int access(), open(), getline()
+int strmatch(), gstrcpy()
+long fstatl()
+errchk open
+
+define err_ 99
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+ call salloc (out, SZ_FNAME, TY_CHAR)
+
+ # Make sure the file exists.
+ if (access (filename, 0, 0) == NO) {
+ if (warn == YES) {
+ call sprintf (Memc[buf], SZ_LINE, "File does not exist:\n`%s'.")
+ call pargstr (filename)
+ call gmsg (XH_GP(xh), "alert", Memc[buf])
+ }
+ goto err_
+ } else if (access (filename, 0, BINARY_FILE) == YES) {
+ if (warn == YES) {
+ call sprintf (Memc[buf], SZ_LINE,
+ "Attempt to load binary file:\n`%s'.")
+ call pargstr (filename)
+ call gmsg (XH_GP(xh), "alert", "pop")
+ call gmsg (XH_GP(xh), "alert", Memc[buf])
+ }
+ goto err_
+ }
+
+ # If we're told not to look for help simply open the file and send
+ # it to the GUI (e.g. used for homepage and online help).
+ if (check_for_help == NO) {
+ call xh_load_file (xh, parameter, filename)
+ call sfree (sp)
+ return
+ }
+
+ # Open the file.
+ iferr (fdi = open (filename, READ_ONLY, TEXT_FILE)) {
+ if (warn == YES) {
+ call sprintf (Memc[buf], SZ_LINE, "Cannot open file\n`%s'.")
+ call pargstr (filename)
+ call gmsg (XH_GP(xh), "alert", Memc[buf])
+ }
+ goto err_
+ }
+
+ # Allocate an array the length of the file, if this isn't a help file
+ # we use this as the message buffer and send it to the GUI.
+ fsize = fstatl (fdi, F_FILESIZE)
+ call salloc (text, fsize+1, TY_CHAR)
+ call aclrc (Memc[text], fsize+1)
+
+ # See whether this is a help file
+ has_help = FALSE
+ ip = text
+ while (getline (fdi, Memc[buf]) != EOF) {
+ if (strmatch (Memc[buf], "^.help") > 0) {
+ has_help = TRUE
+ break
+ }
+ ip = ip + gstrcpy (Memc[buf], Memc[ip], SZ_LINE)
+ }
+ Memc[ip] = EOS
+
+
+ # If the file was found to have a .help block we're positioned at
+ # the beginning of the block. Convert the remainder to an HTML
+ # temp file and send that to the GUI, otherwise we already have the
+ # contents of the file in the text buffer so send that.
+ if (has_help) {
+ # Create an output filename and open it for writing.
+ call mktemp ("tmp$xhelpi", Memc[out], SZ_FNAME)
+ fdo = open (Memc[out], NEW_FILE, TEXT_FILE)
+
+ # Convert the remainder to HTML and send it to the GUI.
+ if (fdo != ERR) {
+ call lroff2html (fdi, fdo, filename, "", "", "", "")
+ call close (fdo)
+
+ call xh_load_file (xh, "helpres", Memc[out])
+ call delete (Memc[out])
+ }
+
+ } else {
+ # No help was found, send the contents straight to the display.
+ call xh_text_msg (XH_GP(xh), "helpres", Memc[text])
+ }
+
+
+err_ if (fdi != ERR)
+ call close (fdi)
+ call sfree (sp)
+end
+
+
+# XH_LOAD_FILE -- Load the named file in the GUI.
+
+procedure xh_load_file (xh, parameter, filename)
+
+pointer xh # task descriptor
+char parameter[ARB] # GUI parameter to notify
+char filename[ARB] # file to display
+
+pointer sp, ip, line, text
+int fd, open(), getline(), gstrcpy()
+long fsize, fstatl()
+errchk open
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ # Open the file and send it to the display.
+ fd = open (filename, READ_ONLY, TEXT_FILE)
+ if (fd != ERR) {
+ fsize = fstatl (fd, F_FILESIZE)
+ call salloc (text, fsize+1, TY_CHAR)
+ call aclrc (Memc[text], fsize+1)
+
+ for (ip=text; getline (fd, Memc[line]) != EOF; )
+ ip = ip + gstrcpy (Memc[line], Memc[ip], SZ_LINE)
+
+ Memc[ip] = EOS
+ call close (fd)
+
+ call xh_text_msg (XH_GP(xh), parameter, Memc[text])
+ }
+
+ call sfree (sp)
+end
+
+
+# XH_TEXT_MSG -- Send a text message to a named UI parameter but first
+# escape all curly braces so it passes through the Tcl correctly.
+
+procedure xh_text_msg (gp, param, msg)
+
+pointer gp
+char param[ARB], msg[ARB]
+
+pointer buf, ip
+int i, nchars
+int strlen()
+
+begin
+ nchars = strlen (msg)
+ call calloc (buf, nchars + SZ_LINE, TY_CHAR)
+
+ ip = buf
+ for (i=1; i < nchars; i=i+1) {
+ if (msg[i] == '{' || msg[i] == '}') {
+ Memc[ip] = '\\'
+ ip = ip + 1
+ }
+ Memc[ip] = msg[i]
+ ip = ip + 1
+ }
+
+ call gmsg (gp, "type", "file")
+ call gmsg (gp, param, Memc[buf])
+ call mfree (buf, TY_CHAR)
+end
diff --git a/pkg/system/help/xhelp/xhpkg.x b/pkg/system/help/xhelp/xhpkg.x
new file mode 100644
index 00000000..44580f15
--- /dev/null
+++ b/pkg/system/help/xhelp/xhpkg.x
@@ -0,0 +1,192 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <fset.h>
+include <error.h>
+include "../help.h"
+include "../helpdir.h"
+include "xhelp.h"
+
+
+# XH_GPKGLIST -- Get the requested package list as a sorted array of pointers.
+# This is essentially a "help <pkg>" request, the caller passes the sorted
+# list returned in 'pkglist" required.
+
+int procedure xh_pkglist (xh, topic, helpdb, pkglist)
+
+pointer xh #i task descriptor pointer
+char topic[ARB] #i search key
+char helpdb[ARB] #i filename of database to be examined
+char pkglist[ARB] #o package list
+
+int i, m
+pointer sp, pknm, hp, pp, sym
+pointer db, ixoff, ix
+
+bool strne()
+int gstrcpy(), strsearch(), hd_getname()
+pointer hdb_open(), hdb_load(), stfind()
+errchk hdb_open, hdb_printpack, hdb_load
+
+begin
+ call smark (sp)
+ call salloc (pknm, MAX_MENUSIZE, TY_POINTER)
+
+ db = hdb_open (helpdb)
+ ixoff = HDB_INDEXPTR(db)
+ pp = NULL
+
+ # Search for the right topic.
+ do i = 1, HDB_NENTRIES(db) {
+ ix = ixoff + (i - 1) * LEN_HDBINDEX
+ if (strne (DBI_KEY(ix), "_index") &&
+ strsearch (DBI_KEY(ix),topic) != 0) {
+
+ iferr (hp = hdb_load (db, DBI_KEY(ix))) {
+ call sfree (sp)
+ call erract (EA_WARN)
+ return (0)
+ }
+
+ # If this isn't the package we're after then move on.
+ if (HD_PAKNAME(hp) == 0 ||
+ strne (topic, Memc[HD_SBUF(hp)+HD_PAKNAME(hp)]))
+ next
+
+ # Extract the names of the modules in the package. Save the
+ # pointers in an array for the table print routine.
+
+ pp = 1
+ for (m=0; m < MAX_MENUSIZE; m=m+1) {
+ call salloc (Memi[pknm+m], MAX_NAMELEN, TY_CHAR)
+ if (hd_getname (hp, m+1, TY_MODNAME, Memc[Memi[pknm+m]],
+ MAX_NAMELEN) <= 0)
+ break
+
+ # Copy the names to the output array.
+ pp = pp + gstrcpy (Memc[Memi[pknm+m]], pkglist[pp], ARB)
+ if (XH_SHOWTYPE(xh) == YES && XH_STP(xh) != NULL) {
+ sym = stfind (XH_STP(xh), Memc[Memi[pknm+m]])
+ if (sym != NULL)
+ pp = pp + gstrcpy (".", pkglist[pp], ARB)
+ }
+ pp = pp + gstrcpy (" ", pkglist[pp], ARB)
+ }
+ break
+ }
+ }
+ if (pp != NULL)
+ pkglist[pp] = EOS
+
+ call hdb_free (db, hp)
+ call hdb_close (db)
+ call sfree (sp)
+ return (pp)
+end
+
+
+# XH_PKGPATH -- Get the package path associated with a particular task.
+# If we're given a parent package follow it back so we get the correct
+# path for a task that may be defined multiple places (e.g. SPLOT).
+
+procedure xh_pkgpath (xh, topic, curpack, path)
+
+pointer xh #i task struct pointer
+char topic[ARB] #i help topic
+char curpack[ARB] #i help topic
+char path[ARB] #o package path
+
+pointer sp, pkg, task, buf
+int strncmp(), xh_pkgname()
+bool streq()
+
+begin
+ call smark (sp)
+ call salloc (pkg, SZ_FNAME, TY_CHAR)
+ call salloc (task, SZ_FNAME, TY_CHAR)
+ call salloc (buf, SZ_FNAME, TY_CHAR)
+
+ if (curpack[1] == EOS ||
+ streq (topic, curpack) ||
+ strncmp ("root", curpack, 4) == 0 ||
+ streq ("clpackage", curpack)) {
+ call strcpy (topic, Memc[task], SZ_FNAME)
+ call strcpy (topic, path, SZ_FNAME)
+ } else {
+ call strcpy (curpack, Memc[task], SZ_FNAME)
+ call sprintf (path, SZ_PATHNAME, "%s.%s")
+ call pargstr (curpack)
+ call pargstr (topic)
+ }
+
+ Memc[pkg] = EOS
+ while (xh_pkgname (xh, Memc[task], Memc[pkg]) == OK) {
+ if (strncmp ("root", Memc[pkg], 4) == 0 ||
+ streq (Memc[task], Memc[pkg]) ||
+ streq ("clpackage", Memc[pkg]))
+ break
+ else {
+ call sprintf (Memc[buf], SZ_PATHNAME, "%s.%s")
+ call pargstr (Memc[pkg])
+ call pargstr (path)
+ call strcpy (Memc[buf], path, SZ_PATHNAME)
+ }
+ call strcpy (Memc[pkg], Memc[task], SZ_FNAME)
+ Memc[pkg] = EOS
+ }
+
+ call sfree (sp)
+end
+
+
+# XH_PKGNAME -- Get the package name associated with a particular task.
+
+int procedure xh_pkgname (xh, topic, pack)
+
+pointer xh #i task struct pointer
+char topic[ARB] #i help topic
+char pack[ARB] #o package
+
+pointer sp, line, fname
+long fsize, fstatl()
+int fd, status, getline(), open(), stridxs()
+
+begin
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (fname, SZ_LINE, TY_CHAR)
+
+ status = ERR
+
+ # Get a temp file name.
+ call mktemp ("tmp$xhelpi", Memc[fname], SZ_FNAME)
+
+ # Open a temp file with the help information found.
+ fd = open (Memc[fname], NEW_FILE, TEXT_FILE)
+ call xh_get_help (fd, topic, "", "", HF_HTML, HELPDB(xh),
+ "all", "files")
+ call close (fd)
+
+ # Open the results file for reading.
+ fd = open (Memc[fname], READ_ONLY, TEXT_FILE)
+ fsize = fstatl (fd, F_FILESIZE)
+
+ # Search the results for the package line.
+ if (fsize != 0) {
+ status = OK
+ while (getline (fd, Memc[line]) != EOF) {
+
+ # Extract the package name.
+ if (stridxs (":", Memc[line]) > 0) {
+ Memc[line+stridxs(".",Memc[line])-1] = EOS
+ call strcpy (Memc[line], pack, SZ_FNAME)
+ break
+ }
+ }
+ }
+
+ call close (fd) # clean up
+ call delete (Memc[fname])
+ call sfree (sp)
+
+ return (status)
+end
diff --git a/pkg/system/help/xhelp/xhprint.x b/pkg/system/help/xhelp/xhprint.x
new file mode 100644
index 00000000..4e273848
--- /dev/null
+++ b/pkg/system/help/xhelp/xhprint.x
@@ -0,0 +1,151 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <error.h>
+include <ctype.h>
+include <ttyset.h>
+include "../help.h"
+include "xhelp.h"
+
+
+# XH_PRINT_HELP -- Print the requested help topic.
+
+procedure xh_print_help (xh, topic, curpack, name)
+
+pointer xh #i task struct pointer
+char topic[ARB] #i help topic
+char curpack[ARB] #i current package
+char name[ARB] #i printer name
+
+int fd
+char fname[SZ_FNAME]
+
+int open()
+errchk open
+
+begin
+ # Open a temp file with the help information.
+ call mktemp ("tmp$xhelpi", fname, SZ_FNAME)
+ fd = open (fname, NEW_FILE, TEXT_FILE)
+ call xh_get_help (fd, topic, curpack, "", HF_PS, HELPDB(xh),
+ "all", OPTION(xh))
+ call close (fd)
+
+ call strcpy (name, PRINTER(xh), SZ_FNAME)
+ call xh_lprint (fname, PRINTER(xh))
+
+ # Clean up.
+ call delete (fname)
+end
+
+
+# XH_LPRINT -- Print a file or files on the lineprinter. TTYPUTLINE is used
+# to output lines to the printer file, so that formfeeds, standout mode, etc.,
+# may be properly translated for the indicated device.
+
+procedure xh_lprint (fname, device)
+
+char fname[ARB]
+char device[ARB]
+
+int out
+pointer sp, lp, ddstr
+
+pointer ttyodes()
+bool streq()
+int envgets(), lpopen(), ttygets()
+string printer "printer"
+errchk clgfil, xh_print_file
+
+begin
+ call smark (sp)
+ call salloc (ddstr, SZ_DDSTR, TY_CHAR)
+
+ # Get device name. Default is "printer", which means that the actual
+ # device name is given by the environment variable "printer".
+
+ if (streq (device, printer))
+ if (envgets (printer, device, SZ_FNAME) <= 0)
+ call syserrs (SYS_ENVNF, printer)
+
+ # Open TTY descriptor and printer file. We deal only with character
+ # data, so open printer as a text file. Output the files to the line
+ # printer device.
+
+ lp = ttyodes (device)
+ if (ttygets (lp, "DD", Memc[ddstr], SZ_DDSTR) <= 0)
+ call error (1, "missing 'DD' parameter in termcap entry")
+
+ out = lpopen (Memc[ddstr], APPEND, TEXT_FILE)
+
+ # Output file, followed by a form feed.
+ iferr {
+ call xh_print_file (out, lp, fname)
+ call flush (out)
+ } then
+ call erract (EA_WARN)
+
+ call close (out)
+ call ttycdes (lp)
+ call sfree (sp)
+end
+
+
+# XH_PRINT_FILE -- Open and print the named text file on the output file,
+# under control of the tty device descriptor LP. Print a header on each
+# page if enabled, and formfeed at the end of the file. The number of lines
+# per page is given by the tty descriptor.
+
+procedure xh_print_file (out, lp, fname)
+
+int out
+pointer lp
+char fname[ARB]
+
+bool one_tab_in
+int lineno, maxlines, status, in
+pointer sp, ip, lbuf
+int open(), getline(), ttystati()
+errchk salloc, open, ttystati, getline, ttyputline
+
+begin
+ call smark (sp)
+ call salloc (lbuf, SZ_LINE+1, TY_CHAR)
+
+ in = open (fname, READ_ONLY, TEXT_FILE)
+ maxlines = ttystati (lp, TTY_NLINES)
+
+ # If printer page is very wide, set page in one tabstop from left
+ # margin.
+
+ one_tab_in = (ttystati (lp, TTY_NCOLS) > WIDE_PAGE)
+ if (one_tab_in) {
+ Memc[lbuf] = '\t'
+ ip = lbuf + 1
+ } else
+ ip = lbuf
+
+
+ # Format and write each page of output. If headers are enabled,
+ # output formfeed and header between pages.
+
+ status = OK
+ while (status != EOF) {
+ # Output one page of text. Each output line is processed by
+ # ttyputline to expand tabs, underline, etc.
+
+ for (lineno=1; lineno <= maxlines; lineno=lineno+1) {
+ status = getline (in, Memc[ip])
+ if (status == EOF)
+ break
+ if (Memc[ip] == '\f') {
+ call ttyputline (out, lp, "\f", YES)
+ call strcpy (Memc[ip+1], Memc[ip], SZ_LINE)
+ }
+ call ttyputline (out, lp, Memc[lbuf], YES)
+ }
+ }
+
+ call close (in)
+ call sfree (sp)
+end
diff --git a/pkg/system/help/xhelp/xhqref.x b/pkg/system/help/xhelp/xhqref.x
new file mode 100644
index 00000000..51912169
--- /dev/null
+++ b/pkg/system/help/xhelp/xhqref.x
@@ -0,0 +1,250 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <syserr.h>
+include <finfo.h>
+include <ctype.h>
+include "../help.h"
+include "xhelp.h"
+
+define MAX_PKGS 200
+define SZ_PKG 32
+define EXTPKG "hlib$extern.pkg"
+
+
+# XH_UPDT_QUICKREF -- Update a quick reference file for the help database
+# if needed.
+
+procedure xh_updt_quickref (xh)
+
+pointer xh
+
+long fiq[LEN_FINFO], fie[LEN_FINFO]
+
+int access()
+long finfo()
+errchk access, finfo
+
+begin
+ # If the quickref file exists, and it is older than the
+ # hlib$extern.pkg file which defines the helpdb rebuild
+ # the quickref file so we're current, otherwise rebuild
+ # the quickref file anyway.
+ if ((access (QUICKREF(xh), 0, 0) == NO) ||
+ (access (PKGFILE, 0, 0) == NO)) {
+ call xh_make_quickref (xh, QUICKREF(xh))
+ } else {
+ if (finfo (QUICKREF(xh), fiq) == ERR)
+ call filerr (QUICKREF(xh), SYS_FOPNNEXFIL)
+ if (finfo (EXTPKG, fie) == ERR)
+ call filerr (EXTPKG, SYS_FOPNNEXFIL)
+
+ if (FI_MTIME[fie] > FI_MTIME[fiq]) {
+ call delete (QUICKREF(xh))
+ call xh_make_quickref (xh, QUICKREF(xh))
+ }
+ }
+end
+
+
+# XH_MAKE_QUICKREF -- Make a quick reference file for the help database.
+
+procedure xh_make_quickref (xh, quickref)
+
+pointer xh #i task struct pointer
+char quickref[ARB] #i quickref filename
+
+pointer pkglist, pp
+int fdi, fdo, fd_err
+int sz_pbuf, npkgs
+char fname[SZ_FNAME], efname[SZ_FNAME]
+char pkg[SZ_PKG], lastpkg[SZ_PKG], line[SZ_LINE]
+
+int open(), access(), getline(), gstrcpy(), strsearch(), strcmp()
+errchk open
+
+begin
+ # Tell the GUI we're actually busy doing something....
+ call gmsg (XH_GP(xh), "alert",
+ "Please wait,\ngenerating QuickRef file...")
+ call gflush (XH_GP(xh))
+
+ # Open the STDERR stream onto a dummy file to catch any
+ # "no help available" messages that may interfere with the
+ # textout GUI parameter.
+ call mktemp ("tmp$xerr", efname, SZ_FNAME)
+ fd_err = open (efname, NEW_FILE, TEXT_FILE)
+ call frediro (STDERR, fd_err)
+
+ # Open a temp file with the raw search information.
+ call mktemp ("tmp$xhelpq", fname, SZ_FNAME)
+ fdi = open (fname, NEW_FILE, TEXT_FILE)
+
+ call xh_get_help (fdi, "[a-z]*.", "", "", HF_HTML, HELPDB(xh), "help",
+ "references")
+ call close (fdi)
+
+ # Close the error file, swap back the descriptors first and delete it.
+ call fswapfd (STDERR, fd_err)
+ call close (fd_err)
+ call delete (efname)
+
+ # Delete existing files.
+ if (access (quickref, 0, 0) == YES)
+ call delete (quickref)
+
+ # Open the references file.
+ iferr (fdo = open (quickref, NEW_FILE, TEXT_FILE)) {
+ call sprintf (line, SZ_LINE, "Cannot create quickref file `%s'.")
+ call pargstr (quickref)
+ call error (0, line)
+ }
+ fdi = open (fname, READ_ONLY, TEXT_FILE)
+
+ # Initialize for the package list.
+ pkg[1] = EOS
+ lastpkg[1] = EOS
+ npkgs = 0
+ sz_pbuf = MAX_PKGS * SZ_PKG
+ call malloc (pkglist, sz_pbuf, TY_CHAR)
+ pp = pkglist
+
+ # Loop over the lines in the file, save the ones that are the
+ # descriptions. Descriptions are assumed to contain a '-' since
+ # this is standard for .men files, to be safe we also required
+ # the bracketed package name generated with a 'references' query.
+ # The package name is used to create the package list symtab we
+ # use to show the item as a task or package.
+
+ while (getline(fdi,line) != EOF) {
+ if (strsearch (line, " - ") != 0 && strsearch (line, "[") != 0) {
+ call putline (fdo, line)
+
+ # Extract the package name. The results aren't sorted at
+ # this point so we see whether this package is the same as
+ # the last before adding it to the package list. This
+ # gives us a unique list of unsorted package names.
+
+ call xh_gname (line, pkg)
+ if (lastpkg[1] == EOS)
+ call strcpy (pkg, lastpkg, SZ_PKG)
+ if (strcmp (pkg, lastpkg) != 0) {
+ npkgs = npkgs + 1
+
+ # Protect against overflowing the buffer.
+ if ((pp - pkglist) > sz_pbuf)
+ call error (1, "Package buffer overflow.")
+
+ pp = pp + gstrcpy (pkg, Memc[pp], SZ_PKG)
+ pp = pp + gstrcpy (" ", Memc[pp], SZ_PKG)
+ call strcpy (pkg, lastpkg, SZ_PKG)
+ }
+ }
+ }
+ Memc[pp] = EOS
+
+ # Close the new references file.
+ call close (fdo)
+
+ # Close and delete the references temp files.
+ call close (fdi)
+ call delete (fname)
+
+ # Sort the lines of the references file.
+ call xh_file_sort (quickref)
+
+ # Now send the package list off to be stored for the next time.
+ call xh_make_pkglist (Memc[pkglist])
+
+ call mfree (pkglist, TY_CHAR)
+
+ # Tell the GUI we're done.
+ call gmsg (XH_GP(xh), "alert", "dismiss")
+ call gflush (XH_GP(xh))
+end
+
+
+# XH_MAKE_PKGLIST -- Update the package symtab file. We are only called
+# when updating the quickref database so delete any existing file before
+# writing the new one.
+
+procedure xh_make_pkglist (list)
+
+char list[ARB] #i package list
+
+pointer sp, err, pkg
+pointer stp, sym
+int i, ip, fd
+
+pointer stopen(), stenter()
+int open(), access(), strlen()
+errchk open
+
+begin
+ call smark (sp)
+ call salloc (err, SZ_LINE, TY_CHAR)
+ call salloc (pkg, SZ_FNAME, TY_CHAR)
+
+ # Delete existing files.
+ if (access(PKGFILE,0,0) == YES)
+ call delete (PKGFILE)
+
+ # Open the package symtab file.
+ iferr (fd = open (PKGFILE, NEW_FILE, BINARY_FILE)) {
+ call sprintf (Memc[err], SZ_LINE, "Can't create pkg symtab `%s'.")
+ call pargstr (PKGFILE)
+ call error (0, Memc[err])
+ }
+
+ # Sort the list before making the symtab.
+ call xh_sort_list (list)
+
+ # Open the symtab.
+ stp = stopen ("package list", LEN_INDEX, LEN_STAB, SZ_SBUF)
+
+ # Enter strings in the symtab.
+ i = 0
+ for (ip=1; list[ip] != EOS; ip=ip+1) {
+ if (list[ip] == ' ') {
+ Memc[pkg+i] = EOS
+ sym = stenter (stp, Memc[pkg], strlen (Memc[pkg]) + 1)
+ i = 0
+ ip = ip + 1
+ }
+ Memc[pkg+i] = list[ip]
+ i = i + 1
+ }
+
+ # Save the symtab file.
+ call stsqueeze (stp)
+ call stsave (stp, fd)
+
+ # Clean up.
+ call stclose (stp)
+ call close (fd)
+ call sfree (sp)
+end
+
+
+# XH_GNAME -- Extract the package name from a 'references' line.
+
+procedure xh_gname (line, pkg)
+
+char line[ARB] #i references line
+char pkg[ARB] #o package name in line
+
+int ip, strlen()
+
+begin
+ # Clear trailing whitespace back to the ']' at end of the
+ # package name.
+ for (ip=strlen(line); line[ip] != ']' || IS_WHITE(line[ip]); )
+ ip = ip - 1
+ line[ip] = EOS
+
+ # Move back to starting '[' of package name.
+ while (line[ip] != '[' && ip > 0)
+ ip = ip - 1
+
+ # What's left is the package name, copy it to the output.
+ call strcpy (line[ip+1], pkg, SZ_PKG)
+end
diff --git a/pkg/system/help/xhelp/xhroot.x b/pkg/system/help/xhelp/xhroot.x
new file mode 100644
index 00000000..9559662a
--- /dev/null
+++ b/pkg/system/help/xhelp/xhroot.x
@@ -0,0 +1,73 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include "xhelp.h"
+
+
+# XH_ROOT_PKG -- Make the root package. Search the help database and
+# create a package list for all modules found. We add special entries for
+# system modules (imfort/math/os) which are not normally in the help tree
+# but provide documents.
+
+procedure xh_root_pkg (xh)
+
+pointer xh #i struct pointer.
+
+pointer sp, fname, buf, ip, op, lp
+int list
+
+int xh_pkglist()
+int gstrcpy(), fntopnb(), fntgfnb()
+bool strne()
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (buf, SZ_FNAME, TY_CHAR)
+
+ # Set initial packages and help databases. This consists of the
+ # system documentation (in sys$sys.hd), the contents of the
+ # clpackage module and each of the external packages.
+
+ lp = XH_LPTR(xh)
+
+ # Create an entry for seldom-read system docs.
+ if (XH_SHOWTYPE(xh) == YES) {
+ lp = lp + gstrcpy ("imfort. ", Memc[lp], ARB)
+ lp = lp + gstrcpy ("math. ", Memc[lp], ARB)
+ lp = lp + gstrcpy ("os. ", Memc[lp], ARB)
+ } else {
+ lp = lp + gstrcpy ("imfort ", Memc[lp], ARB)
+ lp = lp + gstrcpy ("math ", Memc[lp], ARB)
+ lp = lp + gstrcpy ("os ", Memc[lp], ARB)
+ }
+
+ # Add the external packages to the list.
+ list = fntopnb (HELPDB(xh), YES)
+ while (fntgfnb (list, Memc[fname], SZ_FNAME) != EOF) {
+ op = buf
+ ip = fname
+ while (Memc[ip] != '$' && Memc[ip] != EOS && Memc[ip] != ',') {
+ Memc[op] = Memc[ip]
+ ip = ip + 1
+ op = op + 1
+ }
+ Memc[op] = EOS
+ if (strne(Memc[buf],"lib")) {
+ lp = lp + gstrcpy (Memc[buf], Memc[lp], ARB)
+ if (XH_SHOWTYPE(xh) == YES)
+ lp = lp + gstrcpy (".", Memc[lp], ARB)
+ lp = lp + gstrcpy (" ", Memc[lp], ARB)
+ }
+ }
+
+ # Add the clpackage contents to the list.
+ lp = lp + xh_pkglist (xh, "clpackage", HELPDB(xh), Memc[lp])
+
+ if (lp > (XH_LPTR(xh) + SZ_HELPLIST))
+ call error (1, "Memory error: LIST pointer overflow.")
+
+ # Sort the list so it's presentable.
+ call xh_sort_list (LIST(xh))
+
+ call sfree (sp)
+end
diff --git a/pkg/system/help/xhelp/xhsave.x b/pkg/system/help/xhelp/xhsave.x
new file mode 100644
index 00000000..f280146d
--- /dev/null
+++ b/pkg/system/help/xhelp/xhsave.x
@@ -0,0 +1,184 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <ctype.h>
+include "../help.h"
+include "xhelp.h"
+
+define SZ_EXTN 10
+
+
+# XH_SAVE_FILE -- Save the currently displayed page to the named file in
+# the specified format.
+
+procedure xh_save_file (xh, iname, oname, format, overwrite)
+
+pointer xh #i package descriptor
+char iname[ARB] #i input file
+char oname[ARB] #i output filename
+char format[ARB] #i format
+int overwrite #i overwrite flag
+
+pointer sp, buf
+char extn[SZ_EXTN]
+
+int access(), fnextn(), strlen(), strcmp()
+
+begin
+ if (access (oname, 0, 0) == YES && overwrite == NO) {
+ call smark (sp)
+ call salloc (buf, SZ_LINE, TY_CHAR)
+ call sprintf (Memc[buf], SZ_LINE,
+ "Operation would overwrite\nexisting file '%s'")
+ call pargstr (oname)
+ call gmsg (XH_GP(xh), "alert", Memc[buf])
+ call sfree (sp)
+ return
+
+ } else if (access (oname, 0, 0) == YES)
+ call delete (oname)
+
+ call aclrc (extn, SZ_EXTN)
+
+ # Strip off any braces around the arguments that were put
+ # in by the Tcl script.
+ if (iname[1] == '{') {
+ call amovc (iname[2], iname, strlen(iname)-2)
+ iname[strlen(iname)-1] = EOS
+ }
+ if (oname[1] == '{') {
+ call amovc (oname[2], oname, strlen(oname)-2)
+ oname[strlen(oname)-1] = EOS
+ }
+
+ switch (format[1]) {
+ case 's': # source
+ call fcopy (iname, oname)
+ case 't': # text
+ if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0)
+ call xh_save_text (xh, iname, oname)
+ else
+ call fcopy (iname, oname)
+ case 'h': # html
+ if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0)
+ call xh_save_html (xh, iname, oname, YES)
+ else
+ call xh_save_html (xh, iname, oname, NO)
+ case 'p': # postscript
+ if (fnextn(iname, extn, 3) > 0 && strcmp("hlp", extn) == 0)
+ call xh_save_ps (xh, iname, oname, YES)
+ else
+ call xh_save_ps (xh, iname, oname, NO)
+ default:
+ call gmsg (XH_GP(xh), "alert", "Invalid format specifier")
+ }
+end
+
+
+# XH_SAVE_TEXT -- Save the page as a formatted text file.
+
+procedure xh_save_text (xh, in, out)
+
+pointer xh #i package descriptor
+char in[ARB], out[ARB] #i file names
+
+char err[SZ_LINE]
+int fdout, open()
+errchk open
+
+begin
+ # Open the output file.
+ iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) {
+ call sprintf (err, SZ_LINE, "Cannot open output file `%s'.")
+ call pargstr (out)
+ call gmsg (XH_GP(xh), "alert", err)
+ return
+ }
+
+ # Format the help as text.
+ call xh_get_help (fdout, "", "", in, HF_TEXT, HELPDB(xh), "all", "help")
+
+ # Close the file.
+ call close (fdout)
+end
+
+
+# XH_SAVE_HTML -- Save the page as an HTML file.
+
+procedure xh_save_html (xh, in, out, ishelp)
+
+pointer xh #i package descriptor
+char in[ARB], out[ARB] #i file names
+int ishelp #i is this a help file?
+
+char err[SZ_LINE]
+int fdout, fdin, open()
+errchk open
+
+begin
+ # Open the output file.
+ iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) {
+ call sprintf (err, SZ_LINE, "Cannot open output file `%s'.")
+ call pargstr (out)
+ call gmsg (XH_GP(xh), "alert", err)
+ return
+ }
+
+ # Format the help as text.
+ if (ishelp == YES) {
+ call xh_get_help (fdout, "", "", in, HF_HTML, HELPDB(xh),
+ "all", "help")
+ } else {
+ # Open the input file.
+ iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) {
+ call sprintf (err, SZ_LINE, "Cannot open output file `%s'.")
+ call pargstr (out)
+ call gmsg (XH_GP(xh), "alert", err)
+ return
+ }
+
+ call fprintf (out, "<HTML><BODY>\n")
+ call fprintf (out, "<TITLE>%s</TITLE>\n")
+ call pargstr (in)
+ call fprintf (out, "<PRE>\n")
+ call fcopyo (in, out)
+ call fprintf (out, "</PRE>\n")
+ call fprintf (out, "</BODY></HTML>\n")
+
+ call close (fdin)
+ }
+
+ # Close the file.
+ call close (fdout)
+end
+
+
+# XH_SAVE_PS -- Save the page as a postscript file.
+
+procedure xh_save_ps (xh, in, out, ishelp)
+
+pointer xh #i package descriptor
+char in[ARB], out[ARB] #i file names
+int ishelp #i is this a help file?
+
+char err[SZ_LINE]
+int fdout, open()
+errchk open
+
+begin
+ if (ishelp == NO)
+ return
+
+ # Open the output file.
+ iferr (fdout = open (out, NEW_FILE, TEXT_FILE)) {
+ call sprintf (err, SZ_LINE, "Cannot open output file `%s'.")
+ call pargstr (out)
+ call gmsg (XH_GP(xh), "alert", err)
+ return
+ }
+
+ # Format the help as text.
+ call xh_get_help (fdout, "", "", in, HF_PS, HELPDB(xh), "all", "help")
+
+ # Close the file.
+ call close (fdout)
+end
diff --git a/pkg/system/help/xhelp/xhsearch.x b/pkg/system/help/xhelp/xhsearch.x
new file mode 100644
index 00000000..18f1aa28
--- /dev/null
+++ b/pkg/system/help/xhelp/xhsearch.x
@@ -0,0 +1,185 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <fset.h>
+include <ctype.h>
+include "xhelp.h"
+
+
+# XH_SEARCH -- Given a search pattern generate a list of tasks matching the
+# pattern.
+
+procedure xh_search (xh, exact_match, pattern)
+
+pointer xh #i task struct pointer
+int exact_match #i require an exact match?
+char pattern[ARB] #i search pattern
+
+pointer sp, lfile, line, helpstr, item
+pointer tp, lp, pat
+char task[SZ_FNAME], pkg[SZ_FNAME], desc[SZ_FNAME]
+int i, ip, fd, fdl
+long fsize
+
+long fstatl()
+int open(), xh_match(), getline(), gstrcpy()
+errchk open, xh_updt_quickref
+
+begin
+ call smark (sp)
+ call salloc (lfile, SZ_FNAME, TY_CHAR)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (item, SZ_LINE, TY_CHAR)
+ call salloc (pat, SZ_FNAME, TY_CHAR)
+
+ # Open the quick reference file.
+ iferr (fd = open (QUICKREF(xh), READ_ONLY, TEXT_FILE))
+ call error (0, "Cannot open quick-reference file.")
+
+ # Open the temp file for the matched lines.
+ call mktemp ("tmp$xhelpq", Memc[lfile], SZ_FNAME)
+ fdl = open (Memc[lfile], NEW_FILE, TEXT_FILE)
+
+ # Allocate space for the results string.
+ fsize = fstatl (fd, F_FILESIZE)
+
+ # Check pattern for multi-word searches.
+ call aclrc (Memc[pat], SZ_FNAME)
+ for (ip=1; IS_WHITE(pattern[ip]); ip=ip+1)
+ ;
+ if (pattern[ip] == '{') {
+ ip = ip + 1
+ for (i=0; pattern[ip] != '}'; ip=ip+1) {
+ Memc[pat+i] = pattern[ip]
+ i = i + 1
+ }
+ } else
+ call strcpy (pattern[ip], Memc[pat], SZ_FNAME)
+
+ # Loop over the lines in the file and match the pattern.
+ while (getline(fd,Memc[line]) != EOF) {
+ if (xh_match (Memc[line], Memc[pat], exact_match) != 0)
+ call putline (fdl, Memc[line]) # save it to the file
+ }
+ call close (fdl)
+ call close (fd)
+
+ # Now read back the file to see if we matched anything, and so we
+ # can parse the file for task/package names.
+ fdl = open (Memc[lfile], READ_ONLY, TEXT_FILE)
+ fsize = fstatl (fdl, F_FILESIZE)
+
+ # See whether we got anything, if not return.
+ if (fsize == 0) {
+ call sprintf (Memc[line], SZ_LINE,
+ "No help available for\npattern `%s'.")
+ call pargstr (Memc[pat])
+ call gmsg (XH_GP(xh), "alert", Memc[line])
+
+ call close (fdl)
+ call delete (Memc[lfile])
+ call sfree (sp)
+ return
+ }
+ call calloc (helpstr, 5*fsize, TY_CHAR)
+
+ # Read back the sorted list, separate the task name, package, and
+ # descriptions and format it for the GUI.
+ tp = helpstr
+ tp = tp + gstrcpy ("<HTML><BODY><PRE>", Memc[tp], ARB)
+ while (getline(fdl, Memc[line]) != EOF) {
+ Memc[item] = EOS
+ lp = line
+
+ # Get the task name.
+ for (i=1; !IS_WHITE(Memc[lp]); i=i+1) {
+ task[i] = Memc[lp]
+ lp = lp + 1
+ if (Memc[lp] == EOS || i >= SZ_FNAME)
+ break
+ }
+ task[i] = EOS
+
+ # Skip delimiter.
+ while (IS_WHITE(Memc[lp]) || Memc[lp] == '-')
+ lp = lp + 1
+
+ # Get the description up to the '[' package name.
+ for (i=1; Memc[lp] != '['; i=i+1) {
+ desc[i] = Memc[lp]
+ lp = lp + 1
+ if (Memc[lp] == EOS || i >= SZ_FNAME)
+ break
+ }
+ desc[i] = EOS
+
+ # Get the package name up to the ']' delimiter.
+ if (Memc[lp] != EOS) {
+ lp = lp + 1
+ for (i=1; Memc[lp] != ']'; i=i+1) {
+ pkg[i] = Memc[lp]
+ lp = lp + 1
+ if (Memc[lp] == '\n' || Memc[lp] == EOS || i >= SZ_FNAME)
+ break
+ }
+ }
+ pkg[i] = EOS
+
+ call sprintf(Memc[item], SZ_LINE, "<A HREF=%s.%s>%10.10s</A> ")
+ call pargstr (pkg)
+ call pargstr (task)
+ call pargstr (task)
+ tp = tp + gstrcpy (Memc[item], Memc[tp], ARB)
+ call sprintf(Memc[item], SZ_LINE, "<A HREF=%s.%s>%10.10s</A> ")
+ call pargstr (pkg)
+ call pargstr (pkg)
+ call pargstr (pkg)
+ tp = tp + gstrcpy (Memc[item], Memc[tp], ARB)
+ call sprintf(Memc[item], SZ_LINE, " %s\n")
+ call pargstr (desc)
+ tp = tp + gstrcpy (Memc[item], Memc[tp], ARB)
+ }
+ call strcat ("</PRE></BODY></HTML>\n", Memc[tp], SZ_LINE)
+ Memc[tp] = EOS
+ call close (fdl)
+
+ # Send it to the GUI.
+ call gmsg (XH_GP(xh), "apropos", Memc[helpstr])
+
+ # Clean up.
+ call delete (Memc[lfile])
+ call mfree (helpstr, TY_CHAR)
+ call sfree (sp)
+end
+
+
+# XH_MATCH -- Match any or all words in a pattern against the given line.
+# We can either look for an exact match or just the occurence of one word
+# in the pattern.
+
+int procedure xh_match (line, pattern, exact_match)
+
+char line[ARB] #i line to be matched
+char pattern[ARB] #i pattern words
+int exact_match
+
+char word[SZ_FNAME]
+int i, j
+int strsearch()
+
+begin
+ if (exact_match == YES) {
+ return (strsearch(line, pattern))
+ } else {
+ # See if any word in the pattern matches in the line.
+ for (i=1; pattern[i] != EOS; i=i+1) {
+ for (j=1; pattern[i] != EOS && pattern[i] != ' '; j=j+1) {
+ word[j] = pattern[i]
+ i = i + 1
+ }
+ word[j] = EOS
+ if (strsearch(line, word) != 0)
+ return (YES)
+ }
+ return (NO)
+ }
+end
diff --git a/pkg/system/help/xhelp/xhsort.x b/pkg/system/help/xhelp/xhsort.x
new file mode 100644
index 00000000..b5ccc081
--- /dev/null
+++ b/pkg/system/help/xhelp/xhsort.x
@@ -0,0 +1,223 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <ctype.h>
+include "xhelp.h"
+
+define MAXPTR 20000
+define SZ_LINBUF 300000
+
+
+# XH_SORT_LIST -- Take a list of words (as with a package list) and sort them.
+
+procedure xh_sort_list (list)
+
+char list[ARB] #u list to be sorted
+
+pointer sp, index, buf, ip
+int i, j, count, len
+
+int strlen()
+
+begin
+ len = strlen (list)
+
+ call smark (sp)
+ call salloc (index, SZ_HELPLIST, TY_INT)
+ call salloc (buf, len+2, TY_CHAR)
+
+ # Build up the index array.
+ count = 1
+ Memi[index] = 1
+ for (i=2; i<len; i=i+1) {
+ if (list[i] == ' ') {
+ list[i] = EOS
+ Memi[index+count] = i + 1
+ count = count + 1
+ }
+ }
+
+ # Sort the list.
+ call strsrt (Memi[index], list, count)
+
+ # Restore the list.
+ ip = buf
+ do i = 1, count {
+ for (j=0; list[Memi[index+i-1]+j] != EOS; j=j+1) {
+ Memc[ip] = list[Memi[index+i-1]+j]
+ ip = ip + 1
+ }
+ Memc[ip] = ' '
+ ip = ip + 1
+ }
+ Memc[ip-1] = EOS
+ call strcpy (Memc[buf], list, strlen(Memc[buf]))
+ call sfree (sp)
+end
+
+
+# XH_FILE_SORT -- Sort the lines in the named file.
+
+procedure xh_file_sort (fname)
+
+char fname[SZ_FNAME] #i file to be sorted
+
+pointer linbuf, linptr
+int nlines, fd
+int open()
+
+begin
+ call calloc (linptr, MAXPTR, TY_INT)
+ call calloc (linbuf, SZ_LINBUF, TY_CHAR)
+
+ # Sort the file then write it back out.
+ fd = open (fname, READ_ONLY, TEXT_FILE)
+ call xh_gtext (fd, Memi[linptr], nlines, Memc[linbuf])
+ call close (fd)
+ call delete (fname)
+
+ call xh_quick (Memi[linptr], Memc[linbuf], nlines)
+
+ fd = open (fname, NEW_FILE, TEXT_FILE)
+ call xh_ptext (fd, Memi[linptr], nlines, Memc[linbuf])
+
+ call mfree (linbuf, TY_CHAR)
+ call mfree (linptr, TY_INT)
+ call close (fd)
+end
+
+
+# XH_GTEXT -- Get text lines into linbuf.
+
+procedure xh_gtext (infile, linptr, nlines, linbuf)
+
+int infile, linptr[ARB], nlines
+char linbuf[ARB]
+
+int lbp, len, getline()
+errchk getline
+
+begin
+ nlines = 0
+ lbp = 1
+
+ repeat {
+ len = getline (infile, linbuf[lbp])
+ if (len == EOF)
+ break
+ else if (len == 1)
+ # ignore blank lines
+ else {
+ nlines = nlines + 1
+ linptr[nlines] = lbp
+ lbp = lbp + len + 1 # '1' = room for EOS
+ }
+ } until (lbp >= SZ_LINBUF - SZ_LINE || nlines >= MAXPTR)
+end
+
+
+# XH_PTEXT -- Output text lines from linbuf to outfile.
+
+procedure xh_ptext (outfil, linptr, nlines, linbuf)
+
+int outfil, linptr[ARB], nlines
+char linbuf[ARB]
+int i, j
+errchk putline
+
+begin
+ for (i=1; i <= nlines; i=i+1) {
+ j = linptr[i]
+ call putline (outfil, linbuf[j])
+ }
+end
+
+
+# XH_QUICK -- Quicksort for text data. NOTE -- This algorithm is quadratic in
+# the worst case, i.e., when the data is already sorted. A random method of
+# selecting the pivot should be used to improve the behaviour on sorted arrays.
+
+procedure xh_quick (linptr, linbuf, nlines)
+
+int linptr[ARB] # indices of strings in buffer
+char linbuf[ARB] # string buffer
+int nlines # number of strings
+
+define LOGPTR 32
+define swap {temp=$1;$1=$2;$2=temp}
+
+int i, j, k, temp, lv[LOGPTR], p, pivlin, uv[LOGPTR]
+int xh_compare()
+
+begin
+ lv[1] = 1
+ uv[1] = nlines
+ p = 1
+
+ while (p > 0) {
+ if (lv[p] >= uv[p]) # only one elem in this subset
+ p = p - 1 # pop stack
+ else {
+ # Dummy loop to trigger optimizer.
+ do p = p, ARB {
+ i = lv[p] - 1
+ j = uv[p]
+
+ # Select pivot element at midpoint of interval to avoid
+ # quadratic behavior on a sorted list.
+
+ k = (lv[p] + uv[p]) / 2
+ swap (linptr[j], linptr[k])
+ pivlin = linptr[j]
+
+ while (i < j) {
+ for (i=i+1; xh_compare (linptr[i], pivlin, linbuf) < 0;
+ i=i+1)
+ ;
+ for (j=j-1; j > i; j=j-1)
+ if (xh_compare (linptr[j], pivlin, linbuf) <= 0)
+ break
+ if (i < j) # out of order pair
+ swap (linptr[i], linptr[j])
+ }
+
+ j = uv[p] # move pivot to position i
+ swap (linptr[i], linptr[j])
+
+ if (i-lv[p] < uv[p] - i) { # stack so shorter done first
+ lv[p+1] = lv[p]
+ uv[p+1] = i - 1
+ lv[p] = i + 1
+ } else {
+ lv[p+1] = i + 1
+ uv[p+1] = uv[p]
+ uv[p] = i - 1
+ }
+
+ break
+ }
+
+ p = p + 1 # push onto stack
+ }
+ }
+end
+
+
+# XH_COMPARE -- Compare two strings. Return -1 if str1<str2, 1 if str1>str2,
+# or 0 if the two strings are equal.
+
+int procedure xh_compare (lp1, lp2, linbuf)
+
+int lp1, lp2 # pointers to substrings in linbuf
+char linbuf[ARB] # text buffer
+
+int ip1, ip2, answer
+int strcmp()
+
+begin
+ for (ip1=lp1; IS_WHITE(linbuf[ip1]); ip1=ip1+1)
+ ;
+ for (ip2=lp2; IS_WHITE(linbuf[ip2]); ip2=ip2+1)
+ ;
+ answer = strcmp (linbuf[ip1], linbuf[ip2])
+ return (answer)
+end
diff --git a/pkg/system/help/xhelp/zzdebug.x b/pkg/system/help/xhelp/zzdebug.x
new file mode 100644
index 00000000..70a95d9b
--- /dev/null
+++ b/pkg/system/help/xhelp/zzdebug.x
@@ -0,0 +1,59 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+
+# ZZDEBUG.X -- Debug routines for the help formatting system.
+
+task lroff2html = t_lroff2html,
+ lroff2ps = t_lroff2ps
+
+
+# LROFF2HTML -- Test program to convert an Lroff source file to HTML.
+
+procedure t_lroff2html ()
+
+int fdi, fdo
+char iname[SZ_FNAME], oname[SZ_FNAME]
+
+int open()
+errchk open
+
+begin
+ call clgstr ("input", iname, SZ_FNAME) # get parameters
+ call clgstr ("output", oname, SZ_FNAME)
+
+ fdi = open (iname, READ_ONLY, TEXT_FILE) # open the file
+ fdo = open (oname, NEW_FILE, TEXT_FILE)
+
+ # Process it.
+ call lroff2html (fdi, fdo, iname, "", "", "", "")
+
+ call close (fdi)
+ call close (fdo)
+end
+
+
+# LROFF2PS -- Test program to convert an Lroff source file to Postscript.
+
+procedure t_lroff2ps ()
+
+int fdi, fdo
+char iname[SZ_FNAME], oname[SZ_FNAME]
+
+pointer ps
+int open()
+errchk open
+
+begin
+ call clgstr ("input", iname, SZ_FNAME) # get parameters
+ call clgstr ("output", oname, SZ_FNAME)
+
+ fdi = open (iname, READ_ONLY, TEXT_FILE) # open the files
+ fdo = open (oname, READ_ONLY, TEXT_FILE)
+
+ # Process it.
+ ps = NULL
+ call lroff2ps (fdi, fdo, ps, "", "")
+
+ call close (fdi)
+ call close (fdo)
+end