Browse Source

Initial commit of merged but untouched source from

Tom Almy on 2015-05-29
Blake McBride 7 years ago
  1. 7
  2. 1
  3. 1
  4. 1
  5. 1
  6. 1
  7. 1
  8. 1
  9. 1
  10. 1
  11. 1
  12. 4
  13. 1
  14. 1
  15. 469
  16. 118
  17. 856
  18. 44
  19. 171
  20. 134
  21. 121
  22. 61
  23. 142
  24. 80
  25. 11104
  26. 212
  27. 1
  28. 237
  29. 36
  30. 8
  31. 96
  32. 8
  33. 44
  34. 3
  35. 32
  36. 3
  37. 6
  38. 16
  39. 80
  40. 1773
  41. 9
  42. 6
  43. 92
  44. 73
  45. 102
  46. 129
  47. 120
  48. 544
  49. 6
  50. 187
  51. 3
  52. 469
  53. 333
  54. 338
  55. 243
  56. 816
  57. 22
  58. 50
  59. 72
  60. 808
  61. 279
  62. 37
  63. 93
  64. 89
  65. 54
  66. 88
  67. 38
  68. 24
  69. 51
  70. 273
  71. 113
  72. 17
  73. 15
  74. 21
  75. 86
  76. 23
  77. 19
  78. 22
  79. 25
  80. 38
  81. 113
  82. 25
  83. 19
  84. 16
  85. 30
  86. 25
  87. 13
  88. 17
  89. 16
  90. 23
  91. 24
  92. 33
  93. 15
  94. 40
  95. 136
  96. 29
  97. 29
  98. 13
  99. 23
  100. 25
  101. Some files were not shown because too many files have changed in this diff Show More

.gitignore vendored

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@


@ -0,0 +1 @@ @@ -0,0 +1 @@


@ -0,0 +1 @@ @@ -0,0 +1 @@


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc teco/inspect %$


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc teco/inspect %$


@ -0,0 +1 @@ @@ -0,0 +1 @@


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc mung %$


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc mung %$


@ -0,0 +1 @@ @@ -0,0 +1 @@


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc teco %$


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc teco %$


@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
alias teco tecoc teco/norename
alias inspect tecoc/inspect
alias mung tecoc mung
alias tmake tecoc make


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc make %$


@ -0,0 +1 @@ @@ -0,0 +1 @@
tecoc make %$


