diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/utilities/nttools/tedit | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'pkg/utilities/nttools/tedit')
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 |