aboutsummaryrefslogtreecommitdiff
path: root/pkg/utilities/nttools/tedit
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/utilities/nttools/tedit')
-rw-r--r--pkg/utilities/nttools/tedit/bell.x19
-rw-r--r--pkg/utilities/nttools/tedit/command.com6
-rw-r--r--pkg/utilities/nttools/tedit/command.h21
-rw-r--r--pkg/utilities/nttools/tedit/command.x1458
-rw-r--r--pkg/utilities/nttools/tedit/display/curses.h86
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/README387
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/addch.x30
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/addstr.x157
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/bindstruct.x35
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/box.x56
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/clear.x35
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/clearok.x21
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/clrtobot.x56
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/clrtoeol.x45
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/delch.x41
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/deleteln.x41
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/delwin.x42
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/echo.x23
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/endwin.x34
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/erase.x37
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/freescreen.x13
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/getch.x53
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/getscreen.x48
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/getstr.x317
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/getstruct.x27
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/getyx.x22
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/hidewin.x40
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/inch.x49
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/initscr.x33
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/insch.x51
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/insertln.x41
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/leaveok.x21
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/mkpkg49
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/move.x39
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/mvwin.x63
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/mvword.x56
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/newwin.x83
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/omkpkg65
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/putscreen.x84
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/refresh.x42
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/savewin.x23
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/scrollok.x21
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/showwin.x39
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/standout.x48
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/wdimen.x45
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/window.com7
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/window.h28
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/winstat.x51
-rw-r--r--pkg/utilities/nttools/tedit/display/curses/wslide.x91
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/README115
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmbegin.x20
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmcheck.x98
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmend.x12
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmgetform.x89
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmhelp.x132
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmmkform.x82
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmprompt.x70
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/fmredraw.x69
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/formfn.h20
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/formfn.x278
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/forms.com5
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/linefn.h8
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/linefn.x134
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/mkpkg19
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/promptfn.h7
-rw-r--r--pkg/utilities/nttools/tedit/display/forms/promptfn.x134
-rw-r--r--pkg/utilities/nttools/tedit/display/mkpkg14
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/README211
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kbegin.x40
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kcompile.x148
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kconvert.x61
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kdoline.x96
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kend.x49
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kget.x96
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/khelp.x61
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/kpushbk.x11
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/mkpkg32
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psbeep.x9
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psbegin.x59
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psend.x48
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psfill.x135
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psheight.x12
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psintersect.x27
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psscreen.x14
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pssendcap.x74
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pssetcur.x117
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/psslide.x182
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pssynch.x12
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pswidth.x12
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pswrite.x79
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/pswrtcells.x114
-rw-r--r--pkg/utilities/nttools/tedit/display/screen/screen.com18
-rw-r--r--pkg/utilities/nttools/tedit/edit.x70
-rw-r--r--pkg/utilities/nttools/tedit/field.h23
-rw-r--r--pkg/utilities/nttools/tedit/field.x749
-rw-r--r--pkg/utilities/nttools/tedit/mkpkg27
-rw-r--r--pkg/utilities/nttools/tedit/paste.h6
-rw-r--r--pkg/utilities/nttools/tedit/paste.x142
-rw-r--r--pkg/utilities/nttools/tedit/prompt.x225
-rw-r--r--pkg/utilities/nttools/tedit/screen.h18
-rw-r--r--pkg/utilities/nttools/tedit/screen.x699
-rw-r--r--pkg/utilities/nttools/tedit/substitute.x372
-rw-r--r--pkg/utilities/nttools/tedit/table.h22
-rw-r--r--pkg/utilities/nttools/tedit/table.x312
-rw-r--r--pkg/utilities/nttools/tedit/tedit.key23
-rw-r--r--pkg/utilities/nttools/tedit/tedit.x33
-rw-r--r--pkg/utilities/nttools/tedit/tread.x31
-rw-r--r--pkg/utilities/nttools/tedit/window.com8
-rw-r--r--pkg/utilities/nttools/tedit/window.x246
109 files changed, 10208 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/tedit/bell.x b/pkg/utilities/nttools/tedit/bell.x
new file mode 100644
index 00000000..dd939e4e
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/bell.x
@@ -0,0 +1,19 @@
+# RING_BELL -- Ring the bell to wake up the user
+
+procedure ring_bell ()
+
+bool silent # i: do not ring bell
+#--
+bool ring # variable used to hold the value of silent
+
+begin
+ if (ring)
+ call ps_beep
+ return
+
+ entry init_bell (silent)
+
+ ring = ! silent
+ return
+
+end
diff --git a/pkg/utilities/nttools/tedit/command.com b/pkg/utilities/nttools/tedit/command.com
new file mode 100644
index 00000000..391c025e
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/command.com
@@ -0,0 +1,6 @@
+# COMMAND.COM -- Global variables used by commands
+
+int direction # Search direction
+char search_exp[SZ_LINE] # Search expression
+
+common /search/ direction, search_exp
diff --git a/pkg/utilities/nttools/tedit/command.h b/pkg/utilities/nttools/tedit/command.h
new file mode 100644
index 00000000..5e4956f1
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/command.h
@@ -0,0 +1,21 @@
+# COMMAND.H -- Commands which can be executed from the prompt line
+
+define TED_CMDLIST "|add|copy|delete|exit|find|goto|help|insert|lower|next|\
+quit|set|substitute|upper|"
+
+define TED_ADD 1
+define TED_COPY 2
+define TED_DELETE 3
+define TED_EXIT 4
+define TED_FIND 5
+define TED_GOTO 6
+define TED_HELP 7
+define TED_INSERT 8
+define TED_LOWER 9
+define TED_NEXT 10
+define TED_QUIT 11
+define TED_SET 12
+define TED_SUBSTITUTE 13
+define TED_UPPER 14
+
+
diff --git a/pkg/utilities/nttools/tedit/command.x b/pkg/utilities/nttools/tedit/command.x
new file mode 100644
index 00000000..185ad103
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/command.x
@@ -0,0 +1,1458 @@
+include <tbset.h>
+include "screen.h"
+include "table.h"
+include "paste.h"
+include "field.h"
+include "command.h"
+
+define BLANK ' '
+define SQUOTE '\''
+define DQUOTE '"'
+define HARMLESS 0.11
+define MAXROWS 10000
+
+# ADD_CMD -- Add a column or row to the table
+
+procedure add_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int which, iarg
+pointer sp, what, tab
+
+string options "|row|column|"
+string notadded "Cannot add column to table"
+
+int strdic(), option_cmd()
+
+begin
+ call smark (sp)
+ call salloc (what, SZ_LINE, TY_CHAR)
+
+ tab = TED_TABLE(scr)
+
+ # Determine whether a row or column should be added
+
+ which = option_cmd (options, nargs, arglist)
+
+ while (which == 0) {
+ iarg = nargs + 1
+ call getstr_cmd ("Add row or column", iarg, nargs, arglist,
+ Memc[what], SZ_LINE)
+ which = strdic (Memc[what], Memc[what], SZ_LINE, options)
+ }
+
+ # Call the appropriate routine
+
+ if (which == 1) {
+ call addrow_cmd (scr, nargs, arglist)
+
+ } else if (TED_ALLCOLS(tab) == YES) {
+ call addcol_cmd (scr, nargs, arglist)
+
+ } else {
+ call warn1_prompt (scr, notadded)
+ }
+
+ call sfree (sp)
+end
+
+# ADDCOL_CMD -- Add a new column to the table
+
+procedure addcol_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int iarg, type, icol, ncol, code, clen
+pointer sp, cname, cunits, ftnfmt, sppfmt, ctype, errmsg
+pointer tab, paste, tp, cp
+
+string nowrite "Cannot change read only table"
+string nullcol "No column added to table"
+string nocolumn "Cannot add column"
+string nopaste "Could not add column to paste table"
+
+int errget(), tbcigi(), strlen()
+pointer tbcnum()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (cname, SZ_COLNAME, TY_CHAR)
+ call salloc (cunits, SZ_COLUNITS, TY_CHAR)
+ call salloc (ftnfmt, SZ_COLFMT, TY_CHAR)
+ call salloc (sppfmt, SZ_COLFMT, TY_CHAR)
+ call salloc (ctype, SZ_FNAME, TY_CHAR)
+ call salloc (errmsg, SZ_LINE, TY_CHAR)
+
+ # Get table descriptors from screen structure
+
+ paste = TED_PASTE(scr)
+ tp = TED_TABPTR(tab)
+
+ # Get parameters defining new column
+
+ call getstr_cmd ("Column name", 2, nargs, arglist,
+ Memc[cname], SZ_COLNAME)
+
+ if (Memc[cname] == EOS) {
+ call write_prompt (scr, NO, nullcol)
+ return
+ }
+
+ iarg = 3
+ repeat {
+ call getstr_cmd ("Column type (r,d,i,s,b,ch*n)", iarg, nargs,
+ arglist, Memc[ctype], SZ_FNAME)
+
+ iferr (call tbbtyp (Memc[ctype], type)) {
+ iarg = nargs + 1
+ call ring_bell
+ } else {
+ break
+ }
+ }
+
+ iarg = 4
+ repeat {
+ call getstr_cmd ("Column print format", iarg, nargs, arglist,
+ Memc[ftnfmt], SZ_COLFMT)
+ call tbbftp (Memc[ftnfmt], Memc[sppfmt])
+
+ if (Memc[sppfmt] == EOS && Memc[ftnfmt] != EOS) {
+ iarg = nargs + 1
+ call ring_bell
+ } else {
+ break
+ }
+ }
+
+ call getstr_cmd ("Column units", 5, nargs, arglist,
+ Memc[cunits], SZ_COLUNITS)
+
+ # Add new column to paste table
+
+ if (paste != NULL) {
+ iferr {
+ call tbcdef (TED_PSTPTR(paste), cp, Memc[cname], Memc[cunits],
+ Memc[sppfmt], type, 1, 1)
+ } then {
+ call warn1_prompt (scr, nopaste)
+ return
+ }
+ }
+
+ # Add new column to table
+
+ iferr {
+ call tbcdef (tp, cp, Memc[cname], Memc[cunits],
+ Memc[sppfmt], type, 1, 1)
+ } then {
+ code = errget (Memc[errmsg], SZ_LINE)
+ call warn2_prompt (scr, nocolumn, Memc[errmsg])
+ return
+ }
+
+ # Free old arrays containing table info and create new ones
+
+ ncol = TED_NCOLS(tab) + 1
+ call mfree (TED_COLARY(tab), TY_INT)
+ call mfree (TED_TYPARY(tab), TY_INT)
+ call mfree (TED_LENARY(tab), TY_INT)
+
+ call malloc (TED_COLARY(tab), ncol, TY_INT)
+ call malloc (TED_TYPARY(tab), ncol, TY_INT)
+ call malloc (TED_LENARY(tab), ncol, TY_INT)
+
+ # Load new column info into arrays
+
+ TED_DIRTY(tab) = YES
+ TED_NCOLS(tab) = ncol
+ do icol = 1, ncol {
+ cp = tbcnum (tp, icol)
+ TED_COLPTR(tab, icol) = cp
+ TED_COLTYPE (tab,icol) = tbcigi (cp, TBL_COL_DATATYPE)
+ clen = tbcigi (cp, TBL_COL_FMTLEN)
+ call tbcigt (cp, TBL_COL_NAME, Memc[cname], SZ_COLNAME)
+ TED_COLLEN(tab,icol) = max (clen, strlen(Memc[cname]))
+ }
+
+ # Redraw screen
+
+ call move_screen (scr, LEFT, YES)
+ call sfree (sp)
+end
+
+# ADDROW_CMD -- Add null rows to the table
+
+procedure addrow_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int nrow, row, numadd
+pointer tab, tptr
+
+string nowrite "Cannot change read only table"
+
+int tbpsta()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Get current number of rows in the table
+
+ tptr = TED_TABPTR(tab)
+ nrow = tbpsta (tptr ,TBL_NROWS)
+
+ # Read command parameters
+
+ call getint_cmd ("Add after row", 2, nargs, arglist,
+ TED_CURROW(scr), 0, nrow, row)
+
+ call getint_cmd ("Number of rows to add", 3, nargs, arglist,
+ 1, 0, INDEFI, numadd)
+
+ # Return if number of rows to add is zero
+
+ if (numadd == 0)
+ return
+
+ # Add null rows to table
+
+ TED_DIRTY(tab) = YES
+ if (row == nrow) {
+ call tbtwer (tptr, row+numadd)
+
+ } else {
+ call tbrsft (tptr, row, numadd)
+ call tbrnll (tptr, row+1, row+numadd)
+ }
+
+ # Reset label width if table has grown a lot
+
+ TED_LABWIDTH(tab) = log10 (real(nrow + numadd + 1000)) + 1.0
+ TED_LABWIDTH(tab) = max (6, TED_LABWIDTH(tab))
+
+ # Redraw screen
+
+ if (row <= TED_HIROW(scr))
+ call move_screen (scr, LEFT, YES)
+
+end
+
+# COPY_CMD -- Copy a range of lines to the paste buffer
+
+procedure copy_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+bool append
+int nrow, first, last, irow, orow, ncopy
+pointer tab, paste
+
+int tbpsta(), option_cmd()
+pointer opn_paste()
+
+begin
+ tab = TED_TABLE(scr)
+ paste = TED_PASTE(scr)
+ nrow = tbpsta (TED_TABPTR(tab) ,TBL_NROWS)
+
+ # Open paste buffer if not yet open
+
+ if (paste == NULL) {
+ paste = opn_paste (scr)
+ if (paste == NULL)
+ return
+ }
+
+ # Read copy command parameters
+
+ append = option_cmd ("|append|", nargs, arglist) != 0
+
+ call getint_cmd ("First row to copy", 2, nargs, arglist,
+ TED_CURROW(scr), 1, nrow, first)
+ call getint_cmd ("Last row to copy", 3, nargs, arglist,
+ TED_CURROW(scr), 1, nrow, last)
+
+ if (first < last) {
+ irow = first
+ ncopy = last - first + 1
+ } else {
+ irow = last
+ ncopy = first - last + 1
+ }
+
+ if (append) {
+ orow = TED_PSTROWS(paste) + 1
+ TED_PSTROWS(paste) = TED_PSTROWS(paste) + ncopy
+ } else {
+ orow = 1
+ TED_PSTROWS(paste) = ncopy
+ }
+
+ call move_paste (TED_TABPTR(tab), TED_PSTPTR(paste), irow, orow, ncopy)
+
+end
+
+# COUNT_CMD -- Count the number of words in a string
+
+int procedure count_cmd (str)
+
+char str[ARB] # i: String containing words
+#--
+char ch
+int count, ic
+
+begin
+ # The absolute value of count is the number of the current
+ # word of the string, count is negative if we are currently
+ # between words.
+
+ count = 0
+
+ # Loop over all characters in the string
+
+ for (ic = 1 ; str[ic] != EOS; ic = ic + 1) {
+ ch = str[ic]
+
+ if (count > 0) {
+ if (ch <= ' ')
+ count = - count
+
+ } else if (ch > ' ') {
+ count = - count + 1
+ }
+ }
+
+ return (abs(count))
+end
+
+# DELETE_CMD -- Delete a range of lines, copy them to the paste buffer
+
+procedure delete_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+bool append
+int nrow, first, last, irow, orow, ncopy
+pointer tab, tptr, paste
+
+string nowrite "Cannot change read only table"
+
+int tbpsta(), option_cmd()
+pointer opn_paste()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ tptr = TED_TABPTR(tab)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Get paste table
+
+ paste = TED_PASTE(scr)
+ nrow = tbpsta (tptr ,TBL_NROWS)
+
+ if (paste == NULL) {
+ paste = opn_paste (scr)
+ if (paste == NULL)
+ return
+ }
+
+ # Read command parameters
+
+ append = option_cmd ("|append|", nargs, arglist) != 0
+
+ call getint_cmd ("First row to delete", 2, nargs, arglist,
+ TED_CURROW(scr), 1, nrow, first)
+ call getint_cmd ("Last row to delete", 3, nargs, arglist,
+ TED_CURROW(scr), 1, nrow, last)
+
+ if (first < last) {
+ irow = first
+ } else {
+ irow = last
+ last = first
+ first = irow
+ }
+
+ # Copy deleted rows to paste table, then delete from original table
+
+ ncopy = last - first + 1
+
+ if (append) {
+ orow = TED_PSTROWS(paste) + 1
+ TED_PSTROWS(paste) = TED_PSTROWS(paste) + ncopy
+ } else {
+ orow = 1
+ TED_PSTROWS(paste) = ncopy
+ }
+
+ call move_paste (tptr, TED_PSTPTR(paste), irow, orow, ncopy)
+ call tbrdel (tptr, first, last)
+ TED_DIRTY(tab) = YES
+
+ # Add single blank row if all rows were deleted
+
+ nrow = nrow - ncopy
+ if (nrow < 1) {
+ nrow = 1
+ call tbtwer (tptr, 1)
+ }
+
+ # Set current row number and redraw screen
+
+ if (TED_CURROW(scr) >= first && TED_CURROW(scr) <= last)
+ TED_CURROW(scr) = max (1, first-1)
+
+ TED_CURROW(scr) = min (TED_CURROW(scr), nrow)
+
+ if (first <= TED_HIROW(scr))
+ call move_screen (scr, LEFT, YES)
+
+end
+
+# EXIT_CMD -- Process the exit command
+
+procedure exit_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int iscr
+pointer scr2
+
+int get_window()
+
+begin
+ for (iscr = 1; get_window (iscr, scr2) != EOF; iscr = iscr + 1)
+ call del_screen (scr2, YES)
+
+end
+
+# FIND_CMD -- Find the row which makes the expression true
+
+procedure find_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+include "command.com"
+
+int first, last, row
+pointer tab
+
+string badexpr "Syntax error"
+string blankexp "No expression given"
+string notfound "No rows matched expression"
+
+int tbpsta(), option_cmd(), count_cmd(), tbl_search()
+
+begin
+ tab = TED_TABLE(scr)
+
+ # Get arguments of find command
+
+ direction = option_cmd ("|forward|backwards|", nargs, arglist)
+ if (direction == 0)
+ direction = 1
+
+ call getstr_cmd ("Find expression", 2, nargs, arglist,
+ search_exp, SZ_LINE)
+
+ if (count_cmd (search_exp) == 0) {
+ call warn1_prompt (scr, blankexp)
+ search_exp[1] = EOS
+ return
+ }
+
+ # Set limits for search
+
+ if (direction == 2) {
+ first = TED_CURROW(scr)
+ last = 1
+ } else {
+ first = TED_CURROW(scr)
+ last = tbpsta (TED_TABPTR(tab) ,TBL_NROWS)
+ }
+
+ # Perform search and report results
+
+ row = tbl_search (TED_TABPTR(tab), search_exp, first, last)
+
+ if (row == ERR) { # syntax error
+ # Redraw screen to hide error message from evexpr()
+ call move_screen (scr, LEFT, YES)
+ call warn2_prompt (scr, badexpr, search_exp)
+ search_exp[1] = EOS
+
+ } else if (row == 0) { # row not found
+ call write_prompt (scr, NO, notfound)
+
+ } else { # row found, update screen descriptor
+ TED_CURROW(scr) = row
+ }
+
+end
+
+# FUNC_CMD -- Change a single column using a function
+
+procedure func_cmd (scr, nargs, arglist, func)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+extern func # i: Function which modifies a string in place
+#--
+int col, irow, nrow, len
+pointer sp, defcol, colstr, tab, cptr, tptr
+
+string nowrite "Cannot change read only table"
+string numeric "Cannot change numeric column"
+
+int tbpsta()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (defcol, SZ_COLNAME, TY_CHAR)
+
+ # Get name of column
+
+ cptr = TED_COLPTR(tab, TED_CURCOL(scr))
+ call tbcigt (cptr, TBL_COL_NAME, Memc[defcol], SZ_COLNAME)
+
+ call getcol_cmd ("Column to change", 2, nargs, arglist, tab,
+ Memc[defcol], col)
+
+ # Make sure it's a string column
+
+ if (TED_COLTYPE(tab,col) > 0) {
+ call warn1_prompt (scr, numeric)
+
+ } else {
+
+ # Allocate array to hold field
+
+ len = - TED_COLTYPE(tab,col)
+ call salloc (colstr, len, TY_CHAR)
+
+ # Get current number of rows in the table
+
+ tptr = TED_TABPTR(tab)
+ cptr = TED_COLPTR(tab, col)
+ nrow = tbpsta (tptr ,TBL_NROWS)
+
+ # Retrieve each field and convert case
+
+ TED_DIRTY(tab) = YES
+ do irow = 1, nrow {
+ call tbegtt (tptr, cptr, irow, Memc[colstr], len)
+ call func (Memc[colstr])
+ call tbeptt (tptr, cptr, irow, Memc[colstr])
+ }
+ }
+
+ # Redraw screen if column is displayed
+
+ if (col >= TED_LOCOL(scr) && col <= TED_HICOL(scr))
+ call move_screen (scr, LEFT, YES)
+
+ call sfree (sp)
+
+end
+
+# GETCOL_CMD -- Get a column name from the argument list
+
+procedure getcol_cmd (argname, index, nargs, arglist, tab, defcol, icol)
+
+char argname[ARB] # i: Argument name (used as prompt if not found)
+int index # i: Index to string within argument list
+int nargs # i: Number of arguments in list
+char arglist[ARB] # i: List of arguments, separated by EOS characters
+pointer tab # i: Table descriptor
+char defcol[ARB] # i: Default column name (or EOS)
+int icol # o: Column number
+#--
+int ic, ncol, jcol, iarg, junk
+pointer sp, cname, cprompt, colptr[1]
+
+int ctoi()
+
+begin
+ # Allocate memory for temporary strings
+
+ call smark (sp)
+ call salloc (cname, SZ_COLNAME, TY_CHAR)
+ call salloc (cprompt, SZ_LINE, TY_CHAR)
+
+ # Get the string containing the column name
+
+ if (defcol[1] == EOS) {
+ call strcpy (argname, Memc[cprompt], SZ_LINE)
+ } else {
+ call sprintf (Memc[cprompt], SZ_LINE, "%s (%s)")
+ call pargstr (argname)
+ call pargstr (defcol)
+ }
+
+ call getstr_cmd (Memc[cprompt], index, nargs, arglist,
+ Memc[cname], SZ_COLNAME)
+
+ if (Memc[cname] == EOS)
+ call strcpy (defcol, Memc[cname], SZ_COLNAME)
+
+ # Loop until valid column name found
+
+ icol = 0
+ while (icol == 0) {
+ colptr[1] = NULL
+ Memc[cprompt] = EOS
+
+ # Get a column pointer from the column template
+
+ iferr {
+ call tctexp (TED_TABPTR(tab), Memc[cname], 1, ncol, colptr)
+ } then {
+ # More than one column matches the name
+ call strcpy ("Ambiguous column name. ", Memc[cprompt], SZ_LINE)
+
+ } else {
+ # If one name matched, check against list of column pointers
+
+ if (ncol == 1) {
+ for (jcol = 1; jcol <= TED_NCOLS(tab); jcol = jcol + 1) {
+ if (colptr[1] == TED_COLPTR(tab,jcol)) {
+ icol = jcol
+ break
+ }
+ }
+ }
+
+ # Convert name to number, see if number is within range
+
+ if (icol == 0) {
+ ic = 1
+ junk = ctoi (Memc[cname], ic, icol)
+
+ if (Memc[cname+ic-1] != EOS)
+ icol = 0
+ else if (icol < 1 || icol > TED_NCOLS(tab))
+ icol = 0
+ }
+
+ if (icol == 0)
+ call strcpy ("Column not found. ", Memc[cprompt], SZ_LINE)
+ }
+
+ # If column not matched, read new name interactively
+
+ if (icol == 0) {
+ iarg = nargs + 1
+ call strcat (argname, Memc[cprompt], SZ_LINE)
+
+ call getstr_cmd (Memc[cprompt], iarg, nargs, arglist,
+ Memc[cname], SZ_FNAME)
+
+ if (Memc[cname] == EOS)
+ call strcpy (defcol, Memc[cname], SZ_COLNAME)
+ }
+ }
+
+ call sfree (sp)
+end
+
+# GETINT_CMD -- Get an integer from the argument list
+
+procedure getint_cmd (argname, index, nargs, arglist, defval,
+ minval, maxval, value)
+
+char argname # i: Argument name (used as prompt if not found)
+int index # i: Index to string within argument list
+int nargs # i: Number of arguments in list
+char arglist[ARB] # i: List of arguments, separated by EOS characters
+int defval # i: Default legal value (or INDEFI)
+int minval # i: Minimum legal value (or INDEFI)
+int maxval # i: Maximum legal value (or INDEFI)
+int value # o: Output value
+#--
+int ic, iarg, junk
+pointer sp, valstr, prompt
+
+string typemsg "Please enter a number. "
+string rangemsg "Out of range (%d - %d). "
+
+int ctoi()
+
+begin
+ # Allocate memory for temporary strings
+
+ call smark (sp)
+ call salloc (valstr, SZ_FNAME, TY_CHAR)
+ call salloc (prompt, SZ_LINE, TY_CHAR)
+
+ # Get the string representing the value
+
+ if (IS_INDEFI (defval)) {
+ call strcpy (argname, Memc[prompt], SZ_LINE)
+ } else {
+ call sprintf (Memc[prompt], SZ_LINE, "%s (%d)")
+ call pargstr (argname)
+ call pargi (defval)
+ }
+
+ call getstr_cmd (Memc[prompt], index, nargs, arglist,
+ Memc[valstr], SZ_FNAME)
+
+ if (Memc[valstr] == EOS) {
+ value = defval
+ } else {
+ ic = 1
+ junk = ctoi (Memc[valstr], ic, value)
+ if (Memc[valstr+ic-1] != EOS)
+ value = INDEFI
+ }
+
+ # Loop until valid value is found
+
+ repeat {
+ if (IS_INDEFI(value)) {
+ call strcpy (typemsg, Memc[prompt], SZ_LINE)
+
+ } else if ((value < minval && ! IS_INDEFI (minval)) ||
+ (value > maxval && ! IS_INDEFI (maxval)) ) {
+ call sprintf (Memc[prompt], SZ_LINE, rangemsg)
+ call pargi (minval)
+ call pargi (maxval)
+
+ } else {
+ break
+ }
+
+ # If the string was not valid, get the value interactively
+
+ iarg = nargs + 1
+ call strcat (argname, Memc[prompt], SZ_LINE)
+
+ call getstr_cmd (Memc[prompt], iarg, nargs, arglist,
+ Memc[valstr], SZ_FNAME)
+
+ ic = 1
+ junk = ctoi (Memc[valstr], ic, value)
+ if (Memc[valstr+ic-1] != EOS)
+ value = INDEFI
+ }
+
+ call sfree (sp)
+end
+
+# GETSTR_CMD -- Get a string from the command argument list
+
+procedure getstr_cmd (argname, index, nargs, arglist, str, maxch)
+
+char argname # i: Argument name (used as prompt if not found)
+int index # i: Index to string within argument list
+int nargs # i: Number of arguments in list
+char arglist[ARB] # i: List of arguments, separated by EOS characters
+char str[ARB] # o: Output string
+int maxch # i: Maximum length of output string
+#--
+int ic, jc, iarg
+pointer sp, prompt
+
+string nullarg "getstr_cmd: null argument found in argument list"
+
+begin
+ # Allocate dynamic memory for prompt
+
+ call smark (sp)
+ call salloc (prompt, SZ_LINE, TY_CHAR)
+
+ # Read the argument interactively if not supplied by the user
+ # Otherwise, copy from the argument list string
+
+ if (index > nargs) {
+ call strcpy (argname, Memc[prompt], SZ_LINE)
+ call strcat ("?", Memc[prompt], SZ_LINE)
+
+ call read_prompt (Memc[prompt], str, maxch)
+
+ } else {
+ # Skip over leading arguments
+
+ ic = 1
+ for (iarg = 1; iarg < index; iarg = iarg + 1) {
+ if (arglist[ic] == EOS)
+ call err1_prompt (nullarg)
+
+ while (arglist[ic] != EOS)
+ ic = ic + 1
+ ic = ic + 1
+ }
+
+ # Copy into output string
+
+ for (jc = 1; jc <= maxch && arglist[ic] != EOS; jc = jc + 1) {
+ str[jc] = arglist[ic]
+ ic = ic + 1
+ }
+ str[jc] = EOS
+ }
+
+ call sfree (sp)
+end
+
+# GOTO_CMD -- Process the goto command
+
+procedure goto_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int nrow, row, col
+pointer sp, defcol, tab, cptr
+
+int tbpsta()
+
+string notable "No table associated with this screen"
+
+begin
+ # Allocate dynamic memory for column name
+
+ call smark (sp)
+ call salloc (defcol, SZ_COLNAME, TY_CHAR)
+
+ # Get number of rows in table
+
+ tab = TED_TABLE(scr)
+ if (tab == NULL)
+ call err1_prompt (notable)
+ else
+ nrow = tbpsta (TED_TABPTR(tab), TBL_NROWS)
+
+ cptr = TED_COLPTR(tab, TED_CURCOL(scr))
+ call tbcigt (cptr, TBL_COL_NAME, Memc[defcol], SZ_COLNAME)
+
+ # Get the row and column numbers
+
+ call getint_cmd ("Go to row", 2, nargs, arglist,
+ TED_CURROW(scr), 1, nrow, row)
+ call getcol_cmd ("Go to column", 3, nargs, arglist, tab,
+ Memc[defcol], col)
+
+ # Update screen descriptor
+
+ TED_CURROW(scr) = row
+ TED_CURCOL(scr) = col
+
+ call sfree (sp)
+end
+
+# HELP_CMD -- Process the help command
+
+procedure help_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+
+begin
+ call help_screen (TED_WINDOW(scr))
+
+end
+
+# INIT_CMD -- Initialize the global variables used by commands
+
+procedure init_cmd(silent)
+
+bool silent # i: do not ring bell when error occurs
+#--
+include "command.com"
+
+begin
+ direction = 1
+ search_exp[1] = EOS
+ call init_bell (silent)
+end
+
+# INSERT_CMD -- Process an insert command
+
+procedure insert_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int irow, nrow
+pointer tab, paste
+
+string nowrite "Cannot change read only table"
+string nopaste "Paste buffer is empty"
+
+int tbpsta()
+pointer opn_paste()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ paste = TED_PASTE(scr)
+ nrow = tbpsta (TED_TABPTR(tab) ,TBL_NROWS)
+
+ if (paste == NULL) {
+ paste = opn_paste (scr)
+ if (paste == NULL)
+ return
+ }
+
+ # Get insert command parameters
+
+ call getint_cmd ("Insert after row number", 2, nargs, arglist,
+ TED_CURROW(scr), 0, nrow, irow)
+
+ # Check to see if there is something to insert
+
+ if (TED_PSTROWS(paste) <= 0) {
+ call warn1_prompt (scr, nopaste)
+ return
+ }
+
+ TED_DIRTY(tab) = YES
+ if (irow < nrow)
+ call tbrsft (TED_TABPTR(tab), irow+1, TED_PSTROWS(paste))
+
+ call move_paste (TED_PSTPTR(paste), TED_TABPTR(tab),
+ 1, irow+1, TED_PSTROWS(paste))
+
+ if (irow <= TED_HIROW(scr))
+ call move_screen (scr, LEFT, YES)
+
+end
+
+# LOWER_CMD -- Convert a column to lower cse
+
+procedure lower_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+extern strlwr
+
+begin
+ # A common routine handle both the lower and upper case
+ # commands, since they are so similar
+
+ call func_cmd (scr, nargs, arglist, strlwr)
+end
+
+# NEXT_CMD -- Repeat the search for an expression
+
+procedure next_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+include "command.com"
+
+int dir, nrow, first, last, row
+pointer tab
+
+string nofind "No previous find command"
+string badexpr "Syntax error"
+string notfound "No rows matched expression"
+
+int tbpsta(), option_cmd(), tbl_search()
+
+begin
+ tab = TED_TABLE(scr)
+ nrow = tbpsta (TED_TABPTR(tab) ,TBL_NROWS)
+
+ # Make sure there was a previous find command
+
+ if (search_exp[1] == EOS) {
+ call warn1_prompt (scr, nofind)
+ return
+ }
+
+ # Get the command option
+
+ dir = option_cmd ("|forward|backwards|", nargs, arglist)
+ if (dir != 0)
+ direction = dir
+
+ # Set limits for search
+
+ if (direction == 2) {
+ first = max (TED_CURROW(scr)-1, 1)
+ last = 1
+ } else {
+ first = min (TED_CURROW(scr)+1, nrow)
+ last = nrow
+ }
+
+ # Perform search and report results
+
+ row = tbl_search (TED_TABPTR(tab), search_exp, first, last)
+
+ if (row == ERR) { # syntax error
+ call warn2_prompt (scr, badexpr, search_exp)
+ search_exp[1] = EOS
+
+ } else if (row == 0) { # row not found
+ call write_prompt (scr, NO, notfound)
+
+ } else { # row found, update screen descriptor
+ TED_CURROW(scr) = row
+ }
+
+end
+
+# OPTION_CMD -- Get the command option
+
+int procedure option_cmd (optlist, nargs, arglist)
+
+char optlist[ARB] # i: List of legal options
+int nargs # u: Number of command arguments
+char arglist[ARB] # u: Argument list
+#--
+int option, iarg, ic, jc, last[2]
+pointer sp, arg1, arg2
+
+int strdic()
+
+begin
+ # No option if number of arguments < 2
+ if (nargs < 2)
+ return (0)
+
+ # Allocate dynamic memory for optional argument
+
+ call smark (sp)
+ call salloc (arg1, SZ_LINE, TY_CHAR)
+ call salloc (arg2, SZ_LINE, TY_CHAR)
+
+ # Read optional argument, match against list of options
+
+ call getstr_cmd ("Option", 2, nargs, arglist, Memc[arg1], SZ_LINE)
+ option = strdic (Memc[arg1], Memc[arg2], SZ_LINE, optlist)
+
+ # If matched, remove option from argument list
+
+ if (option != 0) {
+ ic = 1
+ do iarg = 1, 2 {
+ while (arglist[ic] != EOS)
+ ic = ic + 1
+ last[iarg] = ic
+ ic = ic + 1
+ }
+
+ ic = last[1]
+ jc = last[2]
+ repeat {
+ ic = ic + 1
+ jc = jc + 1
+ arglist[ic] = arglist[jc]
+ } until (arglist[jc] == EOS && arglist[jc-1] == EOS)
+
+ nargs = nargs - 1
+ }
+
+ call sfree (sp)
+ return (option)
+
+end
+
+# PARSE_CMD -- Parse a command string
+
+procedure parse_cmd (command, code, nargs, arglist, maxch)
+
+char command[ARB] # i: Command to be parsed
+int code # o: Command code (0 if unknown command)
+int nargs # o: Number of arguments (including command name)
+char arglist[ARB] # o: Array of arguments, packed into one string
+int maxch # i: Declared length of arglist
+#--
+int ic, jc, delim
+pointer sp, temp
+
+string cmdlist TED_CMDLIST
+
+int strdic()
+
+begin
+ # Allocate temporary string for full command name
+
+ call smark (sp)
+ call salloc (temp, SZ_FNAME, TY_CHAR)
+
+ # Break command string into arguements
+ # Count the number of arguements
+
+ jc = 1
+ nargs = 0
+ delim = EOS
+ for (ic = 1; command[ic] != EOS && jc <= maxch; ic = ic + 1) {
+ if (delim == EOS) {
+ if (command[ic] > BLANK) {
+ nargs = nargs + 1
+ if (command[ic] == SQUOTE) {
+ delim = SQUOTE
+ } else if (command[ic] == DQUOTE) {
+ delim = DQUOTE
+ } else {
+ ic = ic - 1 # push back non-blank character
+ delim = BLANK
+ }
+ }
+
+ } else if (delim == BLANK) {
+ if (command[ic] <= BLANK) {
+ arglist[jc] = EOS
+ jc = jc + 1
+ delim = EOS
+
+ } else {
+ arglist[jc] = command[ic]
+ jc = jc + 1
+ }
+
+ } else {
+ if (command[ic] == delim) {
+ arglist[jc] = EOS
+ jc = jc + 1
+ delim = EOS
+
+ } else {
+ arglist[jc] = command[ic]
+ jc = jc + 1
+ }
+ }
+ }
+ arglist[jc] = EOS
+
+ # Get the code which corresponds to the first arguement
+ # (the command name)
+
+ if (nargs == 0) {
+ code = 0
+ } else {
+ code = strdic (arglist, Memc[temp], SZ_FNAME, cmdlist)
+ }
+
+ call sfree (temp)
+end
+
+# QUIT_CMD -- Quit the editor without saving files
+
+procedure quit_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int iscr
+pointer scr2
+
+int get_window()
+
+begin
+ for (iscr = 1; get_window (iscr, scr2) != EOF; iscr = iscr + 1)
+ call del_screen (scr2, NO)
+
+end
+
+# SET_CMD -- Set a column to the value of an expression
+
+procedure set_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+include "../tabvar.com"
+
+bool done
+int col, irow, nrow, nbuf, coltype, exptype
+pointer sp, defcol, expr, buffer, tab, cptr, tptr, code
+
+string nowrite "Cannot change read only table"
+string syntax "Syntax error in expression"
+
+extern tabvar
+int tbpsta()
+pointer vex_compile()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (defcol, SZ_COLNAME, TY_CHAR)
+ call salloc (expr, SZ_LINE, TY_CHAR)
+
+ # Get name of column
+
+ cptr = TED_COLPTR(tab, TED_CURCOL(scr))
+ call tbcigt (cptr, TBL_COL_NAME, Memc[defcol], SZ_COLNAME)
+
+ call getcol_cmd ("Column to change", 2, nargs, arglist, tab,
+ Memc[defcol], col)
+
+ call getstr_cmd ("Expression", 3, nargs, arglist,
+ Memc[expr], SZ_LINE)
+
+ # Get table info
+
+ tptr = TED_TABPTR(tab)
+ cptr = TED_COLPTR(tab, col)
+ nrow = tbpsta (tptr, TBL_NROWS)
+
+ coltype = TED_COLTYPE(tab,col)
+ if (coltype < 0) {
+ # String columns copy the expression verbatim
+
+ TED_DIRTY(tab) = YES
+ do irow = 1, nrow
+ call tbeptt (tptr, cptr, irow, Memc[expr])
+
+ } else {
+ # Numeric columns use the expression evaluator
+
+ iferr {
+ code = vex_compile (Memc[expr])
+ } then {
+ call warn2_prompt (scr, syntax, Memc[expr])
+ call sfree (sp)
+ return
+ }
+
+ # Initialize common block used by tabvar()
+
+ tabptr = tptr
+ firstrow = 1
+ lastrow = MAXROWS
+
+ done = false
+ nullval = HARMLESS
+
+ repeat {
+ if (lastrow >= nrow) {
+ done = true
+ lastrow = nrow
+ }
+
+ iferr {
+ call vex_eval (code, tabvar, nullval, exptype)
+ } then {
+ call warn2_prompt (scr, syntax, Memc[expr])
+ call sfree (sp)
+ return
+ }
+
+ nbuf = (lastrow - firstrow) + 1
+
+ # Copy results to column
+
+ switch (coltype) {
+ case TY_BOOL, TY_SHORT, TY_INT, TY_LONG:
+ call malloc (buffer, nbuf, TY_INT)
+ call vex_copyi (code, INDEFI, Memi[buffer], nbuf)
+ call tbcpti (tptr, cptr, Memi[buffer], firstrow, lastrow)
+ call mfree (buffer, TY_INT)
+ case TY_REAL:
+ call malloc (buffer, nbuf, TY_REAL)
+ call vex_copyr (code, INDEFR, Memr[buffer], nbuf)
+ call tbcptr (tptr, cptr, Memr[buffer], firstrow, lastrow)
+ call mfree (buffer, TY_REAL)
+ case TY_DOUBLE:
+ call malloc (buffer, nbuf, TY_DOUBLE)
+ call vex_copyd (code, INDEFD, Memd[buffer], nbuf)
+ call tbcptd (tptr, cptr, Memd[buffer], firstrow, lastrow)
+ call mfree (buffer, TY_DOUBLE)
+ }
+
+ firstrow = firstrow + MAXROWS
+ lastrow = lastrow + MAXROWS
+ } until (done)
+
+ TED_DIRTY(tab) = YES
+ call vex_free (code)
+ }
+
+ # Redraw screen if column is displayed
+
+ if (col >= TED_LOCOL(scr) && col <= TED_HICOL(scr))
+ call move_screen (scr, LEFT, YES)
+
+ call sfree (sp)
+
+end
+
+# SUB_CMD -- Substitute strings in a single column
+
+procedure sub_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+int col, irow, nrow, len
+pointer sp, defcol, from, to, colstr, tab, cptr, tptr
+
+string nowrite "Cannot change read only table"
+string numeric "Cannot change numeric column"
+
+bool substitute()
+int tbpsta()
+
+begin
+ # Check for read only table
+
+ tab = TED_TABLE(scr)
+ if (TED_READONLY(tab) == YES) {
+ call warn1_prompt (scr, nowrite)
+ return
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (defcol, SZ_COLNAME, TY_CHAR)
+ call salloc (from, SZ_LINE, TY_CHAR)
+ call salloc (to, SZ_LINE, TY_CHAR)
+
+ # Get name of column. Make sure it's a string column
+
+ cptr = TED_COLPTR(tab, TED_CURCOL(scr))
+ call tbcigt (cptr, TBL_COL_NAME, Memc[defcol], SZ_COLNAME)
+
+ call getcol_cmd ("Column to change", 2, nargs, arglist, tab,
+ Memc[defcol], col)
+
+ if (TED_COLTYPE(tab,col) > 0) {
+ call warn1_prompt (scr, numeric)
+ call sfree (sp)
+ return
+ }
+
+ # Get target string
+
+ call getstr_cmd ("Search string", 3, nargs, arglist,
+ Memc[from], SZ_LINE)
+
+ if (Memc[from] == EOS) {
+ call sfree (sp)
+ return
+ }
+
+ # Get replacement string
+
+ call getstr_cmd ("Replacement string", 4, nargs, arglist,
+ Memc[to], SZ_LINE)
+
+ # Allocate array to hold field
+
+ len = - TED_COLTYPE(tab,col)
+ call salloc (colstr, len, TY_CHAR)
+
+ # Get current number of rows in the table
+
+ tptr = TED_TABPTR(tab)
+ cptr = TED_COLPTR(tab, col)
+ nrow = tbpsta (tptr ,TBL_NROWS)
+
+ # Retrieve each field and perform substitution
+
+ do irow = 1, nrow {
+ call tbegtt (tptr, cptr, irow, Memc[colstr], len)
+
+ if (substitute (Memc[from], Memc[to], Memc[colstr], len)) {
+ TED_DIRTY(tab) = YES
+ call tbeptt (tptr, cptr, irow, Memc[colstr])
+ }
+ }
+
+ # Redraw screen if column is displayed
+
+ if (col >= TED_LOCOL(scr) && col <= TED_HICOL(scr))
+ call move_screen (scr, LEFT, YES)
+
+ call sfree (sp)
+
+end
+
+# UPPER_CMD -- Convert a column to upper cse
+
+procedure upper_cmd (scr, nargs, arglist)
+
+pointer scr # i: Current screen descriptor
+int nargs # i: Number of arguments
+char arglist[ARB] # i: Argument list
+#--
+extern strupr
+
+begin
+ # A common routine handle both the lower and upper case
+ # commands, since they are so similar
+
+ call func_cmd (scr, nargs, arglist, strupr)
+end
+
diff --git a/pkg/utilities/nttools/tedit/display/curses.h b/pkg/utilities/nttools/tedit/display/curses.h
new file mode 100644
index 00000000..ea12d7f5
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses.h
@@ -0,0 +1,86 @@
+# CURSES.H -- Macros used by the curses subroutines
+
+# Window which covers terminal screen
+
+define STDSCR 1
+
+# The following string defines the set of commands read from the edcap file
+
+define CMDSTR "|MOVE_UP|MOVE_DOWN|MOVE_RIGHT|MOVE_LEFT|NEXT_WORD|PREV_WORD\
+|NEXT_PAGE|PREV_PAGE|MOVE_START|MOVE_END|MOVE_BOL|MOVE_EOL|DEL_CHAR|DEL_LEFT\
+|DEL_WORD|DEL_LINE|UNDEL_CHAR|UNDEL_WORD|UNDEL_LINE|GET_HELP|REPAINT\
+|EXIT_UPDATE|"
+
+# The following values are returned when
+# the corresponding escape sequence is entered
+
+define K_BASE 256 # Smallest value
+
+define K_UP 256 # Move up one row
+define K_DOWN 257 # Move down one row
+define K_RIGHT 258 # Move right one column
+define K_LEFT 259 # Move left one column
+define K_NEXTW 260 # Move forwards one word
+define K_PREVW 261 # Move backwards one word
+define K_NEXTP 262 # Move forwards one window
+define K_PREVP 263 # Move backwards one window
+define K_HOME 264 # Move to first row
+define K_END 265 # Move to last row
+define K_BOL 266 # Move to first column in row
+define K_EOL 267 # Move to last column in row
+define K_DEL 268 # Delete character underneath cursor
+define K_BS 269 # Delete character to left of cursor
+define K_DWORD 270 # Delete previous word
+define K_DLINE 271 # Delete entire line
+define K_UNDCHR 272 # Undelete character
+define K_UNDWRD 273 # Undelete word
+define K_UNDLIN 274 # Undelete line
+define K_HELP 275 # Display help window
+define K_PAINT 276 # Force window redraw
+define K_EXIT 277 # Exit procedure
+
+# Codes used by winstat to retrieve window fields
+
+define W_TOP 1 # Window's top row
+define W_LEFT 2 # Window's leftmost column
+define W_BOT 3 # Window's bottom row
+define W_RIGHT 4 # Window's rightmost column
+define W_CURROW 5 # Cursor row relative to window
+define W_CURCOL 6 # Cursor column relative to window
+define W_CLEAR 7 # Redraw window when refreshed
+define W_LEAVE 8 # Leave cursor after redraw
+define W_SCROLL 9 # Window will scroll
+define W_HIDDEN 10 # Window is hidden
+define W_BOXED 11 # Window is boxed
+define W_ATRIB 12 # Character attribute of window
+
+# Direction to move rectangle used by ps_slide and wslide
+
+define DIR_UP 0
+define DIR_DOWN 1
+define DIR_LEFT 2
+define DIR_RIGHT 3
+
+# Character attributes
+
+define A_NORM 0
+define A_STANDOUT 128
+
+# Definition of rectangle
+
+define RSIZE 4
+define RTOP $1[1]
+define RLEFT $1[2]
+define RBOT $1[3]
+define RRIGHT $1[4]
+
+# Macros used to manipulate rectangles
+
+define RWIDTH ($1[4] - $1[2] + 1)
+define RHEIGHT ($1[3] - $1[1] + 1)
+define RASG {$1[1] = $2; $1[2] = $3; $1[3] = $4; $1[4] = $5}
+define RCPY {$1[1]=$2[1]; $1[2]=$2[2]; $1[3]=$2[3]; $1[4]=$2[4]}
+
+# Constant used to create a rectangle much greater than screen size
+
+define GIANT 9999
diff --git a/pkg/utilities/nttools/tedit/display/curses/README b/pkg/utilities/nttools/tedit/display/curses/README
new file mode 100644
index 00000000..67220c91
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/README
@@ -0,0 +1,387 @@
+The procedures in this directory are an implementation of the Unix
+curses library, with a few deletions and extensions. The procedures
+have been modified to work in an SPP environment instead of a C
+environment. Unlike the C routines, they do not return an error status
+as a function value. In fact, very few of the procedures call error,
+instead they try to do the most reasonable thing. The mv macros are
+not implemented, instead the program should call move() followed by
+the appropriate procedure. Formatted reads and writes to windows are
+not supported, all reading and writing is done using strings.
+Subwindows are also not supported. The user program does not have
+direct access to the window structure, the function winstat() is
+provided to read fields from the structure. In order to make
+customization of windows easier, each window can have an input
+function and data structure bound to it. The functions bindstruct()
+and getstruct() are provided for this purpose. The forms directory
+gives several examples of binding functions and data structures to a
+window. Two other procedures hidewin() and showwin() are provided to
+hide a window which is currently displayed on the terminal and to
+redisplay it.
+
+The procedure initscr() should be called before using any of the
+procedures in the curses directory. It initializes the terminal and
+creates the first window (referred to as STDSCR), which covers the
+terminal scrren. The procedure endwin() should be called at the end of
+the user program. It closes any windows which are still open and
+resets the terminal. Windows are created by calling newwin() and
+destroyed by calling delwin(). The terminal cursor is moved by the
+procedure move(). Text is written into a window by the procedures
+addch() and addstr(). Text is read from the keyboard and displayed in
+the window by the procedures getch() and getstr(). Changes to the
+window are not displayed until refresh() is called. Fuller
+explanations of these and the other curses procedures is given below.
+
+Many procedures in this directory exist in two forms. The first form
+uses the default window, STDSCR. This window is created when initscr()
+is called and covers the entire screen. The second form uses any
+window and has an extra argument to specify which window to use. The
+names of the two forms are the same, except that the second has the
+letter "w" as the first character. For example, addch() adds a
+character to STDSCR, while waddch() adds a character to any window.
+The macro STDSCR is defined in <curses.h>, so it can be used by your
+program. Many of the procedures in this library operate relative to
+the current cursor position in that window. To set the cursor
+position, the program should call move() or wmove() first. Window
+coordinates are passed row first, column second. The upper left corner
+of a window is (1,1).
+
+procedure addch (ch)
+procedure waddch (win, ch)
+
+pointer win # i: Window descriptor
+char ch # i: Character to add
+
+This procedure adds a single character at the current cursor position.
+The character currently at that position is overwritten. A linefeed
+character clears the rest of the line and moves the cursor to the next
+row. A tab character inserts the apropriate number of spaces at the
+current position. A carriage return moves the cursor to the first
+character on the current line. A backspace moves the cursor one column
+left unless the cursor is in the first column of the window.
+
+procedure addstr (str)
+procedure waddstr (win, str)
+
+int win # i: Window descriptor
+char str[ARB] # i: String to add to window
+
+This procedure adds a string at the current cursor position. If part
+of the string extends beyond the right edge of the window, it will be
+truncated. Special characters have the same meaning as those in addch().
+The window will scroll if scrolling is enabled.
+
+procedure bindstruct (func, structure)
+procedure wbindstruct (win, func, structure)
+
+int win # i: Window descriptor
+extern func # i: Input function
+pointer structure # i: Data structure
+
+This procedure binds an input function and a data structure to a
+window. The data structure is used by the input function to maintain
+the window's state. The input function is called by getch() and
+getstr() to process keyboard input instead of the default procedure,
+editfn(). The input function should have the following calling sequence.
+
+procedure func (win, str, maxch)
+
+int win # i: Window descriptor
+char str[ARB] # io: String containing line
+int maxch # i: Maximum line length
+
+When writing this procedure, the default procedure, editfn() should be
+used as a guide. The procedure should update the terminal screen,
+string, and data structure appropriately. When the procedure gets a
+character indicating input is complete, the character should be pushed
+back on the input stream with the procedure k_pushbk(). Then the
+procedure should return the string to the calling program. The calling
+program can also call getstruct() to retrieve the contents of the data
+structure.
+
+procedure box (win, vert, hor)
+
+int win # i: Window descriptor
+char vert # i: Character used for vertical side of window
+char hor # i: Character used for horizontal side of window
+
+This procedure draws a box around a window. The box is inside the
+original area of the window, which is then reduced so that subsequent
+writes to the window will not overwrite the box.
+
+procedure clear ()
+procedure wclear (win)
+
+int win # i: Window descriptor
+
+This procedure clears a window. It is equivalent to calling clearok()
+with flag set to true, followed by calling erase().
+
+procedure clearok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+
+This procedure sets the clear flag for a window. If the clear flag is
+true, the entire window will be redrawn when refresh is called.
+
+procedure clrtobot ()
+procedure wclrtobot (win)
+
+int win # i: Window descriptor
+
+This procedure clears a window from the current cursor position to the
+end of the window.
+
+procedure clrtoeol ()
+procedure wclrtoeol (win)
+
+int win # i: Window descriptor
+
+This procedure clears a window from the current cursor position to the
+end of the line.
+
+procedure delch ()
+procedure wdelch (win)
+
+pointer win # i: Window descriptor
+
+This procedure deletes the character at the current cursor poisition
+in the window. Subsequent characters on the line are moved to the left
+by one.
+
+procedure deleteln ()
+procedure wdeleteln (win)
+
+pointer win # i: Window descriptor
+
+This procedure deletes the current line in the window. Subsequent
+lines in the window slide up by one and the last line is left blank.
+
+procedure delwin (win)
+
+This procedure deletes a window created by newwin(). The terminal area
+that was under the window before it was created is redisplayed. The
+data structure associated with the window is freed, including the data
+structure bound by bindstruct(). STDSCR cannot be deleted by this
+procedure, it is deleted by endwin().
+
+procedure echo ()
+procedure noecho ()
+
+These procedures turn character echoing on and off. Character echoing
+is on when the terminal is initialized. If character ecoing is off,
+procedures addch() and addstr() will return immediately after being
+called.
+
+procedure endwin ()
+
+This procedure should be called at the end of a program which uses the
+curses library. It deletes all windows that are still open (including
+STDSCR) and resets the terminal.
+
+procedure erase ()
+procedure werase (win)
+
+int win # i: Window descriptor
+
+This procedure erases a window, filling it with blanks.
+
+int procedure getch ()
+int procedure wgetch (win)
+
+This procedure reads a single character from the keyboard and adds it
+to the window at the current cursor position. If an input function
+has been bound to the window by bindstruct(), the input procedure is
+called to process the character. The procedure returns after calling
+the input function once, regardless of the value of done. The returned
+character is the first character in the string output by the input
+function.
+
+procedure getstr (str, maxch)
+procedure wgetstr (win, str, maxch)
+
+pointer win # i: Window descriptor
+char str[ARB] # o: String that was read from the keyboard
+int maxch # i: Maximum string length
+
+This procedure reads a string from the keyboard and displays it in the
+window at the current cursor position. Editing keys are recognized;
+however, editing is limited to a single line and keys which change the
+current line cause the procedure to exit. The default behaviour of
+this procedure can be modified by binding an input function to the
+window with bindstruct().
+
+procedure getstruct (structure)
+procedure wgetstruct (win, structure)
+
+int win # i: Window descriptor
+pointer structure # o: Data structure
+
+This procedure returns a pointer to the data structure that was bound
+to the window by bindstruct().
+
+procedure getyx (win, row, col)
+
+int win # i: Window descriptor
+int row # o: Cursor row
+int col # o: Cursor column
+
+This procedure returns the location of the cursor in a window. The
+top left corner of a window is (1,1).
+
+procedure hidewin (win)
+
+int win # i: Window descriptor
+
+This procedure hides a window that is currently displayed on the
+screen. The terminal area under the window is displayed after the
+window is hidden. The window can be redisplayed by calling showwin().
+
+char procedure inch ()
+char procedure winch (win)
+
+pointer win # i: Window descriptor
+
+This procedure returns the character at the current cursor location in
+the window.
+
+procedure initscr ()
+
+This procedure initializes the terminal and creates the default
+window, STDSCR. It should be called before any other procedure in the
+curses library is called.
+
+procedure insch (ch)
+procedure winsch (win, ch)
+
+pointer win # i: Window descriptor
+char ch # i: Character to insert
+
+This procedure inserts a character at the current cursor position.
+
+procedure insertln ()
+procedure winsertln (win)
+
+pointer win # i: Window descriptor
+
+This procedure inserts a blank line on the current row. The current
+line and subsequent lines move down by one and the last line in the
+window is deleted.
+
+procedure leaveok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+
+This procedure sets the leave flag for a window. If the leave flag
+is true, procedures that modify the screen will not move the terminal
+cursor to the window's current cursor position when the window is
+modified. If it is false, the terminal cursor position will be moved
+when the window is updated. When a window is created, the leave flag
+is set to false.
+
+procedure move (row, col)
+procedure wmove (win, row, col)
+
+int win # i: Window descriptor
+int row # i: Cursor row
+int col # i: Cursor column
+
+This procedure moves the cursor position in a window. Coordinates are
+relative to those of the window, and the top left corner of a window
+has the coordinates (1,1)
+
+procedure mvwin (win, row, col)
+
+int win # i: Window descriptor
+int row # i: New top row of window
+int col # i: New left column of window
+
+This position moves the position of a window on the screen. The
+position of a window is the position of the top left corner on the
+terminal screen. If the new corrdinates would place part of the window
+off the screen, the coordinates are modified so that the window stays
+on the screen.
+
+int procedure newwin (nrows, ncols, row, col)
+
+int nrows # i: Window height
+int ncols # i: Window width
+int row # i: Top row of window
+int col # i: Leftmost column of window
+
+This procedure creates a new window. The returned value is the window
+descriptor, which is used as an argument to the other window
+functions. The window position is relative to the top left corner of
+the terminal, which has the coordinates (1,1). If part of the window
+is off the terminal screen, it will be placed and sized so that the
+entire window fits on the screen.
+
+procedure refresh ()
+procedure wrefresh (win)
+
+int win # i: Window descriptor
+
+This procedure causes all changes to a window that have been made by
+other calls in this library to be displayed on the terminal screen. If
+the clear flag has been set to yes by clearok(), the window will be
+cleared and redrawn.
+
+procedure savewin ()
+procedure nosavewin ()
+
+These procedures set and unset the save flag. If the save flag is set,
+whenever a window is created, the area on the terminal screen under is
+saved in a buffer so it can be restored when the window is hidden or
+deleted. If a window will exist throughout the life of a program, the
+save flag can be unset by calling nosavewin() before creating the
+window so that the memory used to hold the buffer will not be wasted.
+The save flag is initially set to yes so that all windows have
+associated screen buffers by default.
+
+procedure scrollok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+
+If the scroll flag is set to true, a window will scroll when an
+attempt is made to write beyond the last line of a window. If the
+scroll flag is false, the last line of the window will be overwritten.
+When a new window is created, the scroll flag is set to false.
+
+procedure showwin (win)
+
+int win # i: Window descriptor
+
+This procedure shows a window that was previously hidden by a call to
+hidewin(). If the window is not hidden, this procedure has no effect.
+
+procedure standout ()
+procedure standend ()
+procedure wstandout (win)
+procedure wstandend (win)
+
+int win # i: Window descriptor
+
+These procedures modify the character attribute of a window. Calling
+standout() causes all characters written to the window after the call
+to be written in standout mode. Calling standend() causes all
+characacters to be written in normal mode. When a window is created,
+the character attribute of the window is normal.
+
+procedure wdimen (win, nrows, ncols)
+
+int win # i: Window descriptor
+int nrows # o: Window height
+int ncols # o: Window width
+
+This procedure returns the height and width of a window.
+
+int procedure winstat (win, what)
+
+int win # i: Window descriptor
+int what # i: Field to retrieve
+
+This procedure returns a field from the window descriptor. The field
+to retrieve is given by a symbolic constant. These constants are
+listed in the include file <curses.h>.
diff --git a/pkg/utilities/nttools/tedit/display/curses/addch.x b/pkg/utilities/nttools/tedit/display/curses/addch.x
new file mode 100644
index 00000000..f08085e4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/addch.x
@@ -0,0 +1,30 @@
+include "../curses.h"
+
+# ADDCH -- Add a character to the standard screen
+#
+# B.Simon 01-Oct-90 Original
+
+procedure addch (ch)
+
+char ch # i: Character to add
+#--
+char str[1]
+
+begin
+ str[1] = ch
+ str[2] = EOS
+ call waddstr (STDSCR, str)
+end
+
+procedure waddch (win, ch)
+
+int win # i: Window descriptor
+char ch # i: Character to add
+#--
+char str[1]
+
+begin
+ str[1] = ch
+ str[2] = EOS
+ call waddstr (win, str)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/addstr.x b/pkg/utilities/nttools/tedit/display/curses/addstr.x
new file mode 100644
index 00000000..f675d151
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/addstr.x
@@ -0,0 +1,157 @@
+include <ctype.h>
+include "../curses.h"
+include "window.h"
+
+define TABSTOP 8
+
+# ADDSTR -- Add a string to a window
+#
+# B.Simon 02-Oct-90 Original
+
+procedure addstr (str)
+
+char str[ARB] # i: String to add to window
+#--
+
+begin
+ call waddstr (STDSCR, str)
+end
+
+procedure waddstr (win, str)
+
+int win # i: Window descriptor
+char str[ARB] # i: String to add to window
+#--
+include "window.com"
+
+bool moved
+int row, col, nrows, ncols, ic, jc, mxchar, itab
+pointer sp, line, pwin
+
+begin
+ pwin = warray[win]
+
+ # Don't print anything if echoing is turned off
+
+ if (echoed == NO)
+ return
+
+ # Allocate an array to hold the string to print
+
+ call smark (sp)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ # Get the current cursor position and window size
+
+ row = WIN_CURROW(pwin)
+ col = WIN_CURCOL(pwin)
+ ncols = WIN_WIDTH(pwin)
+ nrows = WIN_HEIGHT(pwin)
+
+ ic = 0
+ jc = 0
+ moved = false
+
+ repeat {
+ ic = ic + 1
+
+ # If the character is printable, just copy it to the array
+ # The array will be printed when the EOS is read
+
+ if (IS_PRINT(str[ic])) {
+ col = col + 1
+ Memc[line+jc] = str[ic]
+ jc = jc + 1
+
+ } else {
+ # Print any characters in the array before handling
+ # the non-printing character
+
+ Memc[line+jc] = EOS
+ if (jc > 0) {
+ jc = 0
+
+ mxchar = ncols - WIN_CURCOL(pwin) + 1
+ call ps_write (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1,
+ mxchar, Memc[line], WIN_ATRIB(pwin))
+
+ WIN_CURCOL(pwin) = col
+ WIN_CURROW(pwin) = row
+
+ # Check for writing past the edge of the window
+ # and scrolling
+
+ if (col > ncols) {
+ col = 1
+ row = row + 1
+ moved = true
+
+ if (row > nrows) {
+ row = nrows
+ if (WIN_SCROLL(pwin) == YES)
+ call wslide (WIN_RECT(pwin), DIR_UP, 1)
+ }
+ }
+ }
+
+ # Some non-printing characters require special action
+ # Others are mapped to printing characters and written
+ # to the array
+
+ switch (str[ic]) {
+ case EOS:
+ ;
+
+ case '\n':
+ call wclrtoeol (win)
+ col = 1
+ row = row + 1
+ moved = true
+
+ # Scroll window if we've hit the last row
+
+ if (row > nrows) {
+ row = nrows
+ if (WIN_SCROLL(pwin) == YES)
+ call wslide (WIN_RECT(pwin), DIR_UP, 1)
+ }
+
+ case '\t':
+ do itab = 1, TABSTOP - mod (col, TABSTOP) {
+ Memc[line+jc] = ' '
+ jc = jc + 1
+ col = col + 1
+ }
+
+ case '\r':
+ if (col > 1) {
+ col = 1
+ moved = true
+ }
+
+ case '\010':
+ if (col > 1) {
+ col = col - 1
+ moved = true
+ }
+
+ default:
+ Memc[line+jc] = ' '
+ col = col + 1
+ jc = jc + 1
+ }
+ }
+
+ # Move cursor, as required
+
+ if (moved) {
+ moved = false
+ call wmove (win, row, col)
+ }
+
+ } until (str[ic] == EOS)
+
+ call sfree (sp)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/bindstruct.x b/pkg/utilities/nttools/tedit/display/curses/bindstruct.x
new file mode 100644
index 00000000..f9502c3d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/bindstruct.x
@@ -0,0 +1,35 @@
+include "../curses.h"
+include "window.h"
+
+# BINDSTRUCT -- Bind a data structure and function to a window
+
+procedure bindstruct (func, structure)
+
+extern func # i: Input function
+pointer structure # i: Data structure
+#--
+
+begin
+ call wbindstruct (STDSCR, func, structure)
+end
+
+procedure wbindstruct (win, func, structure)
+
+int win # i: Window descriptor
+extern func # i: Input function
+pointer structure # i: Data structure
+#--
+include "window.com"
+
+pointer pwin
+pointer locpr()
+
+begin
+ pwin = warray[win]
+ if (WIN_DATA(pwin) != NULL)
+ call mfree (WIN_DATA(pwin), TY_STRUCT)
+
+ WIN_FUNC(pwin) = locpr (func)
+ WIN_DATA(pwin) = structure
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/box.x b/pkg/utilities/nttools/tedit/display/curses/box.x
new file mode 100644
index 00000000..06eadbcd
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/box.x
@@ -0,0 +1,56 @@
+include "../curses.h"
+include "window.h"
+
+# BOX -- Draw a box around a window
+#
+# B.Simon 01-Oct-90 Original
+
+procedure box (win, vert, hor)
+
+int win # i: Window descriptor
+char vert # i: Character used for vertical side of window
+char hor # i: Character used for horizontal side of window
+#--
+include "window.com"
+
+int vcode, hcode, rect[RSIZE]
+pointer pwin
+
+begin
+ # Don't box window if either dimension < 3 or window is already boxed
+
+ pwin = warray[win]
+ if (WIN_HEIGHT(pwin) < 3 || WIN_WIDTH(pwin) < 3 ||
+ WIN_BOXED(pwin) == YES)
+ return
+
+ # Draw box
+
+ vcode = vert
+ hcode = hor
+
+ RASG(rect, WIN_TOP(pwin), WIN_LEFT(pwin),
+ WIN_TOP(pwin), WIN_RIGHT(pwin))
+ call ps_fill (rect, hcode, WIN_ATRIB(pwin))
+
+ RASG(rect, WIN_BOT(pwin), WIN_LEFT(pwin),
+ WIN_BOT(pwin), WIN_RIGHT(pwin))
+ call ps_fill (rect, hcode, WIN_ATRIB(pwin))
+
+ RASG(rect, WIN_TOP(pwin), WIN_LEFT(pwin),
+ WIN_BOT(pwin), WIN_LEFT(pwin))
+ call ps_fill (rect, vcode, WIN_ATRIB(pwin))
+
+ RASG(rect, WIN_TOP(pwin), WIN_RIGHT(pwin),
+ WIN_BOT(pwin), WIN_RIGHT(pwin))
+ call ps_fill (rect, vcode, WIN_ATRIB(pwin))
+
+ # Reduce size of window's rectangle and mark as boxed
+
+ WIN_TOP(pwin) = WIN_TOP(pwin) + 1
+ WIN_LEFT(pwin) = WIN_LEFT(pwin) + 1
+ WIN_BOT(pwin) = WIN_BOT(pwin) - 1
+ WIN_RIGHT(pwin) = WIN_RIGHT(pwin) - 1
+ WIN_BOXED(pwin) = YES
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/clear.x b/pkg/utilities/nttools/tedit/display/curses/clear.x
new file mode 100644
index 00000000..7b69f63d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/clear.x
@@ -0,0 +1,35 @@
+include "../curses.h"
+include "window.h"
+
+# CLEAR -- Clear window and force a redraw of the screen
+#
+# B.Simon 01-Oct-90 Original
+
+procedure clear ()
+
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[STDSCR]
+ WIN_CLEAR(pwin) = YES
+
+ call werase (STDSCR)
+end
+
+procedure wclear (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+ WIN_CLEAR(pwin) = YES
+
+ call werase (win)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/clearok.x b/pkg/utilities/nttools/tedit/display/curses/clearok.x
new file mode 100644
index 00000000..9d3372a9
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/clearok.x
@@ -0,0 +1,21 @@
+include "window.h"
+
+# CLEAROK -- Set the clear flag for a window
+#
+# B.Simon 01-Oct-90 Original
+
+procedure clearok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+#--
+include "window.com"
+
+pointer pwin
+int btoi()
+
+begin
+ pwin = warray[win]
+ WIN_CLEAR(pwin) = btoi (flag)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/clrtobot.x b/pkg/utilities/nttools/tedit/display/curses/clrtobot.x
new file mode 100644
index 00000000..da60b805
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/clrtobot.x
@@ -0,0 +1,56 @@
+include "../curses.h"
+include "window.h"
+
+# CLRTOBOT -- Clear window to bottom
+#
+# B.Simon 28-Sep-90 Original
+
+procedure clrtobot ()
+
+#--
+
+begin
+ call wclrtobot (STDSCR)
+end
+
+procedure wclrtobot (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int blank, rect[RSIZE]
+pointer pwin
+
+data blank / ' ' /
+
+begin
+ pwin = warray[win]
+
+ # First line may be partial, so it must be handled separately
+
+ if (WIN_CURCOL(pwin) == 1) {
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ } else {
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin) - 1
+ RBOT(rect) = RTOP(rect)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+ call ps_fill (rect, blank, WIN_ATRIB(pwin))
+
+ RTOP(rect) = min (RBOT(rect), RTOP(rect)+1)
+ }
+
+ # Remaining lines form a rectangle
+
+ RLEFT(rect) = WIN_LEFT(pwin)
+ RBOT(rect) = WIN_BOT(pwin)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+
+ call ps_fill (rect, blank, WIN_ATRIB(pwin))
+ if (WIN_LEAVE(pwin) == NO) {
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/clrtoeol.x b/pkg/utilities/nttools/tedit/display/curses/clrtoeol.x
new file mode 100644
index 00000000..2c42a64e
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/clrtoeol.x
@@ -0,0 +1,45 @@
+include "../curses.h"
+include "window.h"
+
+# CLRTOEOL -- Clear window to end of current line
+#
+# B.Simon 01-Oct-90 Original
+
+procedure clrtoeol ()
+
+#--
+
+begin
+ call wclrtoeol (STDSCR)
+end
+
+procedure wclrtoeol (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int blank, rect[RSIZE]
+pointer pwin
+
+data blank / ' ' /
+
+begin
+ pwin = warray[win]
+
+ # Construct the rectangle consisting of the remainder of the
+ # current line and fill with blanks
+
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin) - 1
+ RBOT(rect) = RTOP(rect)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+ call ps_fill (rect, blank, WIN_ATRIB(pwin))
+
+ # Move the cursor to the new end of the line
+
+ if (WIN_LEAVE(pwin) == NO)
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/delch.x b/pkg/utilities/nttools/tedit/display/curses/delch.x
new file mode 100644
index 00000000..a58ed17d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/delch.x
@@ -0,0 +1,41 @@
+include "../curses.h"
+include "window.h"
+
+# DELCH -- Delete a character from the window
+
+procedure delch ()
+
+# B.Simon 01-Oct-90 Original
+
+#--
+
+begin
+ call wdelch (STDSCR)
+end
+
+procedure wdelch (win)
+
+pointer win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ # Construct rectangle to slide
+
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin)
+ RBOT(rect) = RTOP(rect)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+
+ call wslide (rect, DIR_LEFT, 1)
+
+ if (WIN_LEAVE(pwin) == NO)
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/deleteln.x b/pkg/utilities/nttools/tedit/display/curses/deleteln.x
new file mode 100644
index 00000000..f5afa1dd
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/deleteln.x
@@ -0,0 +1,41 @@
+include "../curses.h"
+include "window.h"
+
+# DELETELN -- Delete a line from the window
+#
+# B.Simon 01-Oct-90 Original
+
+procedure deleteln ()
+
+#--
+
+begin
+ call wdeleteln (STDSCR)
+end
+
+procedure wdeleteln (win)
+
+pointer win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ # Construct rectangle to slide
+
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin)
+ RBOT(rect) = WIN_BOT(pwin)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+
+ call wslide (rect, DIR_UP, 1)
+
+ if (WIN_LEAVE(pwin) == NO)
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/delwin.x b/pkg/utilities/nttools/tedit/display/curses/delwin.x
new file mode 100644
index 00000000..5b0db192
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/delwin.x
@@ -0,0 +1,42 @@
+include "../curses.h"
+include "window.h"
+
+# DELWIN --Delete a window
+#
+# B.Simon 28-Sep-90 Original
+
+procedure delwin (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin
+
+begin
+ # Can't free the standard screen
+
+ if (win == STDSCR)
+ return
+
+ pwin = warray[win]
+
+ # Copy the screen under the window back to the terminal
+ # and then free the buffer which held it
+
+ if (WIN_BUFFER(pwin) != NULL) {
+ call wrect (win, YES, rect)
+ call putscreen (rect, WIN_BUFFER(pwin))
+ call freescreen (WIN_BUFFER(pwin))
+ }
+
+ # Free any data structure associated with the window
+
+ if (WIN_DATA(pwin) != NULL)
+ call mfree (WIN_DATA(pwin), TY_STRUCT)
+
+ call mfree (pwin, TY_STRUCT)
+ warray[win] = NULL
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/echo.x b/pkg/utilities/nttools/tedit/display/curses/echo.x
new file mode 100644
index 00000000..8152aff6
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/echo.x
@@ -0,0 +1,23 @@
+include "window.h"
+
+# ECHO -- Turn character echoing on
+#
+# B.Simon 02-Oct-90 Original
+
+procedure echo ()
+
+#--
+include "window.com"
+
+begin
+ echoed = YES
+end
+
+procedure noecho ()
+
+#--
+include "window.com"
+
+begin
+ echoed = NO
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/endwin.x b/pkg/utilities/nttools/tedit/display/curses/endwin.x
new file mode 100644
index 00000000..87a6c826
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/endwin.x
@@ -0,0 +1,34 @@
+include "window.h"
+
+# ENDWIN -- Finish up window routines
+#
+# B.Simon 28-Sep-90 Original
+
+procedure endwin ()
+
+#--
+include "window.com"
+
+int win
+pointer pwin
+
+begin
+ # Release windows that are still active
+
+ do win = 1, MAXWIN {
+ pwin = warray[win]
+ if (pwin != NULL) {
+ if (WIN_BUFFER(pwin) != NULL)
+ call freescreen (WIN_BUFFER(pwin))
+ if (WIN_DATA(pwin) != NULL)
+ call mfree (WIN_DATA(pwin), TY_STRUCT)
+ call mfree (pwin, TY_STRUCT)
+ }
+ }
+
+ # Reset terminal
+
+ call k_end
+ call ps_end
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/erase.x b/pkg/utilities/nttools/tedit/display/curses/erase.x
new file mode 100644
index 00000000..86b529a8
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/erase.x
@@ -0,0 +1,37 @@
+include "../curses.h"
+include "window.h"
+
+# ERASE -- Erase window
+#
+# B.Simon 28-Sep-90 Original
+
+procedure erase ()
+
+#--
+
+begin
+ call werase (STDSCR)
+end
+
+procedure werase (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int blank
+pointer pwin
+
+data blank / ' ' /
+
+begin
+ pwin = warray[win]
+ call ps_fill (WIN_RECT(pwin), blank, WIN_ATRIB(pwin))
+
+ if (WIN_LEAVE(pwin) == NO) {
+ call ps_setcur (WIN_TOP(pwin), WIN_LEFT(pwin))
+ WIN_CURROW(pwin) = 1
+ WIN_CURCOL(pwin) = 1
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/freescreen.x b/pkg/utilities/nttools/tedit/display/curses/freescreen.x
new file mode 100644
index 00000000..66321451
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/freescreen.x
@@ -0,0 +1,13 @@
+# FREESCREEN -- Free a window's buffer
+#
+# B.Simon 26-Sep-90 Original
+
+procedure freescreen (buffer)
+
+pointer buffer # i: Buffer allocated by wgetscr
+#--
+
+begin
+ if (buffer != NULL)
+ call mfree (buffer, TY_CHAR)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/getch.x b/pkg/utilities/nttools/tedit/display/curses/getch.x
new file mode 100644
index 00000000..9d69c11f
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/getch.x
@@ -0,0 +1,53 @@
+include "../curses.h"
+include "window.h"
+
+# GETCH -- Get a character and display it in the window
+
+int procedure getch ()
+
+# B.Simon 01-Oct-90 Original
+
+#--
+int wgetch()
+
+begin
+ return (wgetch (STDSCR))
+end
+
+int procedure wgetch (win)
+
+pointer win # i: Window descriptor
+#--
+include "window.com"
+
+char str[1]
+int ch
+pointer pwin
+
+int k_get()
+
+begin
+ str[1] = EOS
+ str[2] = EOS
+ pwin = warray[win]
+
+ if (WIN_FUNC(pwin) == NULL) {
+ call ps_synch
+ ch = k_get ()
+
+ if (ch < K_BASE) {
+ str[1] = ch
+ call waddstr (win, str)
+ }
+
+ } else {
+ call zcall3 (WIN_FUNC(pwin), win, str, 1)
+ if (str[1] == EOS) {
+ ch = k_get () # get pushed back character
+ } else {
+ ch = str[1]
+ }
+ }
+
+ return (ch)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/getscreen.x b/pkg/utilities/nttools/tedit/display/curses/getscreen.x
new file mode 100644
index 00000000..58020c3f
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/getscreen.x
@@ -0,0 +1,48 @@
+include "../curses.h"
+
+# GETSCREEN -- Retrieve screen contents into a window's buffer
+#
+# B.Simon 26-Sep-90 Original
+
+procedure getscreen (source, buffer)
+
+int source[RSIZE] # i: Rectangle to be retrieved
+pointer buffer # o: Buffer (allocated by this routine)
+#--
+
+int dest[RSIZE]
+int maxcol, maxrow, ncols, nrows, irow
+pointer buf, scr
+
+bool ps_intersect()
+int ps_width(), ps_height()
+pointer ps_screen()
+
+begin
+ # Clip the rectangle to the screen boundary
+ # If the rectangle is entirely off the screen, return
+
+ buffer = NULL
+ maxcol = ps_width ()
+ maxrow = ps_height ()
+ if (! ps_intersect (source, maxrow, maxcol, dest))
+ return
+
+ # Allocate buffer to hold screen contents
+
+ ncols = RWIDTH(dest)
+ nrows = RHEIGHT(dest)
+ call malloc (buffer, ncols*nrows, TY_CHAR)
+
+ # Copy screen contents to buffer
+
+ buf = buffer
+ scr = ps_screen (RTOP(dest), RLEFT(dest))
+
+ do irow = RTOP(dest), RBOT(dest) {
+ call amovc (Memc[scr], Memc[buf], ncols)
+ scr = scr + maxcol
+ buf = buf + ncols
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/getstr.x b/pkg/utilities/nttools/tedit/display/curses/getstr.x
new file mode 100644
index 00000000..6c1d38e6
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/getstr.x
@@ -0,0 +1,317 @@
+include <ctype.h>
+include "../curses.h"
+include "window.h"
+
+# GETSTR -- Get a string from the keyboard and display it in the window
+#
+# B.Simon 12-Dec-90 Original
+# B.Simon 21-Mar-91 Add several new commands
+
+procedure getstr (str, maxch)
+
+char str[ARB] # o: String that was read from the keyboard
+int maxch # i: Maximum string length
+#--
+int ch
+
+int k_get()
+
+begin
+ str[1] = EOS
+ call weditstr (STDSCR, str, maxch)
+
+ ch = k_get () # discard pushed back character
+end
+
+procedure wgetstr (win, str, maxch)
+
+pointer win # i: Window descriptor
+char str[ARB] # o: String that was read from the keyboard
+int maxch # i: Maximum string length
+#--
+int ch
+
+int k_get()
+
+begin
+ str[1] = EOS
+ call weditstr (win, str, maxch)
+
+ ch = k_get () # discard pushed back character
+end
+
+# EDITSTR -- Edit a string while displaying it in the window
+
+procedure editstr (str, maxch)
+
+char str[ARB] # u: String to edit
+int maxch # i: Maximum string length
+#--
+
+begin
+ call weditstr (STDSCR, str, maxch)
+end
+
+procedure weditstr (win, str, maxch)
+
+pointer win # i: Window descriptor
+char str[ARB] # u: String to edit
+int maxch # i: Maximum string length
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ # NOTE: It is the reponsibility of the calling program
+ # to make sure that the current window contents and the
+ # string passed to this procedure are in agreement before
+ # this procedure is called.
+
+ pwin = warray[win]
+
+ if (WIN_FUNC(pwin) == NULL) {
+ call editfn (win, str, maxch)
+ } else {
+ call zcall3 (WIN_FUNC(pwin), win, str, maxch)
+ }
+
+end
+
+# EDITFN -- Default function to process window input
+
+procedure editfn (win, str, maxch)
+
+int win # i: Window descriptor
+char str[ARB] # u: String containing line
+int maxch # i: Maximum line length
+#--
+int row, col, ch, ic, jc, mc, nc
+pointer sp, buffer
+
+int strlen(), k_get(), winstat()
+
+begin
+ ic = 0
+ nc = strlen (str)
+
+ row = winstat (win, W_CURROW)
+ col = winstat (win, W_CURCOL)
+
+ call smark (sp)
+ call salloc (buffer, SZ_LINE, TY_CHAR)
+ Memc[buffer] = EOS
+
+ while (nc < maxch) {
+
+ # Read character from keyboard
+
+ call ps_synch
+ ch = k_get ()
+
+ # Check for carriage return
+
+ if (ch == '\r')
+ break
+
+ if (IS_PRINT(ch)) {
+ ic = ic + 1
+ nc = nc + 1
+
+ if (ic == nc) {
+ str[ic] = ch
+ str[ic+1] = EOS
+ call waddstr (win, str[ic])
+
+ } else {
+ call amovc (str[ic], str[ic+1], nc-ic+1)
+
+ str[ic] = ch
+ call winsch (win, str[ic])
+ }
+
+ } else {
+ switch (ch) {
+ case K_UP: # Move up one field
+ break
+
+ case K_DOWN: # Move down one field
+ break
+
+ case K_RIGHT: # Move right one column
+ if (ic < nc) {
+ ic = ic + 1
+ call wmove (win, row, col+ic)
+ }
+
+ case K_LEFT: # Move left one column
+ if (ic > 0) {
+ ic = ic - 1
+ call wmove (win, row, col+ic)
+ }
+
+ case K_NEXTW: # Move forwards one word
+ call mvword_next (str, ic, jc)
+
+ if (jc > ic) {
+ ic = jc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_PREVW: # Move backwards one word
+ call mvword_prev (str, ic, jc)
+
+ if (jc < ic) {
+ ic = jc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_NEXTP: # Move forwards one screen
+ break
+
+ case K_PREVP: # Move backwards one screen
+ break
+
+ case K_HOME: # Move to first field
+ break
+
+ case K_END: # Move to last field
+ break
+
+ case K_BOL: # Move to first column in line
+ if (ic > 0) {
+ ic = 0
+ call wmove (win, row, col)
+ }
+
+ case K_EOL: # Move to last column in line
+ if (ic < nc) {
+ ic = nc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_DEL: # Delete character underneath cursor
+ if (ic < nc) {
+ mc = strlen (Memc[buffer])
+
+ Memc[buffer+mc] = str[ic+1]
+ Memc[buffer+mc+1] = EOS
+
+ call amovc (str[ic+2], str[ic+1], nc-ic)
+
+ call wdelch (win)
+ nc = nc - 1
+ }
+
+ case K_BS: # Delete character to left of cursor
+ if (ic > 0) {
+ mc = strlen (Memc[buffer])
+
+ call amovc (Memc[buffer], Memc[buffer+1], mc+1)
+ Memc[buffer] = str[ic]
+
+ ic = ic - 1
+ call amovc (str[ic+2], str[ic+1], nc-ic)
+
+ call wmove (win, row, col+ic)
+ call wdelch (win)
+ nc = nc - 1
+ }
+
+ case K_DWORD: # Delete next word
+ call mvword_next (str, ic, jc)
+
+ if (jc > ic) {
+ mc = strlen (Memc[buffer])
+ call strcpy (str[ic+1], Memc[buffer+mc], jc-ic)
+ call amovc (str[jc+1], str[ic+1], nc-jc+1)
+
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+ call wmove (win, row, col+ic)
+ nc = nc - (jc - ic)
+ }
+
+ case K_DLINE: # Delete entire line
+ if (nc > 0) {
+ call strcpy (str[ic+1], Memc[buffer], nc-ic)
+ str[ic+1] = EOS
+
+ call wclrtoeol (win)
+ nc = ic
+ }
+
+ case K_UNDCHR: # Undelete a character
+ mc = strlen (Memc[buffer])
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+2], nc-ic+1)
+ str[ic+1] = Memc[buffer+mc-1]
+
+ Memc[buffer+mc-1] = EOS
+ call winsch (win, str[ic+1])
+
+ ic = ic + 1
+ nc = nc + 1
+ }
+
+ case K_UNDWRD: # Undelete a word
+ mc = strlen (Memc[buffer])
+ call mvword_prev (Memc[buffer], mc, jc)
+
+ mc = mc - jc
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+mc+1], nc-ic+1)
+ call amovc (Memc[buffer+jc], str[ic+1], mc)
+
+ Memc[buffer+jc] = EOS
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+
+ ic = ic + mc
+ nc = nc + mc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_UNDLIN: # Undelete a line
+ mc = strlen (Memc[buffer])
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+mc+1], nc-ic+1)
+ call amovc (Memc[buffer], str[ic+1], mc)
+
+ Memc[buffer] = EOS
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+
+ ic = ic + mc
+ nc = nc + mc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_HELP: # Display help screen
+ break
+
+ case K_PAINT: # Redraw the screen
+ call clearok (STDSCR, true)
+ call wrefresh (STDSCR)
+ call wmove (win, row, col+ic)
+
+ case K_EXIT: # Exit procedure
+ break
+
+ default: # Any other character
+ break
+ }
+ }
+ }
+
+ # Terminate string with EOS and push back character
+ # that terminated input
+
+ if (nc >= maxch)
+ ch = EOS
+
+ str[nc+1] = EOS
+ call k_pushbk (ch)
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/getstruct.x b/pkg/utilities/nttools/tedit/display/curses/getstruct.x
new file mode 100644
index 00000000..9fbce77e
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/getstruct.x
@@ -0,0 +1,27 @@
+include "../curses.h"
+include "window.h"
+
+# GETSTRUCT -- Get the data structure associated with a window
+
+procedure getstruct (structure)
+
+pointer structure # o: Data structure
+#--
+
+begin
+ call wgetstruct (STDSCR, structure)
+end
+
+procedure wgetstruct (win, structure)
+
+int win # i: Window descriptor
+pointer structure # o: Data structure
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+ structure = WIN_DATA(pwin)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/getyx.x b/pkg/utilities/nttools/tedit/display/curses/getyx.x
new file mode 100644
index 00000000..d25b9b46
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/getyx.x
@@ -0,0 +1,22 @@
+include "window.h"
+
+# GETYX -- Get the current cursor position
+#
+# B.Simon 02-Oct-90 Original
+
+procedure getyx (win, row, col)
+
+int win # i: Window descriptor
+int row # o: Cursor row
+int col # o: Cursor column
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ row = WIN_CURROW(pwin)
+ col = WIN_CURCOL(pwin)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/hidewin.x b/pkg/utilities/nttools/tedit/display/curses/hidewin.x
new file mode 100644
index 00000000..f116cffd
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/hidewin.x
@@ -0,0 +1,40 @@
+include "../curses.h"
+include "window.h"
+
+# HIDEWIN -- Hide a window
+#
+# B.Simon 28-Sep-90 Original
+
+procedure hidewin (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin, buffer
+
+begin
+ pwin = warray[win]
+
+ # Don't do anything if the screen under the window wasn't
+ # saved or the window is already hidden
+
+ if (WIN_BUFFER(pwin) == NULL || WIN_HIDDEN(pwin) == YES)
+ return
+
+ # Save the current window contents in a buffer,
+ # and restore the screen under the window
+
+ call wrect (win, YES, rect)
+ call getscreen (rect, buffer)
+ call putscreen (rect, WIN_BUFFER(pwin))
+
+ # Place the window contents in its own buffer and
+ # mark the window as hidden
+
+ call freescreen (WIN_BUFFER(pwin))
+ WIN_BUFFER(pwin) = buffer
+ WIN_HIDDEN(pwin) = YES
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/inch.x b/pkg/utilities/nttools/tedit/display/curses/inch.x
new file mode 100644
index 00000000..9d80df3b
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/inch.x
@@ -0,0 +1,49 @@
+include "../curses.h"
+include "window.h"
+
+# INCH -- Get character at current cursor position
+#
+# B.Simon 02-Oct-90 Original
+
+char procedure inch ()
+
+#--
+char winch()
+
+begin
+ return (winch (STDSCR))
+end
+
+char procedure winch (win)
+
+pointer win # i: Window descriptor
+#--
+include "window.com"
+
+char ch
+int rect[RSIZE]
+pointer pwin, buf
+
+begin
+ pwin = warray[win]
+
+ # Create a box containing the character
+
+ if (WIN_BOXED(pwin) == NO) {
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin) - 1
+ } else {
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin)
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin)
+ }
+ RBOT(rect) = RTOP(rect)
+ RRIGHT(rect) = RLEFT(rect)
+
+ # Get the character under the cursor
+
+ call getscreen (rect, buf)
+ ch = Memc[buf]
+ call freescreen (buf)
+
+ return (ch)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/initscr.x b/pkg/utilities/nttools/tedit/display/curses/initscr.x
new file mode 100644
index 00000000..caa6b9fb
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/initscr.x
@@ -0,0 +1,33 @@
+include "../curses.h"
+include "window.h"
+
+# INITSCR -- Initialize curses routines
+
+procedure initscr ()
+
+#--
+include "window.com"
+
+int stdscr
+string cmdlist CMDSTR
+
+int newwin()
+
+begin
+ # Initialize global variables
+
+ saved = NO
+ echoed = YES
+ call aclri (warray, MAXWIN)
+
+ # Initialize terminal
+
+ call ps_begin
+ call k_begin (cmdlist)
+
+ # Create standard screen (STDSCR)
+
+ stdscr = newwin (GIANT, GIANT, 1, 1)
+ saved = YES
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/insch.x b/pkg/utilities/nttools/tedit/display/curses/insch.x
new file mode 100644
index 00000000..67dc9a7b
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/insch.x
@@ -0,0 +1,51 @@
+include "../curses.h"
+include "window.h"
+
+# INSCH -- Insert a character in the window
+#
+# B.Simon 02-Oct-90 Original
+
+procedure insch (ch)
+
+char ch # i: Character to insert
+#--
+
+begin
+ call winsch (STDSCR, ch)
+end
+
+procedure winsch (win, ch)
+
+pointer win # i: Window descriptor
+char ch # i: Character to insert
+#--
+include "window.com"
+
+char str[1]
+int rect[RSIZE]
+pointer pwin
+
+begin
+
+ pwin = warray[win]
+
+ # Construct rectangle to slide
+
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin) + WIN_CURCOL(pwin) - 1
+ RBOT(rect) = RTOP(rect)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+
+ # Slide rectangle
+
+ call wslide (rect, DIR_RIGHT, 1)
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+
+ # Write new character
+
+ str[1] = ch
+ str[2] = EOS
+ call waddstr (win, str)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/insertln.x b/pkg/utilities/nttools/tedit/display/curses/insertln.x
new file mode 100644
index 00000000..604d860d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/insertln.x
@@ -0,0 +1,41 @@
+include "../curses.h"
+include "window.h"
+
+# INSERTLN -- Insert a blank line in the window
+#
+# B.Simon 02-Oct-90 Original
+
+procedure insertln ()
+
+#--
+
+begin
+ call winsertln (STDSCR)
+end
+
+procedure winsertln (win)
+
+pointer win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ # Construct rectangle to slide
+
+ RTOP(rect) = WIN_TOP(pwin) + WIN_CURROW(pwin) - 1
+ RLEFT(rect) = WIN_LEFT(pwin)
+ RBOT(rect) = WIN_BOT(pwin)
+ RRIGHT(rect) = WIN_RIGHT(pwin)
+
+ call wslide (rect, DIR_DOWN, 1)
+
+ if (WIN_LEAVE(pwin) == NO)
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/leaveok.x b/pkg/utilities/nttools/tedit/display/curses/leaveok.x
new file mode 100644
index 00000000..3ce0f208
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/leaveok.x
@@ -0,0 +1,21 @@
+include "window.h"
+
+# LEAVEOK -- Set the leave flag for a window
+#
+# B.Simon 02-Oct-90 Original
+
+procedure leaveok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+#--
+include "window.com"
+
+pointer pwin
+int btoi()
+
+begin
+ pwin = warray[win]
+ WIN_LEAVE(pwin) = btoi (flag)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/mkpkg b/pkg/utilities/nttools/tedit/display/curses/mkpkg
new file mode 100644
index 00000000..7708de04
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/mkpkg
@@ -0,0 +1,49 @@
+# Update the display library.
+# Author: B.Simon 01-APR-91
+
+$checkout libpkg.a ../../
+$update libpkg.a
+$checkin libpkg.a ../../
+$exit
+
+libpkg.a:
+ addch.x "../curses.h"
+ addstr.x <ctype.h> "../curses.h" "window.h" "window.com"
+ bindstruct.x "../curses.h" "window.h" "window.com"
+ box.x "../curses.h" "window.h" "window.com"
+ clear.x "../curses.h" "window.h" "window.com"
+ clearok.x "window.h" "window.com"
+ clrtobot.x "../curses.h" "window.h" "window.com"
+ clrtoeol.x "../curses.h" "window.h" "window.com"
+ delch.x "../curses.h" "window.h" "window.com"
+ deleteln.x "../curses.h" "window.h" "window.com"
+ delwin.x "../curses.h" "window.h" "window.com"
+ echo.x "window.h" "window.com"
+ endwin.x "window.h" "window.com"
+ erase.x "../curses.h" "window.h" "window.com"
+ freescreen.x
+ getch.x "../curses.h" "window.h" "window.com"
+ getscreen.x "../curses.h"
+ getstr.x "../curses.h" "window.h" "window.com"
+ getstruct.x "../curses.h" "window.h" "window.com"
+ getyx.x "window.h" "window.com"
+ hidewin.x "../curses.h" "window.h" "window.com"
+ inch.x "../curses.h" "window.h" "window.com"
+ initscr.x "../curses.h" "window.h" "window.com"
+ insch.x "../curses.h" "window.h" "window.com"
+ insertln.x "../curses.h" "window.h" "window.com"
+ leaveok.x "window.h" "window.com"
+ move.x "../curses.h" "window.h" "window.com"
+ mvwin.x "../curses.h" "window.h" "window.com"
+ mvword.x
+ newwin.x "../curses.h" "window.h" "window.com"
+ putscreen.x "../curses.h"
+ refresh.x "../curses.h" "window.h" "window.com"
+ savewin.x "window.h" "window.com"
+ scrollok.x "window.h" "window.com"
+ showwin.x "../curses.h" "window.h" "window.com"
+ standout.x "../curses.h" "window.h" "window.com"
+ wdimen.x "../curses.h" "window.h" "window.com"
+ winstat.x "../curses.h" "window.h" "window.com"
+ wslide.x "../curses.h"
+ ;
diff --git a/pkg/utilities/nttools/tedit/display/curses/move.x b/pkg/utilities/nttools/tedit/display/curses/move.x
new file mode 100644
index 00000000..ba3725f7
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/move.x
@@ -0,0 +1,39 @@
+include "../curses.h"
+include "window.h"
+
+# MOVE -- Move the cursor coordinates
+#
+# B.Simon 02-Oct-90 Original
+
+procedure move (row, col)
+
+int row # i: Cursor row
+int col # i: Cursor column
+#--
+
+begin
+ call wmove (STDSCR, row, col)
+end
+
+procedure wmove (win, row, col)
+
+int win # i: Window descriptor
+int row # i: Cursor row
+int col # i: Cursor column
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ WIN_CURROW(pwin) = max (1, row)
+ WIN_CURROW(pwin) = min (WIN_CURROW(pwin), WIN_HEIGHT(pwin))
+
+ WIN_CURCOL(pwin) = max (1, col)
+ WIN_CURCOL(pwin) = min (WIN_CURCOL(pwin), WIN_WIDTH(pwin))
+
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/mvwin.x b/pkg/utilities/nttools/tedit/display/curses/mvwin.x
new file mode 100644
index 00000000..dd7b9d73
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/mvwin.x
@@ -0,0 +1,63 @@
+include "../curses.h"
+include "window.h"
+
+# MVWIN -- Move home position of a window
+#
+# B.Simon 28-Sep-90 Original
+
+procedure mvwin (win, row, col)
+
+int win # i: Window descriptor
+int row # i: New top row of window
+int col # i: New left column of window
+#--
+include "window.com"
+
+bool shown
+int rect[RSIZE]
+int maxrow, maxcol, drow, dcol
+pointer pwin
+
+int ps_width(), ps_height()
+
+begin
+ pwin = warray[win]
+
+ # Compute new rectangle containing window
+ # Make sure it is confined to the current screen
+
+ maxrow = ps_height ()
+ maxcol = ps_width ()
+
+ drow = WIN_HEIGHT(pwin) - 1
+ dcol = WIN_WIDTH(pwin) - 1
+
+ RTOP(rect) = max (1, row)
+ if (RTOP(rect) + drow > maxrow)
+ RTOP(rect) = maxrow - drow
+
+ RLEFT(rect) = max (1, col)
+ if (RLEFT(rect) + dcol > maxcol)
+ RLEFT(rect) = maxcol - dcol
+
+ RBOT(rect) = RTOP(rect) + drow
+ RRIGHT(rect) = RLEFT(rect) + dcol
+
+ # Move the window by hiding it at its old location
+ # and showing it at the new location
+
+ if (RTOP(rect) != WIN_TOP(pwin) || RLEFT(rect) != WIN_LEFT(pwin)) {
+ shown = WIN_HIDDEN(pwin) == NO
+ if (shown)
+ call hidewin (win)
+
+ WIN_TOP(pwin) = RTOP(rect)
+ WIN_LEFT(pwin) = RLEFT(rect)
+ WIN_BOT(pwin) = RBOT(rect)
+ WIN_RIGHT(pwin) = RRIGHT(rect)
+
+ if (shown)
+ call showwin (win)
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/mvword.x b/pkg/utilities/nttools/tedit/display/curses/mvword.x
new file mode 100644
index 00000000..6a606e0d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/mvword.x
@@ -0,0 +1,56 @@
+# MVWORD -- Move one word over in a string
+#
+# B.Simon 20-Mar-91 Original
+
+procedure mvword_next (str, ic, jc)
+
+char str[ARB] # i: String containing words
+int ic # i: Starting character (0 to strlen(str))
+int jc # o: Character before start of next word
+#--
+int nc
+int strlen()
+
+begin
+ # Find next blank
+
+ nc = strlen (str)
+ for (jc = min (ic+1, nc); jc < nc; jc = jc + 1) {
+ if (str[jc] <= ' ')
+ break
+ }
+
+ # Find first non-blank character after blank
+
+ for ( ; jc < nc; jc = jc + 1) {
+ if (str[jc] > ' ') {
+ jc = jc - 1 # back up to previous blank
+ break
+ }
+ }
+
+end
+
+procedure mvword_prev (str, ic, jc)
+
+char str[ARB] # i: String containing words
+int ic # i: Starting character (0 to strlen(str))
+int jc # o: Character before start of next word
+#--
+
+begin
+ # Find previous nonblank character
+
+ for (jc = max (ic-1, 0); jc > 0; jc = jc - 1) {
+ if (str[jc] > ' ')
+ break
+ }
+
+ # Find blank preceding non-blank character
+
+ for ( ; jc > 0; jc = jc - 1) {
+ if (str[jc] <= ' ')
+ break
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/newwin.x b/pkg/utilities/nttools/tedit/display/curses/newwin.x
new file mode 100644
index 00000000..f2195309
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/newwin.x
@@ -0,0 +1,83 @@
+include "../curses.h"
+include "window.h"
+
+# NEWWIN -- Create a new window
+#
+# B.Simon 28-Sep-90 Original
+
+int procedure newwin (nrows, ncols, row, col)
+
+int nrows # i: Window height
+int ncols # i: Window width
+int row # i: Top row of window
+int col # i: Leftmost column of window
+#--
+include "window.com"
+
+int win, maxrow, maxcol
+pointer pwin
+
+int ps_height(), ps_width()
+
+begin
+ # Find an empty slot in the window array and allocate a window
+
+ for (win = 1; win <= MAXWIN; win = win + 1) {
+ if (warray[win] == NULL)
+ break
+ }
+
+ if (win > MAXWIN)
+ call error (1, "Cannot create window")
+
+ call malloc (pwin, LEN_WINSTRUCT, TY_STRUCT)
+ warray[win] = pwin
+
+ # Compute the window's rectangle, making sure it is on the screen
+
+ maxrow = ps_height ()
+ maxcol = ps_width ()
+
+ if (row + nrows - 1 > maxrow)
+ WIN_TOP(pwin) = maxrow - nrows + 1
+ else
+ WIN_TOP(pwin) = row
+ WIN_TOP(pwin) = max (1, WIN_TOP(pwin))
+
+ if (col + ncols - 1 > maxcol)
+ WIN_LEFT(pwin) = maxcol - ncols + 1
+ else
+ WIN_LEFT(pwin) = col
+ WIN_LEFT(pwin) = max (1, WIN_LEFT(pwin))
+
+ WIN_BOT(pwin) = min (maxrow, WIN_TOP(pwin) + nrows - 1)
+ WIN_RIGHT(pwin) = min (maxcol, WIN_LEFT(pwin) + ncols - 1)
+
+ # Set the remaining fields of the window
+
+ WIN_CURROW(pwin) = 1
+ WIN_CURCOL(pwin) = 1
+ WIN_CLEAR(pwin) = NO
+ WIN_LEAVE(pwin) = NO
+ WIN_SCROLL(pwin) = NO
+ WIN_HIDDEN(pwin) = NO
+ WIN_BOXED(pwin) = NO
+ WIN_ATRIB(pwin) = A_NORM
+
+ if (saved == NO) {
+ WIN_BUFFER(pwin) = NULL
+ } else {
+ call getscreen (WIN_RECT(pwin), WIN_BUFFER(pwin))
+ }
+
+ WIN_FUNC(pwin) = NULL
+ WIN_DATA(pwin) = NULL
+
+ # Erase the window
+
+ call werase (win)
+
+ # Return window number
+
+ return (win)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/omkpkg b/pkg/utilities/nttools/tedit/display/curses/omkpkg
new file mode 100644
index 00000000..21c3c249
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/omkpkg
@@ -0,0 +1,65 @@
+
+# Update the newdisp library.
+# Author: B.Simon 26-SEP-90
+
+$set XFLAGS = "-fgq $(XFLAGS)"
+$call default
+$exit
+
+debug:
+ $set XFLAGS = "-fgq $(XFLAGS)"
+ $call default
+ ;
+
+strip:
+ $delete newdisp.a
+ $call default
+ ;
+
+update:
+default:
+ $checkout newdisp.a ../../
+ $update newdisp.a
+ $checkin newdisp.a ../../
+ ;
+
+newdisp.a:
+ addch.x <curses.h>
+ addstr.x <ctype.h> <curses.h> "window.h" "window.com"
+ bindstruct.x <curses.h> "window.h" "window.com"
+ box.x <curses.h> "window.h" "window.com"
+ clear.x <curses.h> "window.h" "window.com"
+ clearok.x "window.h" "window.com"
+ clrtobot.x <curses.h> "window.h" "window.com"
+ clrtoeol.x <curses.h> "window.h" "window.com"
+ delch.x <curses.h> "window.h" "window.com"
+ deleteln.x <curses.h> "window.h" "window.com"
+ delwin.x <curses.h> "window.h" "window.com"
+ echo.x "window.h" "window.com"
+ endwin.x "window.h" "window.com"
+ erase.x <curses.h> "window.h" "window.com"
+ freescreen.x
+ getch.x <curses.h> "window.h" "window.com"
+ getscreen.x <curses.h>
+ getstr.x <curses.h> "window.h" "window.com"
+ getstruct.x <curses.h> "window.h" "window.com"
+ getyx.x "window.h" "window.com"
+ hidewin.x <curses.h> "window.h" "window.com"
+ inch.x <curses.h> "window.h" "window.com"
+ initscr.x <curses.h> "window.h" "window.com"
+ insch.x <curses.h> "window.h" "window.com"
+ insertln.x <curses.h> "window.h" "window.com"
+ leaveok.x "window.h" "window.com"
+ move.x <curses.h> "window.h" "window.com"
+ mvwin.x <curses.h> "window.h" "window.com"
+ newwin.x <curses.h> "window.h" "window.com"
+ putscreen.x <curses.h>
+ refresh.x <curses.h> "window.h" "window.com"
+ savewin.x "window.h" "window.com"
+ scrollok.x "window.h" "window.com"
+ showwin.x <curses.h> "window.h" "window.com"
+ standout.x <curses.h> "window.h" "window.com"
+ wdimen.x <curses.h> "window.h" "window.com"
+ winstat.x <curses.h> "window.h" "window.com"
+ wslide.x <curses.h>
+ ;
diff --git a/pkg/utilities/nttools/tedit/display/curses/putscreen.x b/pkg/utilities/nttools/tedit/display/curses/putscreen.x
new file mode 100644
index 00000000..83bb4966
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/putscreen.x
@@ -0,0 +1,84 @@
+include "../curses.h"
+
+# PUTSCREEN -- Copy buffer back onto screen
+#
+# B.Simon 27-Sep-90 Original
+
+procedure putscreen (source, buffer)
+
+int source[RSIZE] # i: Rectangle to be restored
+pointer buffer # i: Buffer
+#--
+
+bool clear
+int blank, dest[RSIZE]
+int maxcol, maxrow, ncols, nrows, icol, jcol, irow
+pointer sp, buf, ptr, scr
+
+data blank / ' ' /
+
+bool ps_intersect()
+int ps_width(), ps_height()
+pointer ps_screen()
+
+begin
+ # Clip rectangle at screen boundary
+
+ maxcol = ps_width ()
+ maxrow = ps_height ()
+ if (! ps_intersect (source, maxrow, maxcol, dest))
+ return
+
+ call smark (sp)
+ ncols = RWIDTH(dest)
+ nrows = RHEIGHT(dest)
+
+ # If the buffer pointer is null,
+ # copy the current screen contents instead
+
+ if (buffer != NULL) {
+ buf = buffer
+ } else {
+ call salloc (buf, nrows*ncols, TY_CHAR)
+
+ ptr = buf
+ scr = ps_screen (RTOP(dest), RLEFT(dest))
+ do irow = 1, nrows {
+ call amovc (Memc[scr], Memc[ptr], ncols)
+ scr = scr + maxcol
+ ptr = ptr + ncols
+ }
+ }
+
+ # See if clearing the screen first would be faster
+ # if so, do it
+
+ clear = ncols == maxcol
+ if (clear)
+ call ps_fill (dest, blank, A_NORM)
+
+ # Copy buffer to screen using ps_wrtcells
+
+ do irow = RTOP(dest), RBOT(dest) {
+ icol = 1
+ jcol = ncols
+
+ # If the screen has been cleared, don't write blanks
+
+ if (clear) {
+ while (icol <= ncols && Memc[buf+icol-1] == blank)
+ icol = icol + 1
+ while (jcol >= icol && Memc[buf+jcol-1] == blank)
+ jcol = jcol - 1
+ }
+
+ if (jcol >= icol) {
+ call ps_wrtcells (irow, RLEFT(dest)+icol-1,
+ Memc[buf+icol-1], jcol-icol+1)
+ }
+
+ buf = buf + ncols
+ }
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/refresh.x b/pkg/utilities/nttools/tedit/display/curses/refresh.x
new file mode 100644
index 00000000..b65885d8
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/refresh.x
@@ -0,0 +1,42 @@
+include "../curses.h"
+include "window.h"
+
+# REFRESH -- Bring the terminal screen up to date
+#
+# B.Simon 02-Oct-90 Original
+
+procedure refresh ()
+
+#--
+
+begin
+ call wrefresh (STDSCR)
+end
+
+procedure wrefresh (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin
+
+begin
+ pwin = warray[win]
+
+ # If the clear flag is set, redraw the contents of the window
+
+ if (WIN_CLEAR(pwin) == YES) {
+ WIN_CLEAR(pwin) = NO
+ call wrect (win, YES, rect)
+ call putscreen (rect, NULL)
+
+ if (WIN_LEAVE(pwin) == NO) {
+ call ps_setcur (WIN_TOP(pwin)+WIN_CURROW(pwin)-1,
+ WIN_LEFT(pwin)+WIN_CURCOL(pwin)-1)
+ }
+ }
+
+ call ps_synch
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/savewin.x b/pkg/utilities/nttools/tedit/display/curses/savewin.x
new file mode 100644
index 00000000..6be4bc72
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/savewin.x
@@ -0,0 +1,23 @@
+include "window.h"
+
+# SAVEWIN -- Save characters under window when a window is created
+#
+# B.Simon 18-Oct-90 Original
+
+procedure savewin ()
+
+#--
+include "window.com"
+
+begin
+ saved = YES
+end
+
+procedure nosavewin ()
+
+#--
+include "window.com"
+
+begin
+ saved = NO
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/scrollok.x b/pkg/utilities/nttools/tedit/display/curses/scrollok.x
new file mode 100644
index 00000000..dfbb3317
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/scrollok.x
@@ -0,0 +1,21 @@
+include "window.h"
+
+# SCROLLOK -- Set the scroll flag for a window
+#
+# B.Simon 02-Oct-90 Original
+
+procedure scrollok (win, flag)
+
+int win # i: Window descriptor
+bool flag # i: Flag value
+#--
+include "window.com"
+
+pointer pwin
+int btoi()
+
+begin
+ pwin = warray[win]
+ WIN_SCROLL(pwin) = btoi (flag)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/showwin.x b/pkg/utilities/nttools/tedit/display/curses/showwin.x
new file mode 100644
index 00000000..66d4c866
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/showwin.x
@@ -0,0 +1,39 @@
+include "../curses.h"
+include "window.h"
+
+# SHOWWIN -- Show a previously hidden window
+#
+# B.Simon 28-Sep-90 Original
+
+procedure showwin (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+int rect[RSIZE]
+pointer pwin, buffer
+
+begin
+ pwin = warray[win]
+
+ # Don't do anything if the window is already visible
+
+ if (WIN_HIDDEN(pwin) == NO)
+ return
+
+ # Save the screen under the window in a buffer
+ # and display the window's contents
+
+ call wrect (win, YES, rect)
+ call getscreen (rect, buffer)
+ call putscreen (rect, WIN_BUFFER(pwin))
+
+ # Copy the screen buffer into the window's buffer and
+ # mark the window as visible
+
+ call freescreen (WIN_BUFFER(pwin))
+ WIN_BUFFER(pwin) = buffer
+ WIN_HIDDEN(pwin) = NO
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/standout.x b/pkg/utilities/nttools/tedit/display/curses/standout.x
new file mode 100644
index 00000000..855dab58
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/standout.x
@@ -0,0 +1,48 @@
+include "../curses.h"
+include "window.h"
+
+# STANDOUT -- Put the window in standout mode
+#
+# B.Simon 02-Oct-90 Original
+
+procedure standout ()
+
+#--
+
+begin
+ call wstandout (STDSCR)
+end
+
+procedure wstandout (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+ WIN_ATRIB(pwin) = A_STANDOUT
+end
+
+procedure standend ()
+
+#--
+
+begin
+ call wstandend (STDSCR)
+end
+
+procedure wstandend (win)
+
+int win # i: Window descriptor
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+ WIN_ATRIB(pwin) = A_NORM
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/wdimen.x b/pkg/utilities/nttools/tedit/display/curses/wdimen.x
new file mode 100644
index 00000000..55d5a6cf
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/wdimen.x
@@ -0,0 +1,45 @@
+include "../curses.h"
+include "window.h"
+
+# WDIMEN -- Return dimensions of a window
+#
+# B.Simon 11-Oct-90 Original
+
+procedure wdimen (win, nrows, ncols)
+
+int win # i: Window descriptor
+int nrows # o: Window height
+int ncols # o: Window width
+#--
+int rect[RSIZE]
+
+begin
+ call wrect (win, NO, rect)
+
+ nrows = RHEIGHT(rect)
+ ncols = RWIDTH(rect)
+end
+
+# WRECT -- Get the rectangle containing the window
+
+procedure wrect (win, border, rect)
+
+int win # i: Window descriptor
+int border # i: Include border in dimensions?
+int rect[RSIZE] # o: Rectangle containing window dimensions
+#--
+include "window.com"
+
+pointer pwin
+
+begin
+ pwin = warray[win]
+ if (border == NO || WIN_BOXED(pwin) == NO) {
+ RASG(rect, WIN_TOP(pwin), WIN_LEFT(pwin),
+ WIN_BOT(pwin), WIN_RIGHT(pwin))
+
+ } else {
+ RASG(rect, WIN_TOP(pwin)-1, WIN_LEFT(pwin)-1,
+ WIN_BOT(pwin)+1, WIN_RIGHT(pwin)+1)
+ }
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/window.com b/pkg/utilities/nttools/tedit/display/curses/window.com
new file mode 100644
index 00000000..74b0a38c
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/window.com
@@ -0,0 +1,7 @@
+# WINDOW.COM -- Global variables used by the curses subroutines
+
+int saved # Save rectangle under window when creating
+int echoed # Echo characters
+pointer warray[MAXWIN] # Array holding window descriptors
+
+common /window/ saved, echoed, warray
diff --git a/pkg/utilities/nttools/tedit/display/curses/window.h b/pkg/utilities/nttools/tedit/display/curses/window.h
new file mode 100644
index 00000000..41141580
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/window.h
@@ -0,0 +1,28 @@
+# WINDOW.H -- Window structure definitions and macros
+
+define MAXWIN 50 # Maximum number of windows
+define LEN_WINSTRUCT 15 # Length of window structure
+
+# definition of window structure
+
+define WIN_TOP Memi[$1] # Window's top row
+define WIN_LEFT Memi[$1+1] # Window's leftmost column
+define WIN_BOT Memi[$1+2] # Window's bottom row
+define WIN_RIGHT Memi[$1+3] # Window's rightmost column
+define WIN_CURROW Memi[$1+4] # Cursor row relative to window
+define WIN_CURCOL Memi[$1+5] # Cursor column relative to window
+define WIN_CLEAR Memi[$1+6] # Redraw window when refreshed
+define WIN_LEAVE Memi[$1+7] # Leave cursor after redraw
+define WIN_SCROLL Memi[$1+8] # Window will scroll
+define WIN_HIDDEN Memi[$1+9] # Window is hidden
+define WIN_BOXED Memi[$1+10] # Window is boxed
+define WIN_ATRIB Memi[$1+11] # Character attribute of window
+define WIN_BUFFER Memi[$1+12] # Holds characters under the window
+define WIN_FUNC Memi[$1+13] # Function bound to window
+define WIN_DATA Memi[$1+14] # Data structure bound to window
+
+# Macros used to manipulate rectangle
+
+define WIN_RECT Memi[$1]
+define WIN_WIDTH (WIN_RIGHT($1) - WIN_LEFT($1) + 1)
+define WIN_HEIGHT (WIN_BOT($1) - WIN_TOP($1) + 1)
diff --git a/pkg/utilities/nttools/tedit/display/curses/winstat.x b/pkg/utilities/nttools/tedit/display/curses/winstat.x
new file mode 100644
index 00000000..e89e3ca6
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/winstat.x
@@ -0,0 +1,51 @@
+include "../curses.h"
+include "window.h"
+
+# WINSTAT -- Retrieve a field from a window structure
+
+int procedure winstat (win, what)
+
+int win # i: Window descriptor
+int what # i: Field to retrieve
+#--
+include "window.com"
+
+int value
+pointer pwin
+
+string badcode "Unrecognized argument to winstat"
+
+begin
+ pwin = warray[win]
+
+ switch (what) {
+ case W_TOP:
+ value = WIN_TOP(pwin)
+ case W_LEFT:
+ value = WIN_LEFT(pwin)
+ case W_BOT:
+ value = WIN_BOT(pwin)
+ case W_RIGHT:
+ value = WIN_RIGHT(pwin)
+ case W_CURROW:
+ value = WIN_CURROW(pwin)
+ case W_CURCOL:
+ value = WIN_CURCOL(pwin)
+ case W_CLEAR:
+ value = WIN_CLEAR(pwin)
+ case W_LEAVE:
+ value = WIN_LEAVE(pwin)
+ case W_SCROLL:
+ value = WIN_SCROLL(pwin)
+ case W_HIDDEN:
+ value = WIN_HIDDEN(pwin)
+ case W_BOXED:
+ value = WIN_BOXED(pwin)
+ case W_ATRIB:
+ value = WIN_ATRIB(pwin)
+ default:
+ call error (1, badcode)
+ }
+
+ return (value)
+end
diff --git a/pkg/utilities/nttools/tedit/display/curses/wslide.x b/pkg/utilities/nttools/tedit/display/curses/wslide.x
new file mode 100644
index 00000000..b57f68da
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/curses/wslide.x
@@ -0,0 +1,91 @@
+include "../curses.h"
+
+# WSLIDE -- Slide a window's rectangle on the screen
+#
+# B.Simon 25-Sep-90 Original
+
+procedure wslide (source, dir, dist)
+
+int source[RSIZE] # i: Rectangle
+int dir # i: Direction (from display.h)
+int dist # i: Distance (> 0)
+#--
+int blank, dest[RSIZE], rect[RSIZE]
+int maxcol, maxrow, ncols, irow, icol
+pointer sp, buffer, oldscr
+
+data blank / ' ' /
+
+bool ps_slide(), ps_intersect()
+int ps_width(), ps_height()
+pointer ps_screen()
+
+begin
+ # First try to slide the rectangle with ps_slide
+ # (move by using insert and delete control sequences)
+
+ if (ps_slide (source, dir, dist))
+ return
+
+ # If this doesn't work, redraw the rectangle from
+ # the screen buffer using ps_wrtcells and ps_fill
+
+ # The left and write scrolls must first be written
+ # to a buffer to avoid the problem with array overlap
+ # when updating the screen buffer
+
+ maxcol = ps_width ()
+ maxrow = ps_height ()
+ if (! ps_intersect (source, maxrow, maxcol, dest))
+ return
+
+ call smark(sp)
+ ncols = RWIDTH(dest)
+ call salloc (buffer, ncols+dist, TY_CHAR)
+
+ switch (dir) {
+ case DIR_UP:
+ oldscr = ps_screen (RTOP(dest), RLEFT(dest))
+ do irow = RTOP(dest), RBOT(dest)-dist {
+ call ps_wrtcells (irow-dist, RLEFT(dest), Memc[oldscr], ncols)
+ oldscr = oldscr + maxcol
+ }
+
+ RASG (rect, max(RTOP(dest), RBOT(dest)-dist+1), RLEFT(dest),
+ RBOT(dest), RRIGHT(dest))
+ call ps_fill (rect, blank, A_NORM)
+
+ case DIR_DOWN:
+ oldscr = ps_screen (RBOT(dest), RLEFT(dest))
+ do irow = RBOT(dest), RTOP(dest)+dist, -1 {
+ call ps_wrtcells (irow+dist, RLEFT(dest), Memc[oldscr], ncols)
+ oldscr = oldscr - maxcol
+ }
+
+ RASG (rect, RTOP(dest), RLEFT(dest),
+ min(RBOT(dest), RTOP(dest)+dist-1), RRIGHT(dest))
+ call ps_fill (rect, blank, A_NORM)
+
+ case DIR_LEFT:
+ icol = RLEFT(dest) - dist
+ oldscr = ps_screen (RTOP(dest), RLEFT(dest))
+ do irow = RTOP(dest), RBOT(dest) {
+ call amovc (Memc[oldscr], Memc[buffer], ncols)
+ call amovkc (blank, Memc[buffer+ncols], ncols-dist)
+
+ call ps_wrtcells (irow, icol, Memc[buffer], ncols)
+ oldscr = oldscr + maxcol
+ }
+ case DIR_RIGHT:
+ icol = RLEFT(dest) + dist
+ oldscr = ps_screen (RTOP(dest), RLEFT(dest))
+ do irow = RTOP(dest), RBOT(dest) {
+ call amovc (Memc[oldscr], Memc[buffer], ncols)
+
+ call ps_wrtcells (irow, icol, Memc[buffer], ncols)
+ oldscr = oldscr + maxcol
+ }
+ }
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/README b/pkg/utilities/nttools/tedit/display/forms/README
new file mode 100644
index 00000000..cd5feeca
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/README
@@ -0,0 +1,115 @@
+The forms procedures give an example of a display handling library
+built on top of the curses routines. The forms procedures divide the
+terminal screen into two windows, the form and prompt window. The
+form window contains the form fields. Each field in the form occupies
+one line on the screen with the field name on the left side of the
+line and the field value on the right side separated by an equals
+sign. If the number of fields in the form exceed the number of lines
+in the form window, a portion of the fields will be displayed, which
+the user can scroll through. The prompt window is used to read user
+input and display messages. The first line contains a message,
+typically used to list the possible commands, and the second line
+contains the user input.
+
+The following two procedures are used to initialize and terminate the
+form handling. The first procedure, fm_begin, calls the keyboard and
+screen initialization routines, and initializes some global variables.
+The second procedure, fm_end, calls the keyboard and screen
+termination routines.
+
+procedure fm_begin ()
+procedure fm_end ()
+
+The next three procedures handle the form window of the screen. The
+first procedure, fm_mkform(), associates a form with a window. The
+second procedure, fm_getform(), gets user input from the form. The
+third procedure, fm_endform(), frees the data structure associated
+with the form.
+
+The first procedure has the following calling sequence:
+
+procedure fm_mkform (win, nfield, lenname, lenvalue, title, ftype, fname)
+
+int win # i: Window descriptor
+int nfield # i: Number of fields in form
+int lenname # i: Declared length of field name
+int lenvalue # i: Declared length of field value
+char title[ARB] # i: Form title
+int ftype[ARB] # i: Data types of fields
+char fname[lenname,ARB] # i: Names of fields
+
+The first argument, win, is the window descriptor. It is created by
+calling newwin(), the curses procedure which creates windows. The next
+three arguments are used to compute the size of the structure which
+holds the form. The number of fields can be greater than the height of
+the window, as the window will scroll up and down. But the combined
+length of the field name and value must be less than the width of the
+window, as it will not scroll side to side. The title is a string that
+is printed on the title bar, which is the bottom row of the form. The
+title bar also contains the help key escape sequence. Three items of
+information are associated with each field: a type, a name, and a
+value. The type is an integer with the same meaning used by the table
+interface: a negative number if the field is a string whose magnitude
+is equal to the maximum string length or a positive integer equal to
+the spp type code if the field is not a string. The type is used to
+check the field value, the procedure will not let the user enter a
+value of a different type. Each field name is printed on a separate
+line of the form followed by an equals sign.
+
+The second procedure, fm_getform, is used to read or display the
+values associated with the fields of the form. It has the following
+calling sequence:
+
+procedure fm_getform (win, redraw, lenvalue, fvalue)
+
+int win # i: Window descriptor
+bool redraw # i: Redraw screen?
+int lenvalue # i: Declared length of field value
+char fvalue[lenvalue,ARB] # u: Values in fields
+
+The first argument is the window descriptor of the window associated
+with the form. If the second argument, redraw is set to true, the
+window is redrawn when the procedure begins, otherwise the window is
+unchanged. Redraw should set to true the first time this procedure is
+called. The last argument, fvalue, contains the values that are
+displayed on the form. The user updates these values by editing the
+form on the screen. When the user has finished updating the values,
+the modified values are returned to the calling procedure.
+
+The third procedure frees the form data structure. After freeing the
+data structure, the window should be closed by calling delwin. This
+procedure has the following calling sequence:
+
+procedure fm_clsform (win)
+
+int win # i: Window descriptor
+
+
+The next procedure, fm_prompt, handles the prompt window on the screen.
+It has the following calling sequence:
+
+int procedure fm_prompt (commands, message)
+
+char commands[ARB] # i: List of commands
+char message[ARB] # i: Message to print in prompt area
+
+The list of commands is a string containing the possible commands. This
+string is formatted like the dictionary in strdic: the first character
+in the string is a command separator which appears between the commands
+in the string. The message is displayed on the top line of the prompt
+area. If the message is a null string, the command string is displayed
+instead. The user enters one of the commands and presses carriage
+return. The procedure returns the number of the command that the user
+entered if the command is legal, or beeps and displays the list of
+commands if it is not. If the list of commands is a null string, the
+procedure displays the message in the prompt area and returns a value
+of zero without looking for user input.
+
+The last procedure displays the help window. This window covers the
+entire screen. Its argument is the currently active window. It is
+passed so that the cursor can be restored to its previous position
+when the procedure is finished.
+
+procedure fm_help (win)
+
+int win # i: Window which currently is active
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmbegin.x b/pkg/utilities/nttools/tedit/display/forms/fmbegin.x
new file mode 100644
index 00000000..8cf78aba
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmbegin.x
@@ -0,0 +1,20 @@
+# FM_BEGIN -- Initialize form handler
+#
+# B.Simon 25-Jan-88 Original
+# B.Simon 11-Oct-90 Rewritten to use curses
+
+procedure fm_begin ()
+
+#--
+include "forms.com"
+
+begin
+ # Initialize curses
+
+ call initscr
+
+ # Initialize global variables
+
+ helpwin = 0
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmcheck.x b/pkg/utilities/nttools/tedit/display/forms/fmcheck.x
new file mode 100644
index 00000000..d7fa95d4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmcheck.x
@@ -0,0 +1,98 @@
+include <lexnum.h>
+include <ctype.h>
+include <mach.h>
+
+# FM_CHECK -- Check a string against a data type
+#
+# B.Simon 28-Mar-91 Modified to check INDEF correctly
+
+bool procedure fm_check (datatype, str)
+
+int datatype # i: Datatype to check
+char str[ARB] # i: String to be checked
+#--
+bool match
+double strval
+int ic, nc, lextype, strtype
+pointer sp, temp
+
+string yorn "|yes|no|"
+
+bool streq()
+int strlen(), lexnum(), ctod(), strdic()
+
+begin
+ # Don't check null strings
+
+ if (str[1] == EOS)
+ return (true)
+
+ call smark (sp)
+ call salloc (temp, SZ_LINE, TY_CHAR)
+
+ if (datatype < 0)
+
+ # The only check on string types is that they not exceed their
+ # maximum length
+
+ match = strlen (str) <= -(datatype)
+
+ else {
+
+ # Get the data type of the string
+ # Reduce this to character, integer or real
+ # Get the value of the string if it is not character
+
+ if (streq (str, "INDEF")) {
+ strtype = datatype
+ strval = 0.0
+
+ } else {
+ ic = 1
+ lextype = lexnum (str, ic, nc)
+
+ for (ic = ic + nc; IS_WHITE(str[ic]); ic = ic + 1)
+ ;
+ if (str[ic] != EOS)
+ lextype = LEX_NONNUM
+
+ if (lextype == LEX_HEX || lextype == LEX_NONNUM) {
+ strtype = TY_CHAR
+ strval = 0.0
+ } else {
+ if (lextype == LEX_REAL)
+ strtype = TY_REAL
+ else
+ strtype = TY_INT
+
+ ic = 1
+ nc = ctod (str, ic, strval)
+ strval = abs (strval)
+ }
+ }
+
+ # See if the string matches the expected datatype
+
+ switch (datatype) {
+ case TY_BOOL:
+ match = strdic (str, Memc[temp], SZ_LINE, yorn) > 0
+ case TY_CHAR:
+ match = strlen (str) <= 1
+ case TY_SHORT:
+ match = strtype == TY_INT && strval <= MAX_SHORT
+ case TY_INT:
+ match = strtype == TY_INT && strval <= MAX_INT
+ case TY_LONG:
+ match = strtype == TY_INT && strval <= MAX_LONG
+ case TY_REAL:
+ match = strtype != TY_CHAR && strval <= MAX_REAL
+ case TY_DOUBLE:
+ match = strtype != TY_CHAR && strval <= MAX_DOUBLE
+ default:
+ match = true
+ }
+ }
+
+ call sfree (sp)
+ return (match)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmend.x b/pkg/utilities/nttools/tedit/display/forms/fmend.x
new file mode 100644
index 00000000..353ebfe0
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmend.x
@@ -0,0 +1,12 @@
+# FM_END -- Terminate form handler
+#
+# B.Simon 25-Jan-89 Original
+# B.Simon 11-Oct-90 Rewritten to use curses
+
+procedure fm_end ()
+
+#--
+
+begin
+ call endwin
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmgetform.x b/pkg/utilities/nttools/tedit/display/forms/fmgetform.x
new file mode 100644
index 00000000..ebc6d143
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmgetform.x
@@ -0,0 +1,89 @@
+include "../curses.h"
+include "formfn.h"
+
+# FM_GETFORM -- Get user input from a form
+#
+# B.Simon 27-Jan-89 Original
+# B.Simon 12-Dec-90 Rewritten to use curses
+
+procedure fm_getform (win, redraw, lenvalue, fvalue)
+
+int win # i: Window descriptor
+bool redraw # i: Redraw screen?
+int lenvalue # i: Declared length of field value
+char fvalue[lenvalue,ARB] # u: Values in fields
+#--
+bool draw
+int ifield, curfield, topfield, botfield, ch
+pointer data, value
+
+bool fm_check()
+int k_get()
+
+begin
+ # Get pointer to form data structure
+
+ call wgetstruct (win, data)
+
+ # Initialize data structure
+
+ FM_FIELD(data) = 1
+ FM_CHANGE(data) = NO
+
+ # Copy values to data structure
+
+ value = FM_VALARY(data)
+ do ifield = 1, FM_NFIELD(data) {
+ call strcpy (fvalue[1,ifield], Memc[value], lenvalue)
+ value = value + FM_LENVAL(data) + 1
+ }
+
+ # Let user update form
+
+ draw = redraw
+
+ curfield = 1
+ topfield = 1
+ botfield = min (FM_NFIELD(data), topfield + FM_NPAGE(data) - 1)
+
+ repeat {
+
+ # Redraw form and move cursor
+
+ if (draw) {
+ topfield = max (1, curfield - FM_NPAGE(data) / 2)
+ botfield = min (FM_NFIELD(data), topfield + FM_NPAGE(data) - 1)
+ call fm_redraw (win, topfield)
+ }
+
+ call wmove (win, curfield-topfield+1, FM_LENNAM(data)+4)
+
+ value = FM_VALPTR(data,curfield)
+ call weditstr (win, Memc[value], FM_LENVAL(data))
+
+ ch = k_get ()
+
+ if (FM_CHANGE(data) == YES) {
+ if (! fm_check (FM_TYPE(data,curfield),
+ Memc[FM_VALPTR(data,curfield)])) {
+ call ps_beep
+ ch = EOS
+ next
+ }
+ }
+
+ curfield = FM_FIELD(data)
+ FM_CHANGE(data) = NO
+ draw = curfield < topfield || curfield > botfield
+
+ } until (ch == K_EXIT)
+
+ # Copy form values to output array
+
+ value = FM_VALARY(data)
+ do ifield = 1, FM_NFIELD(data) {
+ call strcpy (Memc[value], fvalue[1,ifield], lenvalue)
+ value = value + FM_LENVAL(data) + 1
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmhelp.x b/pkg/utilities/nttools/tedit/display/forms/fmhelp.x
new file mode 100644
index 00000000..8615c031
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmhelp.x
@@ -0,0 +1,132 @@
+include "../curses.h"
+
+define COLWIDTH 40
+define LABEL_FLAG 1
+define NAME_FLAG 2
+
+# FM_HELP -- Display help window for function key sequences
+
+procedure fm_help (win)
+
+int win # i: Window which currently is active
+#--
+include "forms.com"
+
+int key, row, col
+int k_get(), winstat()
+
+begin
+ # If the help screen was created on a previous call,
+ # display it, otherwise make a new help screen
+
+ if (helpwin != 0) {
+ call showwin (helpwin)
+ } else {
+ call fm_hmake (helpwin)
+ }
+
+ # Display help screen and wait for keystroke to hide window
+
+ call refresh
+ key = k_get ()
+
+ # Hide the help window and restore cursor to current window
+
+ call hidewin (helpwin)
+
+ row = winstat (win, W_CURROW)
+ col = winstat (win, W_CURCOL)
+ call wmove (win, row, col)
+
+end
+
+procedure fm_hmake (hwin)
+
+pointer hwin # o: help window
+#--
+int ic, nrows, ncols, irow, icol, flag
+pointer sp, label, name, hline, text, ch
+
+string htitle "Editing Commands"
+string hfooter "(Press any key to continue)"
+string hformat "%4w%-12.12s = %-12.12s"
+
+int newwin(), strlen()
+
+begin
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (label, COLWIDTH, TY_CHAR)
+ call salloc (name, COLWIDTH, TY_CHAR)
+ call salloc (hline, COLWIDTH, TY_CHAR)
+
+ # Create help message
+
+ hwin = newwin (GIANT, GIANT, 1, 1)
+
+ # Write help screen title
+
+ call wdimen (hwin, nrows, ncols)
+ icol = (ncols - strlen(htitle)) / 2
+ call wmove (hwin, 1, icol)
+ call wstandout (hwin)
+ call waddstr (hwin, htitle)
+ call wstandend (hwin)
+
+ ic = 0
+ icol = 0
+ irow = 3
+ flag = LABEL_FLAG
+ call k_help (text)
+
+ # Write each (label=name) pair to the help screen
+
+ for (ch = text; Memc[ch] != EOS; ch = ch + 1) {
+ switch (flag) {
+ case LABEL_FLAG:
+ if (Memc[ch] != '=') {
+ Memc[label+ic] = Memc[ch]
+ ic = ic + 1
+ } else {
+ Memc[label+ic] = EOS
+ flag = NAME_FLAG
+ ic = 0
+ }
+ case NAME_FLAG:
+ if (Memc[ch] != '\n') {
+ Memc[name+ic] = Memc[ch]
+ ic = ic + 1
+ } else {
+ Memc[name+ic] = EOS
+ flag = LABEL_FLAG
+ ic = 0
+
+ # Reformat label/name pair for window
+
+ call sprintf (Memc[hline], COLWIDTH, hformat)
+ call pargstr (Memc[label])
+ call pargstr (Memc[name])
+
+ # Write string to window
+
+ call wmove (hwin, irow, icol * COLWIDTH + 1)
+ call waddstr (hwin, Memc[hline])
+
+ # Calculate next string position
+
+ icol = icol + 1
+ if (icol == 2) {
+ icol = 0
+ irow = irow + 1
+ }
+ }
+ }
+ }
+
+ # Write help screen footer
+
+ call wmove (hwin, nrows, 1)
+ call waddstr (hwin, hfooter)
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmmkform.x b/pkg/utilities/nttools/tedit/display/forms/fmmkform.x
new file mode 100644
index 00000000..00bc8106
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmmkform.x
@@ -0,0 +1,82 @@
+include "formfn.h"
+
+# FM_MKFORM -- Create a form and bind it to a window
+#
+# B.Simon 27-Jan-89 Original
+# B.Simon 15-Oct-90 Rewritten to use curses
+
+procedure fm_mkform (win, nfield, lenname, lenvalue, title, ftype, fname)
+
+int win # i: Window descriptor
+int nfield # i: Number of fields in form
+int lenname # i: Declared length of field name
+int lenvalue # i: Declared length of field value
+char title[ARB] # i: Form title
+int ftype[ARB] # i: Data types of fields
+char fname[lenname,ARB] # i: Names of fields
+#--
+extern formfn
+int nrows, ncols, ifield
+pointer data, name, value, type
+
+begin
+ # Get the dimensions of the form
+
+ call wdimen (win, nrows, ncols)
+
+ # Allocate data structure
+
+ call malloc (data, LEN_FMSTRUCT, TY_STRUCT)
+ call malloc (FM_NAMARY(data), (lenname+1)*nfield, TY_CHAR)
+ call malloc (FM_VALARY(data), (lenvalue+1)*nfield, TY_CHAR)
+ call malloc (FM_TTLPTR(data), SZ_LINE, TY_CHAR)
+ call malloc (FM_TYPARY(data), nfield, TY_INT)
+
+ # Initialize data structure
+
+ FM_FIELD(data) = 1
+ FM_NFIELD(data) = nfield
+ FM_NPAGE(data) = nrows - 1
+ FM_CHANGE(data) = NO
+ FM_LENNAM(data) = lenname
+ FM_LENVAL(data) = lenvalue
+ call strcpy (title, FM_TITLE(data), SZ_LINE)
+
+ name = FM_NAMARY(data)
+ value = FM_VALARY(data)
+ type = FM_TYPARY(data)
+
+ do ifield = 1, nfield {
+ call strcpy(fname[1,ifield], Memc[name], lenname)
+ name = name + lenname + 1
+ Memc[value] = EOS
+ value = value + lenvalue + 1
+ Memi[type] = ftype[ifield]
+ type = type + 1
+ }
+
+ # Bind data structure and function to window
+
+ call wbindstruct (win, formfn, data)
+
+end
+
+procedure fm_clsform (win)
+
+int win # i: Window descriptor
+#--
+pointer data
+
+begin
+ # Get the structure pointer
+
+ call wgetstruct (win, data)
+
+ # Free the substructures hanging off the main structure
+
+ call mfree (FM_NAMARY(data), TY_CHAR)
+ call mfree (FM_VALARY(data), TY_CHAR)
+ call mfree (FM_TTLPTR(data), TY_CHAR)
+ call mfree (FM_TYPARY(data), TY_INT)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmprompt.x b/pkg/utilities/nttools/tedit/display/forms/fmprompt.x
new file mode 100644
index 00000000..b93ef450
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmprompt.x
@@ -0,0 +1,70 @@
+# FM_PROMPT -- Get user input from a prompt window
+#
+# B.Simon 30-Jan-89 Original
+# B.Simon 12-Dec-90 Rewritten to use curses
+
+int procedure fm_prompt (win, commands, message)
+
+int win # i: Prompt window
+char commands[ARB] # i: List of commands
+char message[ARB] # i: Message to print in prompt area
+#--
+char newline
+int option
+pointer sp, response, temp
+
+data newline / '\n' /
+
+int strdic()
+
+begin
+ # Print the message in the window
+
+ call werase (win)
+ call wmove (win, 1, 1)
+ if (message[1] == EOS) {
+ call waddstr (win, commands)
+ call waddch (win, newline)
+ } else {
+ call waddstr (win, message)
+ call waddch (win, newline)
+ }
+
+ # Return if no user response is needed
+
+ if (commands[1] == EOS) {
+ call wrefresh (win)
+ return (0)
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (response, SZ_LINE, TY_CHAR)
+ call salloc (temp, SZ_LINE, TY_CHAR)
+
+ # Get the user response
+
+ repeat {
+ call wgetstr (win, Memc[response], SZ_LINE)
+
+ # Check response against list of commands
+
+ option = strdic (Memc[response], Memc[temp], SZ_LINE, commands)
+ if (option > 0)
+ break
+
+ # Try again if response was not valid
+
+ call werase (win)
+ call wmove (win, 1, 1)
+ call waddstr (win , commands)
+ call waddch (win, newline)
+ call ps_beep
+ }
+
+ # Return the option number
+
+ call sfree (sp)
+ return (option)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/fmredraw.x b/pkg/utilities/nttools/tedit/display/forms/fmredraw.x
new file mode 100644
index 00000000..71e5b781
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/fmredraw.x
@@ -0,0 +1,69 @@
+include "formfn.h"
+define SZ_ESCSEQ 20
+
+# FM_REDRAW -- Redraw the form
+
+procedure fm_redraw (win, topfield)
+
+int win # i: Window descriptor
+int topfield # i: Top field on the form to draw
+#--
+int nrows, ncols, botfield, ifield
+pointer sp, field, footer, escseq, data, name, value
+
+begin
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (field, SZ_LINE, TY_CHAR)
+ call salloc (footer, SZ_LINE, TY_CHAR)
+ call salloc (escseq, SZ_ESCSEQ, TY_CHAR)
+
+ # Get form data structure
+
+ call wgetstruct (win, data)
+
+ # Get the dimensions of the form
+
+ call wdimen (win, nrows, ncols)
+
+ # Clear screen
+
+ call werase (win)
+
+ # Write the form
+
+ name = FM_NAMPTR(data,topfield)
+ value = FM_VALPTR(data,topfield)
+ botfield = min (FM_NFIELD(data), topfield + FM_NPAGE(data) - 1)
+
+ call wmove (win, 1, 1)
+ do ifield = topfield, botfield {
+ call sprintf (Memc[field], SZ_LINE, "%*s = %s\n")
+ call pargi (FM_LENNAM(data))
+ call pargstr (Memc[name])
+ call pargstr (Memc[value])
+
+ call waddstr (win, Memc[field])
+
+ name = name + FM_LENNAM(data) + 1
+ value = value + FM_LENVAL(data) + 1
+ }
+
+ # Write the footer line
+
+ call k_eseq ("GET_HELP", Memc[escseq], SZ_ESCSEQ)
+
+ call sprintf (Memc[footer], ncols, "%4w%s%*tHelp: %s%*t")
+ call pargstr (FM_TITLE(data))
+ call pargi (ncols-SZ_ESCSEQ)
+ call pargstr (Memc[escseq])
+ call pargi (ncols+1)
+
+ call wmove (win, nrows, 1)
+ call wstandout (win)
+ call waddstr (win, Memc[footer])
+ call wstandend (win)
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/formfn.h b/pkg/utilities/nttools/tedit/display/forms/formfn.h
new file mode 100644
index 00000000..b3afbc75
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/formfn.h
@@ -0,0 +1,20 @@
+# FORMFN.H -- Data structure used by formfn()
+
+define LEN_FMSTRUCT 10
+
+define FM_FIELD Memi[$1] # Current field
+define FM_NFIELD Memi[$1+1] # Number of fields on form
+define FM_NPAGE Memi[$1+2] # Number of fields in window
+define FM_CHANGE Memi[$1+3] # Has field been changed ?
+define FM_LENNAM Memi[$1+4] # Length of name field
+define FM_LENVAL Memi[$1+5] # Length of value field
+define FM_NAMARY Memi[$1+6] # Array of field names
+define FM_VALARY Memi[$1+7] # Array of field values
+define FM_TTLPTR Memi[$1+8] # Title array
+define FM_TYPARY Memi[$1+9] # Array of field types
+
+define FM_NAMPTR FM_NAMARY($1)+(($2)-1)*(FM_LENNAM($1)+1)
+define FM_VALPTR FM_VALARY($1)+(($2)-1)*(FM_LENVAL($1)+1)
+
+define FM_TITLE Memc[FM_TTLPTR($1)]
+define FM_TYPE Memi[FM_TYPARY($1)+($2)-1]
diff --git a/pkg/utilities/nttools/tedit/display/forms/formfn.x b/pkg/utilities/nttools/tedit/display/forms/formfn.x
new file mode 100644
index 00000000..b060a87c
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/formfn.x
@@ -0,0 +1,278 @@
+include <ctype.h>
+include "../curses.h"
+include "formfn.h"
+
+# FORMFN -- Function that processes form input
+#
+# B.Simon 12-Dec-90 Original
+
+procedure formfn (win, str, maxch)
+
+int win # i: Window descriptor
+char str[ARB] # u: String containing line
+int maxch # i: Maximum line length
+#--
+int row, col, ch, ic, jc, mc, nc
+pointer sp, data, buffer
+
+int strlen(), k_get(), winstat()
+
+begin
+ ic = 0
+ nc = strlen (str)
+
+ call wgetstruct (win, data)
+ row = winstat (win, W_CURROW)
+ col = winstat (win, W_CURCOL)
+
+ call smark (sp)
+ call salloc (buffer, SZ_LINE, TY_CHAR)
+ Memc[buffer] = EOS
+
+ while (nc < maxch) {
+
+ # Read character from keyboard
+
+ call ps_synch
+ ch = k_get ()
+
+ # Check for carriage return
+
+ if (ch == '\r') {
+ if (FM_FIELD(data) < FM_NFIELD(data)) {
+ FM_FIELD(data) = FM_FIELD(data) + 1
+ break
+ }
+ }
+
+ if (IS_PRINT(ch)) {
+ ic = ic + 1
+ nc = nc + 1
+ FM_CHANGE(data) = YES
+
+ if (ic == nc) {
+ str[ic] = ch
+ str[ic+1] = EOS
+ call waddstr (win, str[ic])
+
+ } else {
+ do jc = nc-1, ic, -1
+ str[jc+1] = str[jc]
+
+ str[ic] = ch
+ call winsch (win, str[ic])
+ }
+
+ } else {
+ switch (ch) {
+ case K_UP: # Move up one field
+ if (FM_FIELD(data) > 1) {
+ FM_FIELD(data) = FM_FIELD(data) - 1
+ break
+ }
+
+ case K_DOWN: # Move down one field
+ if (FM_FIELD(data) < FM_NFIELD(data)) {
+ FM_FIELD(data) = FM_FIELD(data) + 1
+ break
+ }
+
+ case K_RIGHT: # Move right one column
+ if (ic < nc) {
+ ic = ic + 1
+ call wmove (win, row, col+ic)
+ }
+
+ case K_LEFT: # Move left one column
+ if (ic > 0) {
+ ic = ic - 1
+ call wmove (win, row, col+ic)
+ }
+
+ case K_NEXTW: # Move forwards one word
+ call mvword_next (str, ic, jc)
+
+ if (jc > ic) {
+ ic = jc
+ call wmove (win, row, col+ic)
+ }
+
+
+ case K_PREVW: # Move backwards one word
+ call mvword_prev (str, ic, jc)
+
+ if (jc < ic) {
+ ic = jc
+ call wmove (win, row, col+ic)
+ }
+
+
+ case K_NEXTP: # Move forwards one screen
+ if (FM_FIELD(data) < FM_NFIELD(data)) {
+ FM_FIELD(data) = min (FM_FIELD(data) + FM_NPAGE(data),
+ FM_NFIELD(data))
+ break
+ }
+
+ case K_PREVP: # Move backwards one screen
+ if (FM_FIELD(data) > 1) {
+ FM_FIELD(data) = max (FM_FIELD(data) - FM_NPAGE(data),
+ 1)
+ break
+ }
+
+ case K_HOME: # Move to first field
+ if (FM_FIELD(data) > 1) {
+ FM_FIELD(data) = 1
+ break
+ }
+
+ case K_END: # Move to last field
+ if (FM_FIELD(data) < FM_NFIELD(data)) {
+ FM_FIELD(data) = FM_NFIELD(data)
+ break
+ }
+
+ case K_BOL: # Move to first column in line
+ if (ic > 0) {
+ ic = 0
+ call wmove (win, row, col)
+ }
+
+ case K_EOL: # Move to last column in line
+ if (ic < nc) {
+ ic = nc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_DEL: # Delete character underneath cursor
+ if (ic < nc) {
+ FM_CHANGE(data) = YES
+ mc = strlen (Memc[buffer])
+
+ Memc[buffer+mc] = str[ic+1]
+ Memc[buffer+mc+1] = EOS
+
+ call amovc (str[ic+2], str[ic+1], nc-ic)
+
+ call wdelch (win)
+ nc = nc - 1
+ }
+
+ case K_BS: # Delete character to left of cursor
+ if (ic > 0) {
+ FM_CHANGE(data) = YES
+ mc = strlen (Memc[buffer])
+
+ call amovc (Memc[buffer], Memc[buffer+1], mc+1)
+ Memc[buffer] = str[ic]
+
+ ic = ic - 1
+ call amovc (str[ic+2], str[ic+1], nc-ic)
+
+ call wmove (win, row, col+ic)
+ call wdelch (win)
+ nc = nc - 1
+ }
+
+ case K_DWORD: # Delete one word
+ call mvword_next (str, ic, jc)
+
+ if (jc > ic) {
+ FM_CHANGE(data) = YES
+ mc = strlen (Memc[buffer])
+
+ call strcpy (str[ic+1], Memc[buffer+mc], jc-ic)
+ call amovc (str[jc+1], str[ic+1], nc-jc+1)
+
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+ call wmove (win, row, col+ic)
+ nc = nc - (jc - ic)
+ }
+
+ case K_DLINE: # Delete entire line
+ if (nc > 0) {
+ FM_CHANGE(data) = YES
+
+ call strcpy (str[ic+1], Memc[buffer], nc-ic)
+ str[ic+1] = EOS
+
+ call wclrtoeol (win)
+ nc = ic
+ }
+
+ case K_UNDCHR: # Undelete a character
+ mc = strlen (Memc[buffer])
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+2], nc-ic+1)
+ str[ic+1] = Memc[buffer+mc-1]
+
+ Memc[buffer+mc-1] = EOS
+ call winsch (win, str[ic+1])
+
+ ic = ic + 1
+ nc = nc + 1
+ }
+
+ case K_UNDWRD: # Undelete a word
+ mc = strlen (Memc[buffer])
+ call mvword_prev (Memc[buffer], mc, jc)
+
+ mc = mc - jc
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+mc+1], nc-ic+1)
+ call amovc (Memc[buffer+jc], str[ic+1], mc)
+
+ Memc[buffer+jc] = EOS
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+
+ ic = ic + mc
+ nc = nc + mc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_UNDLIN: # Undelete a line
+ mc = strlen (Memc[buffer])
+ if (mc > 0) {
+ call amovc (str[ic+1], str[ic+mc+1], nc-ic+1)
+ call amovc (Memc[buffer], str[ic+1], mc)
+
+ Memc[buffer] = EOS
+ call wclrtoeol (win)
+ call waddstr (win, str[ic+1])
+
+ ic = ic + mc
+ nc = nc + mc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_HELP: # Display help screen
+ call fm_help (win)
+
+ case K_PAINT: # Redraw the screen
+ call clearok (STDSCR, true)
+ call wrefresh (STDSCR)
+ call wmove (win, row, col+ic)
+
+ case K_EXIT: # Exit procedure
+ break
+
+ default: # Any other character
+ call ps_beep
+ }
+ }
+ }
+
+ # Terminate string with EOS and push back character
+ # that terminated input
+
+ if (nc >= maxch)
+ ch = EOS
+
+ str[nc+1] = EOS
+ call k_pushbk (ch)
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/forms.com b/pkg/utilities/nttools/tedit/display/forms/forms.com
new file mode 100644
index 00000000..2e948a0c
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/forms.com
@@ -0,0 +1,5 @@
+# FORMS.COM -- Global variables used by forms procedures
+
+int helpwin # Function key help window
+
+common /form/ helpwin
diff --git a/pkg/utilities/nttools/tedit/display/forms/linefn.h b/pkg/utilities/nttools/tedit/display/forms/linefn.h
new file mode 100644
index 00000000..c263dfce
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/linefn.h
@@ -0,0 +1,8 @@
+# LINEFN.H -- Data structure associated with linefn()
+
+define LEN_LINSTRUCT 4
+
+define LIN_ROW Memi[$1] # Cursor row
+define LIN_COL Memi[$1+1] # Cursor column
+define LIN_ICHAR Memi[$1+2] # Index to current character
+define LIN_LAST Memi[$1+3] # Character which caused return
diff --git a/pkg/utilities/nttools/tedit/display/forms/linefn.x b/pkg/utilities/nttools/tedit/display/forms/linefn.x
new file mode 100644
index 00000000..c122795a
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/linefn.x
@@ -0,0 +1,134 @@
+include "../curses.h"
+include "linefn.h"
+
+# LINEFN -- Function that processes a line of input in a window
+
+procedure linefn (win, ch, maxch, str, data, done)
+
+int win # i: Window descriptor
+int ch # i: Keyboard character
+int maxch # i: Maximum line length
+char str[ARB] # io: String containing line
+pointer data # io: Line data structure
+bool done # o: Flag indicating line is done
+#--
+int ic, jc, nc
+int strlen()
+
+begin
+ done = false
+ if (LIN_ROW(data) == 0 || LIN_COL(data) == 0)
+ call getyx (win, LIN_ROW(data), LIN_COL(data))
+
+ if (ch < K_BASE) {
+ LIN_ICHAR(data) = LIN_ICHAR(data) + 1
+ LIN_COL(data) = LIN_COL(data) + 1
+ ic = LIN_ICHAR(data)
+
+ if (str[ic] == EOS) {
+ if (ic > maxch) {
+ done = true
+ LIN_LAST(data) = EOS
+ } else {
+ str[ic] = ch
+ str[ic+1] = EOS
+ call waddstr (win, str[ic])
+ }
+ } else {
+ nc = strlen (str)
+ if (nc >= maxch) {
+ done = true
+ LIN_LAST(data) = EOS
+ } else {
+ do jc = nc+1, ic, -1
+ str[jc+1] = str[jc]
+
+ str[ic] = ch
+ call winsch (win, str[ic])
+ }
+ }
+
+ if (ch == '\r') {
+ done = true
+ LIN_LAST(data) = '\n'
+ }
+
+ } else {
+ ic = LIN_ICHAR(data)
+ switch (ch) {
+ case K_RIGHT: # Move right one column
+ if (str[ic] == EOS) {
+ done = true
+ LIN_LAST(data) = EOS
+ } else {
+ LIN_ICHAR(data) = LIN_ICHAR(data) + 1
+ LIN_COL(data) = LIN_COL(data) + 1
+ call wmove (win, LIN_ROW(data), LIN_COL(data))
+ }
+
+ case K_LEFT: # Move left one column
+ if (ic == 1) {
+ done = true
+ LIN_LAST(data) = EOS
+ } else {
+ LIN_ICHAR(data) = LIN_ICHAR(data) - 1
+ LIN_COL(data) = LIN_COL(data) - 1
+ call wmove (win, LIN_ROW(data), LIN_COL(data))
+ }
+
+ case K_BOL: # Move to first column in line
+ if (ic > 1) {
+ LIN_ICHAR(data) = 1
+ LIN_COL(data) = LIN_COL(data) - ic + 1
+ call wmove (win, LIN_ROW(data), LIN_COL(data))
+ }
+
+ case K_EOL: # Move to last column in line
+ if (str[ic] != EOS) {
+ LIN_ICHAR(data) = strlen (str) + 1
+ LIN_COL(data) = LIN_COL(data) + LIN_ICHAR(data) - ic
+ call wmove (win, LIN_ROW(data), LIN_COL(data))
+ }
+
+ case K_DEL: # Delete character underneath cursor
+ if (str[ic] != EOS) {
+ while (str[ic] != EOS) {
+ str[ic] = str[ic+1]
+ ic = ic + 1
+ }
+
+ call wdelch (win)
+ }
+
+ case K_BS: # Delete character to left of cursor
+ if (ic > 1) {
+ LIN_ICHAR(data) = LIN_ICHAR(data) - 1
+ LIN_COL(data) = LIN_COL(data) - 1
+
+ ic = ic - 1
+ while (str[ic] != EOS) {
+ str[ic] = str[ic+1]
+ ic = ic + 1
+ }
+
+ call wmove (win, LIN_ROW(data), LIN_COL(data))
+ call wdelch (win)
+ }
+
+ case K_DWORD: # Delete entire line
+ if (str[1] != EOS) {
+ LIN_ICHAR(data) = 1
+ LIN_COL(data) = LIN_COL(data) - ic + 1
+
+ for (ic = 1; str[ic] != EOS; ic = ic + 1)
+ str[ic] = ' '
+ call addstr (win, str)
+ str[1] = EOS
+ }
+
+ default:
+ done = true
+ LIN_LAST(data) = ch
+ }
+ }
+end
diff --git a/pkg/utilities/nttools/tedit/display/forms/mkpkg b/pkg/utilities/nttools/tedit/display/forms/mkpkg
new file mode 100644
index 00000000..e23071d5
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/mkpkg
@@ -0,0 +1,19 @@
+# Update the display library.
+# Author: B.Simon 01-APR-91
+
+$checkout libpkg.a ../../
+$update libpkg.a
+$checkin libpkg.a ../../
+$exit
+
+libpkg.a:
+ fmbegin.x "forms.com"
+ fmcheck.x <lexnum.h> <ctype.h> <mach.h>
+ fmend.x
+ fmhelp.x "../curses.h" "forms.com"
+ fmgetform.x "formfn.h"
+ fmmkform.x "formfn.h"
+ fmprompt.x
+ fmredraw.x "formfn.h"
+ formfn.x "../curses.h" "formfn.h"
+ ;
diff --git a/pkg/utilities/nttools/tedit/display/forms/promptfn.h b/pkg/utilities/nttools/tedit/display/forms/promptfn.h
new file mode 100644
index 00000000..48aba6b4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/promptfn.h
@@ -0,0 +1,7 @@
+# PROMPTFN.H -- Data structure associated with promptfn()
+
+define LEN_PRSTRUCT 3
+
+define PR_START Memi[$1] # Start flag
+define PR_ROW Memi[$1+1] # Cursor row
+define PR_COL Memi[$1+2] # Cursor column
diff --git a/pkg/utilities/nttools/tedit/display/forms/promptfn.x b/pkg/utilities/nttools/tedit/display/forms/promptfn.x
new file mode 100644
index 00000000..c270aabb
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/forms/promptfn.x
@@ -0,0 +1,134 @@
+include "../curses.h"
+include "promptfn.h"
+
+# PROMPTFN -- Function that processes the prompt input
+
+procedure promptfn (win, ch, maxch, str, data, done)
+
+int win # i: Window descriptor
+int ch # i: Keyboard character
+int maxch # i: Maximum line length
+char str[ARB] # io: String containing line
+pointer data # io: Line data structure
+bool done # o: Flag indicating line is done
+#--
+int nrows, ncols, ic, jc, nc
+int strlen()
+
+begin
+ # Check for carriage return
+
+ if (ch == '\r') {
+ done = true
+ return
+ } else {
+ done = false
+ }
+
+ # Initialize data structure on first pass through
+
+ if (PR_START(data) == YES) {
+ call wdimen (win, nrows, ncols)
+ if (nrows == 1)
+ call werase (win)
+
+ PR_START(data) = NO
+ PR_ROW(data) = min (2, nrows)
+ PR_COL(data) = 1
+ }
+
+ if (ch < K_BASE) {
+ ic = PR_COL(data)
+
+ if (str[ic] == EOS) {
+ if (ic <= maxch) {
+ str[ic] = ch
+ str[ic+1] = EOS
+ call waddstr (win, str[ic])
+ }
+ } else {
+ nc = strlen (str)
+ if (nc < maxch) {
+ do jc = nc+1, ic, -1
+ str[jc+1] = str[jc]
+
+ str[ic] = ch
+ call winsch (win, str[ic])
+ }
+ }
+ PR_COL(data) = PR_COL(data) + 1
+
+ } else {
+ ic = PR_COL(data)
+ switch (ch) {
+ case K_RIGHT: # Move right one column
+ if (str[ic] != EOS) {
+ PR_COL(data) = PR_COL(data) + 1
+ call wmove (win, PR_ROW(data), PR_COL(data))
+ }
+
+ case K_LEFT: # Move left one column
+ if (ic != 1) {
+ PR_COL(data) = PR_COL(data) - 1
+ call wmove (win, PR_ROW(data), PR_COL(data))
+ }
+
+ case K_BOL: # Move to first column in line
+ if (ic > 1) {
+ PR_COL(data) = 1
+ call wmove (win, PR_ROW(data), PR_COL(data))
+ }
+
+ case K_EOL: # Move to last column in line
+ if (str[ic] != EOS) {
+ PR_COL(data) = strlen (str) + 1
+ call wmove (win, PR_ROW(data), PR_COL(data))
+ }
+
+ case K_DEL: # Delete character underneath cursor
+ if (str[ic] != EOS) {
+ while (str[ic] != EOS) {
+ str[ic] = str[ic+1]
+ ic = ic + 1
+ }
+
+ call wdelch (win)
+ }
+
+ case K_BS: # Delete character to left of cursor
+ if (ic > 1) {
+ PR_COL(data) = PR_COL(data) - 1
+
+ ic = ic - 1
+ while (str[ic] != EOS) {
+ str[ic] = str[ic+1]
+ ic = ic + 1
+ }
+
+ call wmove (win, PR_ROW(data), PR_COL(data))
+ call wdelch (win)
+ }
+
+ case K_DWORD: # Delete entire line
+ if (str[1] != EOS) {
+ PR_COL(data) = 1
+
+ for (ic = 1; str[ic] != EOS; ic = ic + 1)
+ str[ic] = ' '
+ call addstr (win, str)
+ str[1] = EOS
+ }
+
+ case K_HELP: # Display help screen
+ call fm_help
+
+ case K_PAINT: # Redraw the screen
+ call clearok (STDSCR, true)
+ call wrefresh (STDSCR)
+ call wmove (win, PR_ROW(data), PR_COL(data))
+
+ default:
+ call ps_beep
+ }
+ }
+end
diff --git a/pkg/utilities/nttools/tedit/display/mkpkg b/pkg/utilities/nttools/tedit/display/mkpkg
new file mode 100644
index 00000000..322177b4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/mkpkg
@@ -0,0 +1,14 @@
+
+# Update the display library.
+# Author: B.Simon 01-APR-91
+
+$checkout libpkg.a ../
+$update libpkg.a
+$checkin libpkg.a ../
+$exit
+
+libpkg.a:
+ @curses
+ @forms
+ @screen
+ ;
diff --git a/pkg/utilities/nttools/tedit/display/screen/README b/pkg/utilities/nttools/tedit/display/screen/README
new file mode 100644
index 00000000..6a29f82f
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/README
@@ -0,0 +1,211 @@
+The procedures in this directory implement the lowest level of the
+screen handling routines in the display library. Procedures not
+described in this file are not part of the public interface and should
+not be called by user programs. All the capabilities of the curses
+procedures are layered on top of the procedures in this directory.
+These procedures provide less functionality than the curses routines,
+but can be faster, at the expense of more complications in the user
+program. The procedures in this directory are portable. They are
+written in SPP and they do all their I/O through the IRAF VOS. They
+use the termcap and edcap files so that this library can be used with
+a variety of terminals and the editing commands can be tailored to the
+user's preferences. There are two sets of subroutines in this
+directory. The first set is the keyboard subroutines, prefixed by the
+letter "k", which read the keyboard and translate control key
+sequences to a single character. The second set is the screen
+sunroutines, prefixed by the letters "ps", which write to the
+terminal.
+
+The keyboard subroutines read input from the keyboard, translating
+command key sequences into a single number. The command key sequences
+are read from the edcap file. This is a file located either in the
+user's home directory or the dev$ directory whose name is the value of
+the editor environment variable with an extension of ".ed". See the
+files in the dev$ directory for an example of the file format. The
+keyboard subroutines are initialized by a call to the following
+subroutine:
+
+procedure k_begin (cmdlist)
+
+char cmdlist[ARB] # i: List of editing commands
+
+This subroutine puts the terminal in raw mode, reads the edcap file,
+and sends the keyboard initialization sequence to the terminal. Its
+argument is a list of command names taken from the edcap file that you
+want your program to recognize. The first character in the string is a
+command separator, used to separate the commands in the string. The
+macro CMDSTR in <curses.h> defines the list of commands used by the
+curses routines. The screen initialization routine, ps_begin, must be
+called before k_begin is called. To terminate the keyboard interface,
+call the following subroutine:
+
+procedure k_end ()
+
+This procedure ends raw mode and sends the keyboard termination sequence
+to the terminal. The screen termination routine, ps_end, should be
+called after this routine is called. The following subroutine reads a
+single character from the terminal:
+
+int procedure k_get ()
+
+Command key sequences that were named in the command list passed to
+k_begin are returned as a single number. The value returned by the
+first command key sequence in the command list is K_BASE, the value
+returned by the second sequence is K_BASE+1, and so on. The macro
+K_BASE is defined in <curses.h>.
+
+The next keyboard subroutine returns a pointer to a character string
+containing the help text for the keyboard commands:
+
+procedure k_help (text)
+
+pointer text # o: Help text
+
+The help text string is formatted as a series of command descriptions.
+Each description starts with the name of the edcap command , followed
+by an equals sign, followed by the ascii representation of the key
+sequence which executes the command, and terminated by a newline
+character.The string is formatted as a series of command descriptions.
+Each description starts with the name of the edcap command , followed
+by an equals sign, followed by the ascii representation of the key
+sequence which executes the command, and terminated by a newline
+character.
+
+The following routine copies one of the command descriptions from the
+help text to an output string:
+
+procedure k_eseq (name, eseq, maxch)
+
+char name[ARB] # i: Name bound to command sequence
+char eseq[ARB] # o: String representation of command sequence
+int maxch # i: Maximum length of command sequence
+
+The input parameters are the name of the command sequence and the
+length of the output string. The name of the sequence should be
+the name passed as part of the command string to k_begin(). The output
+is the ascii represntation of the escape sequence of that command.
+
+The screen subroutines are used to send output to the terminal. They
+are based on the subroutines in Marc Rochkind's book, "Advanced C
+Programs for Displays". Several conventions are followed by these
+subroutines. The first is that while strings are passed as arrays of
+characters, individual characters are passed as integers. The second is
+that screen coordinates are passed row first, column second and that the
+coordinates of the upper left corner of the screen are (1, 1). The
+third is that areas on the screen are passed as rectangles, which are
+represented as arrays of four elements, where the four elements are the
+(top, left, bottom, right) corners of the rectangle. The initialization
+and termination routines for the screen subroutines are:
+
+procedure ps_begin ()
+procedure ps_end ()
+
+The first subroutine opens the terminal for I/O and reads the termcap
+file, the second closes the terminal. The calling program get the size
+of the screen by calling the subroutines:
+
+int procedure ps_height ()
+int procedure ps_width ()
+
+These subroutines return the number of screen rows and columns,
+respectively. The following subroutine flushes the output buffer:
+
+procedure ps_synch ()
+
+The user will not see any output sent by these subroutine to the
+terminal until this subroutine is called. To ring the terminal's bell,
+call the following subroutine:
+
+procedure ps_beep ()
+
+To move the cursor on the screen call the following subroutine:
+
+procedure ps_setcur (row, col)
+
+int row # i: Cursor row
+int col # i: Cursor column
+
+To write a string to the screen call the following subroutine:
+
+procedure ps_write (row, col, ncols, str, att)
+
+int row # i: Starting row
+int col # i: Starting column
+int ncols # i: Number of columns to write
+char str[ARB] # i: String to write
+int att # i: Attribute
+
+The number of columns is an upper limit on the number of characters to
+write, if the string is shorter than this, the actual number of
+characters on the screen will be displayed. If the string does not lie
+entirely on the screen, the string will be clipped at the screen boundary.
+The attribute determines whether the string is printed normally or in
+standout mode. The value should be set to either A_NORM or A_STANDOUT,
+which is defined in display.h. To write a string where the screen
+attribute may change from character to characater call the following
+subroutine:
+
+procedure ps_wrtcells (row, col, vector, ncols)
+
+int row # i: Starting row
+int col # i: Starting column
+char vector[ARB] # i: Vector to write
+int ncols # i: Number of columns to write
+
+The string to be written must be at least ncols long and each character
+to be displayed in standout mode should have A_STANDOUT added to its
+ascii code. This subroutine is used when the calling program keeps an
+array whose contents corresponds to the current screen display. To fill
+an area on the screen with a single character call the following
+subroutine:
+
+procedure ps_fill (source, ch, att)
+
+int source[RSIZE] # i: Rectangle
+int ch # i: Fill character
+int att # i: Fill attribute
+
+This subroutine can be used to clear part or all of the screen by
+setting the fill character to blank and the fill attribute to A_NORM.
+The macro RSIZE is equal to 4 and is defined in display.h. To move an
+area of the screen in any of the four directions call the following
+subroutine:
+
+bool procedure ps_slide (source, dir, dist)
+
+int source[RSIZE] # i: Rectangle
+int dir # i: Direction (from display.h)
+int dist # i: Distance (> 0)
+
+This subroutine can be used to scroll the screen up or down, delete one
+or more characters from a line, or move a line over so that a new
+character can be inserted. The direction is given as one of the four
+macros DIR_UP, DIR_DOWN, DIR_LEFT, and DIR_RIGHT, defined in <curses.h>.
+This subroutine may or may not be able to move the screen, depending on
+the capabilities defined in the terminal's termcap file. If the
+subroutine can move the area, it returns true and if it cannot, it
+returns false. In the latter case, it is the responsibility of the
+calling program to redraw the affected area of the screen in order to
+move the area.
+
+The include file display.h contains several macros the can be used to
+manipulate the rectangles passed to the screen subroutines. In order to
+access the elements of a rectangle the following macros can be used:
+
+RTOP(rect) # Top row of a rectangle
+RLEFT(rect) # Left column of a rectangle
+RBOT(rect) # Bottom row of a rectangle
+RRIGHT(rect) # Right column of a rectangle
+
+The dimensions of a rectangle can be computed by the following macros:
+
+RWIDTH(rect) # Number of columns in a rectangle
+RHEIGHT(rect) # Number of rows in a rectangle
+
+A program can set the elements in a rectangle with the following macros:
+
+RASG(newrect, top, left, bottom, right)
+RCPY(newrect, oldrect)
+
+The first macro assigns four scalars to the elements of a rectangle and
+the second macro copies the elements of one rectangle to another.
diff --git a/pkg/utilities/nttools/tedit/display/screen/kbegin.x b/pkg/utilities/nttools/tedit/display/screen/kbegin.x
new file mode 100644
index 00000000..0be12ab6
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kbegin.x
@@ -0,0 +1,40 @@
+include <fset.h>
+include "../curses.h"
+
+# K_BEGIN -- Initialize keyboard
+#
+# B.Simon 23-Jan-89 Original
+
+procedure k_begin (cmdlist)
+
+char cmdlist[ARB] # i: List of editing commands
+#--
+include "screen.com"
+
+int klen
+int strlen()
+
+extern k_error
+
+begin
+ # NOTE: ps_begin must be called before calling this procedure
+
+ # Put terminal in raw mode
+
+ call fseti (ttyin, F_RAW, YES)
+
+ # Set up error exit routine
+
+ call onerror (k_error)
+
+ # Set up function key table and help screen
+
+ call k_compile (cmdlist)
+
+ # Send initialize keypad sequence to terminal
+
+ klen = strlen (ks)
+ if (klen > 0)
+ call ttywrite (ttyout, term, ks, klen, 1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kcompile.x b/pkg/utilities/nttools/tedit/display/screen/kcompile.x
new file mode 100644
index 00000000..9ad162ec
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kcompile.x
@@ -0,0 +1,148 @@
+include <ctype.h>
+include "../curses.h"
+
+define SYNTAX 1
+define K_CMDLEN 7
+
+# K_COMPILE -- Compile a file of editing key definitions (edcap)
+#
+# B.Simon 23-Jan-89 Original
+
+procedure k_compile (cmdlist)
+
+char cmdlist[ARB] # i: List of commands
+#--
+include "screen.com"
+
+char sep
+int ic, maxcmd, nkey, maxkey
+int hlength, hwidth, hstart, hleft, fd, tag
+pointer sp, label, escape, name
+
+bool streq()
+int k_capfile(), ps_width(), fscan(), nscan(), strdic(), gstrcpy()
+
+begin
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (label, SZ_FNAME, TY_CHAR)
+ call salloc (escape, SZ_FNAME, TY_CHAR)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+
+ # Count the number of editing commands
+
+ maxcmd = 0
+ sep = cmdlist[1]
+ for (ic = 1; cmdlist[ic] != EOS; ic = ic + 1) {
+ if (cmdlist[ic] == sep && cmdlist[ic+1] != EOS)
+ maxcmd = maxcmd + 1
+ }
+
+ # Allocate dynamic memory for the function key table
+
+ nkey = 0
+ maxkey = K_CMDLEN * maxcmd
+ call calloc (keytab, 4*maxkey, TY_INT)
+
+ # Set up help text
+
+ hwidth = ps_width() / 2
+ hlength = maxcmd * hwidth
+ call calloc (htext, hlength+1, TY_CHAR)
+ hstart = htext
+ hleft = hlength
+
+ # Add each line from the edcap file to the table of function
+ # key sequences and the help screen
+
+ fd = k_capfile ()
+ while (fscan (fd) != EOF) {
+ call gargwrd (Memc[label], SZ_FNAME)
+ call gargwrd (Memc[escape], SZ_FNAME)
+ call gargwrd (Memc[name], SZ_FNAME)
+
+ # Proceess line only if all three elements of command are present
+ # and command is found in command list
+
+ if (nscan () == 3) {
+
+ if (streq (Memc[label], "EDIT_INIT"))
+ call k_convert (Memc[escape], ks, K_CMDLEN)
+ else if (streq (Memc[label], "EDIT_TERM"))
+ call k_convert (Memc[escape], ke, K_CMDLEN)
+
+ tag = strdic (Memc[label], Memc[label], SZ_FNAME, cmdlist)
+ if (tag > 0) {
+ tag = tag + K_BASE - 1
+
+ # Add escape sequence to function key table
+
+ call k_doline (Memc[escape], tag, maxkey,
+ nkey, Memi[keytab])
+
+ # Add label and name to help text
+
+ if (hleft > hwidth) {
+ hstart = gstrcpy (Memc[label], Memc[hstart], hleft) +
+ hstart
+
+ Memc[hstart] = '='
+ hstart = hstart + 1
+
+ hstart = gstrcpy (Memc[name], Memc[hstart], hleft) +
+ hstart
+
+ Memc[hstart] = '\n'
+ hstart = hstart + 1
+ hleft = hlength - (hstart - htext)
+ }
+ }
+ }
+ }
+
+ Memc[hstart] = EOS
+ call close (fd)
+ call sfree (sp)
+end
+
+# K_CAPFILE -- Open the editing capabilities file (edcap)
+
+int procedure k_capfile ()
+
+#--
+int fd
+pointer sp, editor, edcap
+
+int envgets(), access(), open()
+
+begin
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (editor, SZ_FNAME, TY_CHAR)
+ call salloc (edcap, SZ_FNAME, TY_CHAR)
+
+ # Get the name of the edcap file and open it
+
+ if (envgets ("editor", Memc[editor], SZ_FNAME) <= 0)
+ call error (SYNTAX, "Editor not found")
+
+ call sprintf (Memc[edcap], SZ_FNAME, "home$%s.ed")
+ call pargstr (Memc[editor])
+
+ if (access (Memc[edcap], READ_ONLY, 0) == NO) {
+
+ call sprintf (Memc[edcap], SZ_FNAME, "dev$%s.ed")
+ call pargstr (Memc[editor])
+
+ if (access (Memc[edcap], READ_ONLY, 0) == NO)
+ call error (SYNTAX, "Edcap file not found")
+
+ }
+
+ fd = open (Memc[edcap], READ_ONLY, TEXT_FILE)
+ call sfree (sp)
+
+ return (fd)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kconvert.x b/pkg/utilities/nttools/tedit/display/screen/kconvert.x
new file mode 100644
index 00000000..11e283fa
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kconvert.x
@@ -0,0 +1,61 @@
+include <ctype.h>
+
+# K_CONVERT -- Convert a string with coded escape sequences to the real thing
+#
+# B.Simon 23-Jan-89 Original
+
+procedure k_convert (escstr, escseq, maxch)
+
+char escstr[ARB] # i: Escape sequence string
+char escseq[ARB] # o: Escape key sequence
+int maxch # i: Declared length of key sequence
+#--
+int ic, jc, index, num
+
+string echars "befnrt"
+string ecodes "\010\033\f\n\r\t"
+
+int stridx()
+
+begin
+ ic = 1
+ for (jc = 1; jc <= maxch; jc = jc + 1) {
+
+ # Exit when all characters in escape string have been processed
+
+ if (escstr[ic] == EOS)
+ break
+
+ # Convert escape sequence
+
+ if (escstr[ic] == '\\') {
+ ic = ic + 1
+ index = stridx (escstr[ic], echars)
+ if (index > 0) {
+ escseq[jc] = ecodes[index]
+ } else if (IS_DIGIT(escstr[ic])) {
+ for (num = 0; IS_DIGIT(escstr[ic]); ic = ic + 1)
+ num = 8 * num + TO_DIGIT(escstr[ic])
+ ic = ic - 1
+ escseq[jc] = num
+ } else {
+ escseq[jc] = escstr[ic]
+ }
+
+ # Convert control sequence
+
+ } else if (escstr[ic] == '^') {
+ ic = ic + 1
+ escseq[jc] = mod (int(escstr[ic]), 32)
+
+ # Copy ordinary character
+
+ } else {
+ escseq[jc] = escstr[ic]
+ }
+
+ ic = ic + 1
+ }
+
+ escseq[jc] = EOS
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kdoline.x b/pkg/utilities/nttools/tedit/display/screen/kdoline.x
new file mode 100644
index 00000000..bcdf4a72
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kdoline.x
@@ -0,0 +1,96 @@
+include <ctype.h>
+
+define SYNTAX 1
+define BOUNDS 2
+
+# K_DOLINE -- Add a line containing an escape sequence to the key table
+#
+# B.Simon 23-Jan-89 Original
+
+procedure k_doline (escstr, tag, maxtab, ntab, table)
+
+char escstr[ARB] # i: Key sequence
+int tag # i: Key tag
+int maxtab # i: Maximum number of entries
+int ntab # io: Current number of entries
+int table[4,ARB] # io: Key sequence table
+#--
+int ic, link, new, old
+pointer sp, escseq
+
+int strlen()
+
+string notctrl "Key sequence must begin with a control character"
+string isambig "Ambiguous key sequence"
+string toomany "Too many key definitions"
+
+begin
+ # Convert escape sequence
+
+ call smark (sp)
+ call salloc (escseq, SZ_FNAME, TY_CHAR)
+ call k_convert (escstr, Memc[escseq], SZ_FNAME)
+
+ # Don't process null sequences
+
+ if (Memc[escseq] == EOS)
+ return
+
+ # Check to see if escape sequence is valid
+
+ if (IS_PRINT(Memc[escseq]))
+ call error (SYNTAX, notctrl)
+
+ # Find first character in key sequence that is new
+
+ ic = 0
+ link = 0
+ for (new = 1; new != 0; new = table[link,old]) {
+ old = new
+ if (link == 1)
+ ic = ic + 1
+ if (Memc[escseq+ic] == table[3,old])
+ link = 1
+ else
+ link = 2
+ }
+
+ if (link == 1) {
+
+ # Redefinition of existing sequence
+
+ if (Memc[escseq+ic] != EOS)
+ call error (SYNTAX, isambig)
+ table[4,old] = tag
+
+ } else {
+
+ # New sequence
+
+ if (Memc[escseq+ic] == EOS)
+ call error (SYNTAX, isambig)
+
+ # Check for table overflow
+
+ if (strlen (Memc[escseq+ic]) + ntab > maxtab)
+ call error (BOUNDS, toomany)
+
+ # Insert remainder of key sequence in table
+
+ table[2,old] = ntab + 1
+ while (Memc[escseq+ic] != EOS) {
+ ntab = ntab + 1
+ table[1,ntab] = ntab + 1
+ table[2,ntab] = 0
+ table[3,ntab] = Memc[escseq+ic]
+ table[4,ntab] = 0
+ ic = ic + 1
+ }
+ table[1,ntab] = 0
+ table[4,ntab] = tag
+
+ }
+
+ call sfree (sp)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kend.x b/pkg/utilities/nttools/tedit/display/screen/kend.x
new file mode 100644
index 00000000..57130052
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kend.x
@@ -0,0 +1,49 @@
+include <fset.h>
+
+# K_END -- Terminate keyboard
+#
+# B.Simon 23-Jan-89 Original
+
+procedure k_end ()
+
+#--
+include "screen.com"
+
+int klen
+int strlen()
+
+begin
+ # Restore keyboard to original state and end raw mode
+
+ if (ttyin != NULL) {
+ if (term != NULL) {
+ klen = strlen (ke)
+ if (klen > 0)
+ call ttywrite (ttyout, term, ke, klen, 1)
+ }
+ call fseti (ttyin, F_RAW, NO)
+ }
+
+ # Release dynamic memory
+
+ if (keytab != NULL)
+ call mfree (keytab, TY_INT)
+
+ if (htext != NULL)
+ call mfree (htext, TY_CHAR)
+
+end
+
+# K_ERROR -- Procedure called on error exit
+
+procedure k_error (status)
+
+int status # i: Error status
+#--
+
+begin
+ if (status != OK) {
+ call k_end
+ call ps_end
+ }
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kget.x b/pkg/utilities/nttools/tedit/display/screen/kget.x
new file mode 100644
index 00000000..61364f9e
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kget.x
@@ -0,0 +1,96 @@
+include <ctype.h>
+
+define CAN_ABORT NO
+define ABORT '\003'
+
+# K_GET -- Read a character, translating function keys
+
+int procedure k_get ()
+
+#--
+include "screen.com"
+
+int ch
+
+int first
+int k_cget(), k_lookup()
+
+string abortmsg "Task aborted by ^C"
+
+begin
+ if (keych != EOF) {
+ # Check for a pushed back character, returning it if found
+
+ ch = keych
+ keych = EOF
+
+ } else {
+ # Check character to see if it is the start of a control sequence
+ # If not, return the character without searching the table
+
+ first = k_cget ()
+
+ if (IS_PRINT(first))
+ ch = first
+ else if ((CAN_ABORT == YES) && (first == ABORT))
+ call error (1, abortmsg)
+ else
+ ch = k_lookup (first, Memi[keytab])
+ }
+
+ return (ch)
+
+end
+
+# K_LOOKUP -- Look up a function key sequence in a table
+
+int procedure k_lookup (first, table)
+
+int first # i: First character in the sequence
+int table[4,ARB] # i: Table of function key sequences
+#--
+include "screen.com"
+
+int key, new, old, link
+int k_cget()
+
+begin
+ # Search the table for the control sequence
+
+ link = 0
+ key = first
+
+ for (new = 1; new != 0; new = table[link,old]) {
+ old = new
+ if (link == 1)
+ key = k_cget ()
+ if (key == table[3,old])
+ link = 1
+ else
+ link = 2
+ }
+
+ # Return the control sequence tag if the sequence was found,
+ # otherwise return the first unrecognized key
+
+ if (link == 1)
+ key = table[4,old]
+
+ return (key)
+
+end
+
+# K_CGET -- Read a single character from the terminal
+
+int procedure k_cget ()
+
+#--
+include "screen.com"
+
+int ch
+int and(), getci()
+
+begin
+ ch = getci (ttyin, ch)
+ return (and (ch, 177B))
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/khelp.x b/pkg/utilities/nttools/tedit/display/screen/khelp.x
new file mode 100644
index 00000000..4b075f8a
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/khelp.x
@@ -0,0 +1,61 @@
+include <fset.h>
+
+# K_HELP -- Retrieve help text for function key sequences
+
+procedure k_help (text)
+
+pointer text # o: Help text
+#--
+include "screen.com"
+
+begin
+ text = htext
+end
+
+procedure k_eseq (name, eseq, maxch)
+
+char name[ARB] # i: Name bound to escape sequence
+char eseq[ARB] # o: String representation of escape sequence
+int maxch # i: Maximum length of escape sequence
+#--
+include "screen.com"
+
+bool match, in_name
+int ic
+pointer ch
+
+begin
+ ic = 1
+ match = true
+ in_name = true
+
+ for (ch = htext; Memc[ch] != EOS; ch = ch + 1) {
+ if (in_name) {
+ if (Memc[ch] == '=') {
+ match = match && name[ic] == EOS
+ in_name = false
+ ic = 1
+ } else if (match) {
+ if (Memc[ch] == name[ic]) {
+ ic = ic + 1
+ } else {
+ match = false
+ }
+ }
+
+ } else {
+ if (Memc[ch] == '\n') {
+ if (match)
+ break
+ ic = 1
+ match = true
+ in_name = true
+ } else if (match && ic <= maxch) {
+ eseq[ic] = Memc[ch]
+ ic = ic + 1
+ }
+ }
+ }
+ eseq[ic] = EOS
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/kpushbk.x b/pkg/utilities/nttools/tedit/display/screen/kpushbk.x
new file mode 100644
index 00000000..6e9c05c2
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/kpushbk.x
@@ -0,0 +1,11 @@
+# K_PUSHBK -- Push back a single character read from the keyboard
+
+procedure k_pushbk (ch)
+
+int ch # i: character to be pushed back
+#--
+include "screen.com"
+
+begin
+ keych = ch
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/mkpkg b/pkg/utilities/nttools/tedit/display/screen/mkpkg
new file mode 100644
index 00000000..dc062ae4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/mkpkg
@@ -0,0 +1,32 @@
+# Update the display library.
+# Author: B.Simon 01-APR-91
+
+$checkout libpkg.a ../../
+$update libpkg.a
+$checkin libpkg.a ../../
+$exit
+
+libpkg.a:
+ kbegin.x <fset.h> "../curses.h" "screen.com"
+ kcompile.x <ctype.h> "../curses.h" "screen.com"
+ kconvert.x <ctype.h>
+ kdoline.x <ctype.h>
+ kend.x <fset.h> "screen.com"
+ kget.x <ctype.h> "screen.com"
+ khelp.x "screen.com"
+ kpushbk.x "screen.com"
+ psbegin.x <ttyset.h> "screen.com"
+ psbeep.x
+ psend.x "screen.com"
+ psfill.x <ctype.h> "../curses.h" "screen.com"
+ psheight.x "screen.com"
+ psintersect.x "../curses.h"
+ psscreen.x "screen.com"
+ pssendcap.x "screen.com"
+ pssetcur.x "screen.com"
+ psslide.x "../curses.h" "screen.com"
+ pssynch.x "screen.com"
+ pswidth.x "screen.com"
+ pswrite.x <ctype.h> "../curses.h" "screen.com"
+ pswrtcells.x <ctype.h> "../curses.h" "screen.com"
+ ;
diff --git a/pkg/utilities/nttools/tedit/display/screen/psbeep.x b/pkg/utilities/nttools/tedit/display/screen/psbeep.x
new file mode 100644
index 00000000..252991ba
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psbeep.x
@@ -0,0 +1,9 @@
+# PS_BEEP -- Sound the bell
+#
+# B.Simon 19-Jan-89 Original
+
+procedure ps_beep ()
+
+begin
+ call ps_sendcap ("bl", 1)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psbegin.x b/pkg/utilities/nttools/tedit/display/screen/psbegin.x
new file mode 100644
index 00000000..2bf702cf
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psbegin.x
@@ -0,0 +1,59 @@
+include <ttyset.h>
+include "../curses.h"
+
+# PS_BEGIN -- Initialize physical screen display
+#
+# B.Simon 18-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+
+procedure ps_begin ()
+
+#--
+include "screen.com"
+
+char ch
+data ch / EOS /
+
+string nomove "Terminal does not support cursor movement (cm)"
+
+bool ttygetb()
+int ttopen(), ttystati()
+pointer ttyodes()
+
+begin
+ # Initialize global variables
+
+ ks[1] = EOS
+ ke[1] = EOS
+ keych = EOF
+
+ currow = GIANT
+ curcol = GIANT
+
+ keytab = NULL
+ termscr = NULL
+ htext = NULL
+
+ term = ttyodes ("terminal")
+ lines = ttystati (term, TTY_NLINES)
+ cols = ttystati (term, TTY_NCOLS)
+
+ if (! ttygetb (term, "cm")) {
+ call ttyclose (term)
+ call error (1, nomove)
+ }
+
+ ttyin = ttopen ("dev$tty", READ_ONLY)
+ ttyout = ttopen ("dev$tty", APPEND)
+
+ # Allocate memory for screen and fill with EOS
+
+ call malloc (termscr, lines*cols, TY_CHAR)
+ call amovkc (ch, Memc[termscr], lines*cols)
+
+ # Initialize display
+
+ call ps_sendcap ("ti", 1)
+ call ps_sendcap ("vs", 1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psend.x b/pkg/utilities/nttools/tedit/display/screen/psend.x
new file mode 100644
index 00000000..1d86e6df
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psend.x
@@ -0,0 +1,48 @@
+# PS_END -- Terminate physical display package
+#
+# B.Simon 18-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+
+procedure ps_end()
+
+#--
+include "screen.com"
+
+char newline
+data newline / '\n' /
+
+begin
+ # Restore terminal to original state and release termcap structure
+
+ if (term != NULL) {
+ call ps_sendcap ("ve", 1)
+ call ps_sendcap ("te", 1)
+
+ if (ttyout != NULL) {
+ call ttygoto (ttyout, term, 1, lines)
+ call putc (ttyout, newline)
+ }
+ call ttyclose (term)
+ term = NULL
+ }
+
+ # Release screen memory
+
+ if (termscr != NULL) {
+ call mfree (termscr, TY_CHAR)
+ termscr = NULL
+ }
+
+ # Close terminal descriptor
+
+ if (ttyin != NULL) {
+ call close (ttyin)
+ ttyin = NULL
+ }
+
+ if (ttyout != NULL) {
+ call close (ttyout)
+ ttyout = NULL
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psfill.x b/pkg/utilities/nttools/tedit/display/screen/psfill.x
new file mode 100644
index 00000000..2ceee221
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psfill.x
@@ -0,0 +1,135 @@
+include <ctype.h>
+include "../curses.h"
+
+# PS_FILL -- Fill a rectangle with a single character and attribute
+#
+# B.Simon 19-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+# B.Simon 31-Oct-90 Changed to skip correct lines
+
+procedure ps_fill (source, ch, att)
+
+int source[RSIZE] # i: Rectangle
+int ch # i: Fill character
+int att # i: Fill attribute
+#--
+include "screen.com"
+
+bool canclear, bufflag
+char blank, fill, cell
+int dest[RSIZE]
+int ncols, nrows, irow, icol
+pointer sp, buf, scr
+
+data blank / ' ' /
+
+bool ps_intersect(), ttygetb()
+pointer ps_screen()
+
+begin
+ # Clip the rectangle to the screen boundary
+ # If the rectangle is entirely off the screen, return
+
+ if (! ps_intersect (source, lines, cols, dest))
+ return
+
+
+ # Check for the special cases:
+ # Clear entire screen (cl) and clear to end of screen (cd)
+
+ canclear = (ch == ' ' && att == A_NORM)
+ ncols = RWIDTH(dest)
+ nrows = RHEIGHT(dest)
+
+ if (canclear && ncols == cols && nrows == lines) {
+ if (ttygetb (term, "cl")) {
+ call ps_updcur (1, 1)
+ call ps_sendcap ("cl", nrows)
+ call amovkc (blank, Memc[termscr], lines*cols)
+ return
+ }
+ }
+
+ if (canclear && ncols == cols && RBOT(dest) == lines) {
+ if (ttygetb (term, "cd")) {
+ call ps_setcur (RTOP(dest), 1)
+ call ps_sendcap ("cd", nrows)
+ scr = ps_screen (RTOP(dest), 1)
+ call amovkc (blank, Memc[scr], nrows*cols)
+ return
+ }
+ }
+
+ # Write the rectangle a line at a time
+
+ call smark (sp)
+ call salloc (buf, cols, TY_CHAR)
+
+ if (IS_PRINT(ch))
+ fill = ch
+ else
+ fill = blank
+
+ cell = fill + att
+ bufflag = false
+
+ canclear = canclear && ttygetb (term, "ce")
+
+ do irow = RTOP(dest), RBOT(dest) {
+
+ # Check to see if line is already correct
+ # If so, skip to the next line
+
+ scr = ps_screen (irow, RLEFT(dest))
+
+ for (icol = 1; icol <= ncols; icol = icol + 1) {
+ if (Memc[scr+icol-1] != cell)
+ break
+ }
+
+ if (icol > ncols)
+ next
+
+ # Move cursor to beginning of line and set attribute
+
+ call ps_setcur (irow, RLEFT(dest))
+
+ if (att != A_NORM)
+ call ps_sendcap ("so", 1)
+
+ # Special case: clear to end of line
+
+ if (canclear && RRIGHT(dest) == cols) {
+ call ps_sendcap ("ce", 1)
+ call amovkc (blank, Memc[scr], ncols)
+
+ } else {
+
+ # Fill buffer with character and write to terminal
+
+ if (! bufflag) {
+ bufflag = true
+ call amovkc (fill, Memc[buf], ncols)
+ }
+
+ # Don't write to lower right corner if screen will scroll
+
+ if (irow == lines && RRIGHT(dest) == cols) {
+ if (ttygetb (term, "am"))
+ ncols = ncols - 1
+ }
+
+ call write (ttyout, Memc[buf], ncols)
+ call amovkc (cell, Memc[scr], ncols)
+ call ps_updcur (irow, RRIGHT(dest) + 1)
+ }
+
+ # Set attribute back to normal
+
+ if (att != A_NORM)
+ call ps_sendcap ("se", 1)
+
+ }
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psheight.x b/pkg/utilities/nttools/tedit/display/screen/psheight.x
new file mode 100644
index 00000000..8350e773
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psheight.x
@@ -0,0 +1,12 @@
+# PS_HEIGHT -- Get height of physical screen
+#
+# B.Simon 18-Jan-89 Original
+
+int procedure ps_height ()
+
+#--
+include "screen.com"
+
+begin
+ return (lines)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psintersect.x b/pkg/utilities/nttools/tedit/display/screen/psintersect.x
new file mode 100644
index 00000000..93c11f0f
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psintersect.x
@@ -0,0 +1,27 @@
+include "../curses.h"
+
+# PS_INTERSECT -- Intersection between two rectangles
+#
+# B.Simon 18-Jan-89 Original
+
+bool procedure ps_intersect (source, maxrow, maxcol, dest)
+
+int source[RSIZE] # i: Source rectangle
+int maxrow # i: Max row of clipping rectangle
+int maxcol # i: Max column of clipping rectangle
+int dest[RSIZE] # o: Destination rectangle
+#--
+
+begin
+ # Clip source rectangle to (1,1) and (maxrow,maxcol)
+
+ RTOP(dest) = max (1, RTOP(source))
+ RLEFT(dest) = max (1, RLEFT(source))
+ RBOT(dest) = min (maxrow, RBOT(source))
+ RRIGHT(dest) = min (maxcol, RRIGHT(source))
+
+ # Return true if intersection is non-empty
+
+ return (RTOP(dest) <= RBOT(dest) && RLEFT(dest) <= RRIGHT(dest))
+end
+
diff --git a/pkg/utilities/nttools/tedit/display/screen/psscreen.x b/pkg/utilities/nttools/tedit/display/screen/psscreen.x
new file mode 100644
index 00000000..afdd7b8d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psscreen.x
@@ -0,0 +1,14 @@
+# PS_SCREEN -- Return a pointer to a given character on the screen
+#
+# B.Simon 28-Sep-90 Original
+
+pointer procedure ps_screen (row, col)
+
+int row # i: Screen line
+int col # i: Screen column
+#--
+include "screen.com"
+
+begin
+ return (termscr+cols*(row-1)+(col-1))
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pssendcap.x b/pkg/utilities/nttools/tedit/display/screen/pssendcap.x
new file mode 100644
index 00000000..295a6cff
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pssendcap.x
@@ -0,0 +1,74 @@
+# PS_SENDCAP -- Send a termcap command to the terminal
+#
+# B.Simon 18-Jan-89 Original
+
+procedure ps_sendcap (cap, affcnt)
+
+char cap[ARB] # i: Termcap capability name
+int affcnt # i: Number of lines affected by the command
+#--
+include "screen.com"
+
+int nchar
+pointer sp, capstr
+
+int ttygets()
+
+begin
+ call smark (sp)
+ call salloc (capstr, SZ_FNAME, TY_CHAR)
+
+ # Retrieve the termcap capability string given its name
+ # If it is found, write it to the terminal
+
+ nchar = ttygets (term, cap, Memc[capstr], SZ_FNAME)
+ if (nchar > 0) {
+ call ttywrite (ttyout, term, Memc[capstr], nchar, affcnt)
+ ## call ps_debugcap (cap, Memc[capstr], nchar)
+ }
+
+ call sfree (sp)
+end
+
+# PS_DEBUGCAP -- Print a termcap string for debugging purposes
+
+procedure ps_debugcap (capname, capstr, nchar)
+
+char capname[ARB] # i: Termcap capability name
+char capstr[ARB] # i: Termcap capability string
+int nchar # i: Number of characters in string
+#--
+include "screen.com"
+
+char ch
+int ic, jc
+pointer sp, out
+
+begin
+ # Allocate memory for strings
+
+ call smark (sp)
+ call salloc (out, SZ_LINE, TY_CHAR)
+
+ jc = 0
+ do ic = 1, nchar {
+ ch = capstr[ic]
+ if (ch < ' ') {
+ Memc[out+jc] = '^'
+ jc = jc + 1
+ ch = ch + '@'
+ }
+ Memc[out+jc] = ch
+ jc = jc + 1
+ }
+ Memc[out+jc] = EOS
+
+ # Write string to STDOUT and flush
+
+ call fprintf (ttyout, "%s = %s\n")
+ call pargstr (capname)
+ call pargstr (Memc[out])
+ call flush (ttyout)
+
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pssetcur.x b/pkg/utilities/nttools/tedit/display/screen/pssetcur.x
new file mode 100644
index 00000000..a6954da3
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pssetcur.x
@@ -0,0 +1,117 @@
+define ABSOLUTE YES # disable relative cursor motion if YES
+
+# PS_SETCUR -- Set the cursor position
+#
+# B.Simon 19-Jan-89 Original
+# B.Simon 19-Dec-90 Rewritten to speed cursor motion
+# B.Simon 10-Apr-91 Add switch to disable relative motion
+
+procedure ps_setcur (row, col)
+
+int row # i: Cursor row
+int col # i: Cursor column
+#--
+include "screen.com"
+
+bool moved
+int newrow, newcol, dr, dc
+
+bool ttygetb()
+
+begin
+ newrow = min (lines, max (1, row))
+ newcol = min (cols, max (1, col))
+
+ moved = true
+ dr = newrow - currow
+ dc = newcol - curcol
+
+ if (ABSOLUTE == YES) {
+ if (dr != 0 || dc != 0)
+ moved = false
+
+ } else if (dr == 0) {
+ if (dc == 0) { # no move
+ return
+
+ } else if (dc == 1) { # move right by one
+ if (ttygetb (term, "nd"))
+ call ps_sendcap ("nd", 1)
+ else
+ moved = false
+
+ } else if (dc == -1) { # move left by one
+ if (ttygetb (term, "le"))
+ call ps_sendcap ("le", 1)
+ else
+ moved = false
+
+ } else {
+ moved = false
+ }
+
+ } else if (dr == 1) {
+ if (dc == 0) { # move down by one
+ if (ttygetb (term, "do"))
+ call ps_sendcap ("do", 1)
+ else
+ moved = false
+
+ } else {
+ moved = false
+ }
+
+ } else if (dr == -1) {
+ if (dc == 0) { # move up by one
+ if (ttygetb (term, "up"))
+ call ps_sendcap ("up", 1)
+ else
+ moved = false
+ } else {
+ moved = false
+ }
+
+ } else {
+ moved = false
+ }
+
+ if (! moved) # must use absolute move
+ call ttygoto (ttyout, term, newcol, newrow)
+
+ # Update current cursor position
+
+ currow = newrow
+ curcol = newcol
+end
+
+# PS_UPDCUR -- Update the cursor position
+
+procedure ps_updcur (row, col)
+
+int row # i: New cursor row
+int col # i: New cursor column
+#--
+include "screen.com"
+
+bool ttygetb()
+
+begin
+ if (row >= lines) {
+ currow = lines
+ } else {
+ currow = row
+ }
+
+ if (col >= cols) {
+ if (ttygetb (term, "am")) {
+ currow = min (row + 1, lines)
+ curcol = 1
+ } else {
+ curcol = cols
+ }
+
+ } else {
+ curcol = col
+ }
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/psslide.x b/pkg/utilities/nttools/tedit/display/screen/psslide.x
new file mode 100644
index 00000000..5ad0bc5d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/psslide.x
@@ -0,0 +1,182 @@
+include "../curses.h"
+
+# PS_SLIDE -- Slide a rectangle on the screen
+#
+# B.Simon 19-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+# B.Simon 22-Mar-91 Fix error in left & right slides
+
+bool procedure ps_slide (source, dir, dist)
+
+int source[RSIZE] # i: Rectangle
+int dir # i: Direction (from curses.h)
+int dist # i: Distance (> 0)
+#--
+include "screen.com"
+
+char blank
+int dest[RSIZE]
+int nrows, ncols, irow, icol
+pointer oldscr, newscr, linscr
+
+data blank / ' ' /
+
+bool ps_intersect(), ttygetb()
+pointer ps_screen()
+
+begin
+ if (! ps_intersect (source, lines, cols, dest))
+ return (true)
+
+ ncols = RWIDTH(dest)
+ nrows = RHEIGHT(dest)
+
+ switch (dir) {
+ case DIR_UP:
+ if (RLEFT(dest) != 1 || RRIGHT(dest) != cols)
+ return (false)
+ if ( !(ttygetb (term, "al") && ttygetb (term, "dl")))
+ return (false)
+
+ call ps_setcur (max (1, RTOP(dest)-dist), 1)
+ do irow = 1, dist
+ call ps_sendcap ("dl", lines - RTOP(dest) + dist)
+
+ if (RBOT(dest) < lines) {
+ call ps_setcur (RBOT(dest) + 1, 1)
+ do irow = 1, dist
+ call ps_sendcap ("al", lines - RBOT(dest))
+ }
+
+ oldscr = ps_screen (RTOP(dest), 1)
+ newscr = ps_screen (RTOP(dest)-dist, 1)
+ do irow = 1, nrows-dist {
+ if (newscr >= termscr)
+ call amovc (Memc[oldscr], Memc[newscr], ncols)
+ oldscr = oldscr + cols
+ newscr = newscr + cols
+ }
+ do irow = 1, dist {
+ if (newscr < (termscr + lines * cols))
+ call amovkc (blank, Memc[newscr], ncols)
+ newscr = newscr + cols
+ }
+
+ case DIR_DOWN:
+ if (RLEFT(dest) != 1 || RRIGHT(dest) != cols)
+ return (false)
+ if ( !(ttygetb (term, "al") && ttygetb (term, "dl")))
+ return (false)
+
+ call ps_setcur (min (lines, RBOT(dest)+1), 1)
+ do irow = 1, dist
+ call ps_sendcap ("dl", lines - RBOT(dest))
+
+ call ps_setcur (RTOP(dest), 1)
+ do irow = 1, dist
+ call ps_sendcap ("al", lines - RTOP(dest))
+
+ oldscr = ps_screen (RBOT(dest), 1)
+ newscr = ps_screen (RBOT(dest)+dist, 1)
+ do irow = 1, nrows-dist {
+ if (newscr < (termscr + lines * cols))
+ call amovc (Memc[oldscr], Memc[newscr], ncols)
+ oldscr = oldscr - cols
+ newscr = newscr - cols
+ }
+ do irow = 1, dist {
+ if (newscr >= termscr)
+ call amovkc (blank, Memc[newscr], ncols)
+ newscr = newscr - cols
+ }
+
+ case DIR_LEFT:
+ if (! ((ttygetb (term, "ic") || ttygetb (term, "im")) &&
+ ttygetb (term, "dc")))
+ return (false)
+
+ do irow = RTOP(dest), RBOT(dest) {
+
+ call ps_setcur (irow, max (1, RLEFT(dest)-dist))
+ call ps_sendcap ("dm", 1)
+ do icol = 1, dist
+ call ps_sendcap ("dc", 1)
+ call ps_sendcap ("ed", 1)
+
+ if (RRIGHT(dest) < cols) {
+ call ps_setcur (irow, RRIGHT(dest) - dist + 1)
+ call ps_sendcap ("im", 1)
+ do icol = 1, dist {
+ call ps_sendcap ("ic", 1)
+ call ps_sendcap ("ip", 1)
+ call putc (ttyout, blank)
+ }
+ call ps_sendcap ("ei", 1)
+ call ps_updcur (irow, RRIGHT(dest) + 1)
+ }
+
+ linscr = ps_screen (irow,1)
+ oldscr = ps_screen (irow,RLEFT(dest))
+ newscr = oldscr - dist
+
+ do icol = 1, ncols-dist+1 {
+ if (newscr >= linscr)
+ Memc[newscr] = Memc[oldscr]
+ oldscr = oldscr + 1
+ newscr = newscr + 1
+ }
+
+ do icol = 1, dist {
+ if (newscr < linscr + cols)
+ Memc[newscr] = blank
+ newscr = newscr + 1
+ }
+ }
+ case DIR_RIGHT:
+ if (! ((ttygetb (term, "ic") || ttygetb (term, "im")) &&
+ ttygetb (term, "dc")))
+ return (false)
+
+ do irow = RTOP(dest), RBOT(dest) {
+
+ if (RRIGHT(dest) < cols - 1) {
+ call ps_setcur (irow, RRIGHT(dest) + 1)
+ call ps_sendcap ("dm", 1)
+ do icol = 1, dist
+ call ps_sendcap ("dc", 1)
+ call ps_sendcap ("ed", 1)
+ }
+
+ call ps_setcur (irow, RLEFT(dest))
+ call ps_sendcap ("im", 1)
+ do icol = 1, dist {
+ call ps_sendcap ("ic", 1)
+ call ps_sendcap ("ip", 1)
+ call putc (ttyout, blank)
+ }
+ call ps_sendcap ("ei", 1)
+ call ps_updcur (irow, RLEFT(dest) + dist)
+
+ linscr = ps_screen (irow,1)
+ oldscr = ps_screen (irow,RRIGHT(dest))
+ newscr = oldscr + dist
+
+ do icol = 1, ncols-dist+1 {
+ if (newscr < linscr + cols)
+ Memc[newscr] = Memc[oldscr]
+ oldscr = oldscr - 1
+ newscr = newscr - 1
+ }
+
+ do icol = 1, dist {
+ if (newscr >= linscr)
+ Memc[newscr] = blank
+ newscr = newscr - 1
+ }
+ }
+ default:
+ return (false)
+ }
+
+ return (true)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pssynch.x b/pkg/utilities/nttools/tedit/display/screen/pssynch.x
new file mode 100644
index 00000000..a91474c8
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pssynch.x
@@ -0,0 +1,12 @@
+# PS_SYNCH -- Bring screen up to date
+#
+# B.Simon 18-Jan-89 Original
+
+procedure ps_synch ()
+
+#--
+include "screen.com"
+
+begin
+ call flush (ttyout)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pswidth.x b/pkg/utilities/nttools/tedit/display/screen/pswidth.x
new file mode 100644
index 00000000..d06a190c
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pswidth.x
@@ -0,0 +1,12 @@
+# PS_WIDTH -- Get width of physical screen
+#
+# B.Simon 18-Jan-89 Original
+
+int procedure ps_width ()
+
+#--
+include "screen.com"
+
+begin
+ return (cols)
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pswrite.x b/pkg/utilities/nttools/tedit/display/screen/pswrite.x
new file mode 100644
index 00000000..ea8de0af
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pswrite.x
@@ -0,0 +1,79 @@
+include <ctype.h>
+include "../curses.h"
+
+# PS_WRITE -- Write a string on the physical screen
+#
+# B.Simon 18-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+
+procedure ps_write (row, col, ncols, str, att)
+
+int row # i: Starting row
+int col # i: Starting column
+int ncols # i: Number of columns to write
+char str[ARB] # i: String to write
+int att # i: Attribute
+#--
+include "screen.com"
+
+char blank
+int colstart, colend, idxstart, idxend, idx
+pointer scr
+
+data blank / ' ' /
+
+bool ttygetb()
+int strlen()
+pointer ps_screen()
+
+begin
+ # Don't try to print if string is entirely off the screen
+
+ if (row < 1 || row > lines || col > cols)
+ return
+
+ # Compute the portion of the string that is on the screen
+
+ colstart = max (col, 1)
+ colend = min (ncols, strlen(str)) + col - 1
+ colend = min (colend, cols)
+
+ if (colend == cols && row == lines) {
+ if (ttygetb (term, "am"))
+ colend = colend - 1
+ }
+
+ if (colend < colstart)
+ return
+
+ idxstart = colstart - col + 1
+ idxend = colend - col + 1
+
+ # Move the cursor to the position of the first printed character
+
+ call ps_setcur (row, colstart)
+
+ # Print the string with the proper attribute
+ # All non-printing characters are printed as blanks
+
+ if (att != A_NORM)
+ call ps_sendcap ("so", 1)
+
+ scr = ps_screen (row, colstart)
+ do idx = idxstart, idxend {
+ if (IS_PRINT(str[idx])) {
+ call putc (ttyout, str[idx])
+ Memc[scr] = str[idx] + att
+ } else {
+ call putc (ttyout, blank)
+ Memc[scr] = blank + att
+ }
+ scr = scr + 1
+ }
+
+ if (att != A_NORM)
+ call ps_sendcap ("se", 1)
+
+ call ps_updcur (row, colend + 1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/pswrtcells.x b/pkg/utilities/nttools/tedit/display/screen/pswrtcells.x
new file mode 100644
index 00000000..0e080121
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/pswrtcells.x
@@ -0,0 +1,114 @@
+include <ctype.h>
+include "../curses.h"
+
+# PS_WRTCELLS -- Write a vector of cells
+#
+# B.Simon 19-Jan-89 Original
+# B.Simon 26-Sep-90 Updated to use screen buffer
+
+procedure ps_wrtcells (row, col, vector, ncols)
+
+int row # i: Starting row
+int col # i: Starting column
+char vector[ARB] # i: Vector to write
+int ncols # i: Number of columns to write
+#--
+include "screen.com"
+
+char blank, att, ch
+int colstart, colend, idxstart, idxend, idx
+pointer scr
+
+data blank / ' ' /
+
+bool ttygetb()
+pointer ps_screen()
+
+begin
+ # Don't try to print if vector is entirely off the screen
+
+ if (row < 1 || row > lines || col > cols)
+ return
+
+ # Compute the portion of the vector that is on the screen
+
+ colstart = max (col, 1)
+ colend = min (ncols + col - 1, cols)
+
+ if (colend == cols && row == lines) {
+ if (ttygetb (term, "am"))
+ colend = colend - 1
+ }
+
+ idxstart = colstart - col + 1
+ idxend = colend - col + 1
+
+ # Adjust string start and end so that portions that
+ # duplicate the current screen contents are not printed
+
+ scr = ps_screen (row, colend)
+ while (idxend >= idxstart) {
+ if (vector[idxend] != Memc[scr])
+ break
+
+ colend = colend - 1
+ idxend = idxend - 1
+ scr = scr - 1
+ }
+
+ scr = ps_screen (row, colstart)
+ while (idxstart <= idxend) {
+ if (vector[idxstart] != Memc[scr])
+ break
+
+ colstart = colstart + 1
+ idxstart = idxstart + 1
+ scr = scr + 1
+ }
+
+ if (colend < colstart)
+ return
+
+ # Move the cursor to the position of the first printed character
+
+ call ps_setcur (row, colstart)
+
+ # Print the vector
+
+ att = 0
+ do idx = idxstart, idxend {
+
+ # Set the proper attribute
+
+ if (vector[idx] < A_STANDOUT) {
+ ch = vector[idx]
+ if (att != 0) {
+ att = 0
+ call ps_sendcap ("se", 1)
+ }
+ } else {
+ ch = vector[idx] - A_STANDOUT
+ if (att == 0) {
+ att = vector[idx] - ch
+ call ps_sendcap ("so", 1)
+ }
+ }
+
+ # Print non-printing character as blank
+
+ if (IS_PRINT(ch)) {
+ call putc (ttyout, ch)
+ Memc[scr] = ch + att
+ } else {
+ call putc (ttyout, blank)
+ Memc[scr] = blank + att
+ }
+ scr = scr + 1
+ }
+
+ if (att != 0)
+ call ps_sendcap ("se", 1)
+
+ call ps_updcur (row, colend + 1)
+
+end
diff --git a/pkg/utilities/nttools/tedit/display/screen/screen.com b/pkg/utilities/nttools/tedit/display/screen/screen.com
new file mode 100644
index 00000000..5a13cd02
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/display/screen/screen.com
@@ -0,0 +1,18 @@
+# SCREEN.COM -- Global variables used by the screen routines
+
+pointer keytab # Table of function key sequences
+pointer termscr # Copy of terminal screen contents
+pointer htext # Function key help text
+pointer term # The termcap data structure
+int ttyin # Input file descriptor for the terminal
+int ttyout # Output file descriptor for the terminal
+int lines # The number of lines on the screen
+int cols # The number of columns on the screen
+int currow # Cursor row
+int curcol # Cursor column
+int keych # Pushed back keyboard character
+char ks[7] # Initialize keypad sequence
+char ke[7] # Terminate keypad sequence
+
+common /screen/ keytab, termscr, htext, ttyin, ttyout, term,
+ lines, cols, currow, curcol, keych, ks, ke
diff --git a/pkg/utilities/nttools/tedit/edit.x b/pkg/utilities/nttools/tedit/edit.x
new file mode 100644
index 00000000..8fe14a87
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/edit.x
@@ -0,0 +1,70 @@
+include "command.h"
+
+# EDIT -- Main procedure of table editor
+
+procedure edit (table, columns, silent, rdonly, inplace)
+
+char table[ARB] # i: SDAS table name
+char columns[ARB] # i: list of columns to edit
+bool silent # i: don't ring bell when error occurs
+bool rdonly # i: edit table read only
+bool inplace # i: edit table in place
+#--
+int nargs, code
+pointer sp, scr, command, arglist
+
+begin
+ call smark (sp)
+ call salloc (command, SZ_LINE, TY_CHAR)
+ call salloc (arglist, SZ_LINE, TY_CHAR)
+
+ call init_cmd (silent)
+ call init_screen (table, columns, rdonly, inplace, scr)
+ call help_prompt (scr, NO)
+
+ repeat {
+ call edit_screen (scr)
+ call read_prompt ("Command:", Memc[command], SZ_LINE)
+ call parse_cmd (Memc[command], code, nargs, Memc[arglist], SZ_LINE)
+
+ if (nargs > 0) {
+ switch (code) {
+ case TED_ADD:
+ call add_cmd (scr, nargs, Memc[arglist])
+ case TED_COPY:
+ call copy_cmd (scr, nargs, Memc[arglist])
+ case TED_DELETE:
+ call delete_cmd (scr, nargs, Memc[arglist])
+ case TED_EXIT:
+ call exit_cmd (scr, nargs, Memc[arglist])
+ break
+ case TED_FIND:
+ call find_cmd (scr, nargs, Memc[arglist])
+ case TED_GOTO:
+ call goto_cmd (scr, nargs, Memc[arglist])
+ case TED_HELP:
+ call help_cmd (scr, nargs, Memc[arglist])
+ case TED_INSERT:
+ call insert_cmd (scr, nargs, Memc[arglist])
+ case TED_LOWER:
+ call lower_cmd (scr, nargs, Memc[arglist])
+ case TED_NEXT:
+ call next_cmd (scr, nargs, Memc[arglist])
+ case TED_QUIT:
+ call quit_cmd (scr, nargs, Memc[arglist])
+ break
+ case TED_SET:
+ call set_cmd (scr, nargs, Memc[arglist])
+ case TED_SUBSTITUTE:
+ call sub_cmd (scr, nargs, Memc[arglist])
+ case TED_UPPER:
+ call upper_cmd (scr, nargs, Memc[arglist])
+ default:
+ call help_prompt (scr, YES)
+ }
+ }
+ }
+
+ call end_screen
+ call sfree (sp)
+end
diff --git a/pkg/utilities/nttools/tedit/field.h b/pkg/utilities/nttools/tedit/field.h
new file mode 100644
index 00000000..4a74799c
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/field.h
@@ -0,0 +1,23 @@
+# FIELD.H -- Tedit field descriptor
+
+define TED_FLDLEN 11 # field descriptor length
+
+define TED_FSCREEN Memi[$1] # screen associated with field
+define TED_RDOFLD Memi[$1+1] # is this a read only field?
+define TED_PGSIZE Memi[$1+2] # number of rows on screen
+define TED_LSTROW Memi[$1+3] # last row in table
+define TED_LSTCOL Memi[$1+4] # last column in table
+define TED_NXTROW Memi[$1+5] # next row to edit
+define TED_NXTCOL Memi[$1+6] # next column to edit
+define TED_DIRECT Memi[$1+7] # direction of motion
+define TED_FINDEX Memi[$1+8] # column index
+define TED_MRKFLD Memi[$1+9] # has this field been changed?
+define TED_COMMAND Memi[$1+10] # has command key been pressed?
+
+define SZ_FIELD 512 # Maximum length of a single field
+
+# The following are the legal alignments (used by align_field and move_field)
+
+define LEFT 1
+define CENTER 2
+define RIGHT 3
diff --git a/pkg/utilities/nttools/tedit/field.x b/pkg/utilities/nttools/tedit/field.x
new file mode 100644
index 00000000..5fecad11
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/field.x
@@ -0,0 +1,749 @@
+include <tbset.h>
+include <lexnum.h>
+include <mach.h>
+include <ctype.h>
+include "display/curses.h"
+include "screen.h"
+include "table.h"
+include "field.h"
+
+# FIELD -- Procedures which manipulate a single field (table element)
+
+# ADD_FIELD -- Add a new field to the table and screen
+
+procedure add_field (scr, tabrow, tabcol)
+
+pointer scr # u: screen descriptor
+int tabrow # i: new table row
+int tabcol # i: new table column
+#--
+char blank
+int win, nrows, ncols, row, col, irow, icol, junk, hitab, ic
+pointer tab, tptr, sp, line, temp
+
+data blank / ' ' /
+
+int tbpsta(), itoc()
+
+begin
+ # Get window and table pointers from screen descriptor
+
+ win = TED_WINDOW(scr)
+ tab = TED_TABLE(scr)
+ tptr = TED_TABPTR(tab)
+
+ # Get dimensions of window and table
+
+ call wdimen (win, nrows, ncols)
+ call pos_field (scr, 1, row, col)
+ hitab = tbpsta (tptr, TBL_NROWS)
+
+ # Add new row to table
+
+ call tbtwer (tptr, tabrow)
+ TED_DIRTY(tab) = YES
+
+ # Update current row and column
+
+ TED_CURROW(scr) = tabrow
+ TED_CURCOL(scr) = tabcol
+
+ # If new row is off screen, redraw screen
+
+ if (row >= nrows || col >= ncols) {
+ call move_screen (scr, LEFT, YES)
+ return
+ }
+
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (line, ncols+1,TY_CHAR)
+ call salloc (temp, SZ_LINE, TY_CHAR)
+
+ # Copy table elements to text line
+ # and write the line on the screen
+
+ call wmove (win, row+1, 1)
+ do irow = hitab+1, tabrow {
+ junk = itoc (irow, Memc[temp], SZ_LINE)
+ call align_field (RIGHT, blank, Memc[temp],
+ Memc[line], TED_LABWIDTH(tab))
+
+ ic = TED_LABWIDTH(tab)
+ do icol = TED_LOCOL(scr), TED_HICOL(scr) {
+ Memc[line+ic] = ' '
+ ic = ic + 1
+
+ call tbegtt (tptr, TED_COLPTR(tab,icol), irow,
+ Memc[temp], SZ_LINE)
+
+ call align_field (LEFT, blank, Memc[temp], Memc[line+ic],
+ TED_COLLEN(tab,icol))
+ ic = ic + TED_COLLEN(tab,icol)
+ }
+
+ Memc[line+ic] = '\n'
+ Memc[line+ic+1] = EOS
+ call waddstr (win, Memc[line])
+ }
+
+ # Move cursor to current field and refresh window
+
+ TED_HIROW(scr) = tabrow
+ call move_field (scr)
+
+ call wrefresh (win)
+ call sfree (sp)
+
+end
+
+# ALIGN_FIELD -- Align a string within a larger field
+
+procedure align_field (align, fill, instr, outstr, outlen)
+
+int align # i: alignment of output string
+char fill # i: fill character
+char instr[ARB] # i: input string
+char outstr[ARB] # o: output string
+int outlen # i: length of output string
+#--
+int ibeg, iend, inlen, jbeg, jend, ic, jc, kc
+
+begin
+ # Get the first and last characters in the string
+ # which are not fill characters
+
+ ibeg = 0
+ iend = 0
+ for (ic = 1; instr[ic] != EOS; ic = ic + 1) {
+ if (instr[ic] != fill) {
+ if (ibeg == 0)
+ ibeg = ic
+ iend = ic
+ }
+ }
+ ibeg = max (ibeg, 1)
+ inlen = (iend - ibeg) + 1
+
+ # Check the length of the input string to see
+ # if the alignment problem is trivial
+
+ if (inlen >= outlen) {
+ call strcpy (instr[ibeg], outstr, outlen)
+ return
+ }
+
+ # Calculate the number of fill characters to add at
+ # the beginning and end of the string
+
+ switch (align) {
+ case LEFT:
+ jbeg = 0
+ jend = outlen - inlen
+
+ case CENTER:
+ jbeg = (outlen - inlen) / 2
+ jend = outlen - inlen - jbeg
+
+ case RIGHT:
+ jbeg = outlen - inlen
+ jend = 0
+ }
+
+ # Create the output string
+
+ for (jc = 1; jc <= jbeg; jc = jc + 1)
+ outstr[jc] = fill
+
+ for (ic = ibeg; ic <= iend; ic = ic + 1) {
+ outstr[jc] = instr[ic]
+ jc = jc + 1
+ }
+
+ for (kc = 1; kc <= jend; kc = kc + 1) {
+ outstr[jc] = fill
+ jc = jc + 1
+ }
+
+ outstr[jc] = EOS
+end
+
+# CHECK_FIELD -- Check string to see if it has the correct data type
+
+bool procedure check_field (datatype, field)
+
+int datatype # i: Datatype to check
+char field[ARB] # i: String to be checked
+#--
+bool match
+double fieldval
+int ic, nc, lextype, fieldtype
+pointer sp, temp
+
+string yorn "|yes|no|"
+
+bool streq()
+int strlen(), lexnum(), ctod(), strdic()
+
+begin
+ call smark (sp)
+ call salloc (temp, SZ_LINE, TY_CHAR)
+
+ if (datatype < 0)
+
+ # The only check on string types is that they not exceed their
+ # maximum length
+
+ match = strlen (field) <= -(datatype)
+
+ else {
+
+ # Get the data type of the string
+ # Reduce this to character, integer or real
+ # Get the value of the string if it is not character
+
+ if (streq (field, "INDEF")) {
+ fieldtype = datatype
+ fieldval = 0.0
+
+ } else {
+ ic = 1
+ lextype = lexnum (field, ic, nc)
+
+ for (ic = ic + nc; IS_WHITE(field[ic]); ic = ic + 1)
+ ;
+ if (field[ic] != EOS)
+ lextype = LEX_NONNUM
+
+ if (lextype == LEX_HEX || lextype == LEX_NONNUM) {
+ fieldtype = TY_CHAR
+ fieldval = 0.0
+ } else {
+ if (lextype == LEX_REAL)
+ fieldtype = TY_REAL
+ else
+ fieldtype = TY_INT
+
+ ic = 1
+ nc = ctod (field, ic, fieldval)
+ fieldval = abs (fieldval)
+ }
+ }
+
+ # See if the string matches the expected datatype
+
+ switch (datatype) {
+ case TY_BOOL:
+ match = strdic (field, Memc[temp], SZ_LINE, yorn) > 0
+ case TY_CHAR:
+ match = strlen (field) <= 1
+ case TY_SHORT:
+ match = fieldtype == TY_INT && fieldval <= MAX_SHORT
+ case TY_INT:
+ match = fieldtype == TY_INT && fieldval <= MAX_INT
+ case TY_LONG:
+ match = fieldtype == TY_INT && fieldval <= MAX_LONG
+ case TY_REAL:
+ match = fieldtype != TY_CHAR && fieldval <= MAX_REAL
+ case TY_DOUBLE:
+ match = fieldtype != TY_CHAR && fieldval <= MAX_DOUBLE
+ default:
+ match = true
+ }
+ }
+
+ call sfree (sp)
+ return (match)
+end
+
+# DRAW_FIELD -- Draw a single field on the screen
+
+procedure draw_field (scr)
+
+pointer scr # i: screen descriptor
+#--
+char blank
+pointer sp, value, field, tab
+int win, tabrow, tabcol, row, col, orow, ocol
+
+data blank / ' ' /
+
+int winstat()
+
+begin
+ # Allocate dynamic memory to hold string
+
+ call smark (sp)
+ call salloc (value, SZ_FIELD, TY_CHAR)
+ call salloc (field, SZ_FIELD, TY_CHAR)
+
+ # Get current value
+
+ win = TED_WINDOW(scr)
+ tab = TED_TABLE(scr)
+
+ tabrow = TED_CURROW(scr)
+ tabcol = TED_CURCOL(scr)
+
+ call tbegtt (TED_TABPTR(tab), TED_COLPTR(tab,tabcol),
+ tabrow, Memc[value], SZ_FIELD)
+
+ call align_field (LEFT, blank, Memc[value],
+ Memc[field], TED_COLLEN(tab,tabcol))
+
+ # Redraw field and reposition cursor
+
+ orow = winstat (win, W_CURROW)
+ ocol = winstat (win, W_CURCOL)
+
+ call pos_field (scr, 1, row, col)
+ call wmove (win, row, col)
+
+ call waddstr (win, Memc[field])
+ call wmove (win, orow, ocol)
+
+ call sfree (sp)
+end
+
+# EDIT_FIELD -- Interactively edit a table field
+
+procedure edit_field (win, field, maxch)
+
+int win # i: Window descriptor
+char field[ARB] # u: Table field
+int maxch # i: Maximum line length
+#--
+int row, col, ch, ic, jc, mc, nc
+pointer sp, data, buffer
+
+string nowrite "Cannot change field: table is read only"
+string fullfld "Cannot undelete word: not enough room in field"
+
+int strlen(), k_get(), winstat()
+
+begin
+ call wgetstruct (win, data)
+
+ nc = strlen (field)
+ ic = min (TED_FINDEX(data) - 1, nc)
+
+ row = winstat (win, W_CURROW)
+ col = winstat (win, W_CURCOL) - ic
+
+ call smark (sp)
+ call salloc (buffer, SZ_FIELD, TY_CHAR)
+ Memc[buffer] = EOS
+
+ TED_COMMAND(data) = NO
+
+ repeat {
+
+ # Read character from keyboard
+
+ call ps_synch
+ ch = k_get ()
+
+ if (ch < K_BASE) {
+ # Move to next field down
+
+ if (ch == '\r') {
+ TED_DIRECT(data) = LEFT
+ TED_NXTROW(data) = TED_NXTROW(data) + 1
+ break
+
+ # Move to next field across
+
+ } else if (ch == '\t') {
+ if (TED_NXTCOL(data) < TED_LSTCOL(data)) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTCOL(data) = TED_NXTCOL(data) + 1
+ break
+ }
+
+ # Insert character at current position
+
+ } else if (TED_RDOFLD(data) == NO) {
+
+ # Check to see if field is full, if so, truncate
+
+ if (nc >= maxch) {
+ nc = maxch - 1
+ field[nc+1] = EOS
+ if (ic > nc) {
+ ic = nc
+ call wmove (win, row, col+ic)
+ }
+ }
+
+ ic = ic + 1
+ nc = nc + 1
+ TED_MRKFLD(data) = YES
+
+ if (ic == nc) {
+ field[ic] = ch
+ field[ic+1] = EOS
+ call waddstr (win, field[ic])
+
+ } else {
+ do jc = nc, ic, -1
+ field[jc+1] = field[jc]
+
+ field[ic] = ch
+ call waddstr (win, field[ic])
+ call wmove (win, row, col+ic)
+ }
+
+ # Print warning message, read_only field
+
+ } else {
+ call warn1_prompt (TED_FSCREEN(data), nowrite)
+ }
+
+ } else {
+ switch (ch) {
+ case K_UP: # Move up one field
+ if (TED_NXTROW(data) > 1) {
+ TED_DIRECT(data) = CENTER
+ TED_NXTROW(data) = TED_NXTROW(data) - 1
+ break
+ }
+
+ case K_DOWN: # Move down one field
+ if (TED_NXTROW(data) < TED_LSTROW(data)) {
+ TED_DIRECT(data) = CENTER
+ TED_NXTROW(data) = TED_NXTROW(data) + 1
+ break
+ }
+ case K_RIGHT: # Move right one column
+ if (ic < nc) {
+ ic = ic + 1
+ call wmove (win, row, col+ic)
+
+ } else if (TED_NXTCOL(data) < TED_LSTCOL(data)) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTCOL(data) = TED_NXTCOL(data) + 1
+ break
+ }
+
+ case K_LEFT: # Move left one column
+ if (ic > 0) {
+ ic = ic - 1
+ call wmove (win, row, col+ic)
+
+ } else if (TED_NXTCOL(data) > 1) {
+ TED_DIRECT(data) = RIGHT
+ TED_NXTCOL(data) = TED_NXTCOL(data) - 1
+ break
+ }
+
+ case K_NEXTW: # Move forwards one field
+ if (TED_NXTCOL(data) < TED_LSTCOL(data)) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTCOL(data) = TED_NXTCOL(data) + 1
+ break
+ }
+
+ case K_PREVW: # Move backwards one field
+ if (TED_NXTCOL(data) > 1) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTCOL(data) = TED_NXTCOL(data) - 1
+ break
+ }
+
+ case K_NEXTP: # Move forwards one screen
+ if (TED_NXTROW(data) < TED_LSTROW(data)) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTROW(data) = min (TED_LSTROW(data),
+ TED_NXTROW(data) + TED_PGSIZE(data))
+ break
+ }
+
+ case K_PREVP: # Move backwards one page
+ if (TED_NXTROW(data) > 1) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTROW(data) = max (1,
+ TED_NXTROW(data) - TED_PGSIZE(data))
+ break
+ }
+
+ case K_HOME: # Move to first row
+ if (TED_NXTROW(data) > 1) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTROW(data) = 1
+ break
+ }
+
+ case K_END: # Move to last row and column
+ if (TED_NXTROW(data) < TED_LSTROW(data)) {
+ TED_DIRECT(data) = LEFT
+ TED_NXTROW(data) = TED_LSTROW(data)
+ break
+ }
+
+ case K_BOL: # Move to first column in table
+ if (TED_NXTCOL(data) == 1) {
+ ic = 0
+ call wmove (win, row, col)
+
+ } else {
+ TED_DIRECT(data) = LEFT
+ TED_NXTCOL(data) = 1
+ break
+ }
+
+ case K_EOL: # Move to last column in table
+ if (TED_NXTCOL(data) == TED_LSTCOL(data)) {
+ ic = nc
+ call wmove (win, row, col+ic)
+
+ } else {
+ TED_DIRECT(data) = RIGHT
+ TED_NXTCOL(data) = TED_LSTCOL(data)
+ break
+ }
+
+ case K_DEL: # Delete character underneath cursor
+ if (TED_RDOFLD(data) == NO) {
+ if (ic < nc) {
+ TED_MRKFLD(data) = YES
+ mc = strlen (Memc[buffer])
+
+ Memc[buffer+mc] = field[ic+1]
+ Memc[buffer+mc+1] = EOS
+
+
+ do jc = ic+1, nc
+ field[jc] = field[jc+1]
+ field[nc] = ' '
+ field[nc+1] = EOS
+
+ call waddstr (win, field[ic+1])
+ field[nc] = EOS
+ nc = nc - 1
+
+ call wmove (win, row, col+ic)
+ }
+ } else {
+ call warn1_prompt (TED_FSCREEN(data), nowrite)
+ }
+
+ case K_BS: # Delete character to left of cursor
+ if (TED_RDOFLD(data) == NO) {
+ if (ic > 0) {
+ TED_MRKFLD(data) = YES
+ mc = strlen (Memc[buffer])
+
+ do jc = mc, 0, -1
+ Memc[buffer+jc+1] = Memc[buffer+jc]
+ Memc[buffer] = field[ic]
+
+ ic = ic - 1
+ call wmove (win, row, col+ic)
+
+ do jc = ic+1, nc
+ field[jc] = field[jc+1]
+ field[nc] = ' '
+ field[nc+1] = EOS
+
+ call waddstr (win, field[ic+1])
+ field[nc] = EOS
+ nc = nc - 1
+
+ call wmove (win, row, col+ic)
+ }
+ } else {
+ call warn1_prompt (TED_FSCREEN(data), nowrite)
+ }
+
+ case K_DWORD: # Delete entire field
+ if (TED_RDOFLD(data) == NO) {
+ if (nc > 0) {
+ TED_MRKFLD(data) = YES
+ call strcpy (field[ic+1], Memc[buffer], nc-ic)
+
+ do jc = ic+1, nc
+ field[jc] = ' '
+ field[nc+1] = EOS
+
+ call wmove (win, row, col+ic)
+ call waddstr (win, field[ic+1])
+
+ field[ic+1] = EOS
+ nc = ic
+
+ call wmove (win, row, col+ic)
+ }
+ } else {
+ call warn1_prompt (TED_FSCREEN(data), nowrite)
+ }
+
+ case K_DLINE: # Delete entire line (not supported)
+ call ring_bell
+
+ case K_UNDCHR: # Undelete a character
+ mc = strlen (Memc[buffer])
+ if (mc > 0) {
+ do jc = nc+1, ic+1, -1
+ field[jc+1] = field[jc]
+
+ field[ic+1] = Memc[buffer+mc-1]
+ Memc[buffer+mc-1] = EOS
+
+ call waddstr (win, field[ic+1])
+
+ ic = ic + 1
+ nc = nc + 1
+ call wmove (win, row, col+ic)
+ }
+
+ case K_UNDWRD: # Undelete a word
+ mc = strlen (Memc[buffer])
+ if ((mc + nc) > maxch) {
+ call warn1_prompt (TED_FSCREEN(data), fullfld)
+
+ } else if (mc > 0) {
+ call amovc (field[ic+1], field[ic+mc+1], nc-ic+1)
+ call amovc (Memc[buffer], field[ic+1], mc)
+
+ Memc[buffer] = EOS
+ call waddstr (win, field[ic+1])
+
+ ic = ic + mc
+ nc = nc + mc
+ call wmove (win, row, col+ic)
+ }
+
+ case K_UNDLIN: # Undelete a line (not supported)
+ call ring_bell
+
+ case K_HELP: # Display help screen
+ call help_screen (win)
+
+ case K_PAINT: # Force screen redraw
+ call clearok (STDSCR, true)
+ call wrefresh (STDSCR)
+ call focus_window (win)
+
+ case K_EXIT: # Exit procedure
+ TED_COMMAND(data) = YES
+ break
+
+ default:
+ call ring_bell
+ }
+ }
+ }
+
+ # Terminate field with EOS and push back character
+ # that terminated input
+
+ if (nc >= maxch)
+ ch = EOS
+
+ field[nc+1] = EOS
+ call k_pushbk (ch)
+
+ TED_FINDEX(data) = ic + 1
+
+end
+
+procedure move_field (scr)
+
+pointer scr # i: screen descriptor
+#--
+int row, col
+
+begin
+ # Calculate the screen row and column and move the cursor there
+
+ call pos_field (scr, TED_SCRIDX(scr), row, col)
+ call wmove (TED_WINDOW(scr), row, col)
+
+end
+
+# POS_FIELD -- Find the cursor position in a field
+
+procedure pos_field (scr, index, row, col)
+
+pointer scr # i: screen descriptor
+int index # i: index of character in current field
+int row # o: window row
+int col # o: window column
+#--
+int icol
+pointer tab
+
+begin
+ # Get the table assoicated with this screen
+
+ tab = TED_TABLE(scr)
+
+ # Calculate the screen row and column
+
+ row = TED_LABHEIGHT(tab) + 1 + TED_CURROW(scr) - TED_LOROW(scr)
+
+ col = TED_LABWIDTH(tab) + 1
+ do icol = TED_LOCOL(scr), TED_CURCOL(scr) - 1
+ col = col + TED_COLLEN(tab,icol) + 1
+
+ col = col + index
+end
+
+# TRIM_FIELD -- Remove leading and trailing blanks from field
+
+procedure trim_field (scr, rdonly, coltype, collen, field)
+
+pointer scr # i: screen descriptor
+int rdonly # i: read only table
+int coltype # i: column type
+int collen # i: column length
+char field[ARB] # u: field to trim
+#--
+int ibeg, iend, ic, jc
+
+string toolong "Field too long to display, editing will cause loss of data"
+int strlen()
+
+begin
+ if (coltype < 0) {
+ # Get the start and end of the string
+
+ ibeg = 1
+ iend = strlen (field)
+ if (iend > collen) {
+ iend = collen
+ if (rdonly == NO)
+ call write_prompt (scr, NO, toolong)
+ }
+
+ } else {
+ # Get the first and last characters in the string
+ # which are not blank
+
+ ibeg = 0
+ iend = 0
+ for (ic = 1; field[ic] != EOS; ic = ic + 1) {
+ if (field[ic] != ' ') {
+ if (ibeg == 0)
+ ibeg = ic
+ iend = ic
+ }
+ }
+ }
+
+ # Trim the field to the correct length
+
+ if (ibeg <= 1) {
+ jc = iend + 1
+ } else {
+ jc = 1
+ for (ic = ibeg; ic <= iend; ic = ic + 1) {
+ field[jc] = field[ic]
+ jc = jc + 1
+ }
+ }
+
+ field[jc] = EOS
+
+end
diff --git a/pkg/utilities/nttools/tedit/mkpkg b/pkg/utilities/nttools/tedit/mkpkg
new file mode 100644
index 00000000..6b187882
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/mkpkg
@@ -0,0 +1,27 @@
+# Update the tedit application code in the ttools package library.
+# Author: BSIMON, 1-APR-91
+
+$checkout libpkg.a ../
+$update libpkg.a
+$checkin libpkg.a ../
+$exit
+
+libpkg.a:
+ @display
+
+ bell.x
+ command.x "command.com" "command.h" "field.h" "paste.h" \
+ "table.h" "screen.h" <tbset.h>
+ edit.x "command.h"
+ field.x "field.h" "table.h" "screen.h" "display/curses.h" \
+ <ctype.h> <mach.h> <lexnum.h> <tbset.h>
+ paste.x "paste.h" "table.h" "screen.h" <tbset.h>
+ prompt.x "screen.h" "display/curses.h"
+ screen.x "field.h" "table.h" "screen.h" \
+ "display/curses.h" <tbset.h>
+ substitute.x <ctype.h>
+ table.x "field.h" "table.h" "screen.h" <tbset.h>
+ tedit.x
+ tread.x
+ window.x "window.com" "screen.h" "display/curses.h"
+ ;
diff --git a/pkg/utilities/nttools/tedit/paste.h b/pkg/utilities/nttools/tedit/paste.h
new file mode 100644
index 00000000..92d47fbd
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/paste.h
@@ -0,0 +1,6 @@
+# PASTE.H -- Tedit paste table descriptor
+
+define TED_PSTLEN 2 # paste descriptor length
+
+define TED_PSTPTR Memi[$1] # paste table pointer
+define TED_PSTROWS Memi[$1+1] # number of rows in paste table
diff --git a/pkg/utilities/nttools/tedit/paste.x b/pkg/utilities/nttools/tedit/paste.x
new file mode 100644
index 00000000..f4c9735d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/paste.x
@@ -0,0 +1,142 @@
+include <tbset.h>
+include "screen.h"
+include "table.h"
+include "paste.h"
+
+define char_ 90 # goto label
+define EXTRA_SPACE 20 # extra row length & col descr space
+
+# CLS_PASTE -- Close the paste table and free the descriptor
+
+procedure cls_paste (scr)
+
+pointer scr # u: Screen descriptor
+#--
+pointer sp, fname, paste
+
+string nodelete "Could not delete paste table"
+
+begin
+ paste = TED_PASTE(scr)
+ if (paste == NULL)
+ return
+
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+
+ call tbtnam (TED_PSTPTR(paste), Memc[fname], SZ_FNAME)
+ call tbtclo (TED_PSTPTR(paste))
+
+ iferr (call delete (Memc[fname]))
+ call warn2_prompt (scr, nodelete, Memc[fname])
+
+ call mfree (paste, TY_STRUCT)
+ TED_PASTE(scr) = NULL
+ call sfree (sp)
+
+end
+
+# MOVE_PASTE -- Move rows to or from the paste table
+
+procedure move_paste (itp, otp, irow, orow, ncopy)
+
+pointer itp # i: pointer to descriptor for input table
+pointer otp # i: pointer to descriptor for output table
+int irow # i: first row of input table to be copied
+int orow # i: row number of first output row
+int ncopy # i: number of rows to copy
+#--
+int jrow, krow
+
+begin
+ krow = orow
+ do jrow = irow, irow+ncopy-1 {
+ call tbrcpy (itp, otp, jrow, krow)
+ krow = krow + 1
+ }
+end
+
+# OPN_PASTE -- Open the paste table
+
+pointer procedure opn_paste (scr)
+
+pointer scr # u: Screen descriptor
+pointer paste # o: Paste descriptor
+#--
+int try, junk, ncol
+pointer sp, oldtab, newtab, newdir, tab, tp, pp
+pointer fname
+
+int tbpsta(), tbparse()
+pointer fnldir(), tbtopn()
+
+string nopaste "Cannot create paste table. Command aborted."
+
+begin
+ # Allocate dynamic memory for file names
+
+ call smark (sp)
+ call salloc (oldtab, SZ_FNAME, TY_CHAR)
+ call salloc (newtab, SZ_FNAME, TY_CHAR)
+ call salloc (newdir, SZ_FNAME, TY_CHAR)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+
+ # Get table name (used to build paste table name)
+
+ tab = TED_TABLE(scr)
+ tp = TED_TABPTR(tab)
+
+ call tbtnam (tp, Memc[oldtab], SZ_FNAME)
+ junk = tbparse (Memc[oldtab], Memc[fname], Memc[newdir], SZ_FNAME,
+ junk) # added by PEH, 1998 Apr 15
+ junk = fnldir (Memc[fname], Memc[newdir], SZ_FNAME)
+
+ # Try to open the paste table in the same directory as the
+ # temporary table. If this doesn't work, try the tmp$ directory
+
+ pp = NULL
+ do try = 1, 2 {
+ call strcat ("paste", Memc[newdir], SZ_FNAME)
+ call mktemp (Memc[newdir], Memc[newtab], SZ_FNAME)
+
+ ifnoerr (pp = tbtopn (Memc[newtab], NEW_COPY, tp))
+ break
+
+ call strcpy ("tmp$", Memc[newdir], SZ_FNAME)
+ }
+
+ if (pp == NULL) {
+ call warn1_prompt (scr, nopaste)
+ TED_PASTE(scr) = NULL
+ return (NULL)
+ }
+
+ # Set the parameters of the paste table, then create it
+
+ ncol = tbpsta (tp, TBL_MAXCOLS)
+
+ call tbpset (pp, TBL_WHTYPE, TBL_TYPE_S_ROW)
+ call tbpset (pp, TBL_INCR_ROWLEN, EXTRA_SPACE)
+ call tbpset (pp, TBL_MAXCOLS, ncol + EXTRA_SPACE)
+ call tbpset (pp, TBL_MAXPAR, 0) # no header parameters
+
+ iferr (call tbtcre (pp)) {
+ call warn1_prompt (scr, nopaste)
+ TED_PASTE(scr) = NULL
+ return (NULL)
+ }
+
+ # Create paste table descriptor
+
+ call malloc (paste, TED_PSTLEN, TY_STRUCT)
+ TED_PSTPTR(paste) = pp
+ TED_PSTROWS(paste) = 0
+
+ # Update the screen structure and return the paste descriptor
+
+ TED_PASTE(scr) = paste
+
+ call sfree (sp)
+ return (paste)
+
+end
diff --git a/pkg/utilities/nttools/tedit/prompt.x b/pkg/utilities/nttools/tedit/prompt.x
new file mode 100644
index 00000000..24d2be70
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/prompt.x
@@ -0,0 +1,225 @@
+include "display/curses.h"
+include "screen.h"
+
+# BOOL_PROMPT -- Get a yes or no response from the user
+
+bool procedure bool_prompt (msg)
+
+char msg[ARB] # i: message to print in the prompt area
+#--
+int index
+pointer sp, resp, msg2
+
+string yorn "|yes|no|"
+
+int strdic()
+
+begin
+ # Allocate memory for temporary strings
+
+ call smark (sp)
+ call salloc (resp, SZ_FNAME, TY_CHAR)
+ call salloc (msg2, SZ_LINE, TY_CHAR)
+
+ # Prompt the user for a response
+
+ call read_prompt (msg, Memc[resp], SZ_FNAME)
+ call strlwr (Memc[resp])
+
+ # See if the response is yes or no,
+ # if it isn't, keep asking
+
+ index = strdic (Memc[resp], Memc[resp], SZ_FNAME, yorn)
+ while (index == 0) {
+ call strcpy ("Please answer yes or no. ", Memc[msg2], SZ_LINE)
+ call strcat (msg, Memc[msg2], SZ_LINE)
+
+ call read_prompt (Memc[msg2], Memc[resp], SZ_FNAME)
+ call strlwr (Memc[resp])
+
+ index = strdic (Memc[resp], Memc[resp], SZ_FNAME, yorn)
+ }
+
+ # Convert result into boolean value
+
+ call sfree (sp)
+ return (index == 1)
+end
+
+# CLEAR_PROMPT -- Clear the prompt window
+
+procedure clear_prompt (scr)
+
+pointer scr # i: Currently active screen
+#--
+int win
+
+int prompt_window()
+
+begin
+ win = prompt_window ()
+ call werase (win)
+
+ if (scr != NULL)
+ call focus_window (TED_WINDOW(scr))
+
+end
+
+# ERR1_PROMPT -- Write an error message in the prompt area of the screen
+
+procedure err1_prompt (msg)
+
+char msg[ARB] # i: Message to write
+#--
+
+begin
+ call eprintf ("\r\n")
+ call error (1, msg)
+end
+
+# ERR2_PROMPT -- Write two error messages in the prompt area of the screen
+
+procedure err2_prompt (msg1, msg2)
+
+char msg1[ARB] # i: First message to write
+char msg2[ARB] # i: Second message to write
+#--
+pointer msg
+
+begin
+ call salloc (msg, SZ_LINE, TY_CHAR)
+
+ call sprintf (Memc[msg], SZ_LINE, "%s (%s)")
+ call pargstr (msg1)
+ call pargstr (msg2)
+
+ call eprintf ("\r\n")
+ call error (1, Memc[msg])
+
+end
+
+# HELP_PROMPT -- Write help message in prompt area
+
+procedure help_prompt (scr, bell)
+
+pointer scr # i: Screen descriptor
+int bell # i: Ring the bell after printing message?
+#--
+pointer sp, exit, msg
+
+string helpfmt "Type %s quit to leave editor, %s help for help."
+
+begin
+ call smark (sp)
+ call salloc (exit, SZ_FNAME, TY_CHAR)
+ call salloc (msg, SZ_LINE, TY_CHAR)
+
+ call k_eseq ("EXIT_UPDATE", Memc[exit], SZ_FNAME)
+
+ call sprintf (Memc[msg], SZ_LINE, helpfmt)
+ call pargstr (Memc[exit])
+ call pargstr (Memc[exit])
+
+ call write_prompt (scr, bell, Memc[msg])
+ call sfree (sp)
+end
+
+# READ_PROMPT -- Read a string from the prompt area of the screen
+
+procedure read_prompt (msg, str, maxch)
+
+char msg[ARB] # i: Prompt message
+char str[ARB] # o: Output string
+int maxch[ARB] # i: Maximum length of output string
+#--
+char blank
+int win
+
+data blank / ' ' /
+
+int prompt_window()
+
+begin
+ # Write message in prompt window
+
+ win = prompt_window ()
+
+ call werase (win)
+ call wmove (win, 2, 1)
+ call waddstr (win, msg)
+ call waddch (win, blank)
+
+ # Read string from prompt window
+
+ call wgetstr (win, str, maxch)
+ call werase (win)
+
+end
+
+# WARN1_PROMPT -- Write a warning message in the prompt area of the screen
+
+procedure warn1_prompt (scr, msg)
+
+pointer scr # i: Currently active screen
+char msg[ARB] # i: Message to write
+#--
+
+begin
+ call write_prompt (scr, YES, msg)
+end
+
+# WARN2_PROMPT -- Write two warning messages in the prompt area of the screen
+
+procedure warn2_prompt (scr, msg1, msg2)
+
+pointer scr # i: Currently active screen
+char msg1[ARB] # i: First message to write
+char msg2[ARB] # i: Second message to write
+#--
+pointer sp, msg
+
+begin
+ call smark (sp)
+ call salloc (msg, SZ_LINE, TY_CHAR)
+
+ call sprintf (Memc[msg], SZ_LINE, "%s (%s)")
+ call pargstr (msg1)
+ call pargstr (msg2)
+
+ call write_prompt (scr, YES, Memc[msg])
+
+ call sfree (sp)
+end
+
+# WRITE_PROMPT -- Write a message in the prompt area of the screen
+
+procedure write_prompt (scr, bell, msg)
+
+pointer scr # i: Currently active screen
+int bell # i: Ring bell after writing message?
+char msg[ARB] # i: Message to write
+#--
+int win
+
+int prompt_window()
+
+begin
+ # Write message in prompt window
+
+ win = prompt_window ()
+
+ call werase (win)
+ call wmove (win, 2, 1)
+ call waddstr (win, msg)
+
+ # Ring the bell to wake up the user
+
+ if (bell == YES)
+ call ring_bell
+
+ # Restore cursor to original screen position
+
+ if (scr != NULL)
+ call focus_window (TED_WINDOW(scr))
+
+end
diff --git a/pkg/utilities/nttools/tedit/screen.h b/pkg/utilities/nttools/tedit/screen.h
new file mode 100644
index 00000000..ec9c6fe4
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/screen.h
@@ -0,0 +1,18 @@
+# SCREEN.H -- Tedit screen descriptor
+
+define MAXSCR 10 # maximum number of screens
+
+define TED_SCRLEN 10 # screen descriptor length
+
+define TED_WINDOW Memi[$1] # window descriptor
+define TED_TABLE Memi[$1+1] # table descriptor (or NULL)
+define TED_PASTE Memi[$1+2] # paste table descriptor (or NULL)
+define TED_LOROW Memi[$1+3] # lowest row on screen
+define TED_HIROW Memi[$1+4] # highest row on screen
+define TED_LOCOL Memi[$1+5] # lowest column on screen
+define TED_HICOL Memi[$1+6] # highest column on the screen
+define TED_CURROW Memi[$1+7] # current row on the screen
+define TED_CURCOL Memi[$1+8] # current column on the screen
+define TED_SCRIDX Memi[$1+9] # current character within the field
+
+
diff --git a/pkg/utilities/nttools/tedit/screen.x b/pkg/utilities/nttools/tedit/screen.x
new file mode 100644
index 00000000..5fa3e892
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/screen.x
@@ -0,0 +1,699 @@
+include <tbset.h>
+include "display/curses.h"
+include "screen.h"
+include "table.h"
+include "field.h"
+
+define HELP_FILE "ttools$tedit/tedit.key"
+
+# SCREEN -- Procedures which manipulate screens
+
+# ADD_SCREEN -- Add a new screen
+
+procedure add_screen (scr, table, columns, rdonly, inplace)
+
+pointer scr # u: Screen descriptor
+char table[ARB] # i: SDAS table name
+char columns[ARB] # i: list of columns to edit
+bool rdonly # i: edit table read only
+bool inplace # i: edit table in place
+#--
+extern edit_field
+int iscr, jscr
+pointer oldscr, tab, win, field
+
+bool streq()
+int get_window()
+pointer map_table()
+
+begin
+ # See if the table is already bound to a screen
+
+ jscr = 0
+ for (iscr = 1; get_window (iscr, oldscr) != EOF; iscr = iscr + 1) {
+ tab = TED_TABLE(oldscr)
+ if (tab != NULL) {
+ if (streq (TED_TABNAME(tab), table)) {
+ jscr = iscr
+ break
+ }
+ }
+ }
+
+ # Get table structure from old screen, or create new structure
+
+ if (jscr != 0) {
+ TED_TABLE(scr) = TED_TABLE(oldscr)
+
+ TED_LOROW(scr) = TED_LOROW(oldscr)
+ TED_HIROW(scr) = TED_HIROW(oldscr)
+
+ TED_LOCOL(scr) = TED_LOCOL(oldscr)
+ TED_HICOL(scr) = TED_HICOL(oldscr)
+
+ TED_CURROW(scr) = TED_CURROW(oldscr)
+ TED_CURCOL(scr) = TED_CURCOL(oldscr)
+
+ } else {
+ TED_TABLE(scr) = map_table (scr, table, columns, rdonly, inplace)
+
+ TED_LOROW(scr) = 1
+ TED_HIROW(scr) = 1
+
+ TED_LOCOL(scr) = 1
+ TED_HICOL(scr) = 1
+
+ TED_CURROW(scr) = 1
+ TED_CURCOL(scr) = 1
+ }
+
+ TED_SCRIDX(scr) = 1
+ TED_PASTE(scr) = NULL
+
+ # Draw the new screen
+
+ call move_screen (scr, LEFT, YES)
+
+ # Create field structure and bind to window
+
+ call malloc (field, TED_FLDLEN, TY_STRUCT)
+
+ win = TED_WINDOW(scr)
+ call wbindstruct (win, edit_field, field)
+
+end
+
+# DEL_SCREEN -- Delete screen
+
+procedure del_screen (scr, force)
+
+pointer scr # i: Screen descriptor
+int force # i: Force table to be written
+#--
+int iscr, jscr
+pointer sp, msg, tab1, tab2, scr2, tptr
+
+bool bool_prompt()
+int get_window()
+
+begin
+ # Allocate dynamic memory for message
+
+ call smark (sp)
+ call salloc (msg, SZ_LINE, TY_CHAR)
+
+ # Close the paste table
+
+ call cls_paste (scr)
+
+ # Take no further action if no table is associated with this screen
+
+ if (TED_TABLE(scr) == NULL)
+ return
+
+ # See if this screen's table is associated with any other screen
+
+ jscr = 0
+ tab1 = TED_TABLE(scr)
+ tptr = TED_TABPTR(tab1)
+ TED_TABLE(scr) = NULL
+
+ jscr = 0
+ for (iscr = 1; get_window (iscr, scr2) != EOF; iscr = iscr + 1) {
+ tab2 = TED_TABLE(scr2)
+ if (tab2 != NULL && scr != scr2) {
+ if (tptr == TED_TABPTR(tab2)) {
+ jscr = iscr
+ break
+ }
+ }
+ }
+
+ # If not, close the table
+
+ if (jscr == 0) {
+ if (force == YES) {
+ call wrt_table (scr, tab1)
+
+ } else if (TED_DIRTY(tab1) == YES){
+ call sprintf (Memc[msg], SZ_LINE, "Write %s?")
+ call pargstr (TED_TABNAME(tab1))
+
+ if (bool_prompt (Memc[msg]))
+ call wrt_table (scr, tab1)
+ }
+
+ call unmap_table (scr, tab1, force)
+ }
+
+ call sfree (sp)
+end
+
+# DRAW_SCREEN -- Draw the screen on the terminal
+
+procedure draw_screen (scr)
+
+pointer scr # i: Screen descriptor
+#--
+char blank, uscore
+int height, width, ic, icol, irow, junk
+pointer sp, win, tab, tptr, line, temp
+
+data blank / ' ' /
+data uscore / '_' /
+
+string notable "No table associated with this screen"
+
+int gstrcpy(), itoc()
+
+begin
+ win = TED_WINDOW(scr)
+ call wdimen (win, height, width)
+
+ if (TED_TABLE(scr) == NULL)
+ call err1_prompt (notable)
+
+ tab = TED_TABLE(scr)
+ tptr = TED_TABPTR(tab)
+
+ call smark (sp)
+ call salloc (line, width+1,TY_CHAR)
+ call salloc (temp, SZ_LINE, TY_CHAR)
+
+ # Erase screen window and move cursor to start of window
+
+ call werase (win)
+ call wmove (win, 1, 1)
+
+ # Write top line of screen label
+
+ ic = gstrcpy ("Column", Memc[line], TED_LABWIDTH(tab))
+ do icol = TED_LOCOL(scr), TED_HICOL(scr) {
+ Memc[line+ic] = ' '
+ ic = ic + 1
+
+ junk = itoc (icol, Memc[temp], SZ_LINE)
+ call align_field (CENTER, blank, Memc[temp],
+ Memc[line+ic], TED_COLLEN(tab,icol))
+ ic = ic + TED_COLLEN(tab,icol)
+ }
+
+ Memc[line+ic] = '\n'
+ Memc[line+ic+1] = EOS
+ call waddstr (win, Memc[line])
+
+ # Write second line of screen label
+
+ ic = gstrcpy ("Label ", Memc[line], TED_LABWIDTH(tab))
+ do icol = TED_LOCOL(scr), TED_HICOL(scr) {
+ Memc[line+ic] = ' '
+ ic = ic + 1
+
+ call tbcigt (TED_COLPTR(tab,icol), TBL_COL_NAME,
+ Memc[temp], SZ_LINE)
+
+ call align_field (CENTER, uscore, Memc[temp],
+ Memc[line+ic], TED_COLLEN(tab,icol))
+ ic = ic + TED_COLLEN(tab,icol)
+ }
+
+ Memc[line+ic] = '\n'
+ Memc[line+ic+1] = EOS
+ call waddstr (win, Memc[line])
+
+ # Write the table elements a row at a time
+
+ do irow = TED_LOROW(scr), TED_HIROW(scr) {
+ junk = itoc (irow, Memc[temp], SZ_LINE)
+ call align_field (RIGHT, blank, Memc[temp],
+ Memc[line], TED_LABWIDTH(tab))
+
+ ic = TED_LABWIDTH(tab)
+ do icol = TED_LOCOL(scr), TED_HICOL(scr) {
+ Memc[line+ic] = ' '
+ ic = ic + 1
+
+ call tbegtt (tptr, TED_COLPTR(tab,icol), irow,
+ Memc[temp], SZ_LINE)
+
+ call align_field (LEFT, blank, Memc[temp], Memc[line+ic],
+ TED_COLLEN(tab,icol))
+ ic = ic + TED_COLLEN(tab,icol)
+ }
+
+ Memc[line+ic] = '\n'
+ Memc[line+ic+1] = EOS
+ call waddstr (win, Memc[line])
+
+ }
+
+ # Clear the prompt window
+
+ call clear_prompt (NULL)
+
+ # Move cursor to current field and refresh window
+
+ call move_field (scr)
+ call wrefresh (win)
+ call sfree (sp)
+end
+
+# EDIT_SCREEN -- Interactively edit the table bound to this screen
+
+procedure edit_screen (scr)
+
+pointer scr # i: Screen descriptor
+#--
+int win, row, col, ch
+pointer sp, field, tab, data
+
+string notable "No table associated with this screen"
+string badtype "Illegal data type for this field"
+string notadded "Cannot add row to read only table"
+
+bool check_field()
+int tbpsta(), strlen(), k_get()
+
+begin
+ # Allocate dynamic memory for table field
+
+ call smark (sp)
+ call salloc (field, SZ_FIELD, TY_CHAR)
+ Memc[field] = EOS
+
+ # Get window and table associated with screen
+
+ if (TED_TABLE(scr) == NULL)
+ call err1_prompt (notable)
+
+ win = TED_WINDOW(scr)
+ tab = TED_TABLE(scr)
+
+ # Initialize the field data structure
+
+ call wgetstruct (win, data)
+ TED_FSCREEN(data) = scr
+ TED_RDOFLD(data) = TED_READONLY(tab)
+ TED_PGSIZE(data) = TED_HIROW(scr) - TED_LOROW(scr) + 1
+ TED_LSTROW(data) = tbpsta (TED_TABPTR(tab), TBL_NROWS)
+ TED_LSTCOL(data) = TED_NCOLS(tab)
+ TED_NXTROW(data) = TED_CURROW(scr)
+ TED_NXTCOL(data) = TED_CURCOL(scr)
+ TED_DIRECT(data) = LEFT
+ TED_FINDEX(data) = 1
+ TED_MRKFLD(data) = NO
+ TED_COMMAND(data) = NO
+
+ # Edit fields until user presses the command key
+
+ while (TED_COMMAND(data) == NO) {
+
+ # Read the new field from the table
+
+ row = TED_NXTROW(data)
+ col = TED_NXTCOL(data)
+
+ call tbegtt (TED_TABPTR(tab), TED_COLPTR(tab,col), row,
+ Memc[field], SZ_FIELD)
+ call trim_field (scr, TED_READONLY(tab), TED_COLTYPE(tab,col),
+ TED_COLLEN(tab,col), Memc[field])
+
+ # Set the current row, column, and character
+
+ TED_CURROW(scr) = row
+ TED_CURCOL(scr) = col
+ if (TED_DIRECT(data) == LEFT)
+ TED_SCRIDX(scr) = 1
+ else if (TED_DIRECT(data) == RIGHT)
+ TED_SCRIDX(scr) = strlen(Memc[field]) + 1
+ else
+ TED_SCRIDX(scr) = min (TED_FINDEX(data),
+ strlen(Memc[field]) + 1)
+
+ call move_screen (scr, TED_DIRECT(data), NO)
+
+ # Get the new field value
+
+ TED_MRKFLD(data) = NO
+ TED_FINDEX(data) = TED_SCRIDX(scr)
+ call weditstr (win, Memc[field], TED_COLLEN(tab,col))
+
+ ch = k_get ()
+
+ # If the field has changed, check it and write it to the table
+
+ if (TED_MRKFLD(data) == YES) {
+
+ TED_DIRTY(tab) = YES
+ call tbeptt (TED_TABPTR(tab), TED_COLPTR(tab,col),
+ row, Memc[field])
+
+ # Redraw the field if it does not match the data type
+
+ if (! check_field (TED_COLTYPE(tab,col), Memc[field]))
+ call draw_field (scr)
+
+ }
+
+ # If the cursor has moved beyond the end of the table,
+ # add new rows
+
+ if (TED_NXTROW(data) > TED_LSTROW(data)) {
+ # Check for read only table
+ if (TED_READONLY(tab) == NO) {
+ call add_field (scr, TED_NXTROW(data), TED_NXTCOL(data))
+ TED_LSTROW(data) = TED_NXTROW(data)
+
+ } else {
+ call warn1_prompt (scr, notadded)
+
+ TED_NXTROW(data) = row
+ TED_NXTCOL(data) = col
+ TED_DIRECT(data) = LEFT
+ }
+ }
+ }
+
+ call sfree (sp)
+
+end
+
+# END_SCREEN -- Free all screens and their associated windows
+
+procedure end_screen ()
+
+#--
+
+begin
+ call endwin
+end
+
+# HELP_SCREEN -- Display the help screen
+
+procedure help_screen (win)
+
+int win # i: window that currently contains the cursor
+#--
+bool flag
+int fd, ic, helpwin, nrows, ncols, row, ihelp, key
+pointer sp, ch, eseq, label, name, msg, text
+
+int open(), getline(), newwin(), k_get()
+
+string title1 "The following commands are available after typing %s\n\n"
+string title2 "The following editing commands are available\n\n"
+string footer1 "\nPress any key to continue displaying commands\n"
+string footer2 "\nPress any key to resume editing\n"
+string hformat "%4w%-12.12s = %-12.12s"
+
+begin
+ # Allocate dynamic memory for strings
+
+ call smark (sp)
+ call salloc (eseq, SZ_FNAME, TY_CHAR)
+ call salloc (label, SZ_LINE/2, TY_CHAR)
+ call salloc (name, SZ_LINE/2, TY_CHAR)
+ call salloc (msg, SZ_LINE, TY_CHAR)
+
+ # Create help window
+
+ helpwin = newwin (GIANT, GIANT, 1, 1)
+ call wdimen (helpwin, nrows, ncols)
+
+ # Display list of commands
+
+ ifnoerr {
+ fd = open (HELP_FILE, READ_ONLY, TEXT_FILE)
+
+ } then {
+ call k_eseq ("EXIT_UPDATE", Memc[eseq], SZ_FNAME)
+ call sprintf (Memc[msg], SZ_LINE, title1)
+ call pargstr (Memc[eseq])
+
+ call waddstr (helpwin, Memc[msg])
+
+ # Read a line at a time from the file, pausing
+ # to page after a window full of information
+ # has been displayed
+
+ row = 3
+ while (getline (fd, Memc[msg]) != EOF) {
+ row = row + 1
+ if (row > nrows - 2) {
+ call waddstr (helpwin, footer1)
+
+ row = 1
+ call refresh
+ key = k_get ()
+ call werase (helpwin)
+ }
+ call waddstr (helpwin, Memc[msg])
+ }
+ call close (fd)
+
+ call waddstr (helpwin, footer1)
+ call refresh
+ key = k_get ()
+ }
+
+ # Construct the list of editing commands
+
+ call k_help (text)
+
+ call werase (helpwin)
+ call waddstr (helpwin, title2)
+
+ row = 3
+ ihelp = 0
+ flag = true
+
+ # Retrieve the command name and control sequence from the help
+ # structure. Write the information to the help window.
+
+ for (ch = text; Memc[ch] != EOS; ch = ch + 1) {
+ if (flag) {
+ if (Memc[ch] != '=') {
+ Memc[label+ic] = Memc[ch]
+ ic = ic + 1
+ } else {
+ Memc[label+ic] = EOS
+ flag = false
+ ic = 0
+ }
+ } else {
+ if (Memc[ch] != '\n') {
+ Memc[name+ic] = Memc[ch]
+ ic = ic + 1
+ } else {
+ Memc[name+ic] = EOS
+ ihelp = ihelp + 1
+ flag = true
+ ic = 0
+
+ call sprintf (Memc[msg], SZ_LINE, hformat)
+ call pargstr (Memc[label])
+ call pargstr (Memc[name])
+
+ call waddstr (helpwin, Memc[msg])
+
+ if (mod (ihelp, 2) == 0) {
+ call waddstr (helpwin, "\n")
+
+ row = row + 1
+ if (row >= nrows - 2) {
+ call waddstr (helpwin, footer1)
+
+ row = 1
+ call refresh
+ key = k_get ()
+ call werase (helpwin)
+ }
+ }
+ }
+ }
+ }
+
+ if (mod (ihelp, 2) == 1)
+ call waddstr (helpwin, "\n")
+ call waddstr (helpwin, footer2)
+
+ call refresh
+ key = k_get ()
+
+ # Delete the help window and restore cursor to current window
+
+ call delwin (helpwin)
+ call focus_window (win)
+
+ call sfree (sp)
+end
+
+# INIT_SCREEN -- Initialize the screen handling routines
+
+procedure init_screen (table, columns, rdonly, inplace, scr)
+
+char table[ARB] # i: SDAS table name
+char columns[ARB] # i: list of columns to edit
+bool rdonly # i: edit table read only
+bool inplace # i: edit table in place
+pointer scr # o: initial screen
+#--
+
+begin
+ # Initialize the window handling routines
+
+ call initscr
+
+ # Create the first (and default) screen
+
+ call init_window (scr)
+ call add_screen (scr, table, columns, rdonly, inplace)
+
+end
+
+# JOIN_SCREEN -- Remove this screen from the terminal display
+
+procedure join_screen (scr, force)
+
+pointer scr # u: Screen descriptor
+int force # i: Force screen to be written
+#--
+
+int count_window()
+
+begin
+ if (count_window () < 2)
+ return
+
+ call del_screen (scr, force)
+ call join_window (scr)
+
+end
+
+# MOVE_SCREEN -- Move the table (scroll) within the screen
+
+procedure move_screen (scr, align, force)
+
+pointer scr # i: screen descriptor
+int align # i: column alignment
+int force # i: force redraw
+#--
+int row, col, tabrows, tabcols, nrows, ncols, newrow, newcol, icol
+pointer sp, tab, errmsg
+
+string notable "No table associated with this screen"
+string badsize "Screen size error: t= %d b= %d l= %d r= %d"
+
+int tbpsta()
+
+begin
+ call smark (sp)
+ call salloc (errmsg, SZ_LINE, TY_CHAR)
+
+ if (TED_TABLE(scr) == NULL)
+ call err1_prompt (notable)
+
+ # First check whether field is currently on the screen
+
+ row = TED_CURROW(scr)
+ col = TED_CURCOL(scr)
+
+ if (row >= TED_LOROW(scr) && row <= TED_HIROW(scr) &&
+ col >= TED_LOCOL(scr) && col <= TED_HICOL(scr) && force == NO) {
+ call move_field (scr)
+ return
+ }
+
+ # Get dimensions of table and window
+
+ tab = TED_TABLE(scr)
+ tabrows = tbpsta (TED_TABPTR(tab), TBL_NROWS)
+ call wdimen (TED_WINDOW(scr), nrows, ncols)
+
+ if (row < TED_LOROW(scr) || row > TED_HIROW(scr)) {
+ newrow = max (1, row - (nrows - TED_LABHEIGHT(tab))/ 2)
+ } else {
+ newrow = TED_LOROW(scr)
+ }
+
+ if (col < TED_LOCOL(scr) || col > TED_HICOL(scr)) {
+ newcol = col
+ } else if (align == LEFT) {
+ newcol = TED_LOCOL(scr)
+ } else {
+ newcol = TED_HICOL(scr)
+ }
+
+ # Update screen descriptor
+
+ TED_LOROW(scr) = max (newrow, 1)
+ TED_HIROW(scr) = (nrows - TED_LABHEIGHT(tab)) + (newrow - 1)
+ TED_HIROW(scr) = min (TED_HIROW(scr), tabrows)
+
+ tabcols = TED_LABWIDTH(tab)
+ if (align == LEFT) {
+ TED_LOCOL(scr) = max (newcol, 1)
+ TED_HICOL(scr) = TED_NCOLS(tab)
+ do icol = newcol, TED_NCOLS(tab) {
+ tabcols = tabcols + TED_COLLEN(tab,icol) + 1
+ if (tabcols >= ncols) {
+ TED_HICOL(scr) = icol - 1
+ break
+ }
+ }
+
+ } else {
+ TED_LOCOL(scr) = 1
+ TED_HICOL(scr) = min (newcol, TED_NCOLS(tab))
+ do icol = newcol, 1, -1 {
+ tabcols = tabcols + TED_COLLEN(tab,icol) + 1
+ if (tabcols >= ncols) {
+ TED_LOCOL(scr) = icol + 1
+ break
+ }
+ }
+ }
+
+ # Sanity check for new descriptor values
+
+ if (TED_LOROW(scr) > TED_HIROW(scr) ||
+ TED_LOCOL(scr) > TED_HICOL(scr) ) {
+
+ call sprintf (Memc[errmsg], SZ_LINE, badsize)
+ call pargi (TED_LOROW(scr))
+ call pargi (TED_HIROW(scr))
+ call pargi (TED_LOCOL(scr))
+ call pargi (TED_HICOL(scr))
+
+ call err1_prompt (Memc[errmsg])
+ }
+
+ # Redraw screen
+
+ call draw_screen (scr)
+ call sfree (sp)
+end
+
+procedure split_screen (scr1, scr2, table, columns, rdonly, inplace)
+
+pointer scr1 # u: current screen
+pointer scr2 # o: new screen
+char table[ARB] # i: SDAS table name
+char columns[ARB] # i: list of columns to edit
+bool rdonly # i: edit table read only
+bool inplace # i: edit table in place
+#--
+
+begin
+ # Create new window
+
+ call split_window (scr1, scr2)
+ if (scr2 == NULL)
+ return
+
+ # Fill in the descriptor fields
+
+ call add_screen (scr2, table, columns, rdonly, inplace)
+
+end
+
diff --git a/pkg/utilities/nttools/tedit/substitute.x b/pkg/utilities/nttools/tedit/substitute.x
new file mode 100644
index 00000000..963d2786
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/substitute.x
@@ -0,0 +1,372 @@
+.help substitute
+.nf____________________________________________________________________________
+
+This procedure searches for and replaces text patterns in a string.
+The text patterns are passed to the procedure as arguments, so this
+procedure can be used to perform a variety of text processing tasks.
+The procedure has four arguments: a target pattern string (from), a
+replacement pattern string (to), the string to be modified (str), and
+a maximum length for this string (maxch). The syntax for the target
+and replacement pattern strings largely follows that used in the
+substitute command by the Unix text editors `ed' and `ex'. The pattern
+consists of a sequence of ordinary characters, which match themselves,
+and metacharacters, which match a set of characters. A metacharacter
+can be matched as if it were an ordinary character by preceding it
+with the escape character, `\'. For example, the escape character
+itself is indicated in a pattern by `\\'. The metacharacters which can
+be used in the target pattern are:
+
+ beginning of string ^ end of string $
+ white space # escape character \
+ ignore case { end ignore case }
+ begin character class [ end character class ]
+ not, in char class ^ range, in char class -
+ one character ? zero or more occurences *
+ begin tagged string \( end tagged string \)
+
+
+A set of characters is indicated in the target string by the character
+class construct. For example, punctuation could be indicated by
+`[,;.!]'. A range of characters contiguous in the underlying
+character set can be abbreviated by the range construct. For example,
+`[a-z]' matches any lower case character. The complement of a
+character set is indicated by making `^' the first character in a
+class. For example, `[^0-9]' matches any non-digit. Repetition of a
+character or character class is indicated by the following it with the
+`*' metacharacter. Thus, zero or more occurences of a lower case
+character is indicated by `[a-z]*'. The tagged string metacharacters
+have no effect on the match, they only serve to identify portions of
+the matched string for the replacement pattern. The metacharacters
+which are used in the replacement pattern are the following:
+
+ entire string & tagged string \n
+ capitalize \u upper case \U
+ lower case \L end case conversion \e \E
+
+The ditto metacharacter, `&', indicates that the entire portion of the
+string that was matched by the target pattern. The tag metacharacter
+indicates that the n-th tagged string. For example, `\1' indicates
+the first tagged string and `\2' the second. The remaining
+metacharacters affect the case of the output string. The
+capitalization metacharacter only affects the immediately following
+metacharacter, but the upper and lower case metacharacters must be
+turned off explicitly with `\e' or `\E'. The following are a few
+examples of the results that can be obtained with this subroutine:
+
+ from to action
+ ---- -- ------
+ IRAF SDAS convert all mentions
+ of IRAF to SDAS
+ [a-z][A-Za-z]* \u& capitalize all words
+ "\([^"]*\)" '\1' convert double quoted
+ strings to single
+ quoted strings
+ \([^,]*\),\(?*\) \2,\1 reverse two fields
+ separated by commas
+
+.endhelp_______________________________________________________________________
+
+include <ctype.h>
+
+define DITTO -1 # substitute matched expression
+define TAG -2 # substitute tagged part of matched expression
+define CAP -3 # capitalize next char
+define UCASE -4 # convert to upper case
+define LCASE -5 # convert to lower case
+define ENDCASE -6 # end case conversion
+
+define CH_ESCAPE '\\'
+define CH_DITTO '&'
+define CH_LTAG '('
+define CH_RTAG ')'
+define CH_INDEX '%'
+
+#* HISTORY *
+#* B.Simon 08-Dec-87 First code
+#* B.Simon 05-Jan-93 Modified for substitute command
+
+# SUBSTITUTE -- Substitute characters in second pattern for first pattern
+
+bool procedure substitute (from, to, str, maxch)
+
+char from[ARB] # i: Target pattern
+char to[ARB] # i: Replacement pattern
+char str[ARB] # u: String to be modified
+int maxch # i: Maximum length of string
+#--
+bool match
+int maxpat, ic, jc, nc
+pointer sp, pat, sub, temp
+
+int pat_amatch()
+
+begin
+ # Allocate memory for temporary strings
+
+ maxpat = maxch + SZ_LINE
+
+ call smark (sp)
+ call salloc (pat, maxpat, TY_CHAR)
+ call salloc (sub, maxpat, TY_CHAR)
+ call salloc (temp, maxch, TY_CHAR)
+
+ # Encode target and replacement patterns
+
+ call code_pat (from, Memc[pat], maxpat)
+ call code_sub (to, Memc[sub], maxpat)
+
+ # Perform an anchored match at each character of the string.
+ # If there is a match, substitute the replacement pattern for
+ # the target. Otherwise move the character to the output unchanged
+
+ ic = 1
+ jc = 1
+ match = false
+
+ while (str[ic] != EOS) {
+ nc = pat_amatch (str, ic, Memc[pat])
+ if (nc > 0) {
+ match = true
+ call make_sub (Memc[pat], Memc[sub], str, ic, ic+nc-1,
+ Memc[temp], jc, maxch)
+
+ } else {
+ nc = 1
+ if (jc <= maxch) {
+ Memc[temp+jc-1] = str[ic]
+ jc = jc + 1
+ }
+ }
+
+ ic = ic + nc
+ }
+
+ # Copy from temporary output string back to the original string
+
+ Memc[temp+jc-1] = EOS
+ call strcpy (Memc[temp], str, maxch)
+
+ # Return status indicates if there were any matches
+
+ call sfree (sp)
+ return (match)
+
+end
+
+# CODE_PAT -- Encode the target pattern
+
+procedure code_pat (from, pat, maxch)
+
+char from[ARB] # i: Target string
+char pat[ARB] # o: Encoded target pattern
+int maxch # i: Maximum length of pattern
+#--
+char ch
+int ic, jc, nc
+pointer sp, temp
+
+int patmake()
+
+begin
+ # Allocate memory for temporary string
+
+ call smark (sp)
+ call salloc (temp, maxch, TY_CHAR)
+
+ # Convert target string to a form acceptable to the IRAF pattern
+ # matcher by converting tagged strings to index characters. Also
+ # escape any index characters which might already be in the string.
+
+ ic = 1
+ jc = 1
+ while (from[ic] != EOS) {
+ if (from[ic] == CH_ESCAPE) {
+ if (from[ic+1] == CH_LTAG || from[ic+1] == CH_RTAG) {
+ ch = CH_INDEX
+ ic = ic + 1
+ } else {
+ ch = from[ic]
+ }
+
+ } else if (from[ic] == CH_INDEX) {
+ if (jc <= maxch) {
+ Memc[temp+jc-1] = CH_ESCAPE
+ jc = jc + 1
+ }
+ ch = from[ic]
+
+ } else {
+ ch = from[ic]
+ }
+
+ if (jc <= maxch) {
+ Memc[temp+jc-1] = ch
+ jc = jc + 1
+ }
+
+ ic = ic + 1
+ }
+
+ # Call the IRAF pattern encoder to encode the converted string
+
+ Memc[temp+jc-1] = EOS
+ nc = patmake (Memc[temp], pat, maxch)
+
+ call sfree (sp)
+end
+
+# CODE_SUB -- Encode the replacement pattern
+
+procedure code_sub (to, sub, maxch)
+
+char to[ARB] # i: Replacement string
+char sub[ARB] # o: Encoded replacement pattern
+int maxch # i: Maximum length of encoded pattern
+#--
+char ch
+int ic, jc
+
+int cctoc()
+
+begin
+ # Convert special characters in replacement pattern to codes
+ # Also convert escape sequences to single characters
+
+ ic = 1
+ jc = 1
+
+ while (to[ic] != EOS) {
+ if (to[ic] == CH_DITTO) {
+ ch = DITTO
+
+ } else if (to[ic] == CH_ESCAPE) {
+ switch (to[ic+1]) {
+ case 'u':
+ ch = CAP
+ ic = ic + 1
+ case 'U':
+ ch = UCASE
+ ic = ic + 1
+ case 'L':
+ ch = LCASE
+ ic = ic + 1
+ case 'e', 'E':
+ ch = ENDCASE
+ ic = ic + 1
+ default:
+ if (IS_DIGIT(to[ic+1])) {
+ if (jc <= maxch) {
+ sub[jc] = TAG
+ jc = jc + 1
+ }
+ ch = TO_INTEG(to[ic+1])
+ ic = ic + 1
+
+ } else if (cctoc (to, ic, ch) == 1) {
+ ch = to[ic]
+
+ } else {
+ ic = ic - 1
+ }
+ }
+
+ } else {
+ ch = to[ic]
+ }
+
+ if (jc <= maxch) {
+ sub[jc] = ch
+ jc = jc + 1
+ }
+
+ ic = ic + 1
+ }
+
+ sub[jc] = EOS
+
+end
+
+# COPY_SUB -- Move input characters to the output string
+
+procedure copy_sub (str1, first, last, caseflag, str2, len, maxch)
+
+char str1[ARB] # i: Input string
+int first # i: First character to be moved
+int last # i: Last character to be moved
+int caseflag # u: Case conversion flag
+char str2[ARB] # u: Output string
+int len # u: Length of output string
+int maxch # i: Maximum length of output string
+#--
+char ch
+int ic
+
+begin
+ do ic = first, last {
+ switch (caseflag) {
+ case ENDCASE:
+ ch = str1[ic]
+ case LCASE:
+ ch = str1[ic]
+ if (IS_UPPER (ch))
+ ch = TO_LOWER (ch)
+ case UCASE,CAP:
+ ch = str1[ic]
+ if (IS_LOWER (ch))
+ ch = TO_UPPER (ch)
+ default:
+ ch = str1[ic]
+ }
+
+ if (len <= maxch) {
+ str2[len] = ch
+ len = len + 1
+ }
+
+ if (caseflag == CAP)
+ caseflag = ENDCASE
+ }
+end
+
+# MAKE_SUB Substitute for the chars matched by the target pattern
+
+procedure make_sub (pat, sub, in, first, last, out, oc, maxch)
+
+char pat[ARB] # i: Target pattern
+char sub[ARB] # i: Replacement pattern
+char in[ARB] # i: Input string
+int first # i: First character matched in input string
+int last # i: Last character matched in input string
+char out[ARB] # u: Output string
+int oc # u: Last character in output string
+int maxch # i: Maximum length of output string
+#--
+int caseflag, ic, index, ltag, rtag
+
+int patindex()
+
+begin
+ caseflag = ENDCASE
+ for (ic = 1; sub[ic] != EOS; ic = ic + 1) {
+ switch (sub[ic]) {
+ case ENDCASE:
+ caseflag = ENDCASE
+ case LCASE:
+ caseflag = LCASE
+ case UCASE:
+ caseflag = UCASE
+ case CAP:
+ caseflag = CAP
+ case TAG:
+ ic = ic + 1
+ index = (sub[ic] - 1) * 2 + 1
+ ltag = patindex (pat, index)
+ rtag = patindex (pat, index+1) - 1
+ call copy_sub (in, ltag, rtag, caseflag, out, oc, maxch)
+ case DITTO:
+ call copy_sub (in, first, last, caseflag, out, oc, maxch)
+ default:
+ call copy_sub (sub, ic, ic, caseflag, out, oc, maxch)
+ }
+ }
+end
diff --git a/pkg/utilities/nttools/tedit/table.h b/pkg/utilities/nttools/tedit/table.h
new file mode 100644
index 00000000..ed6bebd5
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/table.h
@@ -0,0 +1,22 @@
+# TABLE.H -- Tedit table descriptor
+
+define TED_TABLEN 13 # table descriptor length
+
+define TED_READONLY Memi[$1] # is table read only?
+define TED_NEWTAB Memi[$1+1] # is this a new table?
+define TED_INPLACE Memi[$1+2] # edit table in place?
+define TED_ALLCOLS Memi[$1+3] # editing all columns?
+define TED_DIRTY Memi[$1+4] # has table been modified?
+define TED_TABPTR Memi[$1+5] # table pointer
+define TED_NAMEPTR Memi[$1+6] # ptr to original table name
+define TED_NCOLS Memi[$1+7] # number of columns
+define TED_LABWIDTH Memi[$1+8] # label width
+define TED_LABHEIGHT Memi[$1+9] # label height
+define TED_COLARY Memi[$1+10] # array of column pointers
+define TED_TYPARY Memi[$1+11] # array of column types
+define TED_LENARY Memi[$1+12] # array of column lengths
+
+define TED_TABNAME Memc[TED_NAMEPTR($1)] # original table name
+define TED_COLPTR Memi[TED_COLARY($1)+($2)-1] # column pointer
+define TED_COLTYPE Memi[TED_TYPARY($1)+($2)-1] # column type
+define TED_COLLEN Memi[TED_LENARY($1)+($2)-1] # column length
diff --git a/pkg/utilities/nttools/tedit/table.x b/pkg/utilities/nttools/tedit/table.x
new file mode 100644
index 00000000..9312a340
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/table.x
@@ -0,0 +1,312 @@
+include <tbset.h>
+include "screen.h"
+include "table.h"
+include "field.h"
+
+# CREATE_TABLE -- Create a new table
+
+procedure create_table (name, tptr)
+
+char name[ARB] # i: Table name
+pointer tptr # o: Table pointer
+#--
+int code, type
+pointer sp, cp, cname, cunits, ftnfmt, sppfmt, ctype, errmsg
+
+string newtable "Table does not exist. Create it?"
+string notable "Task exit. Table does not exist."
+string nocreate "Could not create table"
+string nocolumn "Could not create column"
+string colprompt "Column name? (Press return to exit)"
+
+bool bool_prompt()
+int errget()
+pointer tbtopn()
+
+begin
+ if (! bool_prompt (newtable))
+ call err1_prompt (notable)
+
+ call smark (sp)
+ call salloc (cname, SZ_COLNAME, TY_CHAR)
+ call salloc (cunits, SZ_COLUNITS, TY_CHAR)
+ call salloc (ftnfmt, SZ_COLFMT, TY_CHAR)
+ call salloc (sppfmt, SZ_COLFMT, TY_CHAR)
+ call salloc (ctype, SZ_FNAME, TY_CHAR)
+ call salloc (errmsg, SZ_LINE, TY_CHAR)
+
+ iferr {
+ tptr = tbtopn (name, NEW_FILE, NULL)
+ } then {
+ code = errget (Memc[errmsg], SZ_LINE)
+ call err2_prompt (nocreate, Memc[errmsg])
+ }
+
+ # Get parameters defining each column
+
+ repeat {
+ call read_prompt (colprompt, Memc[cname], SZ_COLNAME)
+ if (Memc[cname] == EOS)
+ break
+
+ repeat {
+ call read_prompt ("Column type? (r,d,i,b,ch*n)",
+ Memc[ctype], SZ_FNAME)
+
+ iferr (call tbbtyp (Memc[ctype], type)) {
+ call ring_bell
+ } else {
+ break
+ }
+ }
+
+ repeat {
+ call read_prompt ("Column format?", Memc[ftnfmt], SZ_COLFMT)
+ call tbbftp (Memc[ftnfmt], Memc[sppfmt])
+
+ if (Memc[sppfmt] == EOS && Memc[ftnfmt] != EOS) {
+ call ring_bell
+ } else {
+ break
+ }
+ }
+
+ call read_prompt ("Column units?", Memc[cunits], SZ_COLUNITS)
+
+ # Add new column to table
+
+ iferr {
+ call tbcdef (tptr, cp, Memc[cname], Memc[cunits],
+ Memc[sppfmt], type, 1, 1)
+ } then {
+ code = errget (Memc[errmsg], SZ_LINE)
+ call err2_prompt (nocolumn, Memc[errmsg])
+ }
+ }
+
+ iferr {
+ call tbtcre (tptr)
+ } then {
+ code = errget (Memc[errmsg], SZ_LINE)
+ call err2_prompt (nocreate, Memc[errmsg])
+ }
+
+ # Add an empty row to the table
+
+ call tbtwer (tptr, 1)
+ call sfree (sp)
+end
+
+# MAP_TABLE -- Map a table into a descriptor so that it can be edited
+
+pointer procedure map_table (scr, table, columns, rdonly, inplace)
+
+pointer scr # i: Screen descriptor
+char table[ARB] # i: SDAS table name
+char columns[ARB] # i: list of columns to edit
+bool rdonly # i: edit table read only
+bool inplace # i: edit table in place
+#--
+bool place, new
+int dirty, numcol, numrow, numptr, iptr
+int height, width, maxcol, clen
+pointer sp, tabname, filename, ext, cname, tptr, tab
+
+string notable "Table does not exist"
+string nowrite "No write access to table"
+string nocols "Column names not found in table"
+string emptytab "Table is empty"
+
+int access(), tbtacc(), tbpsta()
+int tbcigi(), strlen(), btoi()
+
+begin
+ # Allocate dynamic memory for temporary names
+
+ call smark (sp)
+ call salloc (tabname, SZ_FNAME, TY_CHAR)
+ call salloc (filename, SZ_FNAME, TY_CHAR)
+ call salloc (ext, SZ_COLNAME, TY_CHAR)
+ call salloc (cname, SZ_COLNAME, TY_CHAR)
+
+ # Get filename from table name
+
+ call tbfile (table, Memc[tabname], Memc[filename], Memc[ext], SZ_FNAME)
+
+ # Check table permissions
+
+ if (tbtacc (table) == NO) {
+ dirty = YES
+ place = true
+ new = true
+ call create_table (table, tptr)
+ call strcpy (table, Memc[filename], SZ_FNAME)
+
+ } else {
+ dirty = NO
+ place = inplace
+ new = false
+
+ if (access (Memc[filename], READ_WRITE, 0) == NO && ! rdonly)
+ call err2_prompt (nowrite, table)
+
+ call tu_open (table, "ted", rdonly, inplace,
+ tptr, Memc[filename], SZ_FNAME)
+ }
+
+ # Allocate descriptor
+
+ numcol = tbpsta (tptr, TBL_NCOLS)
+ numrow = tbpsta (tptr, TBL_NROWS)
+
+ call malloc (tab, TED_TABLEN, TY_STRUCT)
+ call malloc (TED_NAMEPTR(tab), SZ_FNAME, TY_CHAR)
+ call malloc (TED_COLARY(tab), numcol, TY_INT)
+ call malloc (TED_TYPARY(tab), numcol, TY_INT)
+ call malloc (TED_LENARY(tab), numcol, TY_INT)
+
+ # Fill in scalar fields
+
+ TED_READONLY(tab) = btoi (rdonly)
+ TED_NEWTAB(tab) = btoi (new)
+ TED_INPLACE(tab) = btoi (place)
+ TED_DIRTY(tab) = dirty
+ TED_TABPTR(tab) = tptr
+
+ # Set the width and height of the label area surrounding
+ # the table display
+
+ TED_LABWIDTH(tab) = log10 (real(numrow + 1000)) + 1.0
+ TED_LABWIDTH(tab) = max (6, TED_LABWIDTH(tab))
+ TED_LABHEIGHT(tab) = 2
+
+ call strcpy (Memc[filename], TED_TABNAME(tab), SZ_FNAME)
+
+ # Get vector fields (column pointers, types, and lengths)
+
+ call tctexp (tptr, columns, numcol, numptr, TED_COLPTR(tab,1))
+
+ TED_NCOLS(tab) = numptr
+ if (numptr == 0) {
+ call err2_prompt (nocols, columns)
+ } else if (numcol == numptr) {
+ TED_ALLCOLS(tab) = YES
+ } else {
+ TED_ALLCOLS(tab) = NO
+ }
+
+ call wdimen (TED_WINDOW(scr), height, width)
+ maxcol = width - (TED_LABWIDTH(tab) + 2)
+
+ do iptr = 1, numptr {
+ TED_COLTYPE(tab,iptr) = tbcigi (TED_COLPTR(tab,iptr),
+ TBL_COL_DATATYPE)
+
+ clen = tbcigi (TED_COLPTR(tab,iptr), TBL_COL_FMTLEN)
+ call tbcigt (TED_COLPTR(tab,iptr), TBL_COL_NAME,
+ Memc[cname], SZ_COLNAME)
+
+ TED_COLLEN(tab,iptr) = min (maxcol, max (clen,
+ strlen (Memc[cname])))
+ }
+
+ # Check to see if table is empty
+ # Write a single blank row unless table is read only
+
+ if (numrow < 1 ) {
+ if (rdonly) {
+ call err2_prompt (emptytab, table)
+ } else {
+ TED_DIRTY(tab) = YES
+ call tbtwer (tptr, 1)
+ }
+ }
+
+ # Return pointer to descriptor
+
+ call sfree (sp)
+ return (tab)
+ end
+
+# UNMAP_TABLE -- Release table descriptor
+
+procedure unmap_table (scr, tab, force)
+
+pointer scr # i: Currently active screen
+pointer tab # i: Table descriptor
+int force # i: Force unmap if table is dirty
+#--
+bool quit
+pointer sp, table
+
+begin
+ # Allocate memory for strings
+
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+
+ # Close table if still open and delete if
+ # it was a new table that was not written or not in place
+
+ if (TED_TABPTR(tab) != NULL) {
+ quit = TED_NEWTAB(tab) == YES || TED_INPLACE(tab) == NO
+ call tbtnam (TED_TABPTR(tab), Memc[table], SZ_FNAME)
+
+ call tu_close (TED_TABPTR(tab), TED_INPLACE(tab),
+ quit, Memc[table])
+ }
+
+ # Free descriptor
+
+ call mfree (TED_NAMEPTR(tab), TY_CHAR)
+ call mfree (TED_COLARY(tab), TY_INT)
+ call mfree (TED_TYPARY(tab), TY_INT)
+ call mfree (TED_LENARY(tab), TY_INT)
+
+ call mfree (tab, TY_STRUCT)
+ call sfree (sp)
+end
+
+# WRT_TABLE -- Close table and write back to original file
+
+procedure wrt_table (scr, tab)
+
+pointer scr # i: Currently active screen
+pointer tab # i: Table descriptor
+#--
+bool quit
+pointer sp, table
+
+string noname "Could not rename new table, it has this temporary name"
+
+begin
+ # Return if table already written
+
+ if (TED_TABPTR(tab) == NULL)
+ return
+
+ # Allocate memory for strings
+
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+
+ # Get current file name, then close table
+
+ quit = TED_INPLACE(tab) == NO && TED_DIRTY(tab) == NO
+ call strcpy (TED_TABNAME(tab), Memc[table], SZ_FNAME)
+
+ iferr {
+ call tu_close (TED_TABPTR(tab), TED_INPLACE(tab),
+ quit, Memc[table])
+ } then {
+ call warn2_prompt (scr, noname, Memc[table])
+ TED_INPLACE(tab) = YES
+ }
+
+ # Set table pointer to NULL and set newtab to NO, to mark it as written
+
+ TED_TABPTR(tab) = NULL
+ TED_NEWTAB(tab) = NO
+ call sfree (sp)
+end
+
diff --git a/pkg/utilities/nttools/tedit/tedit.key b/pkg/utilities/nttools/tedit/tedit.key
new file mode 100644
index 00000000..6e2f358d
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/tedit.key
@@ -0,0 +1,23 @@
+All commands may be abbreviated to any unique abbreviation
+
+add column add a new column to the table
+add row add new rows to the table
+copy copy rows to paste buffer, deleting current buffer
+copy append copy rows to paste buffer, saving current buffer
+delete delete rows, add to paste buffer, deleting current buffer
+delete append delete rows, add to paste buffer, saving current buffer
+exit leave table editor after saving changes
+find find next row which makes search expression true
+find forward (same as find)
+find backwards find previous row which makes search expression true
+goto go to row and column in table
+help display this file
+insert insert lines from paste buffer into table
+lower convert a string column to lower case
+next repeat previous find command in current direction
+next forward repeat previous find command in forward direction
+next backwards repeat previous find command in backwards direction
+quit leave table editor without saving changes
+set set a column equal to an expression
+substitute substitute one string for another
+upper convert a string column to upper case
diff --git a/pkg/utilities/nttools/tedit/tedit.x b/pkg/utilities/nttools/tedit/tedit.x
new file mode 100644
index 00000000..c3ced90f
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/tedit.x
@@ -0,0 +1,33 @@
+# TEDIT -- Table editor
+
+procedure t_tedit ()
+
+#--
+pointer table # SDAS table name
+pointer columns # list of columns to edit
+bool silent # don't ring bell when error occurs
+bool rdonly # edit table read only
+bool inplace # edit table in place
+
+pointer sp
+
+bool clgetb()
+
+begin
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+ call salloc (columns, SZ_FNAME, TY_CHAR)
+
+ call clgstr ("table", Memc[table], SZ_FNAME)
+ call clgstr ("columns", Memc[columns], SZ_FNAME)
+
+ silent = clgetb ("silent")
+ rdonly = clgetb ("rdonly")
+ inplace = clgetb ("inplace")
+ inplace = inplace || rdonly
+
+ call edit (Memc[table], Memc[columns], silent, rdonly, inplace)
+ call sfree (sp)
+
+end
+
diff --git a/pkg/utilities/nttools/tedit/tread.x b/pkg/utilities/nttools/tedit/tread.x
new file mode 100644
index 00000000..620c203a
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/tread.x
@@ -0,0 +1,31 @@
+# T_TREAD -- Read only table editor
+
+procedure t_tread ()
+
+#--
+pointer table # SDAS table name
+pointer columns # list of columns to edit
+bool silent # don't ring bell when error occurs
+
+bool rdonly,inplace
+pointer sp
+
+bool clgetb()
+
+begin
+ call smark (sp)
+ call salloc (table, SZ_FNAME, TY_CHAR)
+ call salloc (columns, SZ_FNAME, TY_CHAR)
+
+ call clgstr ("table", Memc[table], SZ_FNAME)
+ call clgstr ("columns", Memc[columns], SZ_FNAME)
+
+ silent = clgetb ("silent")
+ rdonly = true
+ inplace = true
+
+ call edit (Memc[table], Memc[columns], silent, rdonly, inplace)
+ call sfree (sp)
+
+end
+
diff --git a/pkg/utilities/nttools/tedit/window.com b/pkg/utilities/nttools/tedit/window.com
new file mode 100644
index 00000000..20ab1f11
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/window.com
@@ -0,0 +1,8 @@
+# WINDOW.COM -- Tracks windows associated with table editor
+
+int wprompt # The prompt window
+int nscreens # Number of screens currently displayed
+int scrlist[MAXSCR] # List of screens, from top to bottom
+
+common /tedwin/ wprompt, nscreens, scrlist
+
diff --git a/pkg/utilities/nttools/tedit/window.x b/pkg/utilities/nttools/tedit/window.x
new file mode 100644
index 00000000..829bb21b
--- /dev/null
+++ b/pkg/utilities/nttools/tedit/window.x
@@ -0,0 +1,246 @@
+include "display/curses.h"
+include "screen.h"
+
+define MAXSCR 10
+define MIN_HEIGHT 4
+
+# COUNT_WINDOW -- Return number of windows
+
+int procedure count_window ()
+
+#--
+include "window.com"
+
+begin
+ return (nscreens)
+end
+
+# FOCUS_WINDOW -- Move the cursor to its current position in a window
+
+procedure focus_window (win)
+
+pointer win # i: window descriptor
+#--
+int row, col
+
+int winstat()
+
+begin
+ row = winstat (win, W_CURROW)
+ col = winstat (win, W_CURCOL)
+
+ call wmove (win, row, col)
+end
+
+# GET_WINDOW -- Get a window from the list of screens
+
+int procedure get_window (iscr, scr)
+
+int iscr # i: index into list of screens
+pointer scr # o: screen descriptor
+#--
+include "window.com"
+
+begin
+ # Return EOF if this is the last screen on the list
+
+ if (iscr > nscreens) {
+ scr = scrlist[1]
+ return (EOF)
+ } else {
+ scr = scrlist[iscr]
+ return (OK)
+ }
+end
+
+# INIT_WINDOW -- Create the initial set of windows
+
+procedure init_window (scr)
+
+pointer scr # o: initial screen
+#--
+include "window.com"
+
+int nrows, ncols
+
+int newwin()
+
+begin
+ # Get size of terminal screen
+
+ call wdimen (STDSCR, nrows, ncols)
+
+ # Create the initial screen
+
+ call malloc (scr, TED_SCRLEN, TY_STRUCT)
+ TED_WINDOW(scr) = newwin (nrows-2, ncols, 1, 1)
+ TED_TABLE(scr) = NULL
+
+ # Create the prompt window
+
+ wprompt = newwin (2, ncols, nrows-1, 1)
+
+ # Initialze the global variables
+
+ nscreens = 1
+ scrlist[1] = scr
+
+end
+
+# JOIN_WINDOW -- Join screen window with the adjacent window
+
+procedure join_window (scr)
+
+pointer scr # i: screen descriptor
+#--
+include "window.com"
+
+int win1, win2
+int iscr, jscr, top, left, row1, col1, row2, col2
+pointer scr2
+
+string notnull "join_window: table was not closed"
+string notfound "join_window: could not find screen"
+
+int winstat(), newwin()
+
+begin
+ # Cannot join single screen or screen that is still open
+
+ if (nscreens == 1 || TED_TABLE(scr) != NULL)
+ call err1_prompt (notnull)
+
+ # Find the screen and its adjacent screen
+ # Pay attention to which screen is on top
+
+ jscr = 0
+ do iscr = 1, nscreens {
+ if (scrlist[iscr] == scr) {
+ jscr = iscr
+ if (jscr == 1) {
+ win1 = TED_WINDOW(scrlist[1])
+ win2 = TED_WINDOW(scrlist[2])
+ scr2 = scrlist[2]
+ } else {
+ win1 = TED_WINDOW(scrlist[jscr-1])
+ win2 = TED_WINDOW(scrlist[jscr])
+ scr2 = scrlist[jscr-1]
+ }
+ break
+ }
+ }
+
+ if (jscr == 0) {
+ call err1_prompt (notfound)
+
+ } else {
+ # Get dimensions of windows, delete them
+
+ top = winstat (win1, W_TOP)
+ left = winstat (win1, W_LEFT)
+
+ call wdimen (win1, row1, col1)
+ call delwin (win1)
+
+ call wdimen (win2, row2, col2)
+ call delwin (win2)
+
+ # Create new window, assign to adjacent screen
+
+ TED_WINDOW(scr2) = newwin (row1+row2, col2, top, left)
+
+ # Delete screen and remove from list of screens
+
+ call mfree (scr, TY_STRUCT)
+ nscreens = nscreens - 1
+
+ do iscr= jscr, nscreens
+ scrlist[iscr] = scrlist[iscr+1]
+ }
+end
+
+# PROMPT_WINDOW -- Return the prompt window
+
+int procedure prompt_window ()
+
+#--
+include "window.com"
+
+begin
+ return (wprompt)
+end
+
+# SPLIT_WINDOW -- Split window into two windows
+
+procedure split_window (scr1, scr2)
+
+pointer scr1 # u: current screen
+pointer scr2 # o: new screen (or NULL)
+#--
+include "window.com"
+
+int win1
+int iscr, jscr, top, left, row1, col1, row2, col2
+
+string noroom "Screen is too small to split"
+string notfound "split_window: could not find screen"
+
+int winstat(), newwin()
+
+begin
+ # Find screen in list of screens
+
+ jscr = 0
+ do iscr = 1, nscreens {
+ if (scr1 == scrlist[iscr]) {
+ jscr = iscr
+ break
+ }
+ }
+
+ if (jscr == 0) {
+ call err1_prompt (notfound)
+
+ } else {
+ # Get dimensions of current window
+
+ win1 = TED_WINDOW(scr1)
+
+ top = winstat (win1, W_TOP)
+ left = winstat (win1, W_LEFT)
+
+ call wdimen (win1, row1, col1)
+
+ row2 = row1 / 2
+ col2 = col1
+ row1 = row1 - row2
+
+ # Don't split window if it is too small
+
+ if (row2 <= MIN_HEIGHT) {
+ call warn1_prompt (scr1, noroom)
+ scr2 = NULL
+
+ } else {
+ # Delete current window and create new half-size window
+
+ call delwin (win1)
+ TED_WINDOW(scr1) = newwin (row1, col1, top, left)
+
+ # Create new screen and its window
+
+ call malloc (scr2, TED_SCRLEN, TY_STRUCT)
+ TED_WINDOW(scr2) = newwin (row2, col2, top+row1, left)
+ TED_TABLE(scr2) = NULL
+
+ # Add to list of screens
+
+ do iscr = jscr+1, nscreens
+ scrlist[iscr+1] = scrlist[iscr]
+
+ scrlist[jscr+1] = scr2
+ nscreens = nscreens + 1
+ }
+ }
+
+end