@ -0,0 +1,469 @@ @@ -0,0 +1,469 @@
This directory contains TECO-C, a version of TECO written in C.
It was written in C so the author could move comfortably from VAX/VMS
to various other machines, including MicroVaxes, which couldn't execute
TECO-11 prior to VMS 5.0 because they don't support PDP-11 compatibility
mode. TECO32, distributed with v5.0, solved this problem.
TECO-C is meant to be a complete implementation of TECO as defined
by the Standard TECO User's Guide, which is in file TECO.DOC. There is no
manual for TECO-C itself, but the Standard TECO manual was the specification
for TECO-C, so it serves as an excellent manual. TECO-C departs from the
Standard manual in only a few places (like no video mode), listed in file
PROBLEMS.TXT. There is quick-and-dirty "wall chart" of all TECO commands
in file WCHART.TXT.
This version of TECO-C runs under VMX/VMS, MS-DOS, AmigaDOS and Unix
(SunOS, Ultrix and System V on a Data General Aviion). If you find bugs or
have any comments about TECO-C, please contact
Pete Siemsen Pete Siemsen
645 Ohio Avenue #302 University of Southern California
Long Beach, Ca. 90814 1020 West Jefferson Blvd.
Los Angeles, CA 90089-0251
(213) 433-3059 (home) (213) 740-7391 (work)
The following sections describe how to use or build TECO-C for
different environments. The command line syntax is the same as the syntax
for TECO-11 command lines.
U N D E R V A X / V M S
TECO-C was mostly developed under VAX/VMS. It compiles and links
using VAX C 3.1 under VMS version 5.3.
To set up: inspect and modify ZVLOGIN.COM and then add it to your
To compile: inspect/edit ZVBLD.COM, then SUBMIT it
To link: use the "LT" command (defined in ZVLOGIN.COM)
To run: inspect/edit the symbol definitions in ZVLOGIN.COM
Note: TECO-C uses the same command line syntax as TECO32
U N D E R M S - D O S
TECO-C compiles/links under Turbo C v2.00 under MS-DOS 4.01 and
Concurrent DOS 386 v3.0.
To build: run MAKE on MAKEFILE.TC. to build TECO from scratch say:
"make -DALL". see MAKEFILE.TC for other make
-D options. also see MAKETECO.BAT.
To run: use TECO.BAT to edit a file or MUNG.BAT to run a macro,
for example: TECO filename.
To compile and link: use the make utility on "makefile.sun" (for SunOS) or
"makefile.ulx" (for Ultrix) or "makefile.dg" (for System V Unix
on a Data General Aviion).
To run: define aliases and environment variables in your .cshrc file.
Here's an example, assuming my initialization file is named
.tecorc and it's in my home directory, and my macros are in a
directory named tecoc under my main directory. You'll have to
change the directory names, of course.
setenv TEC_INIT \$/home/sol/siemsen/.tecorc
setenv TEC_LIBRARY /home/sol/siemsen/tecoc/
alias te '/home/sol/siemsen/tecoc/tecoc teco -nocreate'
alias mung '/home/sol/siemsen/tecoc/tecoc mung'
alias tma '/home/sol/siemsen/tecoc/tecoc make'
After doing this, "te" runs tecoc.
Unix Command line
---- ------- ----
To make Unix users more comfortable, TECO-C uses Unix-like options syntax
instead of the familiar "/" style used under VAX/VMS. The options can be
abbreviated. They are (optional characters in square brackets):
do nnn,7:W and 1,3:W
Don't separate input into pages. Instead, treat form feeds as
normal characters.
where nnn is any number of digits. Go to line number nnn and set
nopage. Note this uses the UNIX end of line convention for use with
cc output &c. The non-unix line termination will still be used for
nL and other intrinsic TECO commands, this just controls the
starting line AT INVOCATION.
EZ Mode Control Flag
-- ---- ------- ----
To add functionality, TECO-C is sensitive to bits in an extra mode control
flag in addition to the standard ones. Bits in the EZ mode control flag are
used in different ways by different operating systems. Under Unix, bits in
the flag have the following meanings:
1 Mark Henderson, who did much of the Unix port, likes the way
VAX/VMS keeps versions of files. VMS appends a semicolon followed
by a version number to files, and has the PURGE command to clean
out old versions of files. If this bit is off, TECO-C will handle
file version numbers, appending the appropriate version number to
file names. Mark supplied a "purge" program (distributed with TECO-C)
for users of this feature. Setting this flag turns off the feature,
to make TECO-C function as expected by the average Unix user. This
flag is set by default.
8 I don't know what this flag does. It only makes sense when TECO-C
is compiled with CURSES support.
16 If set, when it's time to beep, use an audio beep, and if it fails,
then try a video flash. If clear, try a video flash, and if it
fails, use an audio beep. This bit works only if TECO-C was compiled
with CURSES support. This bit is off by default.
32 If set, and split screen scrolling mode is on (see the 7:W command),
TECO-C puts a line between the upper and lower scrolling regions.
If off, don't display a line. This bit works only if TECO-C was
compiled with CURSES support. This bit is off by default.
128 If set, don't stop on form feeds when reading. If clear, a form
fed in the input stream stops the read (the standard TECO style).
This bit is off by default.
256 If set, use Unix-style newline terminators. This means when files
are read in, carriage-returns are not added to the end of lines,
and when the user types the RETURN key, only a newline is entered
into the command line (usually a carriage-return/line-feed pair is
entered). Old macros (and old TECO users) may get confused if this
bit is set, but it's required if CURSES support is compiled into
2048 If set, use a bottom-tee symbol instead of a diamond to indicate
the end-of-buffer. This bit works only if TECO-C was compiled with
CURSES support. This bit is off by default.
8192 If set, don't show CR in SCROLL mode (like standard TECO). If clear,
show CR (a graphics character indicating a carriage return) when in
SCROLL mode. This bit works only if TECO-C was compiled with CURSES
support. This bit is on by default.
Filename Memory
-------- ------
TECO tries to remember the last file edited by TECO, so that after you've
edited a file once, you can re-edit without having to type the file name
on the command line. TECO-C implements this under Unix by writing and reading
files named /tmp/tecoxxx.tmp, where "xxx" is the process id of the parent
NOTE: There is another TECO in C, written by Matt Fichtenbaum, which
runs under Unix. It is part of the DECUS TECO Collection. Contact Pete
Siemsen at the above address for a copy.
To compile and link: see makefile.ami, (note: it needs tecoc.lnk)
Comments from the author of the Amiga code:
I've completed my TECOC port to the Amiga. It has been tested on an
Amiga 1000 under AmigaDOS 1.3.2. My system configuration is:
68000 microprocessor
2.5 megs memory
80 meg hard drive
Old Amiga chip set
SAS Institute C for the Amiga version 5.10
TECO-C runs in the CLI window it was started from, and it should run
over a terminal hooked to an Amiga serial port as well.
Adding 'W' command stuff would probably best be done by one of the
termcap ports to the Amiga, however, TECO would have to handle
SIGWINCH-like events, unless it is modified to open it's own window of
a particular size without a resizing gadget. It wouldn't be to hard to
write a terminal driver for Amiga windows using hard-coded escape
sequences either, but then that would lose over a serial port.
The EZ flag is system-dependent. Under AmigaDOS, bits in the flag have the
following meanings:
128 If set, don't stop on form feeds when reading. If clear, a form
fed in the input stream stops the read (the standard TECO style).
This bit os off by default.
256 If set, use Unix-style newline terminators. This means when files
are read in, carriage-returns are not added to the end of lines,
and when the user types the RETURN key, only a newline is entered
into the command line (usually a carriage-return/line-feed pair is
entered). Old macros (and old TECO users) may get confused if this
bit is set, but it's required if CURSES support is compiled into
aareadme.txt this readme file
baksrc.c backwards search
bldstr.c build a string with string build constructs
change.tec change macro squished
change.tes change macro source. this macro allows you to
replace one string with another in a group of
files using match constructs.
changes.txt contains teco-c release notes starting from
version 1.00 (TVERSION = 100)
chmacs.h ctype.h for teco-c
clenup.c clean up before exiting teco-c
clpars.h command line parsing macro, created by genclp.c
clpars.tec command line parsing macro squished
clpars.tes command line parsing macro source
cmatch.c match character with match construct
date.tec date macro squished
date.tes date macro source. this macro displays the
date and time.
dchars.h define identifiers for control characters
deferr.h define identifiers for error messages
defext.h EXTERN decarations for global variables
detab.tec de-tabify macro squished
detab.tes de-tabify macro source. this macro converts
tabs to spaces
dir.tec "display directory" macro, in squished form
dir.tes "display directory" macro source. This macro simply
displays the directory. a wildcarded filename
in the edit buffer can control what is displayed.
docjr.c code common to ExeC, ExeJ, and ExeR
doeves.c work code for EV and ES
doflag.c changes a mode control flag (ED,EH,ES,ET,EU,EV,^X)
dscren.h terminal types for 0:W command
echoit.c display character in its printable form
err.c display teco-c's error messages
exea.c execute A
exeats.c execute at-sign @
exeb.c execute B
exebar.c execute |
exebsl.c execute backslash \
exec.c execute C
execcc.c execute control-caret ^^
execln.c execute colon modifiers : and ::
execom.c execute comma ,
execrt.c execute caret ^
execst.c execute a TECO command string
execta.c execute ^A
exectc.c execute ^C
exectd.c execute ^D
execte.c execute ^E
execti.c execute ^I
exectl.c execute ^L
exectn.c execute ^N
execto.c execute ^O
exectp.c execute ^P
exectq.c execute ^Q
exectr.c execute ^R
exects.c execute ^S
exectt.c execute ^T
exectu.c execute ^U
exectv.c execute ^V
exectw.c execute ^W
exectx.c execute ^X
execty.c execute ^Y
exectz.c execute ^Z
exed.c execute D
exedgt.c execute digit (0-9)
exedot.c execute dot .
exedqu.c execute double quote "
exee.c execute E
exeequ.c execute equals =, ==, and ===
exeesc.c execute escape
exeexc.c execute exclamation point !
exeey.c execute EY
exef.c execute F
exefb.c execute FB
exeg.c execute G
exegtr.c execute greater than sign >
exeh.c execute H
exei.c execute I
exeill.c "execute" illegal command
exej.c execute J
exek.c execute K
exel.c execute L
exelbr.c execute left-bracket [
exelst.c execute less than sign <
exem.c execute M
exen.c execute N
exenul.c execute null ^@
exenyi.c "execute" not-yet-implemented command
exeo.c execute O
exeopr.c execute operator (+,-,(,#,/,&,^_,*)
exep.c execute P (see singlp.c)
exeprc.c execute percent sign %
exepw.c execute PW
exeq.c execute Q
exeqes.c execute question mark ?
exer.c execute R
exerbr.c execute right bracket ]
exertp.c execute right paren )
exes.c execute S
exescl.c execute semicolon ;
exet.c execute T
exeu.c execute U
exeund.c execute underscore _
exeusc.c execute unit separator character ^_
exev.c execute V
exew.c execute W
exex.c execute X
exey.c execute Y
exez.c execute Z
findes.c find end of string
findqr.c find q-register name
flowec.c flow to end of conditional
flowee.c flow to else part of conditional
flowel.c flow to end of loop
fmtmac.tec PDP-11 .MAC formatter squished
fmtmac.tes PDP-11 .MAC formatter source. this macro does
case formatting for PDP-11 macro (.MAC) source files
format.tec FORTRAN formatter squished
format.tes FORTRAN formatter source. formats the first part of
a FORTRAN source line.
genclp.c generates the command line parsing macro in clpars.h
getara.c get area in edit buffer an "m,n" argument defines
getnma.c get numeric argument off expression stack
inccbp.c increments command buffer pointer
init.c teco-c initializatin routines
insstr.c insert string into edit buffer
isradx.c is digit within current radix?
ln2chr.c convert line-number to character-number (^Q)
lowcase.tec convert edit buffer to lowercase macro, see upcase.tec
makdbf.c make digit buffer, binary to ascii in current radix
makefile.ami AmigaDOS make file
makefile.cct CodeCenter under SunOS
makefile.dg System V Unix make file (works on Data General Aviion)
makefile.sun SunOS make file Turbo C make file (MS-DOS)
makefile.ulx Ultrix make file
maketeco.bat MS-DOS batch file to make teco. this is probably how
the temdos.exe executable file was made.
makprnt.tec make printable macro squished
makprnt.tes make printable macro squished. this macro makes a
string with embedded control characters printable
makrom.c make room in Q-register for new text
mung.bat MS-DOS batch to execute a teco macro from command line
pg.mem a programmer's guide. it may be useful to anyone
fixing bugs, adding features, or porting teco-c to
a new environment.
pkzip.rsp a PKZIP response file used to build TECOC.ZIP archive
popmac.c pop macro environment off macro stack
problems.txt contains notes about bugs and ideas
pshmac.c push current macro environment on macro stack
pushex.c push expression onto stack, try to reduce it
rdline.c read a line
rdpage.c read a page
readcs.c read command string
replac.c code for search and replace commands
search.c code for most of the search comamnds
search.tec search macro squished
search.tes search macro source. this macro finds a string in
a group of files using teco match constructs
singlp.c does a single P command
skpcmd.c skip over current command in command bufer
squ.bat MS-DOS batch file to run squ.tec w/standard options
squ.tec squish macro squished
squ.tes squish macro source. this macro takes a teco macro
source file and makes it as small and as fast (and
as unreadable) as possible
srclop.c search loop, handles loop arguments for search
sserch.c do a simple search
sub.tec ?
tabort.c terminate teco-c
tctlib.rsp a Turbo C TLIB response file used by
teco.bat MS-DOS batch file to run teco-c
teco.doc Standard TECO documentation from DECUS
teco.tes teco initialization file
tecoc.c the main source module, contains all the definitions
of system-independent global variables, as well as
comments explaining what they are.
tecoc.exe the teco-c executable for VMS
tecoc.h defines structures, general identifiers, and
the in-line debugging scheme.
tecoc.lnk link file needed under AmigaDOS (see makefile.ami)
tecoin.tes teco initialization file
temsdos.exe the teco-c executable for MS-DOS
tst.bat MS-DOS batch file to run the test macros VMS command procedure to run the test macros
tstbsl.tec --
tstcss.tec |
tstequ.tec | these macros contain code which tests some
tsto.tec | aspects of teco-c
tstpw.tec |
tstqr.tec |
tstsrc.tec --
typbuf.c types a buffer on the screen, converting unprintable
characters to printable as nescessary.
type.tec type a file macro squished
type.tes type a file macro source. this macro apparently
types a file on the console with all kinds of
wonderful options.
typest.c types the erroneous command string for errors
uminus.c unary minus (converts -C to -1C)
unsqu.tec unsquish macro squished
unsqu.tes unsquish macro source. this macro does some simple
formatting of a squished teco macro to make it more
readable (like indenting)
upcase.tec convert edit buffer to uppercase macro, see lowcase.tec
vrbmsg.h verbose forms of teco error messages
vtedit.tec vtedit macro squished
vtedit.tes vtedit macro source. humongous screen editor macro.
note: this macro does NOT run under teco-c.
wchart.txt contains a wall chart of TECO commands
wrpage.c write a page
zamiga.c AmigaDOS system dependent code.
zfirst.c dummy module used if CHECKSUM_CODE is TRUE in zport.h
zfrsrc.c do a forward search using VAX SCANC instruction
zmsdos.c MS-DOS system dependant code
zport.h portability header file.
zunix.c SunOS (Unix) system dependant code
zunkn.c UNKNOWN system dependant code (function stubs)
zvms.c VAX/VMS system dependant code
The W command does not work, but the EXEW.C file contains code
to tell you what the command would have done if it had been executed. I used
this to play with executing VTEDIT.TEC under TECOC in order to find bugs.
I maintain the DECUS TECO Collection, a bunch of stuff relating to
TECO. It includes sources for DEC's TECO-11 v39, three TECOs written in C,
including ones for VAX/VMS, MS-DOS, SunOS (Unix) and Ultrix, the current
Standard TECO manual, two EMACs-like macro packages and LOTS of macros.
I you have something that you feel should be included in this
collection, or if you would like to improve the software, please contact
me at the above address.
Pete Siemsen


@ -0,0 +1,118 @@ @@ -0,0 +1,118 @@
Cast is needed to get it to compile under Borland C.
If no EGMEM or if EGMEM and filename starts with a $, then CLPARS
gets totally hosed. Major hacking was needed to fix.
Backup file is created for EW and other occasions. It should only be
created with the EB command (or TECOC TECO on the command line).
Added BOOLEAN Backup argument to ZMSDOS:ZOpOut. Only make backup if
Backup==TRUE. Argument is passed through in EXEE:OpnOut. In
EXEE:ExeEB, value passed is TRUE. In EXEE:ExeEW and EXEE:ExeEPr the
value passed is False. When file is closed in ZMSDOS:ZOClos then if
no backup was wanted we won't create one.
Colon modified macros pass the colon into the internal command. This
prevented the tstqr.tec test file from working.
The fix is to clear the colon flag if it is set within ExeM().
Execution of local macros caused new set of local q registers to be
The fix is to not generate new macro set if macro is local.
n,mFB command did not work unless at gap. Fixed.
ES now ignored if in macro or loop
Changed FB and FC as "implemented" Also G* and G_ as implemented.
Added test for ED_FF flag (in EZ??) to ignore form feeds. Then change
clpars.tes so /NOPAGE will set it *before* yanking.
ZDoCmd used the file name buffer for the command, while ExeEG keeps the
command in a local buffer. This prevents EG from working in any version!
I added arguments to ZDoCmd to pass the command string.
The TEC$LIBRARY environment variable was not being examined for the EI
command, unlike at least the UNIX version. This basically made TEC$LIBARY
worthless since its only other use was during initializaton for video
support, which doesn't exist in MSDOS. So I fixed it.
Tecoc has the ugly habit of allowing you to edit a readonly file,
only to die on you when you finish. It's easy enough to check that
the output file is writable first. The problem is in ZOpOut().
Because MSDOS TECOC creates the temp file in the current directory,
any attempt to EW or EB a file in another drive will cause failure
when the rename is attempted. In these cases the file must be copied.
ZOClos() is the culprit.
I added a "fastcopy" function, much like what was done in zunix.c,
but quite a bit simpler. The OS/2 version will need this since OS/2
prefers copying over renaming to preserve file extended attributes
and PM references. The handling in the OS/2 code is slightly
different in that the only file that ever gets deleted is the
temporary file. When this code is included in the MSDOS version, it
takes too much space for compact model, so I don't update the time stamp
(that allows it to squeek by).
Along the same lines, Tecoc will create a backup file in the wrong
directory if the file name has an explicit path and has a "." in one
of the directory names. ZOClos() is the culprit, again.
I added the "% Superseding existing file" warning message. Why wasn't
it there??
After the attempt to do an EB fails, clpars assumed the failure was
caused by the input file not being found. Added new code to attempt
to open the file via ER - if that succeeds, prints message that file
is being opened read-only.
Added handling for a /NORENAME switch, needed by OS/2. I also added
code to remove quotes in a quoted file name string if OS/2. Reason:
file names can have embedded spaces, yet quotes are not allowed.
I couldn't see any reason to strip spaces from the filename saved
in "memory" since the name had already been processed. This was causing
a problem with the OS/2 version since I stripped the quotes.
I removed the restriction of the +nnn commandline argument so it
would work with MS/DOS and OS/2. Why limit it to UNIX?
Clpars leaves the macro .T around after completion (remember -- it's
not called as a macro if USE_ANSI_CLPARS, which makes it a top level
local macro), and also leaves non-zero values in qy, q8, q.l, q4, and
possibly q.1. Fixed. However I don't understand the reasoning for
*saving* q registers during execution of clpars since there is
nothing in them at the start of the macro execution.


@ -0,0 +1,856 @@ @@ -0,0 +1,856 @@
Programmer's Guide
(last updated February 18, 1991 to reflect TECO-C version 140)
These notes apply to TECOC version 135, which runs under VAX/VMS,
MS-DOS, and Unix (SunOS, which is BSD). See file AAREADME.TXT for the
specifics of operating system and compilers which have been used.
TECO-C is meant to be a complete implementation of TECO as defined by
the Standard TECO User's Guide and Language Reference Manual, (in file
TECO.DOC). It was written so that the author could move to many machines
without knowing many editors.
Conditional compilation directives are used to build TECO-C correctly
for different environments. Identifiers automatically defined by
the different compilers are used. Some identifiers defined in file ZPORT.H
control whether video support or extra debugging code is included. See
"VIDEO" and "DEBUGGING". Files are provided which "build" TECO-C in various
environments. See file AAREADME.TXT for details.
When you run TECO, the command line used to invoke TECO is parsed for
an input/output file name and several optional switches. TECO-11 parses the
command line using a TECO macro imbedded in the program. TECO-C does the
same thing. Actually, the imbedded macro used to parse the command line
was stolen from TECO-11. I commented it and then modified it to repair
minor inconsistencies. Use of TECO-11's macro makes TECO-C invocation
identical to TECO-11's, even responding to "make love" with "Not war?".
The macro is in file CLPARS.TES. The compressed version (no comments
or whitespace) is in file CLPARS.TEC. The GENCLP program converts
CLPARS.TEC into CLPARS.H, an include file suitable for compiling into
The code is not modular. Communication between almost all functions
is through global variables, not argument lists. There is a reason: the
nature of the basic parsing algorithm is to use the characters in the
command string as indices into a table of functions. This makes for very
fast command parsing, but it means that all the functions have to modify
Page 2
global values, because no arguments are passed in. In other words, there
were going to be 130 or so un-modular functions anyway, so I gave up on
modularity. This explanation does not explain some of the complications in
the search code, like the global variable SrcTyp. Oh, well.
Here's a brief list of some of the conventions followed by the code:
1. TECO-C is portable, so some convention was needed to separate
portable code from system-dependent code. There is one file
containing the system-dependent code for each platform TECO-C
supports. These files have names that start with a "Z": ZVMS.C,
All the system-dependent functions in those files start with a
"Z". For example, the function that allocates memory is called
ZAlloc. A VMS version of ZAlloc can be found in ZVMS.C, and an
MS-DOS version can be found in ZMSDOS.C.
An extra file called ZUNKN.C exists to help efforts to port TECO-C
to a new environment. This file contains stubs for all the
system-dependent functions.
2. All system-independent global variables are declared
alphabetically in file TECOC.C. They are defined in DEFEXT.H,
which is included by all modules.
3. File TECOC.H contains the "global" definitions, including those
for most structures.
4. Variables and functions are defined using the portability
identifiers defined in the ZPORT.H file. Functions which do not
return a value are defined as VOID. TECO-C should compile and
link on different machines by changing only the environment
definitions in the ZPORT.H file.
5. At one time, every function was in a file with the same name
as the function. This made it easy to find the code for a
function. The problem was that some groups of functions use data
not needed by the other functions. This was especially true of
the system-dependent functions. Also, some functions were called
only by one other function, so it made sense for them to be in the
same module as the caller and be made "static". So now, most
functions are in a file named the same as the function, with the
following exceptions:
1. All the "Z" functions are in are in the "Z" file for the given
2. The conditionally-compiled functions (ZCpyBl in ZINIT.C, the
"Dbg" functions at the bottom of TECOC.C, the "v" functions in
EXEW.C) aren't in their own files. If they were, then the
command procedures/makefiles that compile the files would need
to contain logic to conditionally compile the files.
Page 3
3. The functions for the "E" and "F" commands are in EXEE.C and
EXEF.C, respectively. So if you want to find function ExeEX,
don't look for a file named EXEEX.C.
6. Symbols are 6 characters long or less. The way I remember it,
this was caused by the first system I wrote TECOC for: CP/M-68k,
which had a limit of 8 characters for file names. The last two
characters had to be ".C", so 6 characters were left for the file
name. Since the file name was the same as the function it
contained, functions were limited to 6 characters in length. When
I saw how nicely the function declarations looked (they fit in one
tab slot), I used 6 characters for other symbols too.
I've since been told that CP/M-68k has 8-character file names
followed by 3-character file types, so CP/M-68k can't be blamed.
So shoot me.
This standard has prevented problems from occurring with compilers
that don't support very many characters of uniqueness.
In order to make up for the resultant cryptic names, upper and
lower case are mixed. An uppercase letter indicates a new word.
For example, "EBfEnd" stands for "Edit Buffer End". If you need
to know what a variable name means, look at the definition of the
variable in DEFEXT.H. The expanded version of the abbreviated
name appears in the comment on the same line as the variable
definition. A detailed description can be found with the
declaration of the variable in TECOC.C.
The limit of 6 letters in variable names is relaxed in
system-dependent code.
7. Variable and function names follow patterns where possible. For
instance, "EBfBeg" and "EBfEnd" are the beginning and end of the
edit buffer. If you see a variable named "BBfBeg", you can assume
that it is the beginning of some other buffer, and that a "BBfEnd"
exists which is the end of that buffer.
8. Character strings are usually represented in C by a pointer to a
sequences of bytes terminated with a null character. I didn't do
that in TECO-C because I thought it was too inefficient. To get
the length of a string, you have to count characters. Most
strings in TECO-C are therefore represented by two pointers, on to
the first character and one to the character following the last
character. With this representation, it's easy to add characters
to a string and trivial to get the length.
9. Each file has a consistent format, which is:
1. a comment describing the function
2. include directives
3. the function declaration
Page 4
4. local variable definitions, in alphabetical order
5. code
The top level code for TECO-C is contained in file TECOC.C. It is
very simple: after initializing, a loop is entered which reads a command
string from the user, executes it, and loops back to read another command
string. If the user executes a command which causes TECO-C to exit, the
program is exited directly via a call to the TAbort function. TECO-C never
exits by "falling out the bottom" of the main function.
After a command string is read, the ExeCSt function is called to
execute the command string. ExeCSt contains the top-level parsing code.
The parse is trivial: each command character is used as an index into a
table of functions. The table contains one entry for each of the 128
possible characters. Each function is responsible for "consuming" its
command so that when it returns, the command string pointer points to the
next command.
5.1 Error Handling
When an error is detected, an error message is displayed at the point
that the error is detected, and the function in which the error was
detected returns a FAILURE status to its caller. Almost always, the caller
returns a FAILURE status to it's caller, which returns a FAILURE status to
it's caller, etc. When a FAILURE status is returned to the main command
string parser, parsing of the command string stops and the user is prompted
for a new command string.
This style tends to cause all function calls to follow the same form,
which is
if (function() == FAILURE)
Things get more complicated in the system-dependent code (in the files
with names that start with a "Z"). I extended TECO's error reporting
slightly to allow the user to see the operating system's reason for an
error, as this is often useful. For example, under VAX/VMS there are many
reasons why an attempt to create an output file might fail. They include:
errors in file name syntax, destination directory non-existence, file
protection violations or disk quota violation. In order to supply enough
information to the user, TECO-C outputs multiple-line error messages when a
system error occurs.
Multiple-line error messages contain one line that describes the
operating system's perception of the error and one line that describe's
TECO's perception of the error. For instance, if a user of VAX/VMS does a
"EW[abc]test.txt$$" command when the directory [abc] does not exist, the
Page 5
error message generated by TECO-C is:
?SYS %RMS-F-DNF, directory not found
?UFO unable to open file "[abc]test.txt" for output
System errors are therefore reported in a system-dependent fashion,
using whatever messages the operating system can supply. Under VAX/VMS,
the system service $GETMSG provides human-readable messages that TECO-C can
use in the "SYS" part of the error message. Under UNIX, syserrlist[error]
is a pointer to these messages.
There is another way in which error reporting in the system-dependent
code is tricky. Under VAX/VMS, some system calls may return a code that is
"successful" but contains extra information. For instance, when a user has
set his directories so that only a limited number of versions of a file can
exist, RMS will automatically purge the oldest version of the file when the
user creates a file. This only happens if the newly created file would
cause too many versions of the file to exist. When this happens, the VMS
service returns a FILEPURGED status, which is successful. TECO-C informs
the user about these things by displaying the message in brackets.
5.2 Command Modifiers (CmdMod)
Command parsing is complicated by command modifiers and numeric
arguments, which may precede some commands. These are implemented in a way
that maintains the basic "jump table" idea. For instance, when an at-sign
(@) modifier is encountered in a command string, the at-sign command
function (ExeAtS) is called. The only thing ExeAtS does is set a flag
indicating that an at-sign has been encountered. Commands which are
affected by an at-sign modifier check this flag and behave accordingly.
The flags which indicate command modifiers are contained in global
variable CmdMod. A bit in CmdMod is reserved for each command modifier.
The modifiers are "@", ":" and "::". Of course, once the flag has been
set, it must be cleared. With this parsing algorithm, the only way to do
that is to make every command function explicitly reset CmdMod before a
successful return. This is not too bad: clearing all the flags in CmdMod
is done with one statement: "CmdMod = '\0';".
For numeric arguments to commands, an expression stack is used (see
Stacks). The EstTop variable is the pointer to the top of the expression
stack. Commands which handle numeric arguments check EStTop to see if the
expression stack contains a value.
A special case of numeric arguments is "m,n". The "m" part is
encountered and causes the value to be pushed onto the expression stack.
The comma causes the ExeCom function to move the value into a special
"m-argument" global variable (MArgmt), clear the expression stack and set
another flag in CmdMod indicating that the "m" part of an "m,n" pair is
defined. Then the "n" is encountered and pushed onto the stack. Commands
which can take "m,n" pairs check the flag in CmdMod.
Page 6
To summarize, CmdMod and EStTop are variables which describe the
context of a command. Each command function tests these variables to see
if it was preceded by modifiers or numbers. For this to work, it is
important that the expression stack and the flags in CmdMod are cleared at
the right times. It is the responsibility of each command function to
leave CmdMod and EStTop with the proper values before successfully
returning. The rules are:
1. If the command function is returning FAILURE, don't worry about
clearing CmdMod or EStTop. They will be cleared before the next
command string is executed.
2. If the command function leaves a value on the expression stack, do
not clear EStTop before returning SUCCESS. If the command calls
GetNmA, do not clear EStTop, as GetNmA does it for you.
Otherwise, clear EStTop before returning SUCCESS.
3. Clear CmdMod unless the command function sets flags or needs to
leave them alone. ExeDgt, for example, handles digit strings and
doesn't clear CmdMod because the MARGIS bit may be set.
The search algorithm in TECO-C is complex. The war between the desire
for a fast search and the need to handle all the features of TECO'ssearch
commands has produced code which can be a real pain to follow. This
section attempts to explain how things got the way they are. The code is
explained in a bottom-up fashion, to follow the way it evolved in the
author's twisted mind.
The basic search idea is to scan a contiguous edit buffer for a search
string. The steps are:
1. Search the edit buffer for the first character in the search
string. If you reach the end of the edit buffer without matching,
the search fails.
2. When the first character of the search string matches a character
in the edit buffer, try to match successive characters in the
search string with the characters which follow the found character
in the edit buffer. If they all match, the search succeeds. If
one doesn't, go back to step 1.
This is basically what TECO-C does. The features of TECO's search
commands has buried these steps deep within some confusing code.
The first complication is introduced by pattern matching characters.
TECO has 17 "match constructs", whiceh are indicated in the search string
by the special characters ^X, ^S, ^N and ^Ex where "x" can be several other
characters. For instance, a ^X in the search string means that any
character is to be accepted as a match in place of the ^X. Characters
Page 7
other than the match constructs represent themselves. An example: the
search string "a^Xb" contains 3 match constructs: a, ^X and b.
TECO also supports forward or backward searching. When searching
backwards, only the search for the first match construct in the search
string is done in a backwards direction. When the character is found, the
characters following it are compared in a forward direction to the edit
buffer characters. This means that once the first match construct has been
found, a single piece of code can be used to compare successive characters
in the search string with successive characters in the edit buffer,
regardless of whether the search is forwards or backwards.
Adding these new features, the new description of searching is:
1. Search the edit buffer forwards or backwards for a character which
matches the first match construct in the search string. If you
reach the end of the edit buffer without matching, the search
2. When the first match construct of the search string matches a
character in the edit buffer, try to match successive match
constructs in the search string with the characters which follow
the found character in the edit buffer. If they all match, the
search succeeds. If one doesn't, go back to step 1.
To begin a description of which routines implement the above steps,
and in order to have a reference for later discussion, the following
hierarchy chart of "who calls who" is presented.
Page 8
ExeEUn ExeFB ExeFC ExeFD ExeFK ExeFN ExeFS ExeFUn ExeN ExeS ExeUnd
| | | | | | | | | | |
| | | | | | | | | | |
| | |
+------+ | +------+
+---+ | | | +---+
| V V | V V |
| ZFrSrc | BakSrc |
| | | | | | |
+---+ | | | +---+
+------+ | +------+
CMatch <--+
| |
At the top are the functions that implement search commands (E_, FB,
FC, FD, FK, FN, FS, F_, N, S and _). All of these functions call the main
search function: Search.
At the lower level are the functions which implement steps 1 and 2
described above. ZFrSrc searches forwards in the edit buffer for
characters which match the first character in the search string. BakSrc
does the same thing, but searches backwards. SSerch calls one of these two
functions and then executes a loop which calls CMatch to compare successive
match constructs in the search string to characters following the found
character in the edit buffer. The reason that ZFrSrc, BakSrc and CMatch
call themselves is to handle some of the more esoteric match constructs.
Case dependence in TECO is controlled by the search mode flag (see the
^X command). The variable SMFlag holds the value of the search mode flag,
and is used by ZFrSrc, BakSrc and CMatch.
One final point to help confuse things: ZFrSrc is system-dependent.
It contains a VAX/VMS-specific version which uses the LIB$SCANC run-time
library routine to access the SCANC instruction. The SCANC instruction
looks like it was designed to handle TECO's match constructs. I couldn't
resist using it, but it was a mistake, as it needlessly complicates an
already messy algorithm. I have decided to remove the VMS-specific code
some time in the future.
Further complications of the search algorithm arise because of the
following capabilities of TECO searches:
Page 9
1. If there is no text argument, use the previous search argument.
2. If colon modified, return success/failure and no error message
3. If the search fails and we're in a loop and a semicolon follows
the search command, exit the loop without displaying an error
4. Handle optional repeat counts
5. If the ES flag is non-zero, verify the search based on the value
of the flag.
6. If bit 64 of the ED flag is set, move dot by one on multiple
7. If bit 16 of the ED flag is set, don't move after a failing
8. Be fast.
7.1 The Edit Buffer And Input Buffer
TECO-C is based on TECO-11, but it uses a different form of edit
buffer memory management. Here's why.
The edit buffer in TECO-11 is implemented as a continuous block of
memory. This allows rapid movement through the edit buffer (by just
maintaining a pointer to the current spot) and makes searches very
straightforward. Insertion and deletion of text is expensive, because each
insertion or deletion requires moving the text following the spot where the
insertion or deletion occurs in order to maintain a continuous block of
memory. This gets to be a real pain when a video editing capability is
added to TECO, because in video mode text is added/deleted one character at
a time very rapidly.
TECO-C uses a edit buffer gap scheme. The edit buffer occupies a
continuous piece of memory, but there is a gap at the "current spot" in the
edit buffer. When the user moves around the edit buffer, the gap is moved
by shuffling text from one side of the gap to the other. This means that
moving around the text buffer is slower than for TECO-11's scheme, but text
insertion and deletion is very fast. Searches are still fast because most
searches start at the current spot and go forwards or backwards, so a
continuous piece of memory is searched. In the future, when some kind of
video mode is added, insertion and deletion one-character-at-a-time will be
fast using the gap scheme.
The variables that maintain pointers to the edit buffer and the gap
within the buffer can be confusing, so here's some examples. Suppose that
10000 bytes are allocated for the edit buffer when TECO-C is initialized.
Page 10
Suppose the allocated memory starts at address 3000.
Empty edit buffer (the gap spans the whole edit buffer):
EBfBeg = 3000 (edit buffer beginning)
GapBeg = 3000 (gap beginning)
GapEnd = 13000 (gap end)
EBfEnd = 13000 (edit buffer end)
Buffer contains "test", character pointer is before the first 't':
EBfBeg = 3000 (edit buffer beginning)
GapBeg = 3000 (gap beginning)
GapEnd = 12996 (gap end)
12997 't'
12998 'e'
12999 's'
EBfEnd = 13000 't' (edit buffer end)
Buffer contains "test", character pointer is after the last 't':
EBfBeg = 3000 't' (edit buffer beginning)
3001 'e'
3002 's'
3003 't'
GapBeg = 3004 (gap beginning)
GapEnd = 13000 (gap end)
EBfEnd = 13000 (edit buffer end)
Buffer contains "test", character pointer is after the 'e':
EBfBeg = 3000 't' (edit buffer beginning)
3001 'e'
GapBeg = 3002 (gap beginning)
GapEnd = 12998 (gap end)
12999 's'
EBfEnd = 13000 't' (edit buffer end)
When an insertion command is executed, the text is inserted starting
at GapBeg. When a deletion command is executed, GapEnd is incremented for
a forward delete or GapBeg is decremented for a backwards delete. When the
character pointer is moved forwards, the gap is moved forwards by copying
text from the end of the gap to the beginning. When the character pointer
is moved backwards, the gap is moved backwards by copying text from the the
area just before the gap to the area at the end of the gap.
There are a few messy cases, such as when a bounded search is executed
and the bounded text area includes the edit buffer gap. In this case, the
gap is temporarily moved so that the search can proceed over a continuous
memory area.
Page 11
In order to confuse things a little, TECO-C has one addition to the
basic edit buffer gap management. Following the end of the edit buffer
(EBfEnd) is the current input stream buffer. Since file input commands
always cause text to be appended to the end of the edit buffer, this is
natural. Thus, no input buffer is needed: text is input directly into the
edit buffer. This makes the code a little confusing, but it avoids the
problem of having an input buffer. When you have an input buffer, you have
to deal with the question of how large the buffer should be and what to do
with it when it's too small. this scheme is fast and and saves some
memory. (see File Input)
7.2 Q-registers
Q-registers have two parts: a numeric part and a text part. Each
q-register is represented by a structure containing three fields: one to
hold the numeric part and two to point to the beginning and end of the
memory holding the text part. If the text part of the q-register is empty,
then the pointer to the beginning of the text is NULL.
There are 36 global q-registers, one for each letter of the alphabet
and 1 for each digit from 0 to 9. These q-registers are accessible from
any macro level. There are 36 local q-registers for each macro level. The
names for local q-registers are preceded by a period. Thus the command
"1xa" inserts a line into global q-register "a", while the command "1x.a"
inserts a line into local q-register ".a". Storage for the data structure
defining local q-registers is not allocated until a local q-register is
first used. This saves space and time, because local q-registers are
rarely used, and doing things this way avoids allocating and freeing memory
every time a macro is executed.
8.1 Expression Stack
An expression stack is used to parse TECO's expressions. Consider the
command string QA+50=$$. When the command string is executed, the value of
QA is pushed on the expression stack, then the operator "+" is pushed on
the expression stack, and then the value "50" is pushed on the expression
stack. Whenever a full expression that can be reduced is on the expression
stack, it is reduced. For the above example, the stack is reduced when the
value "50" is pushed.
The expression stack is implemented in the following variables:
EStack the stack itself, containing saved operators and operands
EStTop index of the top element in EStack
EStBot index of the current "bottom" of the stack in EStack
The "bottom" of the expression stack can change because an expression
can include a macro invocation. For example, the command QA+M3=$$ causes
the value of "QA" to be pushed on the expression stack, then the "+" is
Page 12
pushed, and then the macro contained in q-register 3 is executed. The
macro in q-register 3 returns a value to be used in the expression. When
the macro is entered, a new expression stack "bottom" is established. This
allows the macro to have a "local" expression stack bottom while
maintaining the stack outside the macro.
8.2 Loop Stack
The loop stack contains the loop count and the address of the first
command in the loop. For example, in the command 5<FSMP$mt$>$$, the loop
stack contains the loop count (5) and the address of the first command in
the loop (F). Whenever the end-of-loop character (>) is encountered, the
loop count is decremented. If the loop count is still greater than zero
after it has been decremented, then the command string pointer is reset to
point to the first character in the loop (F).
The loop stack is implemented in the following variables:
LStack the stack itself, containing saved counts and addresses
LStTop index of the top element in LStack
LStBot index of the current "bottom" of the stack in LStack
The loop stack needs a "floating" bottom for the same reason that the
expression stack needs one: macros. Consider the command string
4<Smp$M7$>$$. When the "<" in is encountered, the loop count (4) and the
address of the first character in the loop (S) are placed on the loop
stack. Command execution continues, and the "M7" command is encountered.
Suppose that q-register 7 contains the erroneous command string 10>DL>$$.
When the ">" command is encountered in the macro, TECO expects the loop
stack to contain a loop count and an address for the first character in the
loop. In this example, there is no matching "<" command in the macro which
would have set up the loop stack. It would be very bad if TECO were to
think that the loop count was 4 and the first command in the loop was "S".
In this situation, what TECO should do is generate the error message "BNI >
not in iteration". In order to implement this, the variable LStBot is
adjusted each time a macro is entered or exited. LStBot represents the
bottom of the loop stack for the current macro level.
8.3 Macro Stack
The macro stack is used to preserve context each time a macro is
entered. All important values are pushed onto the stack before a macro is
entered and popped off the stack when the macro is exited. The macro stack
is also used by the EI command, which means it's used when executing
initialization files and mung files.
This section discusses on-line HELP, which is available only under
Page 13
The HELP command is not documented in the TECO manual distributed by
DEC., even though it is supported in TECO-11 and TECO-32. To get help,
simply type "HELP" followed by a carriage return. HELP is the only TECO
command that is not terminated by double escapes.
Help in TECOC is different than help in TECO-11. In TECO-C,
interactive help mode is entered, so that a user can browse through a help
tree, as he can from DCL. In TECO-C, access is provided to only two
libraries: the library specific to TECO-C (pointed to by logical name
TEC$INIT) and the system help library. To get help on TECO-C, just say
"HELP", with or without arguments. To get help from the system library,
say "HELP/S". I find this easier to use than TECO-11's syntax.
The help library for TECO-C is contained in file TECOC.HLB, which is
generated from TECOC.HLP, which is generated from TECOC.RNH. See file
TECOC.RNH for a description of how to do it. This help library is far
broader than the library for TECO-11, but much of it has yet to be filled
The help library is also the repository for verbose error messages,
which are displayed when the help flag (EH) is set to 3. For systems other
than VMS, the ZHelp function displays verbose text contained in static
memory (see file ZHELP.C).
TECO has an elegant design that allows high speed input. There are no
linked list data structures to keep track of, and most file input goes
directly to the end of the edit buffer.
TECO-C takes advantage of this by reading normal file input directly
to the end of the edit buffer. After each input call, nothing needs to be
moved; the pointer to the end of the edit buffer is simply adjusted to
point to the end of the new record. The pointer to the end of the edit
buffer (EBfEnd) serves two purposes: it points to the end of the edit
buffer and to the beginning of the input buffer.
A side effect of this scheme is the sharing of memory between the edit
buffer and the input buffer. When the edit buffer is empty, it can be made
smaller by shrinking the edit buffer gap in order to make the input buffer
larger. Obviously, if the edit buffer needs to be expanded, the input
buffer can suffer before more memory is actually requested from the
operating system. This is easily achieved by moving the pointer to the
"end-of-the-edit-buffer"/ "beginning-of-the-input-buffer".
This scheme works, but provides no support for the other forms of file
input. The EP and ER$ commands provide a complete secondary input stream
which can be open at the same time as the primary stream (two input files
at once). The EI command reads and executes files containing TECO
commands, and is used to execute the initialization file, if one exists.
The EQq command, if implemented, reads the entire contents of a file
Page 14
directly into a Q-register.
A second problem arises: on each of the open files, the quantum unit
of input is not standard. For A, Y and P commands, a form feed or
end-of-file "terminate" the read. For n:A commands, form feed, end-of-line
or end-of-file "terminate" each read. For EI commands, two escapes or
end-of-file "terminate" the read. The input code must "save" the portion
of an input record following a special character and yield the saved text
when the next command for the file is executed.
The scheme used in TECO-C is to read text from the current input
stream directly to the end of the edit buffer. When the input stream is
switched via a EP or ER$ command, the obvious switching of file descriptors
happens, and any text that's "leftover" from the last read is explicitly
saved elsewhere. Note that this happens VERY rarely, so a malloc/free is
For EI and EQq commands, the input memory following the edit buffer is
used as a temporary input buffer. After the file is read, the text is
copied to a Q-register in the case of EQq and to a separate buffer in the
case of EI.
As of 18-Feb-1991, TECO-C supports video only under Unix. The code
was written by Mark Henderson, using the CURSES package. See file
VIDEO.TXT for a discussion of how it works.
TECO-C was written with portability in mind. The first development
machine was "minimal": a SAGE IV (68000) running CP/M-68k. In that
environment, there was no "make" utility.
Initially, the system-independent code (files that don't start with a
"Z") had absolutely no calls to standard C runtime functions. This was
because I had several problems with the "standard" functions not being
"standard" on different machines. With the onset of ANSI C I've grown less
timid, but the main code still references almost no standard functions.
This is less of a limitation than you might think: TECO-C doesn't use
null-terminated strings. It also doesn't use unions, floating point or bit
1. Move the source code to the target machine.
Page 15
2. Inspect file ZPORT.H. You need to select the compiler you want
the code compiled for. For instance, if you are porting to a Unix
system, then fix ZPORT.H so that the unix identifier is defined
(it is usually defined by default by the compiler). If your
compiler is nothing like anything supported by ZPORT.H, then set
the UNKNOWN identifier.
3. Compile and link. See file AAREADME.TXT for descriptions of how
TECO-C is built in supported environments, and steal like mad.
The problem here is that you need a "Z" file for your environment,
containing all the "Z" functions needed by TECO-C. The easiest
thing to do is copy ZUNKN.C to your own "Z" file and link against
that. For instance, if I ever port TECO-C to a Macintosh, I'll
copy ZUNKN.C to ZMAC.C.
4. Fix things so the compile/link is successful. If you have
compiled with UNKNOWN set, you should get an executable file that
displays a message and dies when the first system-dependent
function is called. The strategy is to fix that function (often
by stealing from the code for other operating systems), relink and
deal with the next message until you have something that works.
Functions should be implemented in roughly the following order:
ZInit, ZTrmnl, ZExit, ZDspCh, ZAlloc, ZRaloc, ZFree, ZChin. This
will give you a TECO with everything but file I/O. You can run
it, add text to the edit buffer, delete text, search, use
expressions and the = sign command (a calculator). Then do file
input: ZOpInp, ZRdLin, ZIClos. Then do file output: ZOpout,
ZWrBfr, ZOClos, ZOClDe. Use the test macros (*tst*.tec) to test
how everything works (see Testing).
Testing of TECO-C is performed by executing macros. The macros are
contained in files named TSTxxx.TEC, where XXX is some kind of indication
as to what is tested. For instance, TSTQR.TEC tests q-registers. The test
macros do not test all the functions provided by TECO. They were
originally used to verify that TECO-C performs exactly the same as TECO-11
under the VMS operating system. When I needed to test a chunk of code, I
sometimes did it the right way and wrote a macro.
A debugging system (very ugly, very useful) is imbedded within the
code. It is conditionally complied into the code by turning on or off an
identifier (DEBUGGING) defined in the TECOC.H file. When debugging code is
compiled in, you can access it using the ^P command, which is not used by
regular TECO. The ^P command with no argument will display help about how
to use ^P.
Page 16
If you are working under VMS, it sometimes helps to compare the
execution of TECO-C with TECO-11. Put a test command string into a file.
Use DEFINE/USER_MODE to redirect the output of TECO-C to a file and execute
the macro with TECO-C. Then do the same thing with TECO-11. Use the
DIFFERENCES command to compare the two output files. They should be 100
percent identical.


@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
TECO-C (version number 146)
Copyright 1983, 1990 by Pete Siemsen. This software is provided to
you free of charge for your own use. Use it as you see fit; if it doesn't
work, I disclaim all responsibility. You may re-distribute this software
UNCHANGED only if you include this copy-right notice. Alternatively, if
you change this software, you may re-distribute the result only if you
include BOTH this copyright notice, AND an additional notice identifying
you and indicating that you have changed the software.
This program is still under development. See file PROBLEMS.TXT for
notes I've written to myself about things to do to the program. If you
modify this code to enhance it or fix a bug, please communicate the changes
to me. My address is
Pete Siemsen
645 Ohio Avenue #302
Long Beach, Ca. 90814
(213) 433-3059 (home)
(213) 740-7391 (work)
[NOTE -- This is old information. Better to contact me, Tom Almy, below.]
This archive contains TECO-C modified and compiled for DOS, Win32,
OS/2, and Linux (on Intel 32bit architecture). The modifications have been made by:
Tom Almy
who is a "old time" TECO user. Not only did I port TECO-C but I also
corrected some bugs. For OS/2 modified the file backup algorithm to do
copying rather than renaming as an option. This makes it Workplace
Shell friendly. The Win32, Linux and OS/2 versions allow long file names.
Included files in this archive:
readme.1st This file
readme.txt Operating and install instructions for Linux users
wchart.txt List of all the implemented commands.
teco.doc The official teco reference. TECOC IS CLOSE TO TECO-11 IN FUNCTIONALITY
tecoc Executable
Make link to tecoc
mung link to tecoc
teco link to tecoc
Inspect link to tecoc
*.tes *.tec TECO macros
Full source files for Linux version

doc/readme.osx vendored

@ -0,0 +1,171 @@ @@ -0,0 +1,171 @@
Running TECOC on OS X
Tecoc takes a first argument of mung, teco, or make to control its
operating mode. In this Linux version, the name of the executable is
tested to provide this first argument. Typically soft links are used
to the tecoc executable, however aliases could be used instead. The
mapping is:
Make is tecoc make (note uppercase first letter)
teco is tecoc teco
mung is tecoc mung
inspect is tecoc teco -inspect
The provided TAR file has these four soft links defined. Extract the
TAR file into a directory in your execution path
after making sure none of the command names already exist for other
applications. Necessary environment variables and files are described below.
Several option switches are allowed on the TECO command line:
-in[spect] -- Read file only, don't create an output file.
-noc[reate] -- If file doesn't exist, don't create it.
-noi[ni] -- Don't execute INI file. (valid for MAKE or MUNG as well)
-nom[emory] -- don't save filename as "last edited file" (valid for
MAKE also)
-nop[age] -- Formfeeds don't stop file reads (valid for MAKE also)
+nnn -- sets NOPAGE and positions dot to line nnn.
The part of the switch name in the square brackets is optional. For
instance "-in" is the same as "-inspect".
MAKE filespec
starts tecoc to create file filespec. Does equivalent of EWfilespec$$
TECO filespec
starts tecoc to edit file filespec. Does equivalent of
TECO filespec2=filespec1
starts tecoc to edit filespec1, writing to filespec2. Does
equivalent of ERfilespec1$EWfilespec2$Y$$
starts tecoc to edit last edited file. Filename is saved in file
named teco*.tmp in the current directory, unless overriden
(described below).
MUNG filespec <args>
starts tecoc to execute filespec. Equivalent to
You can use "TECO @filespec <args>" instead of MUNG.
Key Bindings
The keys mentioned in the teco.doc file are somewhat confusing.
This should help:
<DELIM> The "Esc" key, "Esc" echoes as "$", however the
teco.doc file shows it as '`'.
<BS> Type as Control-h, this isn't the "Backspace" key.
<DELETE> The "Backspace" key. This isn't the "Delete" key.
<CR> The "Enter" key.
<LF> Type as Control-j.
Note that the assignments for <BS> and <DELETE> shown here are
swapped. <BS> can be "Backspace" and <DELETE> can be control-h by
clearing ET&2048, e.g. 2048,0ET
The Initialization File.
Tecoc mungs (executes as teco commands) the file TECO.INI in the
current directory before processing the command line. Initialization
can be done instead by defining a TEC_INIT environment variable. The
value is either the list of teco commands to execute or a "$" followed
by the pathname of the file containing the initialization file. This
allows a single, centrally located initialization file. REMEMBER that
the "$" must be escaped, i.e. "\$"
The initialization file can be used to make initial settings. It can
return a value, but the value setting is somewhat obscure.
export TEC_INIT=1es
will cause successful searches to auto-display in all teco sessions.
Changing the location of the memory file.
Define the environment variable TEC_MEMORY to be "$" followed by the
pathname of the file designated the memory file.
Examples (csh):
export TEC_MEMORY=~/teco.mem
will cause the name of the last edit file to be stored in the file
teco.mem in the home directory. By default the file name is tecoN.tmp in
the current directory, where "N" is the process ID of the parent process to
The Libary directory
Defining the environment variable TEC_LIBRARY to be a directory path
(including the final "/") will allow the EI command to fetch
teco commands from this directory if the file is not found in the
current directory.
export TEC_LIBRARY=\$/usr/local/lib/
will cause the directory /usr/local/lib to be searched for teco command files.
Implemented flags:
ED&1 Allow carat "^" character in string searches
ED&2 Allow yank and _ unconditionally
ED&16 Failed searches preserve dot
ED&64 Move dot by one after each match in multiple occurance searches
ET&1 Type out in image mode
ET&2 Use scope for delete and control-U (default=1)
ET&4 Accept lowercase input (default=1)
ET&8 ^T reads without echo
ET&32 ^T reads with no wait
ET&128 MUNG mode (abort on error) cleared by "*" prompt
ET&2048 Swap backspace and delete
ET&4096 We are using 8 bit characters (default=1)
ET&32768 Trap control-C
EZ&1 Mark Henderson, who did much of the Unix port, likes the way
VAX/VMS keeps versions of files. VMS appends a semicolon followed
by a version number to files, and has the PURGE command to clean
out old versions of files. If this bit is off, TECO-C will handle
file version numbers, appending the appropriate version number to
file names. Mark supplied a "purge" program (distributed with TECO-C)
for users of this feature. Setting this flag turns off the feature,
to make TECO-C function as expected by the average Unix user. This
flag is set by default.
EZ&128 Don't stop read on formfeeds
EZ&256 If set, don't do newline translation on file read/write -- binary mode.
TECO is based on separate carriage return (CR) and line feed (LF)