#-h-  intro                      5268  local   01/08/81  11:49:34
.pl 61
.rm 70
.sp 10
.ce
Software Tools Programmer's Manual
.sp 5
.ce
ABSTRACT
.sp
This report describes the software tools and associated
utility routines originally developed by Brian Kernighan
and P. J. Plauger in their book
.ul
Software Tools
and enhanced by members of the Software Tools Users Group.
.sp 4
.ce
January 1981
.sp 10
.ce 9
Documentation and tools assembled and
prepared for distribution by:

Deborah K. Scherrer
Advanced Systems Research Group
Computer Science and Applied Mathematics Department
Lawrence Berkeley Laboratory
Berkeley, CA  94720
.sp 3
LBID 097
.bp 1
.fo ''-#-''
.ce
Software Tools Programmers Manual
.sp 2
.ce
INTRODUCTION
.sp
This manual describes those utilities and programming aids which
are descendants of the tools developed in
.ul
Software Tools
by Brian Kernighan and P. J. Plauger.
The tools described here have been
considerably enhanced
and many new ones added.
.sp
One of the many problems which programmers (and
end users) encounter in their
everyday use of computers is
the lack of common utilities as they move
from system to system.
The software which was presented in
.ul
Software Tools
represents a first step towards a solution
to this problem.
Suddenly, a common editor, text formatter, sorter, and
other program development tools were available in a "portable"
language.  This
portability was achieved via two mechanisms:
.sp
.in +5
.ti -3
1. All source was written in ratfor, a fortran preprocessor language
which is directly translatable into Fortran.
.ti -3
2. Most system dependent quantities were pushed down into primitive
function calls, which are left up to the person in charge of
bringing up the
utilities to implement.
.sp
.in -5
These two mechanisms, together with certain conventions concerning data
types, have permitted more than 300 different sites
to implement these tools
to varying degrees of sophistication.
In fact, if the portable command line interpreter (shell) is
implemented, this software can essentially define
a portable "virtual operating system",
achieving inter-system uniformity at all three levels of
user interface - virtual machine (the primitives),
utilities, and command language.
.sp 2
The manual is divided into four sections:
.sp
.in +5
1.  Tools
.br
2.  Subroutines and Functions
.br
3.  Optional Tools and System-dependent Information
.br
4.  Primers
.sp
.in -5
.sp
Section 1 describes the tools or programs which are usually
invoked directly by the
user from the current command interpreter (or shell).  The utilities
may also be invoked through the use of the
"spawn"
function call (if implemented).
.sp
Section 2 describes the
subroutines and functions which are intended to be called by
user programs.
Included in this section are a number of generally useful
system-independent routines
which perform commonly encountered programming tasks.
Also included are the I/O primitives, which are
implemented specifically for each site when the tools package
is brought up.
These are primarily concerned with I/O and process control.
.sp
Section 3 contains descriptions of additional tools
not available on every system.
It also contains various system-dependent information such
as methods for invoking the software tools.
.sp
Section 4 contains primers,
or detailed help documents for some of the tools.
.sp
All entries are based on a common format,
which includes at least some of the following subsections:
.sp
.in +5
The NAME section repeats the tool or routine name
and gives a very short description
of its purpose.
.sp
The SYNOPSIS section gives the form of the command line necessary
to invoke the tool,
or the form of the call to the subroutine or function.
.sp
The DESCRIPTION section discusses the current entry in detail.
.sp
An IMPLEMENTATION section is included in the writeups for all
primitives and describes possible strategies for implementation.
.sp
The FILES section describes any scratch or data files (other than
indicated by the arguments) which might be used by the tool.
.sp
The SEE ALSO section gives the names of other entries or
additional documentation that is related to the current entry.
.sp
The DIAGNOSTICS section lists error messages or error conditions
that might result.
Messages which may come from the host operating system are
not covered.
.sp
The BUGS/DEFICIENCIES section describes known bugs and
lists possible deficiencies.
.sp
.in -5
.ul
Acknowledgements.
.br
As mentioned above, much of the software described in this manual
originated in
.ul
Software Tools.
The tools were assembled and prepared for distribution by
Debbie Scherrer of Lawrence Berkeley Laboratory with considerable
assistance from Allen Akin of the Georgia Institute of Technology.
Enhancements to the original tools, and well as many new tools, have
been submitted to the Software Tools Users Group by the
following organizations:
.nf
.ne 7
.sp
.ul
University of Arizona   Lawrence Berkelely Laboratory   Georgia Tech.
.sp
David Hanson            Joe Sventek                     Allen Akin
Cary Coutant            Debbie Scherrer                 Dan Forsyth
Chris Fraser            Dennis Hall                     Perry Flinn
Peter Downey
Steve Wampler
.sp 2
.ul
Stanford University     Johns Hopkins University
.sp
Philip Scherrer         Mars Gralia
.fi
#-t-  intro                      5268  local   01/08/81  11:49:34
#-h-  summary                    8998  local   01/09/81  14:25:32
.bp 1
.in 0
.he ''''
.fo ''-#-''
.ce
CONTENTS
.sp 2
1.  TOOLS
.in +6
.sp
.nf
ar ................................. archive file maintainer
cat ....................... concatenate and print text files
ch .................................... change text patterns
comm ....................... print lines common to two files
cpress ................................ compress input files
crt ..................................copy files to terminal
crypt ................... encrypt and decrypt standard input
date ............................... print the date and time
dc ......................................... desk calculator
detab ............................... convert tabs to spaces
diff ..................... isolate differences between files
echo ........................... echo command line arguments
ed .................................................. editor
edin ........................................ in-core editor
entab .................... convert spaces to tabs and spaces
expand .............................. uncompress input files
fb ................ search blocks of lines for text patterns
field ............................ manipulate fields of data
find ....................... search a file for text patterns
format ......................................... format text
includ ......................... file inclusion preprocessor
kwic ............ prepare lines for keyword-in-context index
lam ......................................... laminate files
ll ...................................... print line lengths
macro ...................... general-purpose macro processor
mcol ................................ multicolumn formatting
mv .................................... move (rename) a file
os .................. convert backspaces into multiple lines
pl ................... print specified lines/pages in a file
pr .............................................. print file
ratfor ................................. Ratfor preprocessor
rev .......................................... reverse lines
rm ................................... remove (delete) files
roff ........................................ [see 'format']
sedit ........................................ stream editor
sh ................................ command line interpreter
show ......................... show all characters in a file
sort .......................... sort and/or merge text files
spell ............................... locate spelling errors
split ............................... split file into pieces
tail ............................ print last lines of a file
tee ................... copy input to output and named files
tr ............................... character transliteration
tsort ........................... topologically sort symbols
uniq ............. strip adjacent repeated lines from a file
unrot ...................... unrotate lines prepared by kwic
wc ............. count lines, words, and characters in files
xref ..................... make a cross reference of symbols
.sp 2
.ti -6
.ne 6
2.  SUBROUTINES AND PRIMITIVES
.sp
.fi
(* indicates that the implementation of the routine is system-dependent
.br
# indicates that the routine may, in some cases, be system-dependent)
.nf
.sp 2
.ti -2
definitions .................... standard Ratfor definitions
.sp
.ti -2
.ul
File Manipulation
.br
.ti -1
#amove ......................... move (rename) file1 to file2
.ti -1
*close ................................ close (detach) a file
.ti -1
*create .... create a new file (or overwrite an existing one)
.ti -1
*gettyp .............. get type of file (character or binary)
.ti -1
*isatty .......... determine if file is a teletype/CRT device
.ti -1
#mkuniq ........................... generate unique file name
.ti -1
*open ... open an existing file for reading, writing, or both
.ti -1
*remove .................. remove a file from the file system
.sp
.ti -2
.ul
I/O
.br
fcopy ............................. copy file in to file out
.ti -1
*flush .................... flush output buffer for file 'fd'
getc .................... read character from standard input
.ti -1
*getch ............................. read character from file
.ti -1
#getlin ............................. get next line from file
.ti -1
*note ....................... determine current file position
.ti -1
#prompt ............................... prompt user for input
putc .................... write character to standard output
.ti -1
*putch .............................. write character to file
putdec .................. write integer n in field width >=w
putint ..... write integer n onto file fd in field width >=w
.ti -1
#putlin ..................... output a line onto a given file
putstr ........... write str onto file fd in field width >=w
.ti -1
*readf ............................. read from an opened file
.ti -1
*remark ........................... print single-line message
.ti -1
*seek ............................... move read/write pointer
.ti -1
*writef ............................. write to an opened file
.sp
.ti -2
.ul
Process Control
.br
.ti -1
*spawn ...................................... execute subtask
.sp
.ti -2
.ul
String Manipulation
.br
addset ........... put c in array(j) if it fits, increment j
addstr ...... add string s to str(j) if it fits, increment j
clower ................................ fold c to lower case
concat ...................... concatenate 2 strings together
ctoc ................................. copy string-to-string
ctoi ....... convert string at in(i) to integer, increment i
ctomn  ....... translate ascii control character to mnemonic
cupper ..................... convert character to upper case
equal ............ compare str1 to str2; return YES if equal
esc .... map array(i) into escaped character, if appropriate
fold .......................... convert string to lower case
gctoi .......... generalized character-to-integer conversion
getwrd . get non-blank word from in(i) into out, increment i
gitoc .......... generalized integer-to-character conversion
index ....................... find character c in string str
itoc ................... convert integer to character string
length ............................ compute length of string
lower ......................... convert string to lower case
mntoc ......................... ascii mneumonic to character
scopy ...................... copy string at from(i) to to(j)
sdrop ........................ drop characters from a string
skipbl ...................... skip blanks and tabs at str(i)
stake ........................ take characters from a string
stcopy ........ copy string at from(i) to to(j); increment j
strcmp ................................... compare 2 strings
strim .......... trim trailing blanks and tabs from a string
substr ...................... take a substring from a string
type ........................... determine type of character
upper ......................... convert string to upper case
.sp
.ti -2
.ul
Pattern Matching
.br
amatch ........ look for pattern matching regular expression
getpat .......encode regular expression for pattern matching
makpat ...... encode regular expression for pattern matching
match ....................... match pattern anywhere on line
.sp
.ti -2
.ul
Command Line Handling
.br
.ti -1
*delarg ............. delete command line argument number 'n'
.ti -1
*getarg .......................... get command line arguments
gfnarg .......................... get next filename argument
query ...................... print command usage information
.sp
.ti -2
.ul
Dynamic Storage Allocation
.br
dsfree ..................... free a block of dynamic storage
dsget .................... obtain a block of dynamic storage
dsinit .......................... initialize dynamic storage
.sp
.ti -2
.ul
Symbol Table Manipulation
.br
delete ................... remove a symbol from symbol table
enter ......................... place symbol in symbol table
lookup ..... get string associated with name from hash table
mktabl ................................. make a symbol table
rmtabl ............................... remove a symbol table
sctabl .................. scan all symbols in a symbol table
.sp
.ti -2
.ul
Date Manipulation
.br
fmtdat .................... convert date to character string
.ti -1
*getnow ........................... get current date and time
wkday ...... get day-of-week corresponding to month-day-year
.sp
.ti -2
.ul
Error Handling
.br
cant ...... print 'name: can't open' and terminate execution
error .... print single-line message and terminate execution
.sp
.ti -2
.ul
Miscellaneous
.br
.ti -1
*endst . close all open files and terminate program execution
.ti -1
*initst .. initialize all standard files and common variables
.sp 2
.ne 3
.ti -6
3.  ADDITIONAL TOOLS AND SYSTEM-DEPENDENT INFORMATION
.sp
(To be completed by local installations)
.sp 2
.ne 4
.ti -6
4.  PRIMERS
.sp
edit ................................................ editor
ratfor ................................. ratfor preprocessor
.in -5
.fi
#-t-  summary                    8998  local   01/09/81  14:25:32
#-h-  tools                      2575  local   12/10/80  15:52:45
.bp
.he ''''
.ce
1.  TOOLS
.sp 3
This section describes the use of the various tools.
The invocation of each tool, as described in the SYNOPSIS
subsections, is generally:
.sp
.ce
tool arg1 arg2 ...
.sp
Arguments are frequently input file names, information
needed by the tool, or option flags asking the tool
to perform certain additional tasks.
Option flags are commonly preceded by - or + signs.
In addition, the invocation of a particular tool as
.sp
.ce
tool ?
.sp
where "?" is the only argument, results in the display of the
valid calling sequence for the tool.
(The precise form of invocation and argument specification may
vary on individual systems.
Any changes will be described in Section 3.)
.sp
An integral part of the standard interface to each tool is the idea of
standard input, standard output and error output.
As in the Unix
operating system, the defaults for these units
are the user's terminal.
Thus if a tool is invoked with no arguments, it would read its
input from the terminal, send its output there, and also print
any resulting error messages.
These
I/O streams may be redirected to files (or sometimes other
devices) simply through the use of redirection symbols which
precede the desired file name.
Thus, a "<" sign preceding a filename on the command line means
"take input from this file",
and, likewise, a ">" sign preceding a filename means
"send output to this file".
The complete list of I/O redirections is:
.sp
.nf
.in +5
<file           read input from "file"
>file           send output to "file"
>>file          append output to end of "file"
?file           send error messages to "file"
??file          append error messages to end of "file"
.fi
.sp
.in -5
In addition, most tools also read a list of input files from the
command line.
.sp
If the shell is implemented, a convenient method for "stacking"
utilities together so that the output from one becomes the input
to another is available.
See the writeup on the shell for more details.
.sp 2
The following conventions are used in this manual
for describing arguments
to the tools:
.sp
.in +5
Arguments surrounded by square brackets ([]) are either optional
or the user is expected to make a choice among the various
options.
Several arguments separated by vertical bars (|) also
indicate a choice.
.sp
Ellipses (...) indicate that the previous argument construction
may be repeated 0 or more times.
.sp
Arguments gigen in the documentation as "name" or "file"
almost always refer to file names.
.sp
Arguments beginning with - or + are options to the tool
being invoked.
.in -5
#-t-  tools                      2575  local   12/10/80  15:52:45
#-h-  ar.doc                     6011  local   12/15/80  10:49:46
.bp 1
.in 0
.he 'AR (1)'09/16/80'AR (1)'
.fo ''-#-'
.fi
.in 7
.ti -7
NAME
.br
ar - archive file maintainer
.sp 1
.ti -7
SYNOPSIS
.br
ar [-](d|p|t|u|x)[v] arcname [files]
.sp 1
.ti -7
DESCRIPTION
.br
Ar collects sets of arbitrary files into one big file and
maintains that file as an 'archive'.
Files can be extracted from the archive, new ones can be added,
old ones can be deleted or replaced by updated versions, and
data about the contents can be listed.

If a minus sign ('-') is given as a file name, further file names
are read from the standard input, one file name per line.

Files that are to be added to an archive must exist as
files with the name given.  Files that are extracted from
an archive will be put onto files with the name given.
Files that are added to archives can, of course, be archive files
themselves.  There is no (theoretical) limit to the number
of files that can be nested this way.
Thus AR provides the utility necessary to maintain tree-structured
file directories.

AR is invoked by the command line
.br

.ti +10
AR command archname [optional filenames]

where 'command' is any one of 'dptux', optionally concatenated
with 'v', specifying what operation to perform on the
archive file named 'archname'.
The possible commands are:
.br

.in +10
u - Update named archive by replacing existing files or adding new
ones at end.
If the 'v' option is used, file names will be printed on the
standard output as files are written to the new archived file.

x - Extract named files from archive.  Put onto file of the
same name.
If the 'v' option is added, file names will be printed on the
standard output as files are extracted.

d - Delete named files from archive.
If the 'v' option is used, file names will be printed on
the standard output as they are deleted from the archive.

p - Print named files on standard output.
Using the 'v' option will cause the file name to precede the file.

t - Print table of archive contents.
Normally, the table will contain only the file name.
If the 'v' option is used, the table will also contain
the file's length, type, and date and time of last change.

v - Verbose.  This command may be concatenated to any of the above
commands,
and will cause the archiver to print additional information,
generally file names, on the standard output.
Its specific action for each command has already been described.
.br
.in -10

The optional filenames in the command line specify individual
files that may participate in the action.
If no files are named, the action is done on ALL files in the archive,
but if any files are explicitly named, they are the ONLY ones that
take part in the action.
(The 'd' command is an exception--files may be deleted only by
specifying their names.)


.br

.sp 1
.ti -7
FILES
.br
A file 'arctemp' is created and subsequently deleted for each run.
.sp 1
.ti -7
SEE ALSO
.br
The Unix commands 'ar' and 'ls' in the Unix manual
.sp 1
.ti -7
DIAGNOSTICS
.br
archive not in proper format
.br
.in +10
The basic problem is that archive didn't find a header
line where one was expected.
Typical reasons include misspelling the file name,
using an existing file (not in archive format)
on a creation run, and
referencing an archive file that has been modified
directly (say with the editor).
.br
.in -10

archive integrity in doubt - missing trailer
.br
.in +10
Each file in an archive is terminated by a special line called a
"trailer," which must be present.
The message is caused by the lack of a trailer line when one was
expected.
.br
.in -10


delete by name only
.br
.in +10
For user protection, files are allowed to be deleted from an archive
only by specifying each file name.
.br
.in -10

duplicate file name
.br
.in +10
A file was listed more than once when calling the archiver
.br
.in -10

fatal errors-archive not altered
.br
.in +10
This message is generated whenever one or more of the other
errors have been detected.  An archive is never altered unless
EVERYTHING has run properly.
.br
.in -10

too many file names
.br
.in +10
At the present the user may call the archiver with no more than
25 files at a time.
.br
.in -10

usage:  ar [-](dptux)[v] arcname [files]
.br
.in +10
The command line passed to the archiver is in error.
Possibly the command is wrong or the archive file name
has not been given.
.br
.in -10

'filename': can't add
.br
.in +10
The file specified by 'filename' doesn't exist or can't be
opened (e. g. is locked).
.br

.in -10
'filename': can't create
.br
.in +10
The archiver could not generate a local file by the name
of 'filename'.  Probably the archiver's internal file
buffer space has been exceeded.
.br

.in -10
'filename': not in archive
.br
.in +10
The archiver could not locate the file specified by 'filename' in
the archived file.
.br

.in -10
.sp 1
.ti -7
AUTHORS
.br
Original code from Kernighan and Plauger's 'Software Tools',
with rewrites by Allen Akin (Georgia Institute of Technology)
and minor changes suggested by David Hanson (University
of Arizona).
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
On some systems only text files can be archived.

When the update and print commands are used, the files are
updated or printed
in the order they appear on the
archived file, NOT the order listed on
the command line.

The Unix archiver allows files to be positioned in the
archive, rather than simply added at the end as AR does.
This is done by adding the following commands:
.br
.in +10

m - Move specified files to end of archive

ma posname - Move specified files to position after file 'posname'

mb posname - Move specified files to position before file 'posname'

r - Replace specified files and place at end of archive

ra posname - Replace files and place after file 'posname'

rb posname - Replace files and place before file 'posname'
.br
.in -10

There are some discrepancies between the Unix version of AR and
this version.  Unix uses 'r'--replace instead of 'u'--update.
Unix also requires the user to specify an additional command 'n'
when creating a new archive.
#-t-  ar.doc                     6011  local   12/15/80  10:49:46
#-h-  cat.doc                     966  local   01/06/81  22:51:55
.bp 1
.in 0
.he 'CAT (1)'02/16/78'CAT (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
cat -- concatenate and print text files
.sp 1
.in
SYNOPSIS
.br
.in 7
cat [file] ...
.sp 1
.in
DESCRIPTION
.br
.in 7
Cat reads each file in sequence and writes it on the standard output.
Thus
.sp 1
.ti +5
cat file
.sp 1
prints the file;
.sp 1
.ti +5
cat file1 file2 >file3
.sp 1
concatenates the first two files and places the result on the third,
and,
.sp 1
.ti +5
cat file >>out
.sp 1
appends 'file' onto the back of 'out'.
.sp 1
If no argument or '-' is given, cat reads the standard input.
.sp 1
.in
FILES
.br
.in 7
None
.sp 1
.in
SEE ALSO
.br
.in 7
The "Software Tools" book, p. 77.
.br
crt, pg (if implemented)
.sp 1
.in
DIAGNOSTICS
.br
.in 7
A message is printed if a file cannot be opened;
further processing is terminated.
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
B. Kernighn & P. J. Plauger
.sp 1
.in
BUGS
.br
.in 7
Using the same file for output as well as input may
cause strange results.
#-t-  cat.doc                     966  local   01/06/81  22:51:55
#-h-  ch.doc                     3932  local   01/09/81  00:39:06
.bp 1
.in 0
.he 'CH (1)'4/7/78'CH (1)'
.fo **-#-**
.in 7
.fi
.ti -7
NAME
.br
ch - make changes in text files
.sp 1
.ti -7
SYNOPSIS
.br
ch [-ax] [expr ...] fromexpr [toexpr]
.sp 1
.ti -7
DESCRIPTION
.br
Ch
copies each line of the standard input to the standard output, globally
substituting the text pattern "toexpr" for "fromexpr" on each line that
satisfies matching criteria defined by the leading expressions "expr" and
the switches. (A text pattern is a subset of a "regular expression"--see
the "ed" writeup for a complete description.)  Three possible courses of
action are taken depending upon the number of text patterns(n) found in
the command line:
.sp
.in +5
.ti -5
n=1  The text pattern is assumed to be "fromexpr" with a null "toexpr";
it is equivalent to the ed command
.ti +10
g/fromexpr/s///g
.ti -5
n=2  The first text pattern is "fromexpr", the second is "toexpr"; it
is equivalent to the ed command
.ti +10
g/fromexpr/s//toexpr/g
.ti -5
n>=3 The (n-1)th pattern is "fromexpr", the nth is "toexpr" and patterns
1...n-2 are used to determine the lines upon which to perform the
substitution.  The default is that any line which matches any one of
the n-2 leading expressions are eligible for substitution.  If the -a
flag is specified, only lines which match all n-2 leading expressions in
any order are eligible.  If the -x flag is specified, all lines which
don't satisfy the above criteria are eligible. (See the writeup on find
for more information.)  In particular, if n=3,
.ti +10
ch expr from to
.br
is equivalent to the ed command
.ti +10
g/expr/s/from/to/g
.ti +10
ch -x expr from to
.br
is equivalent to the ed command
.ti +10
x/expr/s/from/to/g
.sp
.in -5
The substitution string "toexpr" may be a string of replacement
characters, null to effect a deletion, or it may include the special
"ditto" character "&" to put back the "fromexpr" string and thus
effect an insertion.  If a deletion is desired with the multiple
leading tag expressions, a "toexpr" of "" -i.e. quotes around an
empty string may be used.

A text pattern consists of the following elements:

.nf
c         literal character
?         any character except newline
%         beginning of line
$         end of line (null string before newline)
[...]     character class (any one of these characters)
[!...]    negated character class (all but these characters)
*         closure (zero or more occurrences of previous pattern)
{...}     'tagged' (marked) pattern
@c        escaped character (e.g., @%, @[, @*)

.fi
Any special meaning of characters in a text pattern is lost when
escaped, inside [...], or for:

.nf
%         not at beginning
$         not at end
*         at beginning

.fi
A character class consists of zero or more of the following
elements, surrounded by [ and ]:

.nf
c         literal character
a-b       range of characters (digits, lower or upper case)
!         negated character class if at beginning
@c        escaped character (@! @- @@ @])

.fi
Special meaning of characters in a character class is lost when
escaped or for

.nf
!         not at beginning
-         at beginning or end

.fi
An escape sequence consists of the character @ followed by a single
character:

.nf
@n        newline
@t        tab
@c        c (including @@)

.fi
For a complete description, see "Software Tools" pages 135-154.
Care should be taken when using the characters % $ [ ] { } ! * @ and
any shell characters
in the text pattern. It is often necessary to enclose the
entire substitution pattern in quotes.
.sp 1
.ti -7
FILES
.br
None
.sp 1
.ti -7
SEE ALSO
.br
sedit, find, tr, ed, the UNIX tool GRES
.sp 1
.ti -7
DIAGNOSTICS
.br
An error message is printed if the pattern given is illegal.
.sp 1
.ti -7
AUTHORS
.br
Original from Kernighan and Plauger's "Software Tools", with
modifications by Joe Sventek (Lawrence Berkeley Laboratory)
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
A minus sign(dash[-]) may not start an expression.
#-t-  ch.doc                     3932  local   01/09/81  00:39:06
#-h-  comm.doc                   1205  local   01/09/81  00:39:07
.bp 1
.in 0
.he 'COMM (1)'1/11/79'COMM (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
comm - print lines common to two files
.sp 1
.in
SYNOPSIS
.br
.in 7
comm
[-123] file1 file2
.sp 1
.in
DESCRIPTION
.br
.in 7
Comm
reads
file1
and
file2,
which should be sorted, and produces a three column output:
lines only in
file1,
lines only in
file2,
and lines in both files.
The filename '-' means the standard input.
If there is only one file argument,
file2
refers to the standard input.

The optional arguments -1, -2, and -3 specify the printing of
only the corresponding column.
Thus
comm -3
prints only the lines common to both files, and
comm -12
prints lines which are in either file, but not in both.
The default is -123.
.sp 1
.in
FILES
.br
.in 7
None
.sp 1
.in
SEE ALSO
.br
.in 7
diff
.sp 1
.in
DIAGNOSTICS
.br
.in 7
A message is printed if an input file cannot be opened.
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Debbie Scherrer (Lawrence Berkeley Laboratory)
.sp 1
.in
BUGS
.br
.in 7
The flags used by this tool are the reverse of those used by the
Unix 'comm'.  In Unix, the flags 1, 2, and 3
.bd
suppress
printing of the corresponding column.
Kernighan, on page 126 of 'Software Tools' suggests the
version used above.
#-t-  comm.doc                   1205  local   01/09/81  00:39:07
#-h-  cpress.doc                  775  local   01/09/81  00:39:08
.bp 1
.in 0
.he 'CPRESS (1)'1/15/79'CPRESS (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
cpress - compress input files
.sp 1
.in
SYNOPSIS
.br
.in 7
cpress
[file ...]
.sp 1
.in
DESCRIPTION
.br
.in 7
Cpress
compresses runs of repeated characters in the input files.
The output file can eventually be expanded with the tool 'expand'.

If no input files are given, or the filename '-' appears, input will
be from the standard input.
.sp 1
.in
FILES
.br
.in 7
.sp 1
.in
SEE ALSO
.br
.in 7
expand
.sp 1
.in
DIAGNOSTICS
.br
.in 7
A message is printed if an input file cannot be opened; further processing
is terminated.
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
From Kernighan & Plauger's 'Software Tools', with modifications by
Debbie Scherrer (Lawrence Berkeley Laboratory)
.sp 1
.in
BUGS
.br
.in 7
#-t-  cpress.doc                  775  local   01/09/81  00:39:08
#-h-  crt.doc                    1190  local   12/19/80  15:04:22
.bp  1
.in 0 
.he 'CRT'1/12/79'CRT'
.fo ''-#-' 
.fi 
NAME 
.br 
.in 7 
crt - copy files to terminal
.sp 1 
.in 
SYNOPSIS 
.br 
.in 7 
crt
[-n] [file ...]
.sp 1 
.in 
DESCRIPTION 
.br 
.in 7 
CRT
is similar to 'cat' except that it prints only n lines (default 22) at
a time.
After each set of lines are printed, crt will wait for instructions
from the user.
Hitting a carriage-return will cause the next n lines to appear, hitting
a 'q' (quit) will cause crt to skip over to the next input file (if
any), and hitting an end-of-file character will cause crt to stop
immediately.
 
If no files are specified, or if the filename '-' is given, lines
will be read from the standard input.
 
The flag -n may be given, where n specifies the number of lines desired
at a time.
 
Crt will stop at the end of each file (except the last), as well as
after each n lines.
.sp 1
.in 
FILES 
.br 
.in 7 
.sp 1 
.in 
SEE ALSO 
.br 
.in 7 
cat, pg (if implemented)
.sp 1 
.in 
DIAGNOSTICS 
.br 
.in 7 
A message is printed if an input file cannot be opened; further processing
is terminated.
.sp 1 
.in 
AUTHORS 
.br 
.in 7 
.sp 1 
Debbie Scherrer, Lawrence Berkeley Laboratory
.sp 1 
.in 
BUGS 
.br 
.in 7 
#-t-  crt.doc                    1190  local   12/19/80  15:04:22
#-h-  crypt.doc                  1046  local   12/10/80  15:52:53
.bp 1
.in 0
.he 'CRYPT (1)'6/30/78'CRYPT (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
crypt - encrypt and decrypt standard input
.nf
.sp
.ti -3
SYNOPSIS
.br
crypt key
.fi
.sp
.ti -3
DESCRIPTION
.br
Crypt
encrypts characters on the standard input by using "key".
The file can eventually be decrypted by running it back through
crypt with the same key.
Multiple encryption (encrypting a file with first one key and then
another) is allowable.
.sp
The size of the encryption key is limited by the MAXKEY definition
in the source code.
.sp
.ti -3
FILES
.br
None
.sp
.ti -3
SEE ALSO
.br
.sp
.ti -3
DIAGNOSTICS
.br
None
.sp
.ti -3
AUTHORS
.br
From Kernighan & Plauger's 'Software Tools'.
.sp
.ti -3
BUGS/DEFICIENCIES
.br
On some systems, encryption results in control characters which
may cause erratic behavior.
For these systems, an optional version of the encryption routine
is provided which avoids encrypting control characters.
When using this optional version, multiple decriptions must be
done in the exact reverse order in which encryption was done.
#-t-  crypt.doc                  1046  local   12/10/80  15:52:53
#-h-  date.doc                    401  local   12/10/80  15:52:54
.bp 1
.in 0
.he 'DATE (1)'1/11/79'DATE (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
date - print the date
.sp 1
.in
SYNOPSIS
.br
.in 7
.bd
date
.sp 1
.in
DESCRIPTION
.br
.in 7
The current date and time are printed.
.sp 1
.in
FILES
.br
.in 7
None
.sp 1
.in
SEE ALSO
.br
.in 7
The Unix command 'date'
.sp 1
.in
DIAGNOSTICS
.br
.in 7
None
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Debbie Scherrer
.sp 1
.in
BUGS
.br
.in 7
#-t-  date.doc                    401  local   12/10/80  15:52:54
#-h-  dc.doc                     5107  local   12/10/80  15:52:55
.bp 1
.in 0
.he 'DC (1)'07/20/80'DC (1)'
.fo ''-#-''
.fi
.in 3
.ti -3
NAME
.br
dc - desk calculator
.sp 1
.ti -3
SYNOPSIS
.br
dc [files ...]
.sp 1
.ti -3
DESCRIPTION
.br
DC evaluates integer expressions from the source files,
one expression per input line.
If no input files are given, or the filename '-' is specified,
dc reads from the standard input.

Ordinarily dc operates on decimal integer arithmetic expressions,
but the user may specify an input base and output base other
than decimal.

Expressions may be simple arithmetic expressions or
replacement expressions.
The values of simple expressions are
written on standard output when they are evaluated.
Replacement expressions are used to hold temporary values, and are
not automatically printed.

A simple expression is a normal arithmetic expression using
numbers, variables, parentheses, and the following
operators, listed in order of precedence:
.in +5
.nf
+  -          unary plus and negation operators.  These may
                          only appear at the start of a simple
                          expression or after a "("

**            exponentiation

*   /   %     multiply, divide, modulo (remainder)

+   -         add, subtract

== !=         relations - equals, not equal to,
>  >=         greater than, greater than or equal to,
<  <=         less than, less than or equal to
                       (!=, ^=, ~= all treated as "not equal")

!             unary logical not (also ~ and ^)

|   &         logical or, and

.in -5
.fi
The logical operators ! | & and the relational operators result in
the values 1 for true and 0 for false.

A replacement expression is:
.sp
.ce
name = simple expression
.sp
where 'name' is a character string of (virtually) any length,
starting with a letter and consisting of only letters and digits.
(The characters a-f should not be considered letters when operating
in hexadecimal mode.)
Variables are automatically declared when they first appear to
the left of an "=" sign,
and they should not be used in a simple expression until they have
been declared.

Radix Control
.br
.in +5
Radix control is available in 2 ways:
.br
1) There are default radix values for both input and output which
may be changed by setting the predefined variables 'ibase'
(input base) and 'obase' (output base).  (Radix 10 is always
used to evaluate and/or print radix-defining expressions.)
For example,
.sp
.in +10
ibase = 2
.br
obase = 16
.in -10
.sp
would accept input in binary and print results in hexadecimal.

2)  The radix of individual numbers may be explicitly given by
following the number with an underscore character and then the
desired radix.
For example,
.sp
.ce
100_16
.sp
would specify the hex number 100 (256 in decimal).
.in -5
.sp
.ti -3
EXAMPLES
.br
.sp
.nf
.ti +15
10 + (-64 / 2**4)
.br
would print the answer "6"
.sp
.in +15
.nf
temp = 101_2
temp == 5
.fi
.in -15
would print the answer "1" (true)

.nf
.in +15
ibase = 16
obase = 2
1a + f
.in -15
.fi
would print the answer "101001"
.sp
.in +15
.nf
ibase = 16
numa = 100_10
numb = 100
numa + numb
.in -15
.fi
would print the answer "356"
.sp 1
.ne 2
.ti -3
FILES
.br
None
.sp 1
.ne 3
.ti -3
SEE ALSO
.br
macro, the UNIX M4 macro package
.br
The UNIX tools dc and bc
.sp 1
.ne 5
.ti -3
DIAGNOSTICS
.br
.in +3
.ti -3
arith evaluation stack overflow
.br
arithmetic expressions have been nested too deeply.
The size of the stack is set by the MAXSTACK definition
in the source code.

.ti -3
number error
.br
an input number has a number/character bigger than the current
radix
.sp
.ne 2
.ti -3
expression error
.br
invalid arithmetic expression
.in -3
.sp 1
.ti -3
AUTHOR
.br
Philip H. Scherrer (Stanford U.)
.sp 1
.ti -3
BUGS/DEFICIENCIES
.br
Dc only works with integers

The maximum value allowed depends on the host machine and is the
largest Fortran integer
#-t-  dc.doc                     5107  local   12/10/80  15:52:55
#-h-  detab.doc                   977  local   12/10/80  15:52:59
.bp 1
.in 0
.he 'DETAB (1)'8/20/79'DETAB (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
detab - convert tabs to spaces
.sp 1
.in
SYNOPSIS
.br
.in 7
detab [<t1>...] [+<n>] [file...]
.sp 1
.in
DESCRIPTION
.br
.in 7
Detab converts tab characters (control-i) to equivalent strings
of blanks.
Tab stops are indicated by <t1>...
(default 8, 16, ...),
while +<n> indicates tab stops
every <n> columns.
Thus the command

.ti +3
detab 5 21 +5

supplies blanks for tabs terminating at column positions 5, 21, 26, etc.
If no files are specified, the standard input is read.
An isolated minus sign also indicates the standard input.
.sp 1
.in
SEE ALSO
.br
.in 7
entab
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Original from Kernighan & Plauger's 'Software Tools', with modifications
by Dennis Hall and Debbie Scherrer (Lawrence Berkeley Laboratory)
#-t-  detab.doc                   977  local   12/10/80  15:52:59
#-h-  diff.doc                   3386  local   01/06/81  22:52:00
.bp 1
.in 0
.he 'DIFF (1)'3/20/80'DIFF (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
diff - isolate differences between files
.nf
.sp
.ti -3
SYNOPSIS
.br
diff [-{c|d|r|s|v}] <old_file> [<new_file>]
.fi
.sp
.ti -3
DESCRIPTION
.br
'Diff' compares the contents of two files
and reports on the differences between them.
The default behavior is to describe the insert, delete, and change
operations that must be performed on <old_file> to convert its
contents into those of <new_file>.
[Editor's note:  the default output is evidently only useful
at Georgia Tech.  The tool should generally be called by 'diff -s'
to produce an editor script, or 'diff -cv' to produce
output similar to that generated by the tool 'cmp'.]
.sp
The second file name argument is optional.
If omitted, the standard input is read for the text of the <new_file>.
.sp
The options currently available are:
.in +10
.rm -5
.sp
.ti -5
-c   Perform a simple line-by-line comparison.
'Diff' will compare successive lines of the input files;
if any corresponding lines differ,
or if one file is shorter than the other,
'diff' prints the message
"different" and exits.
If the files are the same, 'diff' produces no output.
When the "-v" option (see below) is specified,
'diff' prints the lines that differ along with their line
number in the input file, and notifies the user if
one file is shorter than the other.
.sp
.ti -5
-d   List the "differences" between the two files, by highlighting
the insertions, deletions, and changes that will convert <old_file>
into <new_file>.  This is the default option.
If the "verbose" option "-v" (see below) is specified, unchanged
text will also be listed.
.sp
.ti -5
-r   Insert text formatter requests to mark the <new_file>
with revision bars and deletion asterisks.
This option is particularly useful for maintenance of large documents,
like Software Tools reference manuals.
(At present, only GT's version of 'format' can produce revision bars.)
.sp
.ti -5
-s   Output a "script" of commands for the text editor 'ed' that will
convert <old_file> into <new_file>.
This is handy for preparing updates to large programs or data files,
since generally the volume of changes required will be much smaller
than the new text in its entirety.
.sp
.ti -5
-v   Make output "verbose."
This option applies to the "-c" and "-d" options discussed above.
If not selected, 'diff' produces "concise" output;
if selected, 'diff' produces more verbiage.
.sp
.in -10
.rm +5
'Diff' is based on the algorithm found in
Heckel, P., "A Technique for Isolating Differences Between Files",
.ul
Comm. ACM
21, 4 (April 1978), 264-268.
.sp
Examples:
.sp
.nf
diff myfile1 myfile2
diff rf.r nrf.r | pg
diff -c afile maybe_the_same_file
diff -v rf.r nrf.r | sp
diff -r old_manual.fmt new_manual.fmt | fmt
diff -s old new >>update_old_to_new
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
"<file>:  can't open" if either <new_file> or <old_file> is not readable.
.br
"Usage: diff . . ." for illegal options.
.br
.in -3
.fi
.sp
.ne 4
.ti -3
AUTHORS
.br
Allen Akin and friends, Georgia Institute of Technology
.sp
.ne 2
.ti -3
BUGS/DEFICIENCIES
.br
The algorithm used has one quirk: a line or a block of lines which
is not unique within a file will be labeled as an insertion (deletion)
if its immediately adjacent neighbors both above and below are labeled
as insertions (deletions).
.sp
Fails on very large files (> 10000 lines).
#-t-  diff.doc                   3386  local   01/06/81  22:52:00
#-h-  echo.doc                    622  local   12/10/80  15:53:02
.bp 1
.in 0
.he 'ECHO (1)'07/07/78'ECHO (1)'
.fo ''-#-''
.fi
.in 7
.ti -3
NAME
.br
echo - echo command line arguments
.sp 1
.ti -3
SYNOPSIS
.br
.bd
echo
[arg ...]
.sp 1
.ti -3
DESCRIPTION
.br
.bd
Echo
writes its arguments in order as a line on the standard output
file.
It is useful for producing messages and diagnostics in command
files
and for inserting single lines of text into files.
.sp 1
.ti -3
FILES
.br
None
.sp 1
.ti -3
SEE ALSO
.br
The Unix command 'echo' in the Unix manual
.sp 1
.ti -3
DIAGNOSTICS
.br
None
.sp 1
.ti -3
AUTHORS
.br
Debbie Scherrer  (Lawrence Berkeley Lab)
.sp 1
.ti -3
BUGS/DEFICIENCIES
.br
#-t-  echo.doc                    622  local   12/10/80  15:53:02
#-h-  ed.doc                    17387  local   01/09/81  00:39:11
.bp 1
.in 0
.he 'ED (1)'04/21/78'ED (1)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
ed - text editor
.sp 1
.ti -7
SYNOPSIS
.br
ed [-] [file]
.sp 1
.ti -7
DESCRIPTION
.br
Ed is a text editor.
If the 'file' argument is given, the file is read into ed's
buffer so that it can be edited
and its name is remembered for possible future use.
Ed operates on a copy of any file it is editing; changes made
in the copy have no effect on the file until a w (write)
command is given.

The optional '-' suppresses the printing of line counts by the e (edit),
r (read), and w (write) commands.

Ed accepts commands from script files as well as a terminal.
To do this, invoke ed and substitute the script file name for
the standard input, as follows -

                        ed [file] <script

Commands to ed have a simple and regular structure: zero, one, or two
line addresses followed by a single character command, possibly
followed by parameters to the command.  The structure is:

               [line],[line]command <parameters>

The '[line]' specifies a line number or address in the buffer.
Every command which requires addresses has default addresses,
so the addresses can often be omitted.

Line addresses may be formed from the following components:

.nf

           17           an integer number
           .            the current line
           $            the last line in the buffer
           .+n          "n" lines past the current line
           .-n          "n" lines before the current line
           /pattern/    a forward context search
           \pattern\    a backward context search

.fi
Line numbers may be separated by commas or semicolons;
a semicolon sets the current line to the previous address
before the next address is interpreted.  This feature can
be used to determine the starting line for forward and
backward context searches ("/" and "\").


.ne 6
.ce
REGULAR EXPRESSIONS

Ed supports a form of regular expression notation for
specifying patterns in line addresses and in the s command.
A regular expression specifies a set of strings of characters.
That is, regular expressions can be created which can
be used to locate or change
patterns only at particular positions on a line,
patterns which contain certain characters plus perhaps others,
or that match text of indefinite length.
Regular expressions are constructed as follows:

1.  An ordinary character (not one of those discussed below) is a
regular expression and matches that character.

2.  A percent "%" at the beginning of a regular expression matches
the empty string at the beginning of a line.

3.  A dollar sign "$" at the end of a regular expression matches
the null character at the end of a line.

4.  A question mark "?" matches any character except a newline
character.

5.  A regular expression followed by an asterisk "*" matches any
number of adjacent occurrences (including zero) of the regular
expression it follows.

6.  A string of characters enclosed in square brackets "[ ]" matches
any character in the string but no others.  If, however, the first
character of the string is an exclamation point "!" the regular
expression matches any character
except
the characters in the string (and the newline).

7.  The concatenation of regular expressions is a regular expression
which matches the concatenation of the strings matched by the components
of the regular expression.

8.  The null regular expression standing alone is equivalent to the
last regular expression encountered.

9.  Parts of a text pattern may be marked or 'tagged' so that
pieces of a matched string can be put back selectively or rearranged.
A text pattern surrounded by braces ( { and } ) is
remembered and can be
referred to by '@n', where 'n' is a single digit referring to
the string remembered by the nth pair of braces.
For example,
.sp
.ce
s/{???}{?*}/@2@1/
.sp
moves a three-character sequence from the beginning of
a line to the end.
.sp
If it is desired to use one of the regular expression metacharacters
as an ordinary character, that character may be escaped
by preceding it with an
atsign "@".

For example, the regular expression
.sp
.ce
/%a?*b/
.sp
would search for a line which began with "a" and had a "b" in
it, possibly with other characters between "a" and "b".
.bp
.ce
COMMANDS

Following is a list of ed commands.  Default addresses are shown
in parentheses:

(.)a
.br
<text>
.br
.cc +
.
+cc .
.br
.in +5
The append command reads the given text and appends it after the addressed
line.
'.' is left on the last line input, if there were any, otherwise at
the addressed line.
.br
.in -5

(.)b[+/./-][<screensize>]
.br
.in +5
The browse command is a shorthand command to print out a screenful
of data.  It has three basic forms, any of which may have a
number ("screensize") appended to it.
a
The default screensize is 23.
A simple "b" (or b+) prints the the current line and the screenful
after it.
A "b-" prints the screen of text preceding (and including) the
addressed line.
A "b." prints the screen centered on the addressed line.
"." is always
left at the last line printed.  If a screensize is specified, it
becomes the default screensize for the rest of the editing session or
until changed again.
.br
.in -5

(.,.)c
.br
<text>
.br
.cc +
.
+cc .
.br
.in +5
The change command deletes the addressed lines, then accepts input text
which replaces these lines.  '.' is left at the last line input, if
there were any, otherwise at the first line not deleted.
.br
.in -5

(.,.)d
.br
.in +5
The delete command deletes the addressed lines from the buffer.
The line originally AFTER the last line deleted becomes the current line;
however, if the lines deleted were originally at the end, the new last line
becomes the current line.
.br
.in -5

e filename
.br
.in +5
The edit command causes the entire contents of the buffer to be deleted
and then the named file to be read in.
'.' is set to the last line of the buffer.
The number of lines read is typed.
'Filename' is remembered for possible use as a default file name in
a subsequent
r
or
w
command.

.in -5
f filename
.br
.in +5
If 'filename' isn't given, the command prints the currently
remembered file name.
If 'filename' is given, the currently remembered file name is
changed to 'filename'.
.br
.in -5

(1,$)g/regular expression/command
.br
.in +5
In the global command, the given command is executed for every
line which matches the given regular expression.
Multiple commands may be executed by placing each on a preceding
line and terminated each command except the last with an
atsign '@'.
.br
.in -5

(.)i
.br
<text>
.br
.cc +
.
+cc .
.br
.in +5
The insert command inserts the given text BEFORE the addressed line.
'.' is left at the last line input, or if there were none, at the
addressed line.
This command differs from the
"a"
command only in the placement of text.
.br
.in -5

(.,.)k<address>
.br
.in +5
The kopy command copies the addressed lines to the position after
the line
specified by
<address>.
The last of the copied lines becomes the current line.
.br
.in -5

(.,.)m<address>
.br
.in +5
The move command repositions the addressed lines after the line
specified by
<address>.
The last of the moved lines becomes the current line.
.br
.in -5

(.,.)p
.br
.in +5
The print command prints the addressed lines.  '.' is left at the
last line printed.
The
p
command may be placed on the same line after any other command
to cause printing of the last line affected by the command.
.br
.in -5

q
.br
.in +5
The quit command causes ed to exit.
If the file hasn't been written since it was changed, the
user is reminded to do so.
.br
.in -5

(.)r filename
.br
.in +5
The read command reads in the given file after the addressed line.
If no file name is given, the remembered file name is used (see
e
and
f
commands).
The remembered file name is not changed.
Address '0' is legal for this command and causes the file to be
read in at the beginning of the buffer.
If the read is successful, the number of lines read is typed.
'.' is left at the last line read in from the file.
.br
.in -5

(.,.)s/regular expression/replacement/       or,
.br
(.,.)s/regular expression/replacement/g
.br
.in +5
The substitute command searches each addressed line for an occurrence
of the specified regular expression.
On each line in which a match is found, the first occurrence of the
expression is replaced by the replacement specified.
If the global replacement indicator
g
appears after the command, all occurrences of the regular
expression are replaced.
Any character other than space or newline may be used instead of
the slash '/' to delimit the regular expression and replacement.
A question mark '?' is printed if the substitution fails on all
addressed lines.
'.' is left at the last line substituted.
If the regular expression is not specified (e.g. s//pat/),
the last regular expression given is used.

An ampersand '&' appearing in the replacement is replaced by
the string matching the regular expression.
(The special meaning of '&' in this context may be suppressed by
preceding it by '@'.)

Lines may be split or merged by using the symbol '@n' to stand
for the newline character at the end of a line.
.br
.in -5


(1,$)w filename
.br
.in +5
The write command writes the addressed lines onto the given file.
If the file does not exist, it is created.
The remembered file name is
not
changed.
If no file name is given, the remembered file name is used (see
the
e
and
f
commands).
'.' is left unchanged.
If the command is successful, the number of lines written is typed.
.br
.in -5

(1,$)x/regular expression/command
.br
.in +5
The except command is the same as the global command except that the
command is executed for every line
except
those matching the regular expression.

.in -5
(.)=
.br
.in +5
The line number of the addressed line is typed.
'.' is left unchanged.
.br
.in -5

# comment
.br
.in +5
The remainder of the line after the "#" is a comment and ignored by
the editor.  This allows ed scripts to be commented for future
enlightenment.
.br
.in -5

@shell command
.br
.in +5
The remainder of the line after the "@" is sent to the shell as a
command.  If there is nothing else on the line but a bare "@", the
shell will be spawned, allowing a number of commands to be
performed; when that shell quits, the terminal is returned to the
editor.  "." is left unchanged.
.br
.in -5

(.+1)<carriage return>
.br
.in +5
An address alone on a line causes the addressed line to be printed.
A blank line alone is equivalent to '.+1' and thus is useful
for stepping through text.
.in -5
.br
$n
.br
.in +5
Several temporary buffers (i.e. files) are available for
writing into and reading from.
The buffers are referred to as $1, $2, ...$n (where n is
determined by the MAXTBUFS definition in the source code).
These buffers can be used wherever a normal file name may appear.
For example,
.br
.ce 2
1,10w $1
r $1
.fi
If the shell has been implemented, these buffers are also available
to the shell via:
.br
.ce
@tool $1 $2 ...
.br
.in -5
.sp 1
.ti -7
FILES
.br
A temporary file is used to hold
the text being edited ("eds")
.sp
Scratch files named edn, where 1 <= n <= MAXTBUFS, are created
for temporary buffers.
.sp 1
.ti -7
SEE ALSO
.br
.nf
sedit
The "edit" primer
The Unix command "ed" in the Unix manual
"A Tutorial Introduction to the ED Text Editor" by B. W. Kernighan
Kernighan and Plauger's "Software Tools", pages 163-217
"Edit is for Beginners" by David A. Mosher (available from
             UC Berkeley Computer Science Library)
"Edit:  A Tutorial" (also available from the
             UC Berkeley Computer Science Library)
.fi
.sp 1
.ne 5
.ti -7
DIAGNOSTICS
.br
file size exceeded
.br
.in +5
printed whenever the maximum number of lines allowed has been
exceeded.
The number of lines allowed is determined by the MAXBUF
definition in the source code.
.in -5
.sp
A message is printed whenever the user attempts to quit without
writing a file that was changed.
The user must retype the command as a verification.
.sp
The error message "?" is printed whenever an edit command
fails or is not understood.
.sp 1
.ti -7
AUTHORS
.br
Original code by Kernighan and Plauger with modifications
by Debbie Scherrer, Dennis Hall and Joe Sventek
(Lawrence Berkeley Laboratory)
.sp 1
.ti -7
CHANGES
.br
This editor differs from the one originally provided in
.ul
Software Tools
in the following ways:
.sp
.in +5
Both upper and lower case commands are recognized.
.sp
The primitive 'note' has been included to allow random access
to files on systems where a character count alone would not
be sufficient.
.sp
The storage of line pointers in the line buffer has been condensed
and recovery of space used by deleted pointers has been implemented.
Searching of the line pointer array has been optimized
a bit.
.sp
The user is reminded to rewrite a file if necessary before he quits.
.sp
The "b", "k", "@tool" commands have been included,
as well as temporary buffers and
comments.
.sp
Multiple commands to be executed upon a single global search have been
added.
.sp
Tagged patterns have been added.
.sp 1
.in -5
.ti -7
BUGS/DEFICIENCIES
.br
There is a limit to the number of lines in files being edited.

When a global search and substitute combination fails, the
entire global search stops.
.sp
There are several discrepancies between this editor and Unix's ed.
These include:

.in +5
1.  Unix uses 'v' instead of 'x' for the except command.

2.  Unix uses a caret (^) instead of percent (%) for
the beginning-of-line character.

3.  Unix uses '.' instead of '?' to indicate a match of any character.

4.  Unix uses a caret (^) instead of an exclamation mark (!) to
indicate exclusion of a
character class.

5.  Unix uses backslash (\) instead of atsign (@) for the
escape character.

6.  Unix uses a questions mark (?) instead of a backslash (\)
to delimit a backward search pattern.

7.  The Unix 'r' command uses the last line of the file, instead
of the current line, as the default address.

8.  The Unix editor prints the number of characters, rather than
lines read or written when dealing with files.
.in -5
.sp
Problems sometimes occur when removing or inserting NEWLINE
characters (via @n), especially in global commands.
.sp 2
.ne 19
.in 0
.ce
SUMMARY OF SPECIAL CHARACTERS

.fi
The following are special characters used by the editor:

 Character       Usage
 ---------       -----
.br
    ?            Matches any character (except newline)
.br
    %            Indicates beginning of line
.br
    $            Indicates end of line or end of file
.br
    [...]        Character class
                 (any one of these characters)
.br
    [!...]       Negated character class
                 (any character except these)
.br
    *            Closure (zero or more occurences of
                 previous pattern)
    {...}        Tagged pattern
.br
    @            Escaped character (e.g. @%, @[, @*)
.br
    &            Ditto, i.e. whatever was matched
.br
    c1-c2        Range of characters between c1 and c2
.br
    @n           Specifies the newline mark at the end of a line
.br
    @t           Specifies a tab character
.bp
.in 0
.ce
COMMAND SUMMARY
.sp
.in 5
.nf
.ti -5
Addresses:
.br
 17      a decimal number
 .       the "current" line
 $       the last line of the file
 /pat/   search forward for line containing pat
 \pat\   search backward for line containing pat
 line+n  n lines forward from line
 line-n  n lines backward from line
.sp
.ti -5
Defaults:
.br
 (.)     use current line
 (.+1)   use the next line
 (.,.)   use current line for both line numbers
 (1,$)   use all lines
.sp
.ti -5
Commands:
.br
 (.)     a               append text after line
                         (text follows)
 (.,.n)  b n             browse at next "n" number of lines (default
                         n is 22).  If n is negative, print last n
                         lines before current line.  If "b." is
                         specified, print n lines with current
                         line in center of screen.
 (.,.)   c               change text (text follows)
 (.,.)   d               delete text
         e file          discard current text, enter file,
                         remember file name
         f               print file name
         f file          remember file name
 (.)     i               insert text before line (text follows)
 (.,.)   k line3         copy text to after line3
 (.,.)   m line3         move text to after line3
 (.,.)   p               print text (can be appended to other commands)
         q               quit
 (.)     r file          read file, appending after line
 (.,.)   s/pat/new/gp    substitute new for leftmost pat
                         (g implies all occurrences)
 (1,$)   w file          write file, leave current text unaltered
                         (if "file" isn't given, write to current
                         filename)
 (.)     =p              print line number, current line
 (.+1)   <CR>            print next line
 (1,$)   g/pat/command   do command on lines containing pat
                         (except a, c, i, q commands)
 (1,$)   x/pat/command   do command on lines not containing pat
                         (except a, c, i, q commands)
         # .....         comment
         @command        spawn the shell and execute "command"
         $n              write to/read from temporary buffer "n"
.in 0
.fi
#-t-  ed.doc                    17387  local   01/09/81  00:39:11
#-h-  edin.doc                   3056  local   12/10/80  15:53:14
.bp 1
.in 0
.he 'EDIN (1)'7/2/80'EDIN (1)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
edin - in-core text editor
.sp 1
.ti -7
SYNOPSIS
.br
edin [file]
.sp 1
.ti -7
DESCRIPTION
.br
Edin is a simple version of the text editor which keeps the entire
file in a buffer in core (as opposed to storing it on a scratch
file).
It thus can handle only small files.
It is included only as a temporary editor to use while
implementing the full-fledged version of ed.
.sp 1
.ti -7
FILES
.br
None
.sp 1
.ti -7
SEE ALSO
.br
ed (or edit), sedit, find, ch
.br
Kernighan and Plauger's "Software Tools", pages 163-208
.fi
.sp 1
.ne 5
.ti -7
DIAGNOSTICS
.br
file size exceeded
.br
.in +5
printed whenever the maximum number of characters allowed has been
exceeded.
The size of the in-core buffer is determined by the MAXBUF
definition in the source code.
.in -5
.sp
The error message "?" is printed whenever an edit command
fails or is not understood.
.sp 1
.ti -7
AUTHORS
.br
Straight from "Software Tools", with few changes and
very little testing.
.sp
.ti -7
CHANGES
.br
This editor is basically the one provided in the book
except that it has been taught to read both upper and
lower case commands and it prints a message when the
file is too big to fit in the buffer.
.sp
.ti -7
BUGS/DEFICIENCIES
.br
Who knows....
.sp 2
.ne 45
.in 0
.ce
COMMAND SUMMARY
.in 5
.sp
.nf
.ti -5
Addresses:
.br
 17      a decimal number
 .       the "current" line
 $       the last line of the file
 /pat/   search forward for line containing pat
 \pat\   search backward for line containing pat
 line+n  n lines forward from line
 line-n  n lines backward from line
.sp
.ti -5
Defaults:
.br
 (.)     use current line
 (.+1)   use the next line
 (.,.)   use current line for both line numbers
 (1,$)   use all lines
.sp
.ti -5
Commands:
.br
 (.)     a               append text after line
                         (text follows)
 (.,.)   c               change text (text follows)
 (.,.)   d               delete text
         e file          discard current text, enter file,
                         remember file name
         f               print file name
         f file          remember file name
 (.)     i               insert text before line (text follows)
 (.,.)   m line3         move text to after line3
 (.,.)   p               print text (can be appended to other commands)
         q               quit
 (.)     r file          read file, appending after line
 (.,.)   s/pat/new/gp    substitute new for leftmost pat
                         (g implies all occurrences)
 (1,$)   w file          write file, leave current text unaltered
                         (if "file" isn't given, write to current
                         filename)
 (.)     =p              print line number, current line
 (.+1)   <CR>            print next line
 (1,$)   g/pat/command   do command on lines containing pat
                         (except a, c, i, q commands)
 (1,$)   x/pat/command   do command on lines not containing pat
                         (except a, c, i, q commands)
.in 0
.fi
#-t-  edin.doc                   3056  local   12/10/80  15:53:14
#-h-  entab.doc                  1034  local   12/10/80  15:53:15
.bp 1
.in 0
.he 'ENTAB (1)'8-20-79'ENTAB (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
entab - convert spaces to tabs and spaces
.sp 1
.in
SYNOPSIS
.br
.in 7
entab [<t1> ...] [+<n>] [file ...]
.sp 1
.in
DESCRIPTION
.br
.in 7
Entab replaces strings of blanks with equivalent tabs (control-i)
and blanks.
It can be used to read files and produce typewriter-like
text, reducing file size.
Tab stops are indicated by <t1> ... (default 8, 16, ...),
while +<n> indicates tab stops every <n> columns.
Thus the command

.ti +3
entab 5 21 +5

would insert tab stops at columns 5, 21, 26, etc.
If no files are specified, the standard input is read.
An isolated minus sign also indicates the standard input.
.sp 1
.in
SEE ALSO
.br
.in 7
detab
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Original from Kernighan & Plauger's 'Software Tools', with modifications
by Dennis Hall (Lawrence Berkeley Laboratory)
#-t-  entab.doc                  1034  local   12/10/80  15:53:15
#-h-  expand.doc                  700  local   12/10/80  15:53:16
.bp 1
.in 0
.he 'EXPAND (1)'1.15.79'EXPAND (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
expand - uncompress input files
.sp 1
.in
SYNOPSIS
.br
.in 7
.bd
expand
[file ...]
.sp 1
.in
DESCRIPTION
.br
.in 7
.bd
Expand
expands files previously compressed by 'cpress'.
If no input files are given, or if the filename '-' appears,
input will be read from the standard input.
.sp 1
.in
FILES
.br
.in 7
.sp 1
.in
SEE ALSO
.br
.in 7
cpress
.sp 1
.in
DIAGNOSTICS
.br
.in 7
A message is printed if an input file cannot be opened; further
processing is terminated.
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Original from Kernighan & Plauger's 'Software Tools', with minor
modifications by Debbie Scherrer.
.sp 1
.in
BUGS
.br
.in 7
#-t-  expand.doc                  700  local   12/10/80  15:53:16
#-h-  fb.doc                     3916  local   12/10/80  15:53:17
.bp 1
.in 0
.he 'FB (1)'5/28/80'FB (1)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
fb - search blocks of lines for text patterns
.sp 1
.ti -7
SYNOPSIS
.br
.bd
fb
[-acx] [-ln] [-sexpr [-sexpr]] expr [expr ...]
.sp 1
.ti -7
DESCRIPTION
.br
"Fb"
(find block) searches blocks or groups of lines in a file for
text patterns.
It is similar to 'find' except that if a pattern is found,
the entire block of lines is copied to standard output,
rather than simply the line in which the pattern occurred.
Thus it is useful for searching mailing lists, bibliographies,
and similar files where several lines are grouped together to
form cohesive units.

The search patterns may be any regular expression as described
in the 'ed' and 'find' writeups.

"Fb"
assumes the blocks of lines are separated by an empty line or a
line containing only blanks.
When "fb" is called without any options, standard input is read
and each line is checked to see if it matches any of the regular
expressions given as arguments.
If any matches are found,
the entire block is printed on standard output.

Other options include:

.in +10
.ti -8
-a      Only print the block if ALL the arguments are found within it

.ti -8
-x      Only print the block if none of the arguments are
found within it

.ti -8
-c      Only print a COUNT of the number of blocks found which
match/don't match the expressions

.ti -8
-sexpr  Use 'expr' as the block separator (instead of a blank or
empty line).  "Expr" can be a regular expression just as
the search arguments can.

If two "-sexpr" arguments are given, the first one is considered
to be the pattern which starts a block (e.g. -ssubroutine) and
the second is considered the pattern which ends a block
(e.g. -send).

.ti -8
-ln     prints only the first 'n' lines of the block;
if the block contains less than 'n' lines, the block is padded
out with blank lines.
.in -10

.fi
Care should be taken when using the characters % $ [ ] ! * @ and
any shell characters
in the text pattern. It is often necessary to enclose the
entire substitution pattern in quotes.
.sp 1
.ti -7
FILES
.br
A scratch file ("fbt") is used if the internal line buffer
becomes full.
.sp 1
.ti -7
SEE ALSO
.br
find, ed
.br
For a complete description of regular expressions, see
"Software Tools" pages 135-154.
.sp 1
.ti -7
DIAGNOSTICS
.br
Error messages are given if:
.br
.in +3
a)  One of the patterns given is illegal
.br
b)  Too many separators are given (2 are allowed)
.br
c)  The maximum number of expressions is exceeded (9 are allowed)
.br
d)  There are problems opening the scratch file (when the block line
buffer fills up).

.in -3
If the following messages show up, something is dreadfully wrong:
.in +3
a)  "Illegal default separator"
.br
b)  "Block buffer overflow"
.in -3
.sp 1
.ti -7
AUTHORS
.br
Debbie Scherrer (Lawrence Berkeley Laboratory)
.sp 1
.ti -7
BUGS
.br
An expression may not start with a minus sign (-).

Regular expressions can not span line boundaries.
#-t-  fb.doc                     3916  local   12/10/80  15:53:17
#-h-  field.doc                  2209  local   12/22/80  16:21:15
.bp 1
.in 0
.he 'FIELD (1)'7/10/80'FIELD (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
field - manipulate fields of data
.nf
.sp
.ti -3
SYNOPSIS
.br
field [-t[c] | fieldlist] outputformat [file ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
.fi
Field
is used to manipulate data kept in formatted fields.
It selects data from certain fields of the input files
and copies it to certain places in the standard output.

The 'fieldlist' parameter is used to describe the interesting
columns on the input file.
Fields are specified by naming the columns in which they
occur (e.g. 5-10) or the columns in which they start and
an indication of their length (e.g. 3+2, meaning a field
which starts in column 3 and spans 2 columns).
When specifying more than one field, separate the specs
with commas (e.g. 5-10,16,72+8)
Fields may overlap, and need not be in ascending numerical order
(e.g. 1-25,10,3 is OK).

If input fields do not fall in certain columns, but rather are
separated by some character (such as a blank or a comma),
describe the fields by using the '-tc' flag, replacing 'c'
with the appropriate
separator (a tab character is the default).

Once fields have been described with either the '-tc' flag
or a fieldlist, they can be arranged on output by
the 'outputformat' argument.
This argument is actually a picture of what the output line
should look like.
Fields from input are referred to as $1, $2, $3, etc., referring
to the first, second, third, etc. fields that were specified.
(Up to 9 fields are allowed, plus the argument $0 which
refers to the whole line.)
These $n symbols are placed in the output format wherever
that field should appear, surrounded by whatever characters
desired.
For example, an outputformat of:
.ce
           "$2 somewords $1"
would produce an output line such as:
.ce
            field2 somewords field1

If no input files are specified, or if the filename '-' is
found, field will read from the standard input.
.sp
.ti -3
DIAGNOSTICS
.br
illegal field specification
.in +5
The fieldlist specification was in error, probably because
it contained letters or some other
illegal characters
.in -5
.sp
.ti -3
SEE ALSO
.br
sedit
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  field.doc                  2209  local   12/22/80  16:21:15
#-h-  find.doc                   3853  local   12/10/80  15:53:20
.bp 1
.in 0
.he 'FIND (1)'03/03/78'FIND (1)
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
find - search a file for text patterns
.sp 1
.ti -7
SYNOPSIS
.br
.bd
find
[-acx] expr [expr ...]
.sp 1
.ti -7
DESCRIPTION
.br
.bd
find
searches the standard input file for lines matching the text patterns
"expr" (up to 9 patterns may be specified) according to the matching
criterion specified by the switches.  (A text pattern is a subset of a
"regular expression"--see the writeup on "ed" for a complete description
of regular expressions.)  Unless the -c option is specified, each matching
line is copied to the standard output.

By default, any line which matches any one of the expressions is considered
a matching line.  If the -a flag is specified, only lines which match all
expressions in any order are considered to match.  If the -x flag is
specified, all lines which don't satisfy the above criteria are considered
matching lines.  And finally, if the -c option is specified, matching
lines are counted instead of being copied to the standard output, and the
final count is written to the standard output.

A text pattern consists of the following elements:

.nf
c         literal character
?         any character except newline
%         beginning of line
$         end of line (null string before newline)
[...]     character class (any one of these characters)
[!...]    negated character class (all but these characters)
*         closure (zero or more occurrences of previous pattern)
@c        escaped character (e.g., @%, @[, @*)

.fi
Any special meaning of characters in a text pattern is lost when
escaped, inside [...], or for:

.nf
%         not at beginning
$         not at end
*         at beginning

.fi
A character class consists of zero or more of the following
elements, surrounded by [ and ]:

.nf
c         literal character, including [
a-b       range of characters (digits, lower or upper case)
!         negated character class if at beginning
@c        escaped character (@! @- @@ @])

.fi
Special meaning of characters in a character class is lost when
escaped or for

.nf
!         not at beginning
-         at beginning or end

.fi
An escape sequence consists of the character @ followed by a single
character:

.nf
@n        newline
@t        tab
@c        c (including @@)

.fi
For a complete description, see "Software Tools" pages 135-154.
Care should be taken when using the characters % $ [ ] ! * @ and
any shell characters
in the text pattern. It is often necessary to enclose the
entire substitution pattern in quotes.
.sp 1
.ti -7
FILES
.br
None
.sp 1
.ti -7
SEE ALSO
.br
tr, ed, ch and the UNIX grep command.
.sp 1
.ti -7
DIAGNOSTICS
.br
An error message is printed if one of the patterns given is illegal.
.sp 1
.ti -7
AUTHORS
.br
Originally from Kernighan & Plauger's "Software Tools", with major
modifications by Joe Sventek (Lawrence Berkeley Laboratory)
#-t-  find.doc                   3853  local   12/10/80  15:53:20
#-h-  format.doc                 7939  local   12/10/80  15:53:22
.bp 1
.in 0
.he 'FORMAT (1)'3/12/80'FORMAT (1)'
.fo ''-#-''
.sp 2
.in +3
.fi
.ti -3
NAME
.br
format (roff) - format text
.nf
.sp
.ti -3
SYNOPSIS
.br
format [+n] [-n] [-s] [-pon] [files...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Format
formats text according to
request lines
embedded in the text of
the given
files or standard input if no files are given.
If nonexistent filenames are encountered they are
ignored.  The optional flags are as follows:
.in +5
.sp
.ti -5
+n   Start printing at the first page with number "n".
.sp
.ti -5
-n   Stop printing at the first page numbered higher than "n".
.sp
.ti -5
-s   Stop before each page, including the first (useful for
paper manipulation).
The prompt "Type return to begin a page" is
given just once before the first page.
.sp
.ti -5
-pon Move the entire document "n" spaces (default=0) to the right
("page offset").
.sp
.in -5
Input consists of intermixed text lines,
which contain information to be
formatted, and request lines, which contain
instructions about how to format
the text lines.
Request lines begin with a distinguishing "control character", normally
a period.
.sp
Output lines are automatically "filled"; that is, their
right margins are justified, without regard to the format of
the input text lines.
(Right justification may be turned on and off through
the use of the ".ju" and ".nj" commands, though.)
Strings of embedded spaces are retained so that the
output line will contain at least as many spaces between words
as the input line.
However, input lines beginning with a space are output without
modification.

Line "breaks" may be caused at specified places by certain commands,
or by the
appearance of an empty input line or an input line
beginning with a space.
.sp
Because of the nature of its output (backspace and tab characters
and a fixed number of lines per page), it is generally necessary
to have a tool developed especially for printing the output
on the local printers.
On most systems this is a combination of the tools 'os' and
'detab', plus some sort of page eject control of the printer.
If such as tool exists, it should be described in Section 3 of
this manual.
.sp
The capabilities of format are specified in the attached
Request Summary.
Numerical values are denoted by "n", titles by "t", and single
characters by "c".
Numbers may be signed + or -, in which case they signify
relative changes to a quantity; otherwise they signify an absolute
setting.
Missing "n" fields are ordinarily taken to be 1,
missing "t" fields to be
empty, and "c" fields to shut off the
appropriate special interpretation.
.sp
Running titles may appear at the top and bottom of every page.
A title line consists of a line with three distinct fields:
the first is text to be placed flush with the left margin, the
second centered, and the third flush with the right margin.
The first non-blank character in the title will be used as the
delimiter to separate the three fields.
Any "#" characters in a title  are replaced by the
current page number, and
any "%" characters are replaced by the current date.
.sp
The ".nr" defines number registers; there are 26 registers named a-z.
The command ".nr x m" sets number register x to m; ".nr x +m"
increments number register by m; and ".nr x -m" decrements x by m.
The value of number register x is placed in the text by the
appearance of @@nx; a literal @@ may be inserted using @@@@.
.sp
Additional commands may be defined using ".de xx".  For
example,
.sp
.in +3
.nf
.cc +
.de PG
.sp
.ti +3
.en
+cc .
.in -3
.sp
.fi
defines a "paragraph" command PG.
Defined commands may also be invoked with arguments.
Arguments are separated by blanks or tabs.
Within the
definition of a defined command, arguments are referenced using
$1, $2, etc.  There is a maximum of 9 arguments.
Omitted arguments default to the null string.
$0 references
the command name itself.
For example, the following version of the paragraph command
uses the argument to determine the amount of indentation.
.sp
.in +3
.nf
.cc +
.de PG
.sp
.ti +$1
.en
+cc .
.in -3
.sp
.fi
This command could be invoked by
.sp
.in +3
.nf
.cc +
.PG 3
+cc .
.in -3
.sp
.fi
to get the same effect as the previous version.
.sp
The ".so file" command causes the contents of file to be
inserted in place of the ".so" command; ".so" commands may be
nested.
.sp
.ti -3
FILES
.br
None
.sp
.ti -3
SEE ALSO
.br
Kernighan & Plauger's "Software Tools", pages 219-250
.br
whatever tool has been devised for printing formatted output
.br
The roff and nroff/troff UNIX commands
.br
The "nroff" and "troff" users manuals by Joseph F. Ossana,
Bell Laboratories, Murray Hill, New Jersey
.sp
.ti -3
DIAGNOSTICS
.br
.in +3
.ti -3
invalid number register name
.br
names of number registers must be a single letter a-z

.ti -3
missing name in command definition
.br
a macro was defined using the '.de' command, but no 2-letter
name for it was given

.ti -3
so commands nested too deeply
.br
the limit for nesting included source files is dependent upon
the MAXOFILES definition in the standard symbols definition file

.ti -3
too many characters pushed back
.br
the buffer holding input characters has been exceeded; its size
is determined by the BUFSIZE definition in the source code
.in -3
.sp
.ti -3
AUTHORS
.br
Original version by Kernighan and Plauger, with modifications by
David Hanson and friends (U. of Arizona), Joe Sventek
and Debbie Scherrer (Lawrence Berkeley Laboratory)
.nf
.ne 38
.in 0
.ce
.sp
REQUEST SUMMARY
.sp
Request Initial Default Break Meaning
.sp
.cc +
.bd n           n=1     no    boldface the next n lines
.bp n     n=1   n=+1    yes   begin new page and number it n
.br                     yes   break
.cc c     c=.   c=.     no    control character becomes c
.ce n           n=1     yes   center the next n input lines
.cu n           n=1     no    continuously underline next n
+ti +30
input lines
.de xx                  no     command xx; ends at .en
.ef t     t=""  t=""    no    foots on even pages are t
.eh t     t=""  t=""    no    heads on even pages are t
.en                     no    terminate command definition
.fi       yes           yes   begin filling output lines
.fo /l/c/r f="" f=""    no    foot titles are l(eft), c(enter), r(ight)
.he /l/c/r t="" t=""    no    head title is l(eft), c(enter), r(ight)
.in n     n=0   n=0     yes   set left margin to column n+1
.ju       yes   yes     no    begin justifying filled lines
.ls n     n=1   n=1     no    set line spacing to n
.m1 n     n=3   n=3     no    space between top of page and head
.m2 n     n=2   n=2     no    space between head and text
.m3 n     n=2   n=2     no    space between text and foot
.m4 n     n=3   n=3     no    space between foot and bottom
.ne n           n=0     y/n   need n lines; break if new page
.nf       no            yes   stop filling
.nj       no            no    stop justifying
.nr x m   x=0   m=0     no    set number register x to m,
+ti +30
-m, +m for decrement, increment
.of t     t=""  t=""    no    foots on odd pages are t
.oh t     t=""  t=""    no    heads on odd pages are t
.pl n     n=66  n=66    no    set page length to n lines
.po n     n=0   n=0     no    set page offset to n spaces
.rm n     n=65  n=65    no    set right margin to column n
.so file                no    switch input to file
.sp n           n=1     yes   space n lines, except at top of page
.st n           n=0     yes   space to line n from top; -n
+ti +30
spaces to line n from bottom
.ti n           n=0     yes   temporarily indent next output
+ti +30
line n spaces
.ul n           n=1     no    underline words in the next n
+ti +30
input lines
+cc .
#-t-  format.doc                 7939  local   12/10/80  15:53:22
#-h-  includ.doc                 1389  local   12/10/80  16:51:03
.bp 1
.in 0
.he 'INCLUD (1)'2/2/78'INCLUD (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
includ - file inclusion preprocessor
.nf
.sp
.ti -3
SYNOPSIS
.br
includ [file] ...
.fi
.sp
.ti -3
DESCRIPTION
.br
Includ copies the named files to the standard output, except that any
line that begins with

               include file
.br
or
.br
               include "file"

is replaced by the entire contents
of file.
If no files are given, or '-' is specified, includ reads its standard
input.

An included file may contain further includes.
However,
there is a (system-dependent) limit to the nesting of included files.
.fi
.sp
.ti -3
FILES
.br
None
.sp
.ti -3
SEE ALSO
.br
Kernighan and Plauger's "Software Tools", pages 74-77
.br
Ratfor
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
includes nested too deeply
.br
.in +3
The depth of included files allowed was exceeded.
The depth is set by the NFILES definitions in the source code
and is dependent upon the maximum number of opened files allowed
on the particular system.
.in -3
.sp
name: can't include
.br
.in +3
The named file could not be opened; processing continues.
.in -3
.sp
.ti -3
AUTHORS
.br
Original code by Kernighan and Plauger, with modifications by
David Hanson and friends (U. of Arizona)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
The depth of included files allowed is dependent upon the number
of open files allowed by the implementor of the primitives.
#-t-  includ.doc                 1389  local   12/10/80  16:51:03
#-h-  kwic.doc                   1025  local   01/06/81  23:10:13
.bp 1
.in 0 
.he 'KWIC (1)'1/15/79'KWIC (1)'
.fo ''-#-' 
.fi 
NAME 
.br 
.in 7 
kwic - make keyword in context index
.sp 1 
.in 
SYNOPSIS 
.br 
.in 7 
kwic [file ...]
.sp 1 
.in 
DESCRIPTION 
.br 
.in 7 
Kwic
rotates lines from the input files so that each word in the sentence
appears at the beginning of a line, with a special character marking
the original position of the end of the line.
The output from kwic is typically sorted with 'sort' and then
unrotated with 'unrot' to produce a keyword-in-context index.
 
If no input files are given, or if the filename '-' appears, lines
will be read from standard input.
.sp 1
.in 
FILES 
.br 
.in 7 
.sp 1 
.in 
SEE ALSO 
.br 
.in 7 
unrot; sort
.sp 1 
.in 
DIAGNOSTICS 
.br 
.in 7 
A message is printed if an input file cannot be opened; further
processing is terminated.
.sp 1 
.in 
AUTHORS 
.br 
.in 7 
.sp 1 
Original from Kernighan and Plauger's 'Software Tools', with 
minor modifications
by Debbie Scherrer, Lawrence Berkeley Laboratory.
.sp 1 
.in 
BUGS 
.br 
.in 7 
#-t-  kwic.doc                   1025  local   01/06/81  23:10:13
#-h-  lam.doc                    1859  local   12/24/80  12:32:46
.bp 1
.in 0
.he 'LAM (1)'7/30/79'LAM (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
lam - laminate files
.nf
.sp
.ti -3
SYNOPSIS
.br
lam -string | files...
.fi
.sp
.ti -3
DESCRIPTION
.br
Lam laminates the named files to the standard output.
That is, the first output line is the result of concatenating
the first lines of each file, and so on.
If the files are different lengths, null lines are used for the missing
lines in the shorter files.
.sp
The "-string" arguments are used to place strings in each output
line.  Each "string" is placed in the output lines at the point
it appears in the argument list.  For example,
.sp
.in +3
.nf
lam -file1: foo1 "-, file2:" foo2
.in -3
.sp
.fi
results in output lines that look like
.sp
.in +3
.nf
file1: a line from foo1, file2: a line from foo2
.in -3
.sp
.fi
The escape sequences described in find (and change)
are valid in "string"
arguments.  Thus
.sp
.in +3
.nf
lam foo1 -@n foo2
.in -3
.sp
.fi
results in the lines from foo1 and foo2 being interleaved.
.sp
Files and string specifications may appear in any order in the
argument list.
.sp
If no file arguments are given,
or if the file "-" is specified,
lam reads the standard input.
.fi
.sp
.ti -3
FILES
.br
None
.sp
.ne 2
.ti -3
SEE ALSO
.br
comm, tail, field
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
too many arguments
.br
.in +3
The maximum number of command line arguments allowed has been exceeded.
It is set by the MAXARGS definition in the source code.
.in -3
.sp
too many strings
.br
.in +3
The max number of characters in a string has been exceeded.
It is set by the MAXBUF definition in the source code.
.in -3
.sp
output buffer exceeded
.in +3
The size of the output line buffer has been exceeded.
It is set by the MAXOBUF definition in the source code.
.in -3
.sp
.ne 2
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
.sp
.ti -3
BUGS/DEFICIENCES
#-t-  lam.doc                    1859  local   12/24/80  12:32:46
#-h-  ll.doc                      688  local   12/10/80  15:54:26
.bp 1
.in 0
.he 'LL (1)'9/15/78'LL (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
ll - print line lengths
.nf
.sp
.ti -3
SYNOPSIS
.br
ll files...
.fi
.sp
.ti -3
DESCRIPTION
.br
Ll prints the lengths of the shortest and longest lines
in the named files.  The name "-" may be used
to refer to the standard input.  If no files
are given, ll reads the standard input.

NEWLINE characters are not counted as part of the length of a
line.
.fi
.sp
.ti -3
FILES
.br
None
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
A message is issued if a named file could not be opened.
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  ll.doc                      688  local   12/10/80  15:54:26
#-h-  macro.doc                  6491  local   01/06/81  22:52:12
.bp 1
.in 0
.he 'MACRO (1)'10/1/79'MACRO (1)'
.in 3
.ti -3
NAME
.br
macro - general-purpose macro processor
.sp
.ti -3
SYNOPSIS
.br
macro [-0] [files...]
.sp
.ti -3
DESCRIPTION
.br
Macro is a general-purpose macro processor.
Macro reads the files and writes onto the standard output
a new file with the macro definitions deleted and the macro
references expanded.
If no files are given, or the file "-" is specified, the standard
input is read.
.sp
Macros permit the definition of
symbolic constants so that subsequent
occurrences of the constant are replaced by the defining
string of characters.
The general form of a macro definition is
.sp
.ce
define(name,replacement text)
.sp
All subsequent occurrences of "name" in the file will be replaced
by "replacement text".
The placement of blanks in definitions is significant;
they should only appear in the replacement
text where desired.
Upper and lower case letters are also significant.
The replacement text may be more than one
line long.
However, when an entire macro definition is followed
immediately by a newline,
the newline is discarded.  This prevents extraneous blank lines
from appearing in the output.
.sp
Nesting of definitions is allowed, as is recursion.
.sp
An elementary example of a macro is:
.sp
.ce
define(EOF,-1)
.sp
Thereafter, all occurrences of "EOF" in the file would be replaced
by "-1".
.sp
Macros with arguments may also be specified.
Any occurrence in
the replacement text of "$n", where n is between 1 and 9,
will be replaced by the nth argument when the macro is actually
called.
For example,
.sp
.ti +10
define(copen,$3 = open($1,$2)
.ti +18
if ($3 == ERR)
.ti +21
call cant($1)
)
.sp
would define a macro that, when called
by
.sp
.ce
copen(name, READ, fd)
.sp
would expand into
.in +10
.nf
fd = open(name,READ)
if (fd == ERR)
.ti +3
call cant(name)
.sp
.fi
.in -10
If a macro definition refers to an argument that wasn't supplied,
the "$n" will be ignored.
"$0" refers to the name of the macro itself.
If a character other
than a digit follows "$",
the "$" is taken literally.
.sp
Macros can be nested, and any macros encountered during argument
collection are expanded immediately, unless they are surrounded
by brackets "[]".
That is, input surrounded by brackets is
left absolutely alone, except that one level of [ and ] is
stripped off.
Thus it is possible to write the macro "d" as
.sp
.ce
define(d,[define($1,$2)])
.sp
The replacement text for "d", protected by the brackets is
literally "define($1,$2)" so one could say
.sp
.ce
d(a,bc)
.sp
to define "a" as "bc".
Brackets must also be used when it is desired to redefine
a macro, e.g.
.sp
.in +25
define(x,y)
.br
define(x,z)
.sp
.in -25
would define "y" in the second line, instead of redefining "x".
To avoid redefining "y", the operation must be expressed as
.sp
.in +25
define(x,y)
.br
define([x],z)
.sp
.in -25
Normally, brackets appearing outside any macro calls
("level 0" brackets) are
.ul
not
removed, unless the -0 option is specified.
.sp 2
The following built-in macros are provided:
.sp
define(a,b)
.br
.in +5
defines a to be b and returns the null string.
.in -5
.sp
ifelse(a,b,c,d)
.br
.in +5
returns c if a is identical to b and d otherwise.
.in -5
.sp
incr(a)
.br
.in +5
interprets a as an integer and returns a+1.
.in -5
.sp
substr(a,b,c)
.br
.in +5
returns a substring of "a" starting at character number
b and extending for c characters.
.in -5
.sp
len(a)
.br
.in +5
returns the length of a.
.in -5
.sp
includ(a)
.br
.in +5
returns the contents of file a.
.in -5
.sp
expr(a)
.br
.in +5
returns the result of evaluating infix expression a.
Operators in increasing order of precedence are
as follows.  Parentheses may be used as usual.
.br
.sp
.in +5
.nf
| &             logical OR and AND
!               unary logical NOT
== ^= <= < > >= arithmetic comparison (!= and ~= are
.ti +16
equivalent to ^=)
+ -             addition and subtraction
* / %           multiplication, division, modulo (remainder)
**              exponentiation
+ -             unary plus and negation
.fi
.sp
.in -5
Logical operators return 0 or 1 (false or true).
.in -5
.sp
.ti -3
FILES
.br
None
.sp
.ti -3
SEE ALSO
.br
Kernighan and Plauger's "Software Tools", pages. 251-283
.br
ratfor
.sp
.ti -3
DIAGNOSTICS
.br
arith evaluation stack overflow
.in +5
The max level of nested arithmetic expressions has been exceeded.
The size is set by the MAXSTACK definition in the source code.
.sp
.in -5
arg stack overflow
.br
.in +5
The maximum number of total arguments has been exceeded;
the size is set by the ARGSIZE definition in the source code.
.in -5
.sp
call stack overflow
.br
.in +5
The maximum level of nesting of definitions has been exceeded.
The size is set by the CALLSIZE definition in the source code.
.in -5
.sp
EOF in string
.br
.in +5
An end-of-file has been encountered before a bracketed string has
been terminated.
.in -5
.sp
evaluation stack overflow
.br
.in +5
The total number of characters permitted for
name, definition, and arguments
has been exceeded.
Set by the EVALSIZE definition in the source code.
.in -5
.sp
unexpected EOF
.br
.in +5
An end-of-file was reached before the macro definition was terminated.
.in -5
.sp
filename: can't open
.br
.in +5
The indicated file could not be opened.
.in -5
.sp
filename: can't includ
.br
.in +5
The indicated file could not be included via the includ builtin.
.in -5
.sp
includs nested too deeply
.br
.in +5
Includ builtins were nested deeper than the system would
allow.
The number is determined by the MAXOFILES definition in the
general symbols definition file.
.in -5
.sp
expression: invalid infix expression
.br
.in +5
There is a syntax error in the indicated infix expression as
passed to the expr builtin.
.in -5
.sp
too many characters pushed back
.br
.in +5
A macro expansion is too large to be rescanned.
The size is set by the BUFSIZE definition in the source code.
.in -5
.sp
name: too many definitions
.br
.in +5
The table space for macro definitions has been exhausted; this
occurred upon the definition of the indicated macro.
.in -5
.sp
token too long
.br
.in +5
A name or symbol in the input was longer than the token buffer.
Size is determined by the MAXTOK definition in the source code.
.in -5
.sp
.ti -3
AUTHORS
.br
Original by Kernighan and Plauger, with enhancements by
David Hanson and friends (U. of Arizona) and Philip
Scherrer (Stanford U.)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
This macro processor is incompatible with the one included
in the ratfor preprocessor.
#-t-  macro.doc                  6491  local   01/06/81  22:52:12
#-h-  mcol.doc                   2431  local   12/10/80  15:54:31
.bp 1
.in 0
.he 'MCOL (1)'10/1/78'MCOL (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
mcol - multicolumn formatting
.nf
.sp
.ti -3
SYNOPSIS
.br
mcol [-cn] [-ln] [-wn] [-gn] [-dn] [file ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Mcol reads the named files and formats them into multicolumn
output on the standard output.
If the filename "-" is given, or no files are specified, the
standard input is read.

The options are as follows.
.sp
.in +5
.ti -5
-cn  Format the output into "n" columns.  Default is 2.
.sp
.ti -5
-ln  Set the output page size to "n".  Mcol produces its output
in pages, but does not place separators between the pages on
the assumption that some subsequent processor will do that.
(The default page length is 55.)
.sp
.ti -5
-wn  Set the column width to "n" characters.  Lines longer than "n"
characters are truncated.
(The default column width is 60.)
.sp
.ti -5
-gn  Set the "gutter" width to "n".  The gutter is the white space
between columns.
(The default gutter width is 8.)
.sp
.ti -5
-dn  Assume output is to be printed on a display terminal.  The
column size is set to "n" characters and the page size is set to
24 lines.  The number of columns and gutter width are computed
to maximize the amount of information on a single screen.
If "n" is omitted, 10 is used, which is useful for displaying
lists of file names.
.sp
.in -5
.fi
.sp
.ti -3
FILES
.br
None
.sp
.ti -3
SEE ALSO
.br
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
.nf
invalid column count
invalid page size
invalid column width
invalid gutter width
.br
.fi
.in +3
The value of one of the option flags is invalid or exceeds
the limitations of mcol.
.sp
.ti -3
ignoring invalid flag
.br
A command argument option flag was given which mcol didn't recognize.
.in -3
.sp
insufficient buffer space
.br
.in +3
Mcol could not buffer an entire page.  This is usually the result
of options that specify a large page size or many columns.
The buffer size is set by the MAXBUF definition in the source code.
.in -3
.sp
too many lines
.in +3
.br
The number of lines per page times the number of columns
exceeded mcol's line buffer space.
The maximum number of lines allowed is set by the MAXPTR definition
in the source code.
.in -3
.fi
.sp
.ne 2
.ti -3
BUGS/DEFICIENCIES
.br
.sp
.ti -3
AUTHORS
.br
Original by David Hanson and friends (U. of Arizona), with
modifications by Debbie Scherrer (LBL).
#-t-  mcol.doc                   2431  local   12/10/80  15:54:31
#-h-  mv.doc                      711  local   12/10/80  15:54:32
.bp 1
.in 0
.he 'MV (1)'7/16/79'MV (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
mv - move (rename) a file
.nf
.sp
.ti -3
SYNOPSIS
.br
mv file1 file2
.fi
.sp
.ti -3
DESCRIPTION
.br
Mv changes the name of "file1" to "file2".
If "file2" already exists, it is overwritten.
Mv usually performs a "rename" operation, but in cases
where this fails, it copies "file1" to "file2"
and then deletes "file1".
.fi
.sp
.ti -3
FILES
.br
None
.sp
.ne 2
.ti -3
SEE ALSO
.br
rm
.fi
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
.sp
.ne 2
.ti -3
BUGS/DEFICIENCIES
.br
Results may be strange if the terminal is specified as
either file.
.sp
If mv must copy "file1", it does so assuming that
"file1" is a character file.
#-t-  mv.doc                      711  local   12/10/80  15:54:32
#-h-  os.doc                      910  local   01/06/81  22:52:16
.bp 1
.in 0 
.he 'OS (1)'1/16/79'OS (1)'
.fo ''-#-' 
.fi 
NAME 
.br 
.in 7 
os - overstrike - convert backspaces into multiple lines
.sp 1 
.in 
SYNOPSIS 
.br 
.in 7 
os
[file ...]
.sp 1 
.in 
DESCRIPTION 
.br 
.in 7 
Os
(overstrike) looks for backspaces in the files specified and 
generates a sequence of print lines with carriage control codes
to reproduce the effect of the backspaces.
 
If no files are given, or the filename '-' appears, input is
taken from the standard input.
.sp 1
.in 
FILES 
.br 
.in 7 
.sp 1 
.in 
SEE ALSO 
.br 
.in 7 
detab, lpr (if one is implemented)
.sp 1 
.in 
DIAGNOSTICS 
.br 
.in 7 
A message is printed if an input file cannot be opened; further
processing is terminated.
.sp 1 
.in 
AUTHORS 
.br 
.in 7 
.sp 1 
Original from Kernighan & Plauger's 'Software Tools', with 
minor modifications by Debbie Scherrer, Lawrence Berkeley Laboratory.
.sp 1 
.in 
BUGS 
.br 
.in 7 
#-t-  os.doc                      910  local   01/06/81  22:52:16
#-h-  pl.doc                     1752  local   12/10/80  15:54:33
.bp 1
.in 0
.he 'PL (1)'9/18/79'PL (1)
.sp 2
.in +3
.fi
.ti -3
NAME
.br
pl - print specified lines/pages in a file
.nf
.sp
.ti -3
SYNOPSIS
.br
pl [-pn] numbers [file ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Pl
prints the specified lines from each of the named files
on the standard output.  If no files are given, or if
the name "-" is specified, pl reads the standard input.
.sp
The "numbers" argument is a list of line numbers
separated by commas, e.g.
.sp
.in +3
.nf
pl 4,5,26,55 foo bazrat
.in -3
.sp
.fi
prints lines 4, 5, 26, and 55 in file "foo" and
"bazrat".  The line
numbers may be given in any order.
Repeated numbers cause the specified lines to be
printed once for each occurrence of the line number.
Line number ranges can also be given, e.g. 4-15.
.sp
The "-p" option causes pl to print pages instead of lines,
and the numbers refer to page numbers.  If an integer follows
the "-p", it is taken as the page size; the default is 23.
Repeated numbers cause the specified pages to be printed
once for each occurrence of the page number.
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
bad page size
.in +5
Invalid page size specified after '-p' flag
.in -5
bad number
.in +5
Invalid number given as argument
.in -5
bad range
.in +5
Invalid range given as argument
.in -5
too many numbers
.in +5
Number of lines/pages specified overflowed the buffer.
Maximum number of lines is determined by the MAXLINES definition
in the source code.
.in -5
ignoring invalid argument
.in +5
An invalid flag was specified.   Processing continues.
.in -5
.fi
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
There is a limit to the size of pages which can be buffered.
This is set by the MAXBUF definition in the source code.
#-t-  pl.doc                     1752  local   12/10/80  15:54:33
#-h-  pr.doc                     1216  local   12/24/80  13:22:42
.bp 1
.in 0
.he 'PR (1)'1/15/77'PR (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
print - paginate files to standard output
.nf
.sp
.ti -3
SYNOPSIS
.br
pr [-ln] [file ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Pr
paginates the named files to standard output.
Each file is printed as a sequence of pages.  Each page
is 66 lines
long, including a 6-line header and 3-line footer.
The header includes the file name, possibly the date and time, and
the page number.

If the file '-' is specified, or no file names are given,
the standard input is read.

Option flags include:
.in +11
.ti -5
-ln   Sets the page length to 'n'.
Default page length is 66.
.in -11
.sp
.fi
.ne 2
.ti -3
SEE ALSO
.br
os, detab, mcol, format, cat
.sp
.ti -3
DIAGNOSTICS
.br
ignoring invalid argument
.in +3
An option flag was specified which pr did not understand

.in -3
A message is printed if an input file could not be opened
.sp
.ti -3
AUTHORS
.br
Original from the Kernighan-Plauger 'Software Tools' book,
with modifications by David Hanson and friends (U. of Arizona)
and Debbie Scherrer (LBL)
.sp
.ti -3
BUGS/DEFICIENCES
.br
The header and trailer spacing can be modified by adjusting the
MARGIN1, MARGIN2, and
BMARGIN definitions in the source code.
#-t-  pr.doc                     1216  local   12/24/80  13:22:42
#-h-  ratfor.doc                17825  local   01/06/81  22:52:18
.bp 1
.in 0
.he 'RATFOR (1)'06/12/80'RATFOR (1)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
ratfor - Ratfor preprocessor
.sp 1
.ti -7
SYNOPSIS
.br
ratfor [files...] >outfile
.sp 1
.ti -7
DESCRIPTION
.br
Ratfor translates the ratfor programs in the named files into Fortran.
If no input files are given, or the filename '-' appears, the
standard input will be read.

A file containing general purpose software tools definitions
(e.g. EOF, NEWLINE, EOS, etc.) will be automatically opened and
processed before any of the files specified are read.
.sp 2
Syntax:

Ratfor has the following syntax:
.nf
           prog:   stmt
                   prog stmt
           stmt:   if (expr) stmt
                   if (expr) stmt else stmt
                   while (expr) stmt
                   repeat (expr) stmt
                   repeat stmt until (expr)
                   for (init expr; test expr; incr expr) stmt
                   do expr stmt
                   do n expr stmt
                   break
                   break n
                   next
                   next n
                   return (expr)
                   switch (expr)
                     {
                     case expr:  stmt
                     ....
                     default: stmt
                     }
                   digits stmt
                   { prog }  or  [ prog ]
                   anything unrecognizable (i.e. fortran)

.fi
where 'stmt' is any Fortran or Ratfor statement.
A statement is terminated by an end-of-line or a semicolon.
.sp
.ne 13
Character Translation:
.sp
The following character translations are performed:
.in +5
.nf
<       .lt.
<=      .le.
==      .eq.
!=      .ne.         ^=      .ne.         ~=      .ne.
>=      .ge.
>       .gt.
|       .or.
&       .and.
!       .not.        ^       .not.        ~       .not.
.in -5
.fi
.sp 2
Included files:

.fi
The statement

.in +15
.nf
include file        or
include "file"
.in -15

.fi
will insert the contents of the specified file into the ratfor input
in place of the 'include' statement.
Quotes must surround the file name if it contains characters other
than alphanumerics or underscores.
.sp 2
Macro Definitions:

The statement

.ti +15
define(name,replacement text)

defines 'name' as a macro which will be replaced with the indicated text
when encountered in the source files.  Any occurrences of the strings
'$n' in the replacement text, where 1 <= n <= 9, will be replaced with the
nth argument when the macro is actually invoked.  For example:

.ti +15
define(bump, $1 = $1 + 1)

will cause the source line

.ti +15
bump(i)

to be expanded into

.ti +15
i = i + 1

The names of macros may contain letters, digits and underline
characters, but must start with a letter.  Upper case is
not equivalent to lower case in macro names.

The replacement text is copied directly into the lookup table with no
intepretation of the arguments, which differs from the procedure used in
the macro utility.  This "deferred evaluation" has the effect of eliminating
the need for bracketing strings to get them through the macro processor
unchanged.  A side effect of the deferred evaluation is that defined names
cannot be forced through the processor - i.e. the
string "define" will never
be output from the preprocessor.
The inequivalence of upper and lower case in macro names may be used in this
case to force the name of a user defined macro onto the output - i.e. if the
user has defined a macro named mymac, the replacement text may contain the
string MYMAC, which is not defined, and will pass through the processor.

(For compatibility, an "mdefine" macro call has been included
which interprets definitions before stacking them, as does the
macro tool.
When using this version, use "$(" and "$)" to indicate deferred
evaluation, rather than the "[" and "]" used by the macro tool.)

In addition to define, four other built-in macros are provided:

.in +17
.ti -16
arith(x,op,y)   performs the "integer" arithmetic specified by op (+,-,*,/)
on the two numeric operands and returns the result as its replacement.
.ti -16
incr(x)         converts the string x to a number, adds one to it, and returns
the value as its replacement (as a character string).
.ti -16
ifelse(a,b,c,d) compares a and b as character strings; if they are the same,
c is pushed back onto the input, else d is pushed back.
.ti -16
substr(s,m,n)   produces the substring of s which starts at position m
(with origin one), of length n.  If n is omitted or too big, the rest of
the string is used, while if m is out of range the result is a null string.
.in -17

Note: the statement

.ti +15
define name text

may also be used, but will not always perform correctly for macros with
parameters or multi-line replacement text.
The functional form is preferred.


.ne 9
Conditional Preprocessing:

The statements

.in +15
ifdef(macro,text)
.br
ifnotdef(macro,text)
.in -15

conditionalize the preprocessing upon whether the macro has been previously
defined or not.
.br


String Data Types:

The statements

.in +10
string name "character string"          or
.br
string name(size) "character string"

.in -10
declare 'name' to be a character array long enough to accomodate
the ascii codes for the given character string, one per array
element.
The array is then filled by data statements.
The last word of 'name' is initialized to the symbolic parameter
EOS, and indicates the end of a string.
EOS must be defined either in the standard definitions file or
by the user.
If a size is given, name is declared to be a character array
of 'size' elements.
If several string declarations appear consecutively, the
generated declarations for the arrays will precede the data
statements that initialize them.
.sp 2
String Literals:

Conversion of in-line quoted strings to hollerith constants is performed
in the following manner:

.in +5
.nf
"str"         nHstr
'str'         nHstr
         (where 'n' is the number of characters in str)
.in -5
.br
.fi
String literals can be continued across line boundaries by ending
the line to be continued with an underline.
The underline is not included as part of the literal.
Leading blanks and tabs on the next line are ignored.
.sp 2
Integer Constants:

Integer constants in bases other than decimal may be specified
as n%dddd... where 'n' is a decimal number indicating
the base and 'dddd...' are digits in that base.
For bases > 10, letters are used for digits above 9.
Examples include:  8%77 (=63), 16%2ff (=767), 2%0010011 (=19).
The number is converted to the equivalent decimal value using
multiplication; this may cause sign problems if the number has
too many digits.
.sp 2
Lines and Continuation:

.fi
Input is free-format; that is, statements may appear anywhere
on a line,
and the end of the line is generally considered the end of the statement.
However,
lines ending in special characters such as comma, +, -,
and * are assumed to be continued on the next line.
An exception to this rule is within a condition; the line
is assumed to be continued if the condition does not fit on one line.
Explicit continuation is indicated by ending a line with an
underline character (_).
The underline character is not copied to the output file.
.sp 2
Comments:

Comments are preceded by '#' signs and may appear anywhere in
the code.
.sp 2
Literal (unprocessed) Lines:

Lines can be passed through ratfor without being processed by
putting a percent "%" as the first character on the line.
The percent will be removed and the line shifted one position to the
left, but otherwise will be output without change.
Macro invocations, long names, etc., appearing in the line will not
be processed.
.sp 2
Long Variable Names

Unlike Fortran, Ratfor variable names may be essentially any length,
and may contain underscores as well as letters and digits.
Every character in a variable name is significant;
"very_long_variable_name_1" is different from "very_long_variable_name_2".
.sp
Ratfor converts such exceptional names into legal Fortran names of
six alphanumeric characters, and guarantees that no conflicts will
arise from converting two special names or from user variables that
happen to be the same as a Ratfor-generated name.
.sp
In the unfortunate event that it ever becomes necessary to debug the
Fortran output of Ratfor, Ratfor outputs a "long name dictionary"
as a series of comments at the end of its output code.
This dictionary shows each internal variable name along with its
Fortran equivalent.
.sp 4
.ne 4
.ti -7
CHANGES
.br
This ratfor preprocessor differs from the original (as released
by Kernighan and Plauger) in the following ways:

The code has been rewritten and reorganized.

Hash tables have been added for increased efficiency in searching
for macro definitions and Ratfor keywords.

The 'string' declaration has been included.

The define processor has been augmented to support macros with arguments.

Conditional preprocessing upon the definition (or lack therof) of a
symbol has been included.

Many extraneous gotos have been avoided.

Blanks have been included in the output for increased readability.

Multi-level 'break' and 'next' statements have been included.

The Fortran 'DO' is allowed, as well as the ratfor one.

The capability of specifying integer constants in bases other than
decimal has been added.

Underscores have been allowed in names.

The 'define' syntax has been expanded to include the form:
define name value

The 'return(value)' feature has been added.

Quoted file names following 'include' statements have been added
to allow for special characters in file names.

A method for allowing lines to pass through un-processed has been added.

The 'switch' control statement has been included.

Continuation lines have been implemented.

Brackets have been allowed to replace braces
(but NOT $( and $) )

Variable names that are longer than 6 characters or that contain
underscores are automatically converted to legal Fortran variable names.
.sp 3
.ti -7
FILES
.br
A generalized definition file (e.g. 'ratdef') is automatically
opened and read.
.sp 3
.ti -7
SEE ALSO
.br
.nf
Kernighan and Plauger's "Software Tools"
Kernighan's "RATFOR - A Preprocessor for a Rational Fortran"
The Unix command rc in the Unix Manual
The tools 'incl' and 'macro'
.fi
.sp 1
.ti -7
DIAGNOSTICS
.br
(The errors marked with asterisk '*' are fatal; all others are simply
warning messages.)
.sp 1
.in +5
.ti -5
* arg stack overflow
.br
The argument stack for the macro processor has been exceeded.  The size of the
stack is determined by the symbol ARGSIZE in the source definitions file.
.br
.ti -5
* buffer overflow
.br
One of the preprocessor's internal buffers overflowed,
possibly, but not necessarily, because the string buffers
were exceeded.
The definition SBUFSIZE in the preprocessor symbols file
determines the size
of the string buffers.
.br
.ti -5
* call stack overflow
.br
The call stack (used to store call frames) in the macro processor has
been exceeded.
The definition CALLSIZE in the source definition file determines the
size of this stack.
.br
.ti -5
can't open standard definitions file
.br
The special file containing general purpose ratfor definitions
could not be opened, possibly because it did not exist or the
user did not have access to the directory on which it resides.
.br
.ti -5
can't open include
.br
File to be included could not be located,
the user did not have privilege to access it,
or the file could not be opened due to some problem in the
local primitives.
.br
.ti -5
* definition too long
.br
The number of characters in the name to be defined exceeded
Ratfor's internal array size.
The size is defined by the MAXTOK definition in the preprocessor
symbols file.
.br
.ti -5
* EOF in string
.br
The macro processor detected an EOF in the current input file while
evaluating a macro.
.ti -5
* evaluation stack overflow
.br
The evaluation stack for the macro processor has been exceeded.
This stack's size is determined by the symbol EVALSIZE in the
source definition file.
.br
.ti -5
* for clause too long
.br
The internal buffer used to hold the clauses for the 'for'
statement was exceeded.
Size of this buffer is determined by the MAXFORSTK definition
in the preprocessor symbols file.
.br
.ti -5
* getdef is confused
.br
There were horrendous problems when attempting to access
the definition table
.br
.ti -5
illegal break
.br
Break did not occur inside a valid "while", "for", or "repeat" loop
.br
.ti -5
illegal else
.br
Else clause probably did not follow an "if" clause
.br
.ti -5
illegal next
.br
"Next" did not occur inside a valid "for", "while", or "repeat" loop
.br
.ti -5
illegal right brace
.br
A right brace was found without a matching left brace
.br
.ti -5
* in dsget:  out of dynamic storage space
.br
There is insufficient memory for macro definitions, long variable names,
etc.
Increase the MEMSIZE definition in the preprocessor.
.br
.ti -5
includes nested too deeply
.br
There is a limit to the level of nesting of included files.
It is dependent upon the maximum number of opened files allowed
at a time,
and is set by the
NFILES definition in the preprocessor symbols file.
.br
.ti -5
invalid for clause
.br
The "for" clause did not contain a valid init, condition, and/or
increment section
.ti -5
invalid string size
.br
The string format 'string name(size) "..."' was used, but the
size was given improperly.
.br
.ti -5
* missing comma in define
.br
Definitions of the form 'define(name,defn)' must include the
comma as a separator.
.br
.br
.ti -5
missing function name
.br
There was an error in declaring a function
.br
.ti -5
missing left paren
.br
A parenthesis was expected, probably in an "if" statement, but
not found
.br
.ti -5
missing parenthesis in condition
.br
A right parenthesis was expected, probably in an "if" statement,
but not found
.br
.ti -5
missing quote
.br
A quoted string was not terminated by a quote
.br
.ti -5
missing right paren
.br
A right parenthesis was expected in a Fortran (as opposed to
Ratfor) statement but not found
.br
.ti -5
missing string token
.br
No array name was given when declaring a string variable
.br
.ti -5
* non-alphanumeric name
.br
Definitions may contain only alphanumeric characters
and underscores.
.br
.ti -5
* stack overflow in parser
.br
Statements were nested at too deep a level.
The stack depth is set by the MAXSTACK definition in the
preprocessor symbols file.
.br
.ti -5
token too long
.br
A token (word) in the source code was too long to fit into one
of Ratfor's internal arrays.
The maximum size is set by the MAXTOK definition in the
preprocessor symbols file.
.br
.ti -5
* too many characters pushed back
.br
The source code has illegally specified a Ratfor command, or has
used a Ratfor keyword in an illegal manner, and the parser has
attempted but failed to make sense out of it.
The size of the push-back buffer is set by BUFSIZE in the
preprocessor symbols file.
.br
.ti -5
unbalanced parentheses
.br
Unbalanced parentheses detected in a Fortran (as opposed
to Ratfor) statement
.br
.ti -5
unexpected brace or EOF
.br
A brace occurred after a Fortran (but not Ratfor) statement
or an end-of-file was reached before the end of a statement
.br
.ti -5
unexpected EOF
.br
An end-of-file was reached before all braces had been
accounted for.  This is usually caused by unmatched braces
somewhere deep in the source code.
.br
.ti -5
warning:  possible label conflict
.br
This message is printed when the user has labeled a statement
with a label in the 23000-23999 range.  Ratfor statements are
assigned in this range and a user-defined one may conflict
with a Ratfor-generated one.
.br
.ne 3
.ti -5
"file":  cannot open
.br
Ratfor could not open an input file specified by the user
on the command line.
.br
.in -5
.sp 2
.ti -7
AUTHORS
.br
Original by B. Kernighan and P. J. Plauger, with rewrites and
enhancements by David Hanson and friends (U. of Arizona),
Joe Sventek and Debbie Scherrer (Lawrence Berkeley Laboratory),
and Allen Akin (Georgia Institute of Technology).
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
Missing parentheses or braces may cause erratic behavior.
Eventually  Ratfor should be taught
to terminate parenthesis/brace checking at the end of each subroutine.
.sp
Although one bug was fixed which caused line numbers in error
messages to be incorrect, they still aren't quite right.
(newlines in macro text are difficult to handle properly).
Use them only as a general area in which to look for errors.
.sp
Extraneous 'continue' statements are generated within Fortran
'do' statements.
The 'next' statement does not work properly when used within Fortran
'do' statements.
.sp
There is no way to explicitly cause a statement to begin in column 6
(i.e. a Fortran continued statement),
although implicit continuation is performed.
.sp
The 'switch' statement generates a variable to be used in a computed
goto.
This variable is undeclared and its type may be incorrect due to a
preceding 'implicit' declaration.
Because of this and other (minor) faults, the 'switch' statement
should be considered experimental and subject to change or deletion
in the future.
Use it with care!
.sp
Ratfor is very slow, principally in the lexical analysis,
character input, and macro processing routines (in that order).
Attempts to speed it up should concentrate on the routines 'gtok',
'ngetch', and 'deftok'.
An even better approach would be to re-work the lexical analyzer and
parser completely.
.sp
Problems arise with the long variable name conversion process if
subprograms or common blocks with long names are compiled separately.
The easiest way to avoid this is to use 6-character or shorter names
(with no underscores and not ending in the character zero) for
external subprograms and common blocks.
In the future, a "linkage" statement will be added to get around this
difficulty.
#-t-  ratfor.doc                17825  local   01/06/81  22:52:18
#-h-  rev.doc                     511  local   12/10/80  15:54:44
.bp 1
.in 0
.he 'REV (1)'7/11/79'REV (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
rev - reverse lines
.nf
.sp
.ti -3
SYNOPSIS
.br
rev [files ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Rev copies the named files to the standard output,
reversing the order of the characters in every
line.

If no files are given, or the filename '-' is specified,
rev reads from the standard input.
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  rev.doc                     511  local   12/10/80  15:54:44
#-h-  rm.doc                     1510  local   12/10/80  15:54:45
.bp 1
.in 0
.he 'RM (1)'7/9/80'RM (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
rm - remove (delete) files
.nf
.sp
.ti -3
SYNOPSIS
.br
rm [-v] [-a] [files ....]
.fi
.sp
.ti -3
DESCRIPTION
.br
Rm removes (deletes) the named files.  The -v option ("verbose")
causes rm to print the name of each file as it is removed.

The -a option ("ask") causes rm to print the message
.sp
.in +3
.nf
name ?
.in -3
.sp
.fi
for each file "name" that is to be removed and read one line
from the user's terminal.  If the line begins with "y", the file
is removed.
If the line begins with 'q', no further files in the list
are removed.
If the line begins with "g", the file is removed,
along with all subsequent files in the list,
and the -a option is turned off.
If the line begins with
anything else, the file is not removed.

If the filename '-' is specified as an argument,
the names of files to be removed
will be read from standard input, one per line.
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
name: can't remove
.br
.in +3
The named file did not exist or could not be removed.
.in -3
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona), with changes by
Debbie Scherrer (LBL)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
Watch out for the 'g' response when using the -a flag and a
list of files from standard input--it'll cause all subsequent
files in the list to be removed.
#-t-  rm.doc                     1510  local   12/10/80  15:54:45
#-h-  sedit.doc                  4994  local   12/10/80  15:54:46
.bp 1
.in 0
.he 'SEDIT (1)'11/30/79'SEDIT (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
sedit - stream editor
.nf
.sp
.ti -3
SYNOPSIS
.br
sedit [-n] {[-e script | -f sfile]... | script} [file]...
.fi
.sp
.ti -3
DESCRIPTION
.br
Sedit
copies the named input
files
to the standard output, performing
editing as directed by sedit commands in "script" or
in "sfile".
The -e
flag indicates that the next argument is
to be interpreted as an sedit command (see below).
The -f
flag indicates that the next argument is the name of a file
in which
sedit commands appear one per line.
The
-e and -f
arguments may be intermixed in any order.
The order of command
execution
is the order in which commands are read.
If no
-e or -f
flags are given, the first argument is used as an sedit command.
Normally, sedit writes each line of input to the output after editing;
the -n option suppresses this action.  As a result, the only output
is that resulting from sedit commands.
.sp
When the first argument not in the scope of a flag is encountered,
it and all succeeding arguments are taken as input files.
If no files are given, or if the name "-" is specified, the
standard input is read.
.sp
Sedit commands
have the general form
.sp
.in +3
.nf
line1 [, line2] command arguments
.in -3
.sp
.fi
A line number (line1 or line2) is either a decimal number
that refers to a specific input line (input lines
are counted cumulatively across files), a "$" that
refers to the last line of input,
or a /pattern/ where pattern is a regular expression (as in edit).
Line number 0 may be used to specify commands that should be
executed before any input is read.
.sp
A command with no line numbers
is applied to every line of input.
A command with one line number
is applied to every line of input that matches the line number.
A command with two line numbers
is applied to every line of input beginning with the first line
that matches line1 through the next line that
matches line2.  Thereafter, the process is repeated, looking again
for a line that matches line1.
.sp
Sedit accepts the following commands.  Each command may be
used with 0, 1, or 2 line numbers.
The a, c, and i commands may not appear in command line scripts.
.sp
.nf
.cc +
a
<text>
.
+cc .
.fi
.in +3
Append.  The <text> is placed on the output after each selected
line.  The <text> does not change the line number nor is it subject
to subsequent sedit commands.
.in -3
.sp
.ne 5
.nf
.cc +
c
<text>
.
+cc .
.fi
.in +3
Change.  The selected lines are deleted and
<text> is placed on the output in their place.
The <text> does not change the line number nor is it subject
to subsequent sedit commands.
.in -3
.sp
d
.in +3
Delete.  The selected lines are deleted.
.in -3
.sp
.nf
.cc +
i
<text>
.
+cc .
.fi
.in +3
Insert.  The <text> is placed on the output before each selected
line.  The <text> does not change the line number nor is it subject
to subsequent sedit commands.
.in -3
.sp
p
.in +3
Print.  The selected lines are printed on the standard output.
.in -3
.sp
r file
.in +3
Read file.  The contents of "file" are placed on the output after
each selected line exactly as if the contents
were given as <text> in an
a command.  The new lines
do not change the line number nor are they subject
to subsequent sedit commands.
.in -3
.sp
s/pat/new/gp
.in +3
Substitute.  The leftmost
occurrences of pat in the selected lines is changed to new.
If g is specified, all occurrences are changed.  If p is
specified, the resulting line is printed.
.in -3
.sp
w file
.in +3
Write file.  The selected lines are appended to "file".  Files
mentioned in w commands are created before processing begins.
The limit on the number of w commands depends on the number
of files that can be opened at the same time.
.in -3
.sp
=
.in +3
Print line number.  The current line number is printed
on the output as a line.
.in -3
.sp
Text appended by a, c, or r commands is placed on the output in
the same order as the execution of the commands.
Similar comments apply to text inserted by i commands.
.sp
Sedit
can accomodate commands totaling approximately 5000 characters
(including <text> arguments), and lines up to 120 characters in length.
.fi
.sp
.ne 2
.ti -3
SEE ALSO
.br
edit, change, find, tr
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
In addition to the usual error messages resulting from file access
failure, sedit issues the following messages preceeding by the
offending command line.
.sp
bad line numbers
.in +3
indicates that the line number expressions are invalid.
.in -3
.sp
invalid command
.in +3
indicates that the command preceeding the message is illegal.
This message is issued for a, i, or c commands if they appear
in command string scripts.
.in -3
.sp
too many commands
.in +3
indicates exhaustion of space to hold commands.
The size of the command buffer is determined by the MAXBUF definition
in the source code.
.in -3
.sp
.ti -3
AUTHOR
.br
Chris Fraser (U. of Arizona)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
The '$' indicator for end-of-file doesn't always work.
#-t-  sedit.doc                  4994  local   12/10/80  15:54:46
#-h-  sh.doc                    14286  local   12/10/80  16:24:38
.bp 1
.in 0
.he 'SH'1/16/79'SH'
.fo ''-#-'
.fi
.in 7
.ti -7
NAME
.br
sh - shell (command line interpreter)
.sp 1
.ti -7
SYNOPSIS
.br
sh
[-vnxc] [name [args]
.sp 1
.ti -7
DESCRIPTION
.br
Sh
is a command line interpreter:
it reads lines typed by the user and interprets them as requests to
execute other programs.


.ul
Commands.
.br
In simplest form, a command line consists of the command name followed
by arguments to the command, all separated by spaces:
.ce
command arg1 arg2 ... argn
The shell splits up the command name and the arguments into separate
strings.
Then a file with name
command
is sought;
command
may be a path name to specify any file in the system.
If
command
is found, it is brought into memory and executed.
The arguments collected by the shell are accessible to the command.
When the command is finished, the shell resumes its own execution and
indicates its readiness to accept another command by typing a
prompt character.

If file
command
cannot be found in the current directory or through its pathname, the
shell searches a specific system directory of commands intended
to be available to sh users in general.

An example of a simple command is:
.ce
sort list
which would look for the tool 'sort' in the current directory,
then in the system directory, and
then sort the contents of file 'list', printing the
output at the user's terminal.

Some characters on the command line have special meanings to the
shell (these are discussed below).
The character '@' may be included anywhere in the command line
to cause the following character to lose any special meaning
it may have to the shell (to be 'escaped').
Sequences of characters enclosed in double (") or single (')
quotes are also taken literally.


.ul
Standard I/O
.br
Shell programs in general have open three standard files:
'input', 'output', and 'error output'.
All three are assigned to the user's terminal unless redirected by
the special arguments '<', '>', '?', '>>', '??', (and sometimes
'-').

An argument of the form '<name' causes the file
'name' to be used as the standard input file of the associated
command.

An argument of the form '>name' causes file 'name' to be used
as the standard output.

An argument of the form '?name' causes the file 'name' to be used
as the standard error output.

Arguments of the form '>>name' or '??name' cause program output
to be appended to 'name' for standard output or error output
respectively.
If 'name' does not exist, it will be created.

Most tools have the capability to read their input from a series
of files.
In this case, the list of files overrides reading from standard
input.
However, many of the tools allow the user to read from both a list
of files and from input by specifying the filename '-' for
standard input.
For example,
.ce
roff file1 - file2
would read its input from 'file1', then from the standard input,
then from 'file2'.


.ul
Filters and Pipes.
.br
The output from one command may be directed to the input of another.
A sequence of commands separated by vertical bars (|) or carets ('^')
causes the shell to arrange that the standard output of each command
be delivered to the standard input of the next command in sequence.
Thus in the command line:
.ce
sort list | uniq | crt
'sort' sorts the contents of file 'list';
its output is passed to 'uniq',
which strips out duplicate lines.
The output from 'uniq' is then input to 'crt', which prepares
the lines for viewing on the user's crt terminal.

The vertical bar is called a 'pipe'.
Programs such as 'sort', 'uniq', and 'crt', which copy standard
input to standard output (making some changes along the way) are called
'filters'.


.ul
Command separators
.br
Commands need not be on different lines; instead they may be
separated by semicolons:
.ce
ar t file; ed
The above command will first list the contents of the archived
file 'file', then
enter the editor.

The shell also allows commands to be grouped together with
parentheses, where the group can then be used as a filter.
For example,
.ce
(date; cat chocolate) | comm vanilla
writes first the date and then the file 'chocolate' to standard
output, which is then read as input by 'comm'.
This tool compares the results with existing file 'vanilla' to
see which lines the two files have in common.


.ul
Multitasking
.br
On many systems the shell also allows processes to be executed
in the background.
If a command is followed by '&', the shell will not wait for the
command to finish before prompting again; instead,
it is ready immediately to accept a new command.
For instance,
.ce
ratfor ambrose >george &
preprocesses the file 'ambrose', putting the output on 'george'.
No matter how long the compilation takes,
the shell returns immediately.
The identification number of the process running that command is
printed.
This identification may be used to wait for the completion of
the command or to terminate it.

The '&' may be used several times in a line.
Parentheses and pipes are also allowed (within the same background
process).


.ul
Script files.
.br
The shell itself is a command, and may be called recursively,
either implicitly or explicitly.
This is primarily useful for executing files containing lines
of shell commands.
For instance, suppose you had a file named 'nbrcount'
which looked like this:
.in +15
.nf
echo 'Counting strings of digits'
tr <program 0-9 9 | tr !9 | wc -c
.fi
.in -15
These commands count all the digit strings in 'program'.
You could have the shell execute the commands by typing:
.ce
sh nbrcount
The shell will also execute script files implicitly.
For example, giving the command
.ce
nbrcount
would cause the shell to notice that the file 'nbrcount' contained
text rather than executable code.
The shell would then execute itself again, using 'nbrcount' as
its input.

Arguments may also be passed to script files.
In script files, character sequences of the form '$n',
where n is a digit between 1 and 9, are replaced by the
nth argument to the invocation of the shell.
For instance, suppose the file 'private' contained the following
commands:
.in +15
.nf
cat $1 $2 $3 | crypt key >$4
ar u loveletters $4
.fi
.in -15
Then, executing the command
.ce
private Dan John Harold fair
would merge the files 'Dan', 'John', and 'Harold', encrypt
them, and store them away in an archive under the name 'fair'.

Script files may be used as filters in pipelines just like regular
commands.

Script files sometimes require in-line data to be available to them.
A special input redirection notation "<<" is used to achieve this effect.
For example, the editor normally takes its commands from the standard
input.
However, within a shell procedure commands could be embedded this way:

                           ed file <<!
                           editing requests
                           !

The lines between <<! and ! are called a 'here' document; they are read
by the shell and made available as the standard input.
The character '!' is arbitrary, the document being terminated by a line
that consists of whatever character followed the <<.



.ul
Shell Flags.
.br
The shell accepts several special arguments when it is invoked.
The argument -v asks the shell to print each line of a script
file as it is read as input.
For instance,
.ce
sh -v private Jasmine Irma Jennifer twostars
would print each line of the script file 'private' as soon as
it is read by the shell.

The argument -x is similar to the -v above except that commands
are printed right before they are executed.
These commands will be printed in the actual format the
system expects when attempting to execute the program.

The argument -n suppresses execution of the command entirely.

The argument -c causes the remaining arguments to be executed
as a shell command.


.ul
Termination.
.br
The shell may be left by typing an end-of-file or by typing
'logout' as a command.


.ne 5
.ti -7
FILES
.br
Scratch files for pipelines are created with the names "Pn"
where n is the number of the pipe on the command line
(e.g. 1, 2, etc.).
Scratch files named "doc" are created for 'here documents'.
.sp 1
.ti -7
SEE ALSO
.br
The Unix command 'sh'
.br
The Bell system Technical Journal, vol. 57, no. 6, part 2,
July-Aug 1978

.sp 1
.ti -7
DIAGNOSTICS
.br
.in +4
.ti -4
cannot locate shell
.br
Issued whenever the shell is attempting to spawn a copy of itself to
process a script file.
The shell was unable to find the correct file.
(The file is set in a string declaration in the "scrf" routine.)
.sp
.ti -4
cannot spawn background process
.br
Spawn returned an error status when attempting to execute a command
in the background.
Possibly system quotas were overflowed.
.sp
.ti -4
cannot spawn process
.br
The requested task could not be executed by "spawn".
Generally indicates some sort of system problem.
.sp
.ti -4
can't open 'here document'
.br
The shell creates a temporary file for each 'here document'
and this file could not be created for some reason.
Perhaps the maximum number of opened files has been exceeded
or the user does not have the appropriate privileges for
creating files.
.sp
.ti -4
can't open teletype channel
.br
The shell was attempting to open an output channel to the user's
teletype for prompting and was unable to do so.
.sp
.ti -4
dopar -- invalid token following parenthesis
.br
Syntax error on the command line.
.sp
.ti -4
empty command
.br
Parentheses, pipes, or other shell characters showed up without
any commands between them.
.sp
.ti -4
invalid shell command
.br
An unlikely error which means part of the code thought it had
found a shell command, but another part thought it hadn't.
.sp
.ti -4
invalid task
.br
Printed whenever a command could not be located
in the various directories searched.
.sp
.ti -4
mktree -- tree buffer size exceeded
.br
The parse tree overflowed.
Its size is determined by the TREESIZE definition in the source code.
.sp
.ti -4
stack size exceeded
.br
The size of a stack of pointers into the parse tree was exceeded.
The size of the stack is determined by the MAXSTACK definition
in the source code.
.sp
.ti -4
syntax error
.br
There was some sort of error in the syntax of the command line.
Sometimes a suggested reason is printed.
.sp
.ti -4
unbalanced quotes
.br
There weren't matching pairs of single and/or double quotes
.sp
.ti -4
unbalanced right parenthesis
.br
.ti -4
unbalanced left parenthesis
.br
Unmatched parentheses
.sp
.ti -4
too many characters pushed back
.br
There were some horrible problems in attempting to read
the input line and put characters back onto a stack for
re-reading.
The size of the stack is determined by the BUFSIZE definition
in the source code.
.sp
.in -4
.nf
execut -- invalid parse tree
mktree -- too many children
setree -- doubly defined argument
.in +4
.br
These are primarily debugging aids for the parser.
Contact a systems programmer if they show up...
.in -4
.sp 1
.ti -7
AUTHORS
.br
.sp 1
Dennis Hall, Debbie Scherrer, Joe Sventek
(Lawrence Berkeley Laboratory)
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
If a user wants to escape a shell special character that appears
as the first character of an argument, he must escape it with
quotes rather than an '@' sign.
#-t-  sh.doc                    14286  local   12/10/80  16:24:38
#-h-  show.doc                    860  local   12/15/80  11:05:36
.bp 1
.in 0
.he 'SHOW (1)'7/1/79'SHOW (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
show - show all characters in a file
.nf
.sp
.ti -3
SYNOPSIS
.br
show [files ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Show copies the named files to the standard output,
replacing control characters by "^c", where c is the ascii
character used to enter the control character when
depressing the "control" key on most terminals.
More precisely, c is the ascii character whose
value is 100 (octal) plus the value of the control
character.
.sp
Control characters are those ascii characters with
values between 0 and 31, inclusive.  Newline characters
are displayed as usual, however.
.sp
If no filenames are given, or the name '-' is specified,
show will read from the standard input.
.fi
.sp
.ne 2
.ti -3
SEE ALSO
.br
cat, crt
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  show.doc                    860  local   12/15/80  11:05:36
#-h-  sort.doc                   3309  local   12/10/80  15:54:49
.bp 1
.in 0
.he 'SORT (1)'04/15/78'SORT (1)
.fo ''-#-''
.fi
.in 7
.ti -7
.br
NAME
.br
sort - sort and/or merge text files

.ti -7
SYNOPSIS
.br
sort [-bdfimr] [+sn] [file] ...

.ti -7
DESCRIPTION
.br
Sort sorts lines of all the named files together and writes the result
on the standard output.
If no files are given or the filename '-' appears, standard input
is read.

The sort key is an entire line.
Default ordering is alphabetic by characters as they are represented
in ASCII format.
The ordering is affected by the
following flags, one or more of which may appear.

.in +4
.ti -3
-b Leading blanks  are not included in keys.

.ti -3
-d 'Dictionary' order: only letters, digits and blanks are significant
in comparisons.

.ti -3
-f Fold all letters to a single case.

.ti -3
-i Ignore all nonprinting nonblank characters.

.ti -3
-m Merge only, the input files are already sorted.

.ti -3
-r Reverse the sense of the sort

.ti -4
+sn Sort according to the subfield starting on column n

.in -4

.ti -7
FILES
.br
A series of scratch files are generated and subsequently deleted.
Presently the files are named "Sn" where "n" is a sequence number.

.ti -7
SEE ALSO
.br
tsort
.br
The Unix command "sort" in the Unix User's Manual.
.br

.ti -7
DIAGNOSTICS
.br
file:  can't open
.br
.in +5
This message is printed if either an input file or a scratch
file cannot be opened; execution ceases.
.in -5
.sp
too many arguments
.in +5
Printed if too many files are specified on the command line.
The limit is determined by the FLMAX definition in the source code.
.in -5

.ti -7
AUTHORS
.br
Original design from Kernighan and Plauger's "Software Tools",
with modificatations by
Joe Sventek (Lawrence Berkeley Laboratory).

.ti -7
BUGS
.br
The merge phase is performed with a polyphase merge/sort algorithm,
which requires an end-of-run delimiter on the scratch files.
The one chosen is
a bare ^D (ASCII code 4) on a line.  If this is in conflict with your
data files, the symbol CTRLD in the sort symbol definitions
should be redefined.
#-t-  sort.doc                   3309  local   12/10/80  15:54:49
#-h-  spell.doc                   830  local   01/09/81  00:39:22
.bp 1
.rm 70
.in 0 
.he 'SPELL'1/11/79'SPELL'
.fo ''-#-' 
.fi 
NAME 
.br 
.in 7 
spell - find spelling errors
.sp 1 
.in 
SYNOPSIS 
.br 
.in 7 
spell [file] ...
.sp 1 
.in 
DESCRIPTION 
.br 
.in 7 
Spell
copies the named files (or standard input if none are specified) to
standard output while looking up each word in a dictionary.  If any
spelling errors are found in a particular line, an additional line
will be printed immediately following the line with asterisks (*)
beneath the offending words.
.sp 1
.in 
FILES 
.br 
.in 7 
dict - a dictionary file
.br
dictdx - an index into the dictionary file, created the first
time spell is called
.sp 1 
.in 
SEE ALSO 
.br 
.in 7 
.br
.sp 1 
.in 
DIAGNOSTICS
.br 
.in 7 
.sp 1 
.in 
AUTHORS 
.br 
.in 7 
.sp 1 
Joe Sventek, Lawrence Berkeley Laboratory
.sp 1 
.in 
BUGS 
.br 
.in 7 
#-t-  spell.doc                   830  local   01/09/81  00:39:22
#-h-  split.doc                  1983  local   12/10/80  15:54:51
.bp 1
.in 0
.he 'SPLIT (1)'10/30/78'SPLIT (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
split - split a file
.nf
.sp
.ti -3
SYNOPSIS
.br
split -n | +from [-to] file [name]
.fi
.sp
.ti -3
DESCRIPTION
.br
Split splits a file into a number of small files.
Depending on the arguments, "file" is split into n-line pieces
or according to specified patterns.  If "file" is omitted or
is "-", split reads the standard input.
.sp
Normally, split outputs the pieces of "file" into files
named "xaa", "xab", "xac", ..., "xzz".  This convention
permits upto 676 files.  If "file" requires more than
676 files to be split, the rest of "file" is placed in "xzz".
If the "name" argument is given, it is used as the prefix
for the output file names.  For each output file,
the 2-character sequence (e.g. "aa", "ab", etc.) is appended
to "name" and the result is used as the output file.
Note that "file" must be given in order to specify "name".
.sp
To split "file" into n-line pieces, use
.sp
.in +3
.nf
split -n file [name]
.in -3
.sp
.fi
If n is omitted, 100 is assumed.
.sp
The command
.sp
.in +3
.nf
split +from file [name]
.in -3
.sp
.fi
splits "file" into pieces that begin with the pattern "from".
The command
.sp
.in +3
.nf
split +from -to file [name]
.in -3
.sp
.fi
splits "file" into pieces that begin with the pattern "from"
and end with the "to".  Note that in this case, portions
of "file" may not appear in the output files.
For example, the command
.sp
.in +3
.nf
split +subroutine -end foo
.in -3
.sp
.fi
might be used to extract the subroutines from foo.
.sp
The "from" and "to" patterns may be any regular expression
pattern as described in edit.
.fi
.sp
.ne 2
.ti -3
SEE ALSO
.br
change, edit, find, lam
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
bad argument
.br
.in +3
The value of "n" is invalid.
.in -3
.sp
illegal from pattern
.br
illegal to pattern
.br
.in +3
The specification for the indicated pattern is invalid.
.in -3
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  split.doc                  1983  local   12/10/80  15:54:51
#-h-  tail.doc                    884  local   12/10/80  15:54:52
.bp 1
.in 0
.he 'TAIL (1)'8/26/79'TAIL (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
tail - print last lines of a file
.nf
.sp
.ti -3
SYNOPSIS
.br
tail [-n] [file....]
.fi
.sp
.ti -3
DESCRIPTION
.br
Tail
prints the last "n" lines of the indicated file.
If 'n' is omitted, the last 23 lines are printed.

If "file" is omitted or is "-", tail reads the standard input.
.sp
.ti -3
SEE ALSO
.br
split
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
.sp
.ti -3
BUGS/DEFICIENCIES
.br
An internal buffer of MAXBUF characters is kept.
If the value of "n" would require buffering more characters than
the buffer can hold,
tail
prints the last MAXBUF characters of the file.
In this case, the first line of output may not be an entire line.
MAXBUF is a definition in the source code which may be adjusted.
#-t-  tail.doc                    884  local   12/10/80  15:54:52
#-h-  tee.doc                     743  local   12/10/80  15:54:52
.bp 1
.in 0
.he 'TEE (1)'9/1/78'TEE (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
tee - copy input to output and named files
.nf
.sp
.ti -3
SYNOPSIS
.br
tee files...
.fi
.sp
.ti -3
DESCRIPTION
.br
Tee copies its standard input to the standard output and
makes copies in the named files.  It is useful for
making copies of or
seeing what is being transmitted through a pipeline,
viz.,
.sp
.in +3
.nf
prog1 | tee file tty: | prog2
.in -3
.sp
.fi
causes the output of prog1 to be saved in "file", displayed
on the terminal, and input to prog2.
.fi
.sp
.ne 2
.ti -3
SEE ALSO
.br
cat, page
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
A message is issued if one of the named files cannot be
created.
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  tee.doc                     743  local   12/10/80  15:54:52
#-h-  tr.doc                     2484  local   12/24/80  15:51:25
.bp 1
.in 0
.he 'TR (1)'07/06/78'TR (1)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
tr - character transliteration
.sp 1
.ti -7
SYNOPSIS
.br
tr <infile >outfile from [to]
.sp 1
.ti -7
DESCRIPTION
.br
"TR" copies the standard input to the standard output with
substitution or deletion of selected characters.  Input
characters found in "FROM" are mapped into the corresponding
characters of "TO".
Ranges of characters may be specified by separating
the extremes by a dash.
For example, a-z stands for the string of characters whose ascii
codes run from character a through character z.

If the number of characters
in "FROM" is the same as in "TO", a one to one corresponding
translation will be performed on all occurrences of the characters
in "FROM".
If the number of characters in "FROM" is more than in "TO", the
implication is that the last character in the "TO" string is
to be replicated as often as necessary to make a string as long
as the "FROM" string, and that this replicated character should
be collapsed into only one.  If the "TO" string is missing or
empty, "TR" will take this condition as a request to delete
all occurrences of characters in the "FROM" string.
.sp 1
"TR" differs from the tool "CH" since it deals only with
single characters or ranges of characters, while "CH" deals
with character strings.  For example  tr xy yx  would change
all x's into y's and all y's into x's, whereas ch xy yx
change all the patterns "xy" into "yx".
.sp 1
One of the most common functions of "TR" is to translate
upper case letters to lower case, and vice versa.  Thus,

.ce
tr A-Z a-z

would map all upper case letters to lower
case.
Users of systems which cannot pass
both upper and lower case characters on a command line
should remember to include the appropriate escape flags.
.sp 1
.ti -7
FILES
.br
None
.sp 1
.ti -7
SEE ALSO
.br
.nf
find, ch, edit, sedit
The "Software Tools" book, p. 51-61.
The "UNIX Programmer's Manual", p. TR(I).
.fi
.sp 1
.ti -7
DIAGNOSTICS
.br
"usage: translit from to."
.br
.in +5
The command line passed to transit is in error.
.br
.in -5
"from: too large."
.br
.in +5
The string for "from" is too large.  Current limit is 100 characters
including E0S.
.br
.in -5
"to: too large."
.br
.in +5
The string for "to" is too large.  Current limit is 100 characters
including EOS.
.sp 1
.in -5
.ti -7
AUTHORS
.br
Original code from Kernighan and Plauger's "Software Tools",
with minor modifications by Debbie Scherrer.
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
#-t-  tr.doc                     2484  local   12/24/80  15:51:25
#-h-  tsort.doc                  2136  local   12/10/80  15:54:54
.bp 1
.in 0
.he 'TSORT (1)'10/1/78'TSORT (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
tsort - topologically sort symbols
.nf
.sp
.ti -3
SYNOPSIS
.br
tsort [files ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Tsort
topologically sorts the symbols in the named files.
If no files are specified, or the filename '-' is given,
tsort reads the standard input.

A symbol is considered any string of characters delimited
by blanks or tabs.

Each line of the input is assumed to be of the form
.sp
.in +3
.nf
a b c ...
.in -3
.sp
.fi
which states that
a
precedes
b, a
precedes
c,
and so on.
Note that there is nothing implied about the ordering of
b
and
c.
A line consisting of a single symbol simply "declares"
that symbol without specifying any ordering relations about it.
The output is a topologically sorted
list of symbols, one per line.
.sp
.fi
For example, suppose you have trouble getting up in the morning
because you can't quite remember what actions have to be
performed in which order.
However, you do know that the first action in the following
list precedes all others on the line:

.in +5
.nf
set_alarm   turn_off_alarm
wake_up    get_out_of_bed    turn_off_alarm
set_alarm     wake_up
.in -5
.fi

Using tsort to sort the above list would produce the following
set of actions for getting out of bed:

.in +5
.nf
set_alarm
wake_up
turn_off_alarm
get_out_of_bed
.fi
.in -5
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
circular
.br
.in +3
The input specifies a graph that contains at least one cycle.
.in -3
.sp
out of storage
.br
.in +3
The input is too large.
The size of tsort's buffer is determined by the MAXBUF
definition in the source code.
.in -3
.sp
.ne 2
.ti -3
SEE ALSO
.br
sort
.ne 3
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  tsort.doc                  2136  local   12/10/80  15:54:54
#-h-  uniq.doc                    869  local   01/09/81  00:39:24
.bp 1
.in 0
.he 'UNIQ (1)'1/11/79'UNIQ (1)'
.fo ''-#-'
.fi
NAME
.br
.in 7
uniq - strip adjacent repeated lines from a file
.sp 1
.in
SYNOPSIS
.br
.in 7
uniq [-c] [file ...]
.sp 1
.in
DESCRIPTION
.br
.in 7
Uniq
reads the input file(s), comparing adjacent lines.
Second and succeeding copies of repeated lines are removed; the
remainder is written to standard output.

If the '-c' flag is given,
each line is preceded by a count of the number of occurrences of
that line.
.sp 1
.in
FILES
.br
.in 7
.sp 1
.in
SEE ALSO
.br
.in 7
The tool 'comm'; the Unix command 'uniq'
.sp 1
.in
DIAGNOSTICS
.br
.in 7
A message is printed if an input file cannot be opened and
processing is terminated.
.sp 1
.in
AUTHORS
.br
.in 7
.sp 1
Originally from Kernighan and Plauger's 'Software Tools', with
modifications by Debbie Scherrer (Lawrence Berkeley Laboratory)
.sp 1
.in
BUGS
.br
.in 7
#-t-  uniq.doc                    869  local   01/09/81  00:39:24
#-h-  unrot.doc                   890  local   01/06/81  23:25:46
.bp 1
.in 0 
.he 'UNROT (1)'1/15/79'UNROT (1)'
.fo ''-#-' 
.fi 
NAME 
.br 
.in 7 
unrot - unrotate lines rotated by kwic
.sp 1 
.in 
SYNOPSIS 
.br 
.in 7 
unrot [-n] [file ...]
.sp 1 
.in 
DESCRIPTION 
.br 
.in 7 
Unrot
processes the rotated output of 'kwic' to generate a keyword-in-context
index.
 
The -n flag may be used to specify the width of the output lines.
The default is 80.
 
If no input files are given, or the filename '-' appears, lines will
be read from standard input.
.sp 1
.in 
FILES 
.br 
.in 7 
.sp 1 
.in 
SEE ALSO 
.br 
.in 7 
kwic; sort
.sp 1 
.in 
DIAGNOSTICS 
.br 
.in 7 
A message is printed if an input file cannot be opened; further processing
is terminated.
.sp 1 
.in 
AUTHORS 
.br 
.in 7 
.sp 1 
Original from Kernighan and Plauger's 'Software Tools', with 
minor modifications
by Debbie Scherrer, Lawrence Berkeley Laboratory.
.sp 1 
.in 
BUGS 
.br 
.in 7 
#-t-  unrot.doc                   890  local   01/06/81  23:25:46
#-h-  wc.doc                      913  local   12/10/80  15:54:56
.bp 1
.in 0
.he 'WC (1)'2/15/79'WC (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
wc - count lines, words, and characters in files
.nf
.sp
.ti -3
SYNOPSIS
.br
wc [-lwc] files...
.fi
.sp
.ti -3
DESCRIPTION
.br
Wc prints the number of lines, words, and characters in the named
files.
The filename "-" specifies the standard input.
A total is also printed.  A "word" is any sequence of characters
delimited by white space.
.sp
The options -l, -w, and -c specify, respectively, that only the line,
word, or character count be printed.  For example,
.sp
.in +3
.nf
wc -lc foo
.in -3
.sp
.fi
prints the number of lines and characters in "foo".
.sp
If no files are given, wc reads its standard input and the total
count is suppressed.
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
name: can't open
.in +5
Printed when an input file can't be opened; processing ceases
.in -5
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
#-t-  wc.doc                      913  local   12/10/80  15:54:56
#-h-  xref.doc                   1297  local   12/10/80  15:54:56
.bp 1
.in 0
.he 'XREF (1)'1/1/79'XREF (1)'
.sp 2
.in +3
.fi
.ti -3
NAME
.br
xref - make a cross reference of symbols
.nf
.sp
.ti -3
SYNOPSIS
.br
xref [-f] [files ...]
.fi
.sp
.ti -3
DESCRIPTION
.br
Xref
produces a cross-reference
list of the symbols in each of the named files
on the standard output.
Each symbol is listed followed by the numbers of the lines
in which it appears.
If no files are given,
or the file "-" is specified, xref reads the standard input.
.sp
A symbol is defined as a string of letters, digits, underlines,
or periods that begins with a letter.
Symbols exceeding an internal limit are truncated.
This limit is determined by the MAXTOK definition in
the source code, and is currently set to 15.
.sp
Normally, xref treats upper- and lower-case letters as different
characters.  The -f option causes all letters to be folded to
lower-case.
.fi
.sp
.ne 2
.ti -3
DIAGNOSTICS
.br
out of storage
.br
.in +3
The file contains too many symbols or references to fit
within the current limitations of xref.
The size of the buffer is determined by the MAXBUF definition
in the source code.
.in -3
.fi
.sp
.ti -3
AUTHORS
.br
David Hanson and friends (U. of Arizona)
.sp
.ne 2
.ti -3
BUGS/DEFICIENCIES
.br
There should be a means of suppressing "junk" symbols such
as "the", "a", etc.
#-t-  xref.doc                   1297  local   12/10/80  15:54:56
#-h-  library                    2573  local   01/07/81  01:58:02
.bp 1
.in 0
.he ''''
.ce
2.  SUBROUTINES AND FUNCTIONS
.sp 2
This section describes the use of the subroutines and functions
generally available with the software tools.
(The user should consult Section 3 for information about
linking these routines with his own programs.)
.sp
The library consists of system-independent routines as well
as a set of "primitives", those functions that are
machine-dependent and must be implemented for each local
operating system.
However, the form of invocation of the primitives is
machine-independent;
it is the implementation of the primitives themselves
that is specific to a given system.
.sp
For each primitive there is an IMPLEMENTATION section, which
describes possible implementation strategies or suggestions
to the local implementor when she is preparing the primitives
for her local system.
.sp
The SYNOPSIS subsection of each entry gives the form of
the invocation, the type of the arguments (in the form of
Fortran declarations), and the type of the returned value if
the entry is a function.
The type "character" refers to a right-justified ASCII
character, and arrays of type character are sequences of
right-justified ASCII characters, stored one per array
element, and terminated by the value of the parameter
EOS.
All software tools programs deal with only ASCII arrays, even
though the local system may use a different character type.
Conversion from local to ASCII is done in the primitives
(getch, putch).
.sp
The names of arguments are chosen to help convey the kind
of data transmitted in them.
Some commonly used names are as follows:
.sp
.in +5
"fd" is used where the argument or returned value is a
file descriptor as returned by "open" or "create".
File descriptors are simply small integers used as arguments
to I/O primitives.
Their actual value is of no concern to the programmer,
other than for transmission to the primitives.
.sp
"name" or "file" is used when the argument refers to a character
string representing a file name.
.sp
"str" or "lin" is used when the argument refers to a character
string as described above.
.sp
"i", "k", "n", etc. are used when the argument or
returned value refers to an index.
.sp
"stat" or "status" is used when the argument or returned value
indicates some form of status information.
Commonly used values of status are ERR, NOERR, OK, YES, NO, etc.
.sp
.in -5
Note that the names of the functions do not conform to the
usual Fortran defaults for the names of integer and
real functions.
It is therefore advisable to explicitly declare all
variables and functions used.
#-t-  library                    2573  local   01/07/81  01:58:02
#-h-  defns                      4301  local   01/09/81  13:50:35
.bp 1
.in 0
.he 'DEFINITIONS (2)'7/28/80'DEFINITIONS (2)'
.in 7
.ti -7
NAME
.br
standard Ratfor symbol definitions
.sp
.ti -7
DESCRIPTION
.br
The following macro definitions are generally made available to the
user automatically whenever ratfor is called.
Case is significant:
.sp
.nf

# ASCII control character definitions:

NUL        ENQ        LF         SI         DC4        EM         RS
SOH        ACK        VT         DLE        NAK        SUB        US
STX        BEL        FF         DC1        SYN        ESC        SP
ETX        BS         CR         DC2        ETB        FS         DEL
EOT        HT         SO         DC3        CAN        GS


# Synonyms for important non-printing ASCII characters:

BACKSPACE  BELL       BLANK      NEWLINE    RUBOUT     TAB


# Printable ASCII characters:

ACCENT     BIGH       BIGW       DIG7       LETE       LETT       RBRACE
AMPER      BIGI       BIGX       DIG8       LETF       LETU       RBRACK
AMPERSAND  BIGJ       BIGY       DIG9       LETG       LETV       RPAREN
AND        BIGK       BIGZ       DOLLAR     LETH       LETW       SEMICOL
ATSIGN     BIGL       CARET      DQUOTE     LETI       LETX       SHARP
BACKSLASH  BIGM       COLON      EQUALS     LETJ       LETY       SLASH
BANG       BIGN       COMMA      ESCAPE     LETK       LETZ       SQUOTE
BAR        BIGO       DASH       GREATER    LETL       LPAREN     STAR
BIGA       BIGP       DIG0       LBRACE     LETM       MINUS      TAB
BIGB       BIGQ       DIG1       LBRACK     LETN       NOT        TILDE
BIGC       BIGR       DIG2       LESS       LETO       OR         UNDERLINE
BIGD       BIGS       DIG3       LETA       LETP       PERCENT
BIGE       BIGT       DIG4       LETB       LETQ       PERIOD
BIGF       BIGU       DIG5       LETC       LETR       PLUS
BIGG       BIGV       DIG6       LETD       LETS       QMARK


# Ratfor language extensions:

andif      CHARACTER  filedes    IS_LETTER  long_real  min        POINTER
ARB        DS_DECL    FILEDES    IS_LOWER   max        MIN
character  elif       IS_DIGIT   IS_UPPER   MAX        pointer



.ne 3
# Input/output modes:

APPEND     READ       READWRITE  WRITE


# Standard input/output ports:

ERROUT          # standard error file
STDERR
STDIN           # standard input file
STDOUT          # standard output file
TERMINAL_IN     # name of terminal (input channel)
TERMINAL_OUT    # name of terminal (output channel)


# Manifest constants included for readability and modifiability:

ALPHA           # flag for alphabetic character
ASCII           # flag for ascii character file
BEGINNING_OF_FILE  # flag to seek for positioning at
                   # the beginning of a file
BINARY          # flag for indicating binary file
DIGIT           # flag for number
END_OF_FILE     # flag to seek for positioning at end of file
EOF             # flag for end-of-file
EOS             # used to mark end of character strings
ERR             # error return from functions
HUGE            # some arbitrarily large number
LAMBDA          # end of list marker
LETTER          # flag for ascii letter
LOCAL           # flag for local-type character file
NO
NOERR           # flag for successful completion
OK              # success flag
YES


.ne 7
# Size limiting definitions for important objects:

FILENAMESIZE    # max characters in file name
MAXARG          # max size of command line argument
MAXCARD         # "card" size
MAXCHARS        # max nbr of chars when converting
                # from integers to characters
MAXLINE         # normal size of line buffers
MAXNAME         # max size of file name
MAXOFILES       # max nbr opened files allowed at a time
MAXPAT          # max size of encoded patterns
                # (used in string matching)
NCHARS          # number of special characters


# Machine-dependent parameters:

BITS_PER_CHAR
BITS_PER_WORD
CHARS_PER_WORD
MAX_INTEGER
MIN_INTEGER
MAX_REAL_EXP
MIN_REAL_EXP
REAL_PRECISION


 DRIVER         #main driving routine (may not be necessary)
 DRETURN        #return from main driving routine

 
# Definitions for 'spawn' primitive (if implemented):

WAIT            # wait for subprocess to complete
NOWAIT          # control returns as soon as
                # subprocess starts
BACKGR          # spawning a background process


.fi
.in 0
#-t-  defns                      4301  local   01/09/81  13:50:35
#-h-  addset                      984  local   12/10/80  15:55:00
.bp 1
.in 0
.he 'ADDSET (2)'11/13/78'ADDSET (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
addset - put c in array(j) if it fits, increment j
.sp 1
.ti -7
SYNOPSIS
.br
.nf
stat = addset(c, array, j, maxsize)

character c, array(ARB)
integer j                 # j is incremented
integer maxsize
integer stat returned as YES/NO
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Adds a character at a time to a specified position of an array
and increments the index.
It also checks that there's enough room to do so.

The array is an ascii character array stored one character per
word.
'c' is a single ascii character.

YES is returned if the routine succeeded, otherwise NO.
.sp 1
.ti -7
SEE ALSO
.br
scopy, stcopy, addstr, concat
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  addset                      984  local   12/10/80  15:55:00
#-h-  addstr                     1161  local   12/10/80  15:55:01
.bp 1
.in 0
.he 'ADDSTR (2)'7/23/80'ADDSTR (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
addstr - add string s to str(j) if it fits, increment j
.sp 1
.ti -7
SYNOPSIS
.br
.nf
stat = addstr(s, array, j, maxsize)

character s(ARB), array(ARB)
integer j                 # j is incremented
integer maxsize
integer stat returned as YES/NO
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Copies the string 's' to array 'str', starting in location 'j'.
J is incremented to point to the next free position in 'str'.

If the addition of s to str will exceed its maximum length (maxsize),
no copying is done and the status NO is returned.

Both s and str are ascii character arrays stored one character per
array element.

YES is returned if the routine succeeded, otherwise NO.
.sp 1
.ti -7
SEE ALSO
.br
scopy, stcopy, addset, concat
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  addstr                     1161  local   12/10/80  15:55:01
#-h-  amatch                     1329  local   12/10/80  16:02:22
.bp 1
.in 0
.he 'AMATCH (2)'7/23/80'AMATCH (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
amatch - look for pattern matching regular expression; returns
its location
.sp 1
.ti -7
SYNOPSIS
.br
.nf
loc = amatch (line, from, pat, tagbeg, tagend)

character line(ARB), pat(MAXPAT)
integer from
integer tagbeg(10), tagend(10)
(element "i + 1" returns start or end, respectively,
of "i"th tagged subpattern)
integer loc returns location/0
matched; if no match, loc is returned as 0
.br
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Amatch scans 'line' starting at location 'from', looking
for a pattern which matches the
regular expression coded in 'pat'.
If the pattern is found, its starting location in line is returned.
If the pattern is not found, amatch returns 0.

The regular expression in 'pat' must have been previously
encoded by 'getpat' or 'makpat'.
(For a complete description of regular expressions,
see the
writeup on the editor.)

Amatch is a special-purpose version of match, which should be
used in most cases.
.sp 1
.ti -7
SEE ALSO
.br
match, getpat, makpat
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  amatch                     1329  local   12/10/80  16:02:22
#-h-  amove                      1399  local   01/07/81  22:55:45
.bp 1
.in 0
.he 'AMOVE (2)'11/10/78'AMOVE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
amove - move (rename) file1 to file2
.sp 1
.ti -7
SYNOPSIS
.br
stat = amove (name1, name2)
.br
.sp
.nf
character name1(FILENAMESIZE), name2(FILENAMESIZE)
integer stat returned as OK/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Amove
moves the contents of the file specified by
name1
to the file specified by
name2.
It is essentially a renaming of the file.
If the file could be moved properly, OK is returned.
If there were problems either creating the new file or
deleting the old one, ERR is returned.

Both file names are ascii character strings terminated with an
EOS marker.

The files need not be connected to the running program to be
renamed.
.sp 1
.ti -7
IMPLEMENTATION
.br
Amove primarily exists to change the name of a file,
such as when moving the archive scratch file back to the original.
If possible, this should be implemented with a "rename"
primitive in the local operating system.
If this capability isn't available, amove could be implemented
as a copy/delete combination.
.sp
Amoves from different devices will most likely have to be 
implemented as copy/remove operations.
.sp
If the system supports naming conventions for devices
such as TTYs, then amoving a file to a TTY should copy the file
to the TTY and then remove it.
.sp 1
.ti -7
SEE ALSO
.br
fcopy, remove
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  amove                      1399  local   01/07/81  22:55:45
#-h-  cant                        709  local   12/10/80  16:02:25
.bp 1
.in 0
.he 'CANT (2)'11/13/78'CANT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
cant - print 'name: can't open' and terminate execution
.sp 1
.ti -7
SYNOPSIS
.br
call cant(name)

character name(ARB)
.sp 1
.ti -7
DESCRIPTION
.br
On ERROUT, prints the filename specified by 'name' followed by the
message "can't open" and terminates execution.
All open files are closed.
Name is an ascii character array terminated with an EOS marker.
.sp
Cant is essentially:
.br
.in +5
.nf
call putlin (name, ERROUT)
call remark (": can't open.")
call endst
.fi
.in -5
.sp 1
.ti -7
SEE ALSO
.br
error, remark
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  cant                        709  local   12/10/80  16:02:25
#-h-  close                      1088  local   01/07/81  22:55:46
.bp 1
.in 0
.he 'CLOSE (2)'11/10/78'CLOSE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
close - close (detach) a file
.sp 1
.ti -7
SYNOPSIS
.br
call close (fd)
.sp
filedes fd
.sp 1
.ti -7
DESCRIPTION
.br
Close disassociates file descriptor "fd" from the opened
file to which it refers.
If "fd" is the only descriptor referring to that file,
all pending I/O is completed and the file is closed.
If "fd" does not refer to an opened file, close simply returns.
"fd" is an internal file descriptor as returned from an
open
or
create
call.

.ti -7
IMPLEMENTATION
.br
Close
breaks the connection between the program and a file accessed via
open
or
create.
If necessary, the file's write buffer is flushed and the end
of the file is marked so that subsequent reads will find an EOF.
If a file has been opened multiple times (that is, more than one
internal descriptor has been assigned to a file), care is
taken that multiple closes will not damage the file.
.sp 1
.ti -7
SEE ALSO
.br
open, create, endst
.sp 1
.ti -7
DIAGNOSTICS
.br
If the file descriptor is in error, the routine simply returns.
#-t-  close                      1088  local   01/07/81  22:55:46
#-h-  clower                      466  local   12/10/80  16:02:28
.bp 1
.in 0
.he 'CLOWER (2)'11/13/78'CLOWER (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
clower - fold c to lower case
.sp 1
.ti -7
SYNOPSIS
.br
c = clower(c)

character c
.sp 1
.ti -7
DESCRIPTION
.br
Fold character c to lower case, if not already there.
If c is not alphabetic, returns it unchanged.
.sp 1
.ti -7
SEE ALSO
.br
fold, upper, lower, clower
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  clower                      466  local   12/10/80  16:02:28
#-h-  concat                      731  local   12/10/80  16:02:28
.bp 1
.in 0
.he 'CONCAT (2)'7/23/80'CONCAT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
concat - concatenate 2 strings together
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call concat(buf1, buf2, outstr)

character buf1(ARB), buf2(ARB), outstr(ARB)
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Copies the arrays buf1 and buf2 into the array outstr.

All arrays are ascii character arrays stored one character per
array element.

.sp 1
.ti -7
SEE ALSO
.br
scopy, stcopy, addset, addstr
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  concat                      731  local   12/10/80  16:02:28
#-h-  create                     1355  local   01/07/81  22:56:17
.bp 1
.in 0
.he 'CREATE (2)'11/10/78'CREATE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
create - create a new file (or overwrite an existing one)
.sp 1
.ti -7
SYNOPSIS
.br
fd = create (name, access)
.br

.nf
character name(FILENAMESIZE)
integer access
filedes fd - returned as a file descriptor/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Create
creates a new file whose name is contained in "name"
and then opens it for I/O according to the value of "mode",
as if open had been called (see "open").
If the file already exists, it is truncated and prepared for
overwriting.
.sp
If the creation succeeded, create returns a file descriptor
which is used to refer to the file in subsequent I/O calls.
If the file could not be created, ERR is returned.
.sp 1
.ti -7
IMPLEMENTATION
.br
Create
creates a new file from within a running program
and connects the external name of the file to an internal
identifier
which is then usable in subsequent subroutine calls.
If the file already exists, the old version is removed or
truncated to 0 length and overwritten.
All other functions are similar to
open.

On some systems a default character type (ASCII or LOCAL) is
assigned to a newly-created file.
.sp 1
.ti -7
SEE ALSO
.br
open, close
.sp 1
.ti -7
DIAGNOSTICS
.br
The function returns ERR if the file could not be created or if
there are already too many files open.
#-t-  create                     1355  local   01/07/81  22:56:17
#-h-  ctoc                       1180  local   12/10/80  16:02:30
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd CTOC 03/23/80
copy string-to-string, observing length limits
.sy
integer function ctoc (from, to, len)
integer len
character from (ARB), to (len)
.fs
'Ctoc' copies an EOS-terminated unpacked string from one array to
another, observing a maximum-length constraint on the destination array.
The function return is the number of characters copied (i.e., the
length of the string in the parameter 'to').
.sp
Note that the other string copy routine, 'scopy', is not protected;
if the length of the source string exceeds the space available in the
destination string, some portion of memory will be garbled.
.im
A simple loop copies characters from 'from' to 'to' until
an EOS is encountered or all the space available in the destination
array is used up.
.am
to
.sa
scopy (2), other conversion routines ('cto?*' and '?*toc') (2)
#-t-  ctoc                       1180  local   12/10/80  16:02:30
#-h-  ctoi                       1161  local   12/10/80  16:02:31
.bp 1
.in 0
.he 'CTOI (2)'11/13/78'CTOI (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
ctoi - convert string at in(i) to integer, increment i
.sp 1
.ti -7
SYNOPSIS
.br
.nf
n = ctoi(in, i)

character in(ARB)
integer i               # i is incremented
integer n is returned as the converted integer
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts a character string to an integer.
Starts looking at position
i
of
in.
Plus and minus signs are not allowed.
Leading blanks and tabs are ignored; any subsequent digits are
converted to the correct numeric value.
The first non-digit seen terminates the scan; upon return,
i
points to this position.
n
is returned as the value of the integer.

The
in
array is an ascii character array terminated with an EOS marker
(or a non-numeric character).

Zero is returned if no digits are found.
.sp 1
.ti -7
SEE ALSO
.br
itoc
.sp 1
.ti -7
DIAGNOSTICS
.br
There are no checks for machine overflow.
#-t-  ctoi                       1161  local   12/10/80  16:02:31
#-h-  ctomn                       956  local   12/10/80  16:02:31
.hd CTOMN 03/28/80
translate ASCII control character to mnemonic
.sy
integer function ctomn (c, rep)
character c, rep (4)
.fs
'Ctomn' is used to convert an unprintable ASCII character to its
official ASCII mnemonic.
The first argument is the character to be converted;
the second is a string to receive the mnemonic.
The function return is the length of the string placed in the second
argument.
.sp
If the character passed is printable, it is copied through unchanged
to the receiving string.
If not, its two- or three-character ASCII mnemonic
(e.g. NUL, SOH, etc.) is copied into the receiving string.
.im
If the character is printable, it is placed in the receiving string,
which is then terminated with EOS.
If the character is between 0 and 32, inclusive,
or equals 127,
its value is
used to compute an index into a string table containing the
mnemonics.
The mnemonic thus selected is copied into the receiving string.
.am
rep
.ca
scopy
.sa
mntoc (2)
#-t-  ctomn                       956  local   12/10/80  16:02:31
#-h-  cupper                      499  local   12/10/80  16:02:32
.bp 1
.in 0
.he 'CUPPER (2)'11/13/78'CUPPER (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
cupper - convert character to upper case
.sp 1
.ti -7
SYNOPSIS
.br
.nf
c = cupper(c)

character c
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts ascii character c to upper case, if not already there.
Non-alphabetic characters are returned unchanged.
.sp 1
.ti -7
SEE ALSO
.br
upper, clower, fold, lower
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  cupper                      499  local   12/10/80  16:02:32
#-h-  delarg                      675  local   01/07/81  22:55:48
.bp 1
.in 0
.he 'DELARG (2)'6/5/79'DELARG (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
delarg - delete command line argument number 'n'
.sp 1
.ti -7
SYNOPSIS
.br
call delarg (n)
.sp
integer n
.sp 1
.ti -7
DESCRIPTION
.br
Delarg
deletes the "n"th command line argument, if it exists.
After a successful call to delarg, calls to getarg
behave as though the deleted argument had never
been specified.
.sp 1
.ti -7
IMPLEMENTATION
.br
Delarg
works in conjunction with 'getarg'.
It generally re-orders indices to an array holding the command
line arguments.
.sp 1
.ti -7
SEE ALSO
.br
getarg,
initst
.sp 1
.ti -7
DIAGNOSTICS
.br
If argument 'n' does not exist, delarg simply returns.
#-t-  delarg                      675  local   01/07/81  22:55:48
#-h-  delete                     1242  local   12/10/80  16:02:33
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd DELETE 03/23/80
remove a symbol from a symbol table
.sy
subroutine delete (symbol, table)
character symbol (ARB)
pointer table
.fs
'Delete' removes the character-string symbol given as its first argument
from the symbol table given as its second argument.
All information associated with the symbol is lost.
.sp
The symbol table specified must have been generated by the routine 'mktabl'.
.sp
If the given symbol is not present in the symbol table, 'delete'
does nothing; this condition is not considered an error.
.im
'Delete' calls 'stlu' to determine the location of the given symbol
in the symbol table.
If present, it is unlinked from its hash chain.
The dynamic storage space allocated to the symbol's node is returned
to the system by a call to 'dsfree'.
.ca
stlu, dsfree
.sa
enter (2), lookup (2), mktabl (2), rmtabl (2), stlu (2),
dsget (2), dsfree (2), dsinit (2), sctabl (2)
#-t-  delete                     1242  local   12/10/80  16:02:33
#-h-  dsfree                     1528  local   12/10/80  16:02:38
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd DSFREE 03/23/80
free a block of dynamic storage
.sy
subroutine dsfree (block)
pointer block
.fs
'Dsfree' returns a block of storage allocated by 'dsget' to the
available space list.
The argument must be a pointer returned by 'dsget'.
.sp
See the remarks under 'dsget' for required initialization measures.
.im
'Dsfree' is an implementation of Algorithm B on page 440 of Volume 1
of The Art of Computer Programming, by Donald E. Knuth.
The reader is referred to that source for detailed information.
.sp
'Dsfree' and 'dsget' maintain a list of free storage blocks,
ordered by address.
'Dsfree' searches the list to find the proper location for the block
being returned, and inserts the block into the list at that location.
If blocks on either side of the newly-returned block are available,
they are coalesced with the new block.
If the block address does not correspond to the address of any
allocated block, 'dsfree' remarks "attempt to free unallocated
block" and waits for the user to type a letter "c" to continue.
If any other character is typed, the program is terminated.
.bu
The algorithm itself is not the best.
.sa
dsget (2), dsinit (2), dsdump (2), dsdbiu (2)
#-t-  dsfree                     1528  local   12/10/80  16:02:38
#-h-  dsget                      2360  local   12/10/80  16:02:39
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd DSGET 03/23/80
obtain a block of dynamic storage
.sy
pointer function dsget (w)
integer w
.fs
'Dsget' searches its available memory list for a block that is
at least as large as its first argument.
If such a block is found, its index in the memory list is returned;
otherwise, an error message is printed and the program terminates.
.sp
In order to use 'dsget', the following declaration must be present:
   DS_DECL (mem, MEMSIZE)
.br
where MEMSIZE is supplied by the user, and may take on any positive
value between 6 and 32767, inclusive.
Furthermore, memory must have been initialized with a call to 'dsinit':
   call dsinit (MEMSIZE)
.im
'Dsget' is an implementation of Algorithm A' on pages 437-438 of
Volume 1 of The Art of Computer Programming, by Donald E. Knuth.
The reader is referred to that source for detailed information.
.sp
'Dsget' searches a linear list of available blocks for one of
sufficient size.
If none are available, a call to 'error' results;
otherwise, the block found is broken into two pieces, and the index
(in array 'mem') of the piece of the desired size is returned to
the user.
The remaining piece is left on the available space list.
Should this procedure cause a block to be left on the available
space list that is smaller than a threshhold size, the few extra
words are awarded to the user and the block is removed entirely,
thus speeding up the next search for space.
If insufficient space is available, 'dsget' reports "out of storage
space" and allows the user to obtain a dump of dynamic storage
space if he desires.
.ca
error, dsdump
.bu
Should probably return error status to the user if space is not found.
It is also somewhat annoying for the user to have to declare
the storage area, but Fortran prevents effective use of pointers,
so this inconvenience is necessary for now.
Note that the storage area is declared as
.ul
integer,
not
.ul
character,
which may be cause for caution in some implementations.
.sa
dsfree (2), dsinit (2), dsdump (2), dsdbiu (2)
#-t-  dsget                      2360  local   12/10/80  16:02:39
#-h-  dsinit                     1256  local   12/10/80  16:02:40
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd DSINIT 03/23/80
initialize dynamic storage space
.sy
subroutine dsinit (w)
integer w
.fs
'Dsinit' initializes an area of storage in the common block CDSMEM
so that the routines 'dsget' and 'dsfree' can be used for dynamic
storage allocation.
The memory to be managed must be supplied by the user, by a
declaration of the form:
   DS_DECL (mem, MEMSIZE)
.br
which turns into something similar to
   integer mem (MEMSIZE)
   common /cdsmem/ mem
.br
The memory size must then be passed to 'dsinit' as its argument:
   call dsinit (MEMSIZE)
.im
'Dsinit' sets up an available space list consisting of two blocks,
the first empty and the second containing all remaining memory.
The first word of memory (below the available space list) is set
to the total size of memory; this information is used only by the
dump routines 'dsdump' and 'dsdbiu'.
.ca
error
.sa
dsget (2), dsfree (2), dsdump (2), dsdbiu (2)
#-t-  dsinit                     1256  local   12/10/80  16:02:40
#-h-  endst                       846  local   01/07/81  22:57:28
.bp 1
.in 0
.he 'ENDST (2)'11/10/78'ENDST (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
endst - close all open files and terminate program execution
.sp 1
.ti -7
SYNOPSIS
.br
call endst
.sp 1
.ti -7
DESCRIPTION
.br
Normally called at the end of any ratfor program or program
which uses the software tools primitives.
Closes all open files and terminates program execution.
.sp
On many systems a call to endst is made automatically, either
by the system or by specifically inserting the call into
code processed by the ratfor preprocessor.
.sp 1
.ti -7
IMPLEMENTATION
.br
Any open files are closed.
If any files have been opened multiple times (that is, they have more
than one internal descriptor assigned to them), care is
taken that multiple closes do not damage
the file.
.sp 1
.ti -7
SEE ALSO
.br
close, initst
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  endst                       846  local   01/07/81  22:57:28
#-h-  enter                      1662  local   12/10/80  16:02:42
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd ENTER 03/23/80
place symbol in symbol table
.sy
subroutine enter (symbol, info, table)
character symbol (ARB)
integer info (ARB)
pointer table
.fs
'Enter' places the character-string symbol given as its first argument,
along with the information given in its second argument, into the symbol
table given as its third argument.
.sp
The symbol table used must have been created by the routine 'mktabl'.
The size of the info array must be at least as large as the symbol
table node size, determined at table creation time.
.sp
Should the given symbol already be present in the symbol table,
its information field will simply be overwritten with the new information.
.sp
'Enter' uses the dynamic storage management routines, which
require initialization by the user; see 'dsinit' for further details.
.im
'Enter' calls 'stlu' to find the proper location for the symbol.
If the symbol is not present in the table, a call to 'dsget' fetches
a block of memory of sufficient size, which is then linked onto the
proper chain from the hash table.
Once the location of the node for the given symbol is known, the
contents of the information array are copied into the node's information
field.
.ca
stlu, dsget
.sa
lookup (2), delete (2), mktabl (2), rmtabl (2), stlu (2),
dsget (2), dsfree (2), dsinit (2), sctabl (2)
#-t-  enter                      1662  local   12/10/80  16:02:42
#-h-  equal                       585  local   12/10/80  16:02:43
.bp 1
.in 0
.he 'EQUAL (2)'11/13/78'EQUAL (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
equal - compare str1 to str2; return YES if equal
.sp 1
.ti -7
SYNOPSIS
.br
.nf
stat = equal(str1, str2)

character str1(ARB), str2(ARB)
integer stat is returned as YES/NO
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Compares two strings, returning YES if they are the same, NO
if they differ.
Each string is an ascii character array
terminated with an EOS marker.
.sp 1
.ti -7
SEE ALSO
.br
strcmp
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  equal                       585  local   12/10/80  16:02:43
#-h-  error                      1068  local   12/10/80  16:02:44
.bp 1
.in 0
.he 'ERROR (2)'7/23/80'ERROR (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
error - print single-line message and terminate execution
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call error (message)

integer message          #message is a hollerith array
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Error
writes the message onto the standard error file ERROUT.
A NEWLINE is always generated, even though one may not appear in
the message.
Endst is called
and execution ceases.

Error is essentially a call to 'remark' and then to 'endst'.

The message array is a Fortran hollerith string in the
format generated by the Ratfor quoted string capability.
On some systems,
it may be necessary to terminate the string with a '.' or other
end-of-string marker.
.sp 1
.ti -7
SEE ALSO
.br
remark, putlin, prompt, endst
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  error                      1068  local   12/10/80  16:02:44
#-h-  esc                        1095  local   12/10/80  16:18:07
.bp 1
.in 0
.he 'ESC (2)'7/23/80'ESC (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
esc - map array(i) into escaped character, if appropriate
.sp 1
.ti -7
SYNOPSIS
.br
.nf
c = esc(array, i)

character array(ARB)
integer i              # i may be incremented
character c is returned as the escaped character or array(i)

.fi
.sp 1
.ti -7
DESCRIPTION
.br
This function checks array(i) for the existence of an
escape character (as defined by ESCAPE in the general
symbol definitions).
If an escape is found and is appropriate, array(i+1) is
returned as the escaped character.

Escaped n (@n) is mapped into NEWLINE, and escaped t
(@t) is mapped into TAB.

If no escape is found, the function returns array(i).
.sp 1
.ti -7
SEE ALSO
.br
index, type
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  esc                        1095  local   12/10/80  16:18:07
#-h-  fcopy                       701  local   12/10/80  16:18:07
.bp 1
.in 0
.he 'FCOPY (2)'11/13/7'FCOPY (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
fcopy - copy file in to file out
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call fcopy (in, out)

integer in, out
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Assuming that both files are opened, positioned, and ready to go,
the routine copies lines from the current file position until
an EOF is reached on file 'in'.
'in' and 'out' are file identifiers returned by open or create.
.sp 1
.ti -7
IMPLEMENTATION
.br
'Fcopy' simply makes repeated calls to getlin and putlin.
.sp 1
.ti -7
SEE ALSO
.br
open, create, getlin, putlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  fcopy                       701  local   12/10/80  16:18:07
#-h-  flush                       998  local   01/07/81  22:55:51
.bp 1
.in 0
.he 'FLUSH (2)'7/24/79'FLUSH (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
flush - flush output buffer for file 'fd'
.sp 1
.ti -7
SYNOPSIS
.br
call flush (fd)
.sp
filedes fd
.sp
.sp 1
.ti -7
DESCRIPTION
.br
Flush assures that any remaining characters in the output buffer
of the file specified by "fd" are sent out to the file.
It is useful for sending lines to a teletype-like device without
requiring a NEWLINE character, and also for flushing buffers
after calls to "writef".
.sp
.ti -7
IMPLEMENTATION
.br
It is expected that most software tools installations will employ
some form of buffered I/O.
Flush is intended to define the buffer-clearing operation that
takes place before file closing, and to provide a means of
insuring that output directed to a terminal has appeared
on that terminal (e.g. before obtaining some input after
a prompt).
On systems with unbuffered I/O, flush is a no-op.
.sp 1
.ti -7
SEE ALSO
.br
prompt, writef, putch, putlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  flush                       998  local   01/07/81  22:55:51
#-h-  fmtdat                     1255  local   12/10/80  16:18:09
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd FMTDAT 09/25/80
convert date information to character string
.sy
subroutine fmtdat (date, time, now, form)
character date (ARB), time (ARB)
integer now (7), form
.fs
'Fmtdat' is used to convert date information (such as that provided
by 'getnow') into human-readable graphics.
The first argument is a character string to receive the representation
of the current date.
The second argument is a character string to receive the representation
of the current time.
The third argument is a date specification in the same 7-word integer
array format as is returned by 'getnow' (year including century,
month, day, hour, minute, second, millisecond).
The fourth argument selects the format of the character representations;
at present, only 0 is used, giving a date in the form MM/DD/YY and a time
in the form HH:MM:SS.
.im
Simple integer-to-character conversions.
.am
date, time
.sa
getnow (2), date (1)
#-t-  fmtdat                     1255  local   12/10/80  16:18:09
#-h-  fold                        600  local   12/10/80  16:18:10
.bp 1
.in 0
.he 'FOLD (2)'11/13/78'FOLD (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
fold - convert string to lower case
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call fold (str)

character str(ARB)
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts the array 'str' to lower case characters.
Non-alphabetic characters are left unchanged.
The 'str' array is ascii characters terminated by an EOS marker.
.sp
(This routine is exactly the same as 'lower'.)
.sp 1
.ti -7
SEE ALSO
.br
clower, cupper, upper, lower
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  fold                        600  local   12/10/80  16:18:10
#-h-  gctoi                      1836  local   12/10/80  16:18:10
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd GCTOI 03/23/80
generalized character-to-integer conversion
.sy
integer function gctoi (str, i, radix)
character str (ARB)
integer radix, i
.fs
'Gctoi' is  similar to the routine 'ctoi', except that it
accepts base indicators and signs.
Conversion begins on the string 'str' at position
'i'.
The converted integer is returned as the value of the
function.
'I' will be updated to indicate the first position
not used in the conversion.
.sp
Input to 'gctoi' consists of a number containing
an optional plus or minus sign, an optional base indicator,
and a string of digits allowable for the input base.
The base indicator consists of the (decimal) radix of the
desired base followed by the letter "r"
(in the style of Algol 68).
The digits corresponding to the
numbers 10 through 15 are entered as the letters "a" through
"f".
If no base indicator occurs in the string, the number in 'radix'
is used as the default base.
Conversion stops when a character not allowable in the number
is encountered.
.im
'Gctoi' first checks for a leading sign, and records it if found.
If the first one or two digits of the number are numeric and
if they are followed by a lower case "r", then they are converted
to binary and used as the radix of the remaining digits;
otherwise, the 'radix' argument is used.
The remaining digits of the number are converted by a simple
multiply-and-add-successive-digits algorithm.
.am
i
.ca
index
.sa
ctoi (2), other conversion routines ('cto?*' and '?*toc') (2)
#-t-  gctoi                      1836  local   12/10/80  16:18:10
#-h-  getarg                     2266  local   01/07/81  22:55:52
.bp 1
.in 0
.he 'GETARG (2)'11/10/78'GETARG (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getarg - get command line arguments
.sp 1
.ti -7
SYNOPSIS
.br
stat = getarg (n, array, maxsize)
.nf
.sp
integer n, maxsize
character array(ARB)
integer stat returned as length/EOF
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Getarg returns the "n"th argument to the current program in the
array "arg", one character per array element.
The argument is terminated by an EOS marker.
'Maxsize'
is passed as the maximum
number of characters array is prepared to deal with (including
the EOS);  getarg truncates the argument if necessary.
Getarg returns the length of the argument in "arg"
(excluding the EOS), or EOF
if "n" specified a non-existent argument.
.sp
On some systems, if "n" is zero, the name of the current program
is returned in "arg" and,
if "n" is -1, the function returns the number of
arguments on the command line.
.sp
Also, on some systems, command line arguments can only be passed
in a single case (upper or lower).
On these systems an escape mechanism may be necessary to
indicate case when specifying arguments.
.sp 1
.ti -7
IMPLEMENTATION
.br
.sp 1
The implementation of 'getarg' may be quite different on different
operating systems.
Some systems allow only upper case (or lower case) on the command line;
they may limit size; they may not even provide access at all without
considerable contortions.

When implementing 'getarg', the designer should keep in mind that
a 'delarg' will also be needed.
One possible design would be to create a routine 'makarg', which would
pick up the arguments from the system, convert them to ascii strings,
handle any upper-lower case escape conventions, and store them in an
array.
'Getarg' could then access this array, stripping off any quoted strings
surrounding the arguments, and passing them along to the user.
'Delarg' could also access this array when removing reference to
arguments.

If it is absolutely impossible to pick up command line arguments from
the system, 'makarg' could be taught to prompt the user for them.

If the shell is implemented, 'getarg' (or perhaps 'markarg')
will have to be altered to read arguments as passed from the shell.
.sp 1
.ti -7
SEE ALSO
.br
initst, delarg
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getarg                     2266  local   01/07/81  22:55:52
#-h-  getc                        900  local   12/10/80  16:18:12
.bp 1
.in 0
.he 'GETC (2)'11/10/78'GETC (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getc - read character from standard input
.sp 1
.ti -7
SYNOPSIS
.br
.nf
c = getc (c)

character c
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Getc
reads the next character from the standard input.
The character is returned in ascii format both as the functional
return and in the parameter c.
If the end of a line has been encountered, NEWLINE is returned.
If the end of the file has been encountered, EOF is returned.

If the input file is not ascii, characters are mapped
into their corresponding ascii format.

.sp 1
.ti -7
SEE ALSO
.br
getch, getlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getc                        900  local   12/10/80  16:18:12
#-h-  getch                       988  local   01/07/81  22:55:53
.bp 1
.in 0
.he 'GETCH (2)'11/10/78'GETCH (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getch - read character from file
.br
.sp
.ti -7
SYNOPSIS
.br
c = getch (c, fd)
.sp
.nf
character c
filedes fd
.fi
.br
.sp 1
.ti -7
DESCRIPTION
.br
Getch
reads the next character from the file specified by
fd.
The character is returned in ascii format both as the functional
return and in the parameter
c.
If the end of a line has been encountered, NEWLINE is returned.
If the end of the file has been encountered, EOF is returned.
.sp 1
.ti -7
IMPLEMENTATION
.br
Interspersed calls to
getch and getlin
work properly.
A common implementation is to have
getlin
work by repeated calls to
getch.

If the input file is not ascii, characters are mapped
into their corresponding ascii format via
a routine called "inmap".

Getch
is able to recognize an end-of-file marker from either
a terminal or a file.

.sp 1
.ti -7
SEE ALSO
.br
getc, getlin, putch, putlin, readf, writef
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getch                       988  local   01/07/81  22:55:53
#-h-  getlin                     2028  local   01/07/81  22:55:54
.bp 1
.in 0
.he 'GETLIN (2)'11/10/78'GETLIN (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getlin - get next line from file
.sp 1
.ti -7
SYNOPSIS
.br
stat = getlin (line, fd)
.sp
.nf
character line(MAXLINE)
filedes fd
integer stat returned as length/EOF
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Getlin reads the next line from the file opened on file
descriptor "fd" into the ascii character array "line".
Characters are copied until a NEWLINE character
(or other end-of-record marker)
is found or until MAXLINE characters have
been copied.
A NEWLINE character is returned whenever an end-of-line marker
has been sensed and the entire string is termined with an EOS.

If the line is longer than MAXLINE characters, some systems
truncate the line to MAXLINE, while other systems return
the remainder of the line in the next call to getlin.

Getlin
returns EOF when it encounters an end-of-file, and
otherwise returns the line length (excluding the EOS).

Interspersed calls to getlin and getch are allowed and work properly.
.sp 1
.ti -7
IMPLEMENTATION
.br
Getlin reads characters either directly from a file or from
an internal buffer set up when the file was opened.
When an end-or-record is encountered (by whatever means the
system does that sort of thing), a NEWLINE character is returned
by getlin.
If the file contains characters in a representation other than
ascii, the characters are mapped (via
inmap)
into their internal ascii representation.

Getlin generally assumes a maximum size of the array
line
passed to it (MAXLINE).
If the input line exceeds the limit, either truncate the
line or return the rest of it in subsequent calls to getlin.

Getlin
and
getch
are compatible;
that is, interspersed calls to
getlin
and
getch
are allowed and work properly.
A common implementation is to have
getlin
call getch until a NEWLINE character is found
(or MAXLINE is reached).

Getlin
is able to recognize end-of-file marks from both terminals
and files.
.sp 1
.ti -7
SEE ALSO
.br
getch, putch, putlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getlin                     2028  local   01/07/81  22:55:54
#-h-  getnow                     1299  local   01/07/81  22:57:31
.bp 1
.in 0
.he 'GETNOW (2)'09/25/80'GETNOW (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getnow -
determine current date and time
.sp 1
.ti -7
SYNOPSIS
.br
.nf
subroutine getnow (now)
integer now (7)
.fi
.sp
.ti -7
DESCRIPTION
.br
'Getnow' is used to query the operating system for the current date
and time.
The requested information is returned in a seven-word integer array,
where:
word 1 contains the year (e.g. 1980);
word 2 contains the month (e.g. 9);
word 3 contains the day (e.g. 25);
word 4 contains the hour (e.g. 13);
word 5 contains the minute (e.g. 39);
word 6 contains the second (e.g. 14);
word 7 contains the millisecond (e.g. 397).
.sp
The information returned by 'getnow' may be used as-is or further
useful processing may be done by 'fmtdat' or 'wkday'.
.sp
.ti -7
IMPLEMENTATION
.br
Operating systems generally have some mechanism for picking
up the current date and time.
If yours has one, use it.
.sp
Getnow is not critical to the implementation of the tools and
can be left as a stub if the operating system cannot supply
the needed information.
.sp
.ti -7
ARGUMENTS MODIFIED
.br
now
.sp
.ti -7
BUGS
.br
Some systems cannot obtain all the time information described.
Array elements that cannot be filled default to zero.
.sp
.ti -7
SEE ALSO
.br
fmtdat (2), wkday (2), date (1)
#-t-  getnow                     1299  local   01/07/81  22:57:31
#-h-  getpat                     1555  local   12/10/80  16:18:15
.bp 1
.in 0
.he 'GETPAT (2)'7/23/80'GETPAT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getpat - prepare regular expressions for subsequent pattern matching
.sp 1
.ti -7
SYNOPSIS
.br
.nf
stat = getpat (arg, pat)

character arg(ARB), pat(MAXPAT)
.br
integer stat returned as length/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Getpat is used to translate a regular expression into a format
convenient for subsequent pattern matching via 'match'
or 'amatch'.
(For a complete description of regular expressions, see the
writeup on the editor.)

A typical scenario for pattern-matching might be:

.nf
.in +5
stat = getpat(pattern_you_want_located, pattern_array)
YES/NO = match(input_line, pattern_array)
.in -5
.fi
.sp
The pattern array should be dimensioned at least MAXPAT
characters long, a definition available in the standard
symbol definitions file.
.sp
If the pattern can be made, the functions returns the number
of characters in "pat";
otherwise it returns ERR.
.sp
Getpat is essentially a call to makpat with the
following parameters:

.ce
getpat = makpat (arg, 1, EOS, pat)

.sp 1
.ti -7
SEE ALSO
.br
makpat, match, amatch
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getpat                     1555  local   12/10/80  16:18:15
#-h-  gettyp                     1604  local   01/07/81  22:55:55
.bp 1
.in 0
.he 'GETTYP (2)'01/7/81'GETTYP (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
gettyp - get type of file (character or binary)
.sp 1
.ti -7
SYNOPSIS
.br
type = gettyp (name)
.sp
.nf
character name(FILENAMESIZE)
integer type returned as ASCII, LOCAL, BINARY
.fi
.sp 1
.ti -7
DESCRIPTION
.br
'Gettyp' determines whether the file specified by 'name' is ascii
characters, local characters (if different from ascii), or
binary.
The type is returned as ASCII, LOCAL, or BINARY in the functional call.
 
.sp 1
.ti -7
IMPLEMENTATION
.br
A file's type may be determined by locating system information about
the file, or 'gettyp' might have to actually open the file
and read part of it, making a reasonable 'guess' as to its flavor.
 
The shell uses 'gettyp' to determine whether a command verb
given by the user represents a script file or an executable tool.
If the file turns out to be a character (i.e. script) file, the
shell then spawns itself with the file as input.
Thus, if 'gettyp' could not be reliably implemented on a
particular system, the user would have to specifically execute
her script files by:
.ce
% sh script ...
.sp
'Gettyp' may also be called by the archiver to store a file's type
in the
archive header (for informational purposes only).
.sp
This primitive is not considered finalized.
Most likely, another primitive will be specified which is
used to pick up an assortment of information about a file.
'Gettyp' is temporarily used by the shell until the final
version is specified.
.sp 1
.ti -7
SEE ALSO
.br
.sp 1
.ti -7
DIAGNOSTICS
.br
ERR is returned if the file does not exist
#-t-  gettyp                     1604  local   01/07/81  22:55:55
#-h-  getwrd                     1018  local   12/10/80  16:18:15
.bp 1
.in 0
.he 'GETWRD (2)'11/13/78'GETWRD (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
getwrd - get non-blank word from in(i) into out, increment i
.sp 1
.ti -7
SYNOPSIS
.br
.nf
size = getwrd(in, i, out)

character in(ARB), out(ARB)
integer i               # i is incremented
integer size is returned as the length of the word found
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Starting at position 'i' in array 'in', skips any leading blanks
and tabs and returns the next word and its length.
A word is any series of characters terminated by a BLANK,
TAB, or NEWLINE.
The terminator is not returned as part of the word.
'i' is incremented to the position just past the end of the
word.
The word is returned in array 'out'.

Both 'in' and 'out' are ascii character arrays terminated with an
EOS marker.
.sp 1
.ti -7
SEE ALSO
.br
skipbl
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  getwrd                     1018  local   12/10/80  16:18:15
#-h-  gfnarg                     3202  local   12/10/80  16:18:16
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd GFNARG 03/23/80
get next file name argument from argument list
.sy
integer function gfnarg (name, state)
character name (MAXPATH)
integer state (4)
.fs
'Gfnarg' is used to fetch "file name" arguments (those not beginning
with a dash) from the command line.
More importantly, it observes the convention that a "-n" argument
implies that file names are to be read from an input file until
EOF is reached, rather than simply from the argument list.
.sp
In summary, each time 'gfnarg' is called, it returns a file name.
From its initial state, 'gfnarg' will fetch the next argument from
the command line.
If the argument is a file name, then it is passed back in 'name',
'state' is updated (in ways to be discussed later), and the function
return is OK.
If the argument begins with "-n", it indicates that file names are
to be take from a file.
("-n" implies the standard port STDIN, "-n2" implies STDIN2,
"-n3" implies STDIN3, and "-nfilename" implies the named file.)
Successive calls of 'gfnarg' then return successive lines of the
named file (sans newline at the end of each line).
When EOF is reached, 'gfnarg' resumes its scan of the command
line arguments.
Whenever a non-filename, non-"-n" argument is encountered,
'gfnarg' returns ERR.
When no more filename arguments are available, 'gfnarg' returns
EOF.
.sp
As a boundary condition, if there are no arguments on the command
line, 'gfnarg' returns the name "/dev/stdin1", reflecting the
convention that programs invoked without arguments take their
input from their standard ports.
.sp
Use of 'gfnarg' requires one initialization step.
The first element of the state vector must be set to 1,
then the first call to 'gfnarg' may be issued.
For example:
.sp
.nf
.in +5
state (1) = 1
call gfnarg (argument, state)
.in -5
.fi
.sp
'Gfnarg' will maintain the state vector internally after the
initialization.
.im
The four elements of the state vector have the following
interpretations:
state(1) is the current state of 'gfnarg', which may be
(1) uninitialized, (2) reading arguments from the command line,
(3) reading from an input file, (4) end of command line reached,
or (5) no more file arguments are available (EOF);
state(2) is the index of the next argument in the command line;
state(3) is the file descriptor for the current "-n" input file;
state(4) is a count of the number of file name arguments returned
so far.
The initial state is used by 'gfnarg' to set up the other elements
of the state vector.
From that point on, the contents of the argument list cause changes
in state.
As a special case, if the end of the command line is reached
without finding any file names, "/dev/stdin1" is returned
and state(1) is altered to cause an EOF return on the next call
to 'gfnarg'.
.bu
Should probably return argument length, like 'getarg' does,
whenever it finds a filename.
.sa
getarg (2)
#-t-  gfnarg                     3202  local   12/10/80  16:18:16
#-h-  gitoc                      2416  local   12/10/80  16:18:17
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd GITOC 03/23/80
convert integer to any radix string
.sy
integer function gitoc (int, str, size, base)
integer int, size, base
character str (size)
.fs
'Gitoc' will convert an integer to
character string representation in any radix from 2 to 16 (inclusive).
The integer to be converted may be considered as either signed or
unsigned.
.sp
'Int' is the integer to be converted;
'str' is a character array into which the string representation will be
stored;
'size' is the size of 'str'.
The absolute value of 'base' is the conversion radix.  If 'base' is
negative, then 'int' is treated as an unsigned number; otherwise,
'int' is considered to be a signed.
If the specified radix is not in the range 2:16, then a decimal
conversion is performed.
.sp
For a signed conversion,
if the integer is less than zero, its absolute value is preceded by
a minus sign in the converted string; a positive number is never
preceded by a sign.
.sp
The function return is the number of characters required to
represent the integer.
.im
'Gitoc' uses a typical divide-and-remainder algorithm to perform
the conversion; that is, a digit is generated by taking the remainder
when the integer is divided by the radix.
For signed conversions, the absolute value of the number is first taken,
the digits generated, and the minus sign inserted if needed.
For unsigned conversions,
the least significant bit of the number is saved, and then
the number is shifted right one bit position
to put it into the precision range of a standard integer (and effectively
dividing the unsigned number by 2).
Then, as each digit value is generated, it is doubled and added to
the carry from the previous digit position (with the initial carry
being the saved least significant digit) and a new carry value is
generated.
.am
str
.bu
It is suspected that this routine will not work properly on
one's-complement machines.
Also note that it depends on the MAX_INT definition in the Software
Tools library to mask off the sign bit of a word.
.sa
itoc (2), other conversion routines ('cto?*' and '?*toc') (2)
#-t-  gitoc                      2416  local   12/10/80  16:18:17
#-h-  index                       652  local   12/10/80  16:18:18
.bp 1
.in 0
.he 'INDEX (2)'11/13/78'INDEX (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
index - find character c in string str
.sp 1
.ti -7
SYNOPSIS
.br
.nf
loc = index(str, c)

character str(ARB), c
integer loc is returned as the location is str where c was located
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Returns the index of the first character in 'str' that matches 'c',
or zero if 'c' isn't in the array.
'Str' is an ascii character array terminated with an EOS marker.
'c' is a single ascii character.
.sp 1
.ti -7
SEE ALSO
.br
match, getpat
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  index                       652  local   12/10/80  16:18:18
#-h-  initst                     1818  local   01/07/81  22:57:33
.bp 1
.in 0
.he 'INITST (2)'11/10/78'INITST (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
initst - initialize all standard files and common variables
needed for the software tools primitives
.sp 1
.ti -7
SYNOPSIS
.br
call initst
.sp 1
.ti -7
DESCRIPTION
.br
This routine is generally the first routine called by any
program desiring to
use the software tools primitives.
It opens STDIN, STDOUT, and ERROUT files, performing any file
substitutions indicated on the command line.
It also prepares the list of arguments needed by
getarg
and sets up any buffers, variables, etc. needed by the
software tools primitives.

On many systems, the calls to 'initst' and 'endst' are done
automatically either by having the ratfor preprocessor insert
them into the code, or by having the system itself call them
before executing the user's program.
.sp 1
.ti -7
IMPLEMENTATION
.br
'Initst'
initializes any common blocks, variables, buffers, arrays, or
whatever is necessary to allow the other software tools
primitives to operate.
It may also have to retrieve (via 'makarg') the list of command arguments
passed to the program, if this is not automatically available from the
operating system.

'Initst'
is also responsible for parsing the command line
to determine if there have been any file substitutions for
STDIN, STDOUT, or ERROUT.
The appropriate files (either the user's terminal or the substitutions)
are then opened and properly positioned.
Arrangements are made so that 'getarg' won't pick up standard
file substitution flags on subsequent calls
(probably by a call to 'delarg').
.sp 1
.ti -7
SEE ALSO
.br
endst, getarg, delarg

.sp 1
.ti -7
DIAGNOSTICS
.br
If
initst
cannot function for some reason, the program
generally aborts
(possibly without an error message since the standard error file
may not
have been opened).
#-t-  initst                     1818  local   01/07/81  22:57:33
#-h-  isatty                      893  local   01/07/81  22:55:57
.bp 1
.in 0
.he 'ISATTY (2)'11/13/78'ISATTY (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
isatty - determine if file is a teletype/CRT device
.sp 1
.ti -7
SYNOPSIS
.br
stat = isatty (fd)
.sp
.br
filedes fd
.br
integer stat returned as YES/NO
.sp 1
.ti -7
DESCRIPTION
.br
This function returns
YES if the file specified by 'fd' is a teletype-like device,
otherwise it returns NO.
'Fd' is a file descriptor returned by a call to open or create.
.sp 1
.ti -7
IMPLEMENTATION
.br
When a file is opened, a flag is usually set indicating what device
the file is associated with.  This function generally reads that
flag.
Other implementations are possible, depending upon the operating
system involved.

'Isatty' is generally used by the tools to determine whether they
should issue prompts or not.
.sp 1
.ti -7
SEE ALSO
.br
open, create
.sp 1
.ti -7
DIAGNOSTICS
.br
NO is returned if 'fd' is in error.
#-t-  isatty                      893  local   01/07/81  22:55:57
#-h-  itoc                        794  local   12/10/80  16:18:22
.bp 1
.in 0
.he 'ITOC (2)'11/13/78'ITOC (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
itoc - convert integer to character string
.sp 1
.ti -7
SYNOPSIS
.br
.nf
length = itoc(int, str, size)

integer int, size
character str(ARB)
integer length returned as the number of characters needed
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts an integer 'int' to characters in array 'str', which
is at most 'size' characters long.
'length' is returned as the number of characters the integer
took, not including the EOS marker.
Characters are stored in ascii character arrays terminated with
an EOS marker.
.sp
Negative numbers are handled correctly.
.sp 1
.ti -7
SEE ALSO
.br
ctoi, putdec, putint
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  itoc                        794  local   12/10/80  16:18:22
#-h-  length                      546  local   12/10/80  16:18:23
.bp 1
.in 0
.he 'LENGTH (2)'11/13/78'LENGTH (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
length - compute length of string
.sp 1
.ti -7
SYNOPSIS
.br
.nf
n = length(str)

character str(ARB)
integer n returned as the number of characters in str
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Computes the length of a character string, excluding the EOS.
The string is an ascii character array terminated with an EOS
marker.
.sp 1
.ti -7
SEE ALSO
.br
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  length                      546  local   12/10/80  16:18:23
#-h-  lookup                     1634  local   12/10/80  16:18:25
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd LOOKUP 03/23/80
retrieve information from a symbol table
.sy
integer function lookup (symbol, info, table)
character symbol (ARB)
integer info (ARB)
pointer table
.fs
'Lookup' examines the symbol table given as its third argument for the
presence of the character-string symbol given as its first argument.
If the symbol is not present, 'lookup' returns 'NO'.
If the symbol is present, the information associated with it is copied
into the information array passed as the second argument to 'lookup',
and 'lookup' returns 'YES'.
.sp
The symbol table used must have been created by the routine 'mktabl'.
The size of the information array must be at least as great as the
symbol table node size, specified at its creation.
.sp
Note that all symbol table routines use dynamic storage space, which
must have been previously initialized by a call to 'dsinit'.
.im
'Lookup' calls 'stlu' to determine the location of the symbol in the
table.
If 'stlu' returns NO, then the symbol is not present, and 'lookup'
returns NO.
Otherwise, 'lookup' copies the information field from the appropriate
node of the symbol table into the information array and returns
YES.
.am
info
.ca
stlu
.sa
enter (2), delete (2), mktabl (2), rmtabl (2), stlu (2),
sctabl (2), dsinit (2), dsget (2), dsfree (2)
#-t-  lookup                     1634  local   12/10/80  16:18:25
#-h-  lower                       601  local   12/10/80  16:21:01
.bp 1
.in 0
.he 'LOWER (2)'7/23/80'LOWER (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
lower - convert string to lower case
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call lower (str)

character str(ARB)
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts the array 'str' to lower case characters.
Non-alphabetic characters are left unchanged.
The 'str' array is ascii characters terminated by an EOS marker.
.sp
(This routine is exactly the same as 'fold'.)
.sp 1
.ti -7
SEE ALSO
.br
clower, cupper, upper, fold
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  lower                       601  local   12/10/80  16:21:01
#-h-  makpat                     1289  local   12/10/80  16:21:01
.bp 1
.in 0
.he 'MAKPAT (2)'7/23/80'MAKPAT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
makpat - prepare regular expressions for subsequent pattern matching
.sp 1
.ti -7
SYNOPSIS
.br
.nf
i/ERR = makpat (arg, from, delim, pat)

character arg(ARB), pat(MAXPAT), delim
integer from
.br
.fi
integer function returns ERR/updated index
.sp 1
.ti -7
DESCRIPTION
.br
Makpat is similar to getpat, but slightly more special purpose.
It is used to translate a regular expression into a format
convenient for subsequent pattern matching via 'match'
or 'amatch'.
(For a complete description of regular expressions, see the
writeup on the editor.)
.sp
Makpat scans "arg" starting at location "from" and terminates
the scan at the 'delim' character.
The characters between arg(from) and the delimiter are
then encoded into a pattern suitable for subsequent
matching.
The function returns an index into arg of the next character
past the delimiter, or ERR if there was some problem encoding
the pattern.
.sp
The pattern array should be dimensioned at least MAXPAT
characters long, a definition available in the standard
symbol definitions file.
.sp 1
.ti -7
SEE ALSO
.br
getpat, match, amatch
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  makpat                     1289  local   12/10/80  16:21:01
#-h-  match                      1223  local   12/10/80  16:21:03
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd MATCH 03/23/80
match pattern anywhere on a line
.sy
integer function match (lin, pat)
character lin (ARB), pat (MAXPAT)
.fs
'Match' attempts to find a match for a regular expression
anywhere in a given line of text.
The first argument contains the text line;
the second contains the pattern to be matched.
The function return is YES if the pattern was found anywhere in
the line, NO otherwise.
.sp
The pattern in 'pat' is a standard Software Tools encoded regular
expression.
'Pat' can be generated most conveniently by a call to the routine
'makpat'.
.im
'Match' calls 'amatch' at each position in 'lin', returning
YES whenever 'amatch' indicates it found a match.
If the test fails at all positions, 'match' returns NO.
.ca
amatch
.bu
Not exactly blindingly fast.
.sa
amatch (2), makpat (2), maksub (2), catsub (2), find (1), change (1),
ed (1),
.ul
Software Tools
#-t-  match                      1223  local   12/10/80  16:21:03
#-h-  mktabl                     1580  local   12/10/80  16:21:04
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd MKTABL 03/23/80
make a symbol table
.sy
pointer function mktabl (nodesize)
integer nodesize
.fs
'Mktabl' creates a symbol table for manipulation by the routines
'enter', 'lookup', 'delete', and 'rmtabl'.
The symbol table is a general means of associating data with a symbol
identified by a character string.
The sole argument to 'mktabl' is the number of (integer) words of
information that are to be associated with each symbol.
The function return is the address of the symbol table in
dynamic storage space (see 'dsinit' and 'dsget').
This value must be passed to the other symbol table routines to
select the symbol table to be manipulated.
.sp
Note that dynamic storage space must be initialized by a call to
'dsinit' before using any symbol table routines.
.im
'Mktabl' calls 'dsget' to allocate space for a hash table in dynamic
memory.
Each entry in the hash table is the head of a linked list (with zero
used as a null link) of symbol table nodes.
'Mktabl' also records the nodesize specified by the user, so
'enter' will know how much space to allocate  when a new symbol
is entered in the table.
.ca
dsget
.sa
enter (2), lookup (2), delete (2), rmtabl (2), stlu (2),
dsget (2), dsfree (2), dsinit (2), sctabl (2)
#-t-  mktabl                     1580  local   12/10/80  16:21:04
#-h-  mkuniq                     1912  local   01/07/81  22:57:35
.bp 1
.in 0
.he 'MKUNIQ (2)'6/5/79'MKUNIQ (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
mkuniq - generate unique file name
.sp 1
.ti -7
SYNOPSIS
.br
len = mkuniq (seed, name)
.sp
.nf
character seed(ARB), name(FILENAMESIZE)
integer len returned as length/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Mkuniq generates a "unique" file name from a given seed string.
This name is intended for use in subsequent calls to create
and open.
"Len" is returned as the number of characters in "name", not
including the EOS marker.
If there was some problem in creating the name, ERR is returned.
.sp
Mkuniq is generally used for generating scratch file names,
such as those needed by the editor and archiver.
.sp
On single-user systems or others where the unique naming of
scratch files is not important, mkuniq simply returns "seed".
More sophisticated versions may construct a file name in a special
directory, use process ids or time-and-date to insure uniqueness.
.sp 1
.ti -7
IMPLEMENTATION
.br
'Mkuniq' is used to avoid conflicts which occur when more than
one user is logged in under a single user or directory name.
The optimum implementation would be to return an absolutely unique
file name based on 'seed'.
However, on most systems this is impossible.
Another solution would be to append (or prepend) some sort of process
identifier to 'seed', thus making the file name at least unique to
the calling process.
To avoid privilege violations it might also be necessary to choose
a specific directory for all scratch files, with appropriate privileges
being assigned to it.
.sp
On some systems, 'seed' is limited to a certain number of
characters.

On single-user systems, systems with local files, or other circumstances
where unique file names are not a problem, 'mkuniq' can simply return
the 'seed' as 'name'.
.sp 1
.ti -7
SEE ALSO
.br

.sp 1
.ti -7
DIAGNOSTICS
.br
If a file name could not be generated, ERR is returned.
#-t-  mkuniq                     1912  local   01/07/81  22:57:35
#-h-  mntoc                      1501  local   12/10/80  16:21:05
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd MNTOC 03/28/80
convert ASCII mnemonic to character
.sy
character function mntoc (buf, p, default)
character buf (ARB), default
integer p
.fs
'Mntoc' is used to convert a standard ASCII mnemonic
(e.g. ACK, BEL, BS) into an ASCII character code.
The argument 'buf' is an EOS-terminated string presumed to contain
either a single character or a two- or three-character ASCII
mnemonic (in either upper or lower case), starting at position 'p'.
The function return depends on the outcome of the conversion as follows:
(1) if 'buf' contains only one character, the function return is
equivalent to that character;
(2) if 'buf' contains an ASCII mnemonic terminated by a nonalphanumeric
character, the function return is the character code associated with that
mnemonic;
(3) otherwise, the function return is equivalent to the character specified
as the third argument ('default').
In all cases, 'p' is advanced to the first character beyond the presumed
mnemonic or single character.
.im
The mnemonic is transferred to an internal character buffer,
then used in a search of a string table containing the
ASCII mnemonics.
.am
p
.ca
lower
.sa
ctomn (2)
#-t-  mntoc                      1501  local   12/10/80  16:21:05
#-h-  note                       1444  local   01/07/81  22:55:59
.bp 1
.in 0
.he 'NOTE (2)'11/13/78'NOTE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
note - determine current file position
.sp 1
.ti -7
SYNOPSIS
.br
stat = note (offset, fd)
.sp
.nf
integer offset(2)
filedes fd
integer stat returned as OK/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Note determines the current value of a file's read/write pointer.
The argument "offset" is a 2-word integer array that will receive
the information.
Offset is maintained untouched by the user and passed to "seek"
when desiring to return to that particular location in the file.
.sp
Note is usually used as the file is being written,
picking up the pointer
to the end of the file before each record is inserted there.
.sp
On text files (e.g. those created by calls to putch, putlin),
note is guaranteed to work at line boundaries only.
However, it should work anywhere on a file created by calls
to writef.
.sp 1
.ti -7
IMPLEMENTATION
.br
Note
is compatible with whatever implementation is chosen for
seek
and
the opening of files at READWRITE access.
.sp
Offset is a two-word integer in which is stored a character count,
word address, block and record address, or whatever is appropriate
for the local operating system.
Note should be taught to return BEGINNING_OF_FILE and END_OF_FILE
where appropriate.
.sp
In the editor, note is called to locate the end of file for
subsequent writes.
.sp 1
.ti -7
SEE ALSO
.br
seek, readf, writef
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  note                       1444  local   01/07/81  22:55:59
#-h-  open                       3472  local   01/07/81  22:56:00
.bp 1
.in 0
.he 'OPEN (2)'11/10/78'OPEN (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
open - open an existing file for reading, writing, or both
.sp 1
.ti -7
SYNOPSIS
.br
fd = open (name, access)
.nf
.sp
character name(FILENAMESIZE)
integer access
.br
.fi
filedes fd - returned as file descriptor/ERR
.sp 1
.ti -7
DESCRIPTION
.br
Open opens the file whose name is contained in "name" for I/O
according to the value of "mode", which may be READ, WRITE,
READWRITE, or APPEND.
If the file exists and can be opened according to "mode",
open returns a file descriptor.
If the file cannot be opened, ERR is returned.

After a file is opened, it is positioned at the beginning,
unless APPEND access is requested, in which case the file
is prepared for extension.

Opening the same file for reading more than once is permissible
and works correctly.
However, on many systems a file may be opened only once in
WRITE, APPEND, or READWRITE mode.

There is generally a limit to the number of files that can be
opened simultaneously.
This number is specified by the definition MAXOFILES in the
general symbol definition file.
.sp 1
.ti -7
IMPLEMENTATION
.br
Open
attaches an existing file to a running program
and associates the external
file name with an internal identifier
which is then usable by the program.
The file is opened for I/O according to the value of "mode",
where mode may be READ, WRITE, READWRITE, or APPEND.
"Name" is passed as an ascii character array, stored one character
per array element.
The access modes READ, WRITE, READWRITE, and APPEND are global
symbols defined in the standard definitions file.
.sp
Open
does whatever manipulations
are necessary to allow reading and/or writing to the file.
An internal descriptor (usually an integer) is assigned to the file
and subsequently
used when calling other primitives such as close, getch, putch,
getlin, and putlin.
.sp
'Open' should be able to open a channel to the teletype in
responce to the filenames defined by TERMINAL_IN and
TERMINAL_OUT.
It also might be taught to respond to other device names
where appropriate.
.sp
Open
may have to set up an internal I/O buffer for the file.
It may also have to determine the file's
type (teletype, character file, binary file).
Information about the file's type and
teletype characteristics (yes or no) is generally maintained
and made available to the user via "isatty" and possibly
other file characteristics primitives.

Open
is sometimes taught to read characters of ascii type as well as local
character type (if not ascii).
Translation of characters from local to ascii is done when
the characters are passed to
getch
and
getlin.

Opening a fresh instance of an already opened file is permissible
and does not affect the position of the file as accessed by
subsequent or previous calls.

There is generally a limit to the maximum number of files
open at any one time.
10-15 is a common range.
.sp
READWRITE access may cause problems, or even be impossible
on many systems.
The only tool which needs this access is the editor.
If necessary, READWRITE access may be implemented by opening
the file twice--once at READ and once at WRITE access.
.sp 1
.ti -7
SEE ALSO
.br
create, close, remove, getch, putch, readf, writef, seek, note, isatty
.sp 1
.ti -7
DIAGNOSTICS
.br
Open returns ERR if the
file does not exist, if one of the necessary directories (if any)
does not exist or is unreadable, if the file is not readable/writeable,
or if too many files are open.
#-t-  open                       3472  local   01/07/81  22:56:00
#-h-  prompt                     1058  local   01/07/81  22:56:02
.bp 1
.in 0
.he 'PROMPT (2)'6/5/79'PROMPT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
prompt - prompt user for input
.sp 1
.ti -7
SYNOPSIS
.br
call prompt (str, buf, fd)
.sp
.nf
character str(ARB), buf(MAXLINE)
filedes fd
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Prompt determines if "fd" refers to a teletype-like device
and, if so, writes the
prompt string "str" to the TTY, and flushes its output buffer
to insure the prompt is printed.
A line of input is then read from fd by "getlin".
.sp
No carriage return/line feed sequence is done unless specified
by a NEWLINE in the prompt string.
.sp 1
.ti -7
IMPLEMENTATION
.br
The version of 'prompt' on the tape is essentially:
.sp
.in +10
.nf
if (isatty(fd) == YES)
.in +5
{
call putlin(str, fd)
call flush (fd)
stat = getlin (buf, fd)
}
.in -15
.fi
Note that prompt expects to be able to read from and write
to 'fd'.
If this is not possible on your system, modify prompt
to open a separate channel to the teletype for the write.
.sp
.ti -7
SEE ALSO
.br
putlin, remark, flush, isatty
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  prompt                     1058  local   01/07/81  22:56:02
#-h-  putc                        686  local   12/10/80  16:21:09
.bp 1
.in 0
.he 'PUTC (2)'11/10/78'PUTC (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putc - write character to standard output
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call putc (c)

character c
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Putc
writes a character onto the standard output file (STDOUT).
If
c
is a NEWLINE character,
the appropriate action is taken to indicate the end of the record
on the file.
The character is assumed to be in ascii format; however, if
the output file is not ascii, characters are mapped
into their corresponding format.
.sp 1
.ti -7
SEE ALSO
.br
putch, putlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putc                        686  local   12/10/80  16:21:09
#-h-  putch                       921  local   01/07/81  22:56:03
.bp 1
.in 0
.he 'PUTCH (2)'11/10/78'PUTCH (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putch - write character to file
.br
.sp 1
.ti -7
SYNOPSIS
.br
call putch (c, fd)
.sp
.br
character c
.br
filedes fd
.sp 1
.ti -7
DESCRIPTION
.br
Putch
writes the character
c
onto the file specified by
file descriptor "fd".
If
c
is the NEWLINE character,
the appropriate action is taken to indicate the end of the record
on the file.
The character is assumed to be in ascii format; however, if
the output file is not of ascii type, the necessary conversion
is done.
.sp 1
.ti -7
IMPLEMENTATION
.br
Interspersed calls to
putch
and
putlin
work properly.
One implementation is to have
putlin
perform repeated calls to
putch.

If the output file is not ascii, characters are mapped
into their corresponding format via
the routine outmap.
.sp 1
.ti -7
SEE ALSO
.br
putc, putlin, getch, getlin, readf, writef
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putch                       921  local   01/07/81  22:56:03
#-h-  putdec                      659  local   12/10/80  16:21:10
.bp 1
.in 0
.he 'PUTDEC (2)'11/13/78'PUTDEC (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putdec - write integer n in field width >=w
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call putdec(n, w)

integer n, w
.fi
.sp 1
.ti -7
DESCRIPTION
.br
This routine writes onto the standard output the number 'n'
as a string of at
least 'w' characters, including a sign if 'n' is negative.
If fewer than 'w' characters are needed, blanks are inserted to
the left to make up the count; if more than 'w' are needed, more
are provided.
.sp 1
.ti -7
SEE ALSO
.br
itoc, putint
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putdec                      659  local   12/10/80  16:21:10
#-h-  putint                      891  local   12/10/80  16:21:10
.bp 1
.in 0
.he 'PUTINT (2)'7/23/80'PUTINT (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putint - write integer n onto file fd in field width >=w
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call putint(n, w, fd)

integer n, w, fd
.fi
.sp 1
.ti -7
DESCRIPTION
.br
This routine writes on the file specified by 'fd' the number 'n'
as a string of at
least 'w' characters, including a sign if 'n' is negative.
If fewer than 'w' characters are needed, blanks are inserted to
the left to make up the count; if more than 'w' are needed, more
are provided.
If 'w' is negative, the number is left-justified in the field.
.sp
'Fd' is a a file descriptor as returned by open or create.

.sp 1
.ti -7
SEE ALSO
.br
itoc, putdec
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putint                      891  local   12/10/80  16:21:10
#-h-  putlin                     1385  local   01/07/81  22:56:04
.bp 1
.in 0
.he 'PUTLIN (2)'11/10/78'PUTLIN (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putlin - output a line onto a given file
.sp 1
.ti -7
SYNOPSIS
.br
call putlin (line, fd)
.sp
.nf
character line(ARB)
filedes fd
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Putlin writes the characters in "line" to the file opened on
file descriptor "fd".
If a NEWLINE character is located, appropriate action is
taken to indicate the end-of-record in whatever format
is necessary for the local operating system.
If no NEWLINE character is specified, no carriage return (or
end-of-record) is assumed.
This probably means that the output buffer will not be flushed.

Any necessary character translation is done if the output file
is not of ascii type.
.sp 1
.ti -7
IMPLEMENTATION
.br
Putlin should write the line onto the file and, if a NEWLINE
is encountered,
do whatever is necessary to indicate to the local operating
system that a record has been generated.
If the output file is to contain characters in a representation
other than
ascii, the characters are mapped (via
outmap)
into their proper representation.

Putlin
and
putch
are compatible;
that is, interspersed calls to
putlin
and
putch
are allowed and work properly.
A common implementation is to have
putlin
call
putch
until an EOS marker is found.
.sp 1
.ti -7
SEE ALSO
.br
putch, prompt, remark, getch, getlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putlin                     1385  local   01/07/81  22:56:04
#-h-  putstr                      897  local   12/10/80  16:21:11
.bp 1
.in 0
.he 'PUTSTR (2)'7/23/80'PUTSTR (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
putstr - write str onto file fd in field width >=w
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call putstr(str, w, fd)

character str(ARB)
integer w, fd
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Putstr writes the character string 'str' onto the file
specified by 'fd',
in a field at least 'w' characters long.
If fewer than 'w' characters are needed, blanks are inserted to
the left to make up the count; if more than 'w' are needed, more
are provided.
If 'w' is negative, the characters are left-justified in the field.
.sp
'Fd' is a a file descriptor as returned by open or create.

.sp 1
.ti -7
SEE ALSO
.br
putch, putlin, remark, error
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  putstr                      897  local   12/10/80  16:21:11
#-h-  query                      1114  local   12/10/80  16:21:11
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd QUERY 09/25/80
print command usage information on request
.sy
subroutine query (usage)
hollerith_string usage (ARB)
.fs
Many Software Tools commands will supply usage information
when invoked with a single argument consisting only of a question
mark.
'Query' exists to simplify this convention for the programmer.
.sp
The sole argument is a period-terminated hollerith literal,
such as that passed to 'error'.
.sp
When called, 'query' checks to see that the command calling it was
invoked with exactly one argument, and that that argument is a question
mark.
If so, the usage message is passed along to 'error' and the command
terminates.
If not, 'query' returns quietly.
.im
Two calls to 'getarg', some tests, and a call to 'error'.
.ca
error
.sa
error (2)
#-t-  query                      1114  local   12/10/80  16:21:11
#-h-  readf                      1244  local   01/07/81  22:56:05
.bp 1
.in 0
.he 'READF (2)'6/30/78'READF (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
readf - read from an opened file
.br
.sp
.ti -7
SYNOPSIS
.br
count = readf (buf, n, fd)
.sp
.nf
character buf(ARB)   or   integer buf(ARB)
integer n
filedes fd
integer count returned as count/EOF
.fi
.br
.sp 1
.ti -7
DESCRIPTION
.br
Readf reads "n" bytes (or words) from the file opened on file
descriptor "fd" into the array "buf".
The bytes (or words) are placed in "buf" one per array element.
Readf is the typical way of doing binary reads on files.
Whether buf is declared an integer or a character array is
dependent upon which is most appropriate for the host operating
system.
.sp
Readf returns the number of bytes/words actually read.
In most cases, this is equal to "n".
However, it may be less if an EOF has been encountered or if
"fd" specified a device such as a terminal where less than
"n" bytes were input.
.sp 1
.ti -7
IMPLEMENTATION
.br
Readf is the typical way of implementing binary I/O.
Do whatever is necessary on your system to allow users
to get at the file directly.
.sp
If reasonable, design readf to work properly in conjunction
with getch and getlin.
.sp 1
.ti -7
SEE ALSO
.br
writef, getch, putch
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  readf                      1244  local   01/07/81  22:56:05
#-h-  remark                     1600  local   01/07/81  22:56:06
.bp 1
.in 0
.he 'REMARK (2)'11/13/78'REMARK (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
remark - print single-line message
.sp 1
.ti -7
SYNOPSIS
.br
call remark (message)

integer message - message is a hollerith array
.sp 1
.ti -7
DESCRIPTION
.br
Remark
writes the message onto the standard error file ERROUT.
A NEWLINE is always generated, even though one may not appear in
the message.
The message array is generally a Fortran hollerith string in the
format generated by the Ratfor quoted string capability.
On some systems it may be necessary to indicate the end of the
message with a period ".".
For example,
.sp
.ce
call remark ("this is a warning message.")
.sp
The escape character "@" may be used to output a period
(e.g. @.) and
on some systems, the escape sequences "@t" and "@n" and "@b"
may be used to output a TAB, NEWLINE, and BACKSPACE respectively.
.sp 1
.ti -7
IMPLEMENTATION
.br
Remark
is very similar to
error
except it returns after printing, instead of stopping.
It expects its argument to be a hollerith string
which is produced by the ratfor quoted string capability.
If your system has no way of determining the end of hollerith
strings, you might have to require users to include a
termination character such as a ".".
(All the quoted strings in the software tools source code do
terminate with a dot.)

Remark is similar to the following, except the message string
is hollerith rather than character:
.in +5
.nf
call putlin (message, ERROUT)
call putch  (NEWLINE, ERROUT)
.in -5
.fi


.sp 1
.ti -7
SEE ALSO
.br
error, putlin, putch, prompt
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  remark                     1600  local   01/07/81  22:56:06
#-h-  remove                      916  local   01/07/81  22:56:06
.bp 1
.in 0
.he 'REMOVE (2)'11/10/78'REMOVE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
remove - remove a file from the file system
.sp 1
.ti -7
SYNOPSIS
.br
stat = remove (filename)
.br
.sp
.nf
character filename(FILENAMESIZE)
integer stat returned as OK/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
From within a running program, remove (or delete) the file
specified by "name" from the file system.
"Name" is an ascii character array.
The file need not be opened to be removed.

If the file exists and can be removed, OK is returned.
If the file does not exist or cannot be removed for some
other reason, the function returns ERR.
.sp 1
.ti -7
IMPLEMENTATION
.br
The file to be removed need not be connected to the running program.
However, if it is,
remove
closes the file before removing it.

.sp 1
.ti -7
SEE ALSO
.br
open, close, create
.sp 1
.ti -7
DIAGNOSTICS
.br
If the file does not exist the routine returns ERR.
#-t-  remove                      916  local   01/07/81  22:56:06
#-h-  rmtabl                     1532  local   12/10/80  16:21:13
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd RMTABL 03/23/80
remove a symbol table
.sy
subroutine rmtabl (table)
pointer table
.fs
'Rmtabl' is used to remove a symbol table created by 'mktabl'.
The sole argument is the address of a symbol table in dynamic storage
space, as returned by 'mktabl'.
.sp
'Rmtabl' deletes each symbol still in the symbol table, so it is normally
not necessary to empty a symbol table before deleting it.
However, if the information associated with a symbol includes a pointer
to dynamic storage space, the space will not be reclaimed.
(This problem can be averted by scanning the symbol table with 'sctabl'
and freeing dynamic objects, then removing the symbol table with 'rmtabl'.)
.sp
Please see the manual entry for 'dsinit' for instructions on
initializing the dynamic storage space used by the symbol table
routines.
.im
'Rmtabl' traverses each chain headed by the hash table created by 'mktabl'.
Each symbol table node encountered along the way is returned to free
storage by a call to 'dsfree'.
Once all symbols are removed, the hash table itself is returned by
a similar call.
.ca
dsfree
.sa
mktabl (2), enter (2), lookup (2), delete (2), dsget (2),
dsfree (2), dsinit (2), sctabl (2)
#-t-  rmtabl                     1532  local   12/10/80  16:21:13
#-h-  scopy                       523  local   12/10/80  16:21:14
.bp 1
.in 0
.he 'SCOPY (2)'11/13/78'SCOPY (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
scopy - copy string at from(i) to to(j)
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call scopy(from, i, to, j)

character from(ARB), to(ARB)
integer i, j
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Copies the (sub)string of 'from', starting in location 'i',
into array 'to', starting at 'j'.
.sp 1
.ti -7
SEE ALSO
.br
stcopy, addset, addstr, concat
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  scopy                       523  local   12/10/80  16:21:14
#-h-  sctabl                     2727  local   12/10/80  16:24:25
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd SCTABL 03/16/80
scan all symbols in a symbol table
.sy
integer function sctabl (table, symbol, info, posn)
pointer table, posn
integer info (ARB)
character symbol (ARB)
.fs
'Sctabl' provides a means of accessing all symbols present in a
symbol table (c.f. 'mktabl') without knowledge of the table's
internal structure.
After a simple initialization (see below), successive calls
to 'sctabl' return symbols and their associated information.
When the return value of 'sctabl' is EOF, the entire table
has been scanned.
.sp
The first argument is the index in dynamic storage of the symbol
table to be accessed.
(This should be the value returned by 'mktabl'.)
.sp
The second and third arguments receive the character text of and
integer information associated with the symbol currently under
scan.
.sp
The fourth argument is used to keep track of the current position
in the symbol table.
It must be initialized to zero before 'sctabl' is called for the
first time for a given scan.
Furthermore, if the scan must be terminated early (before 'sctabl'
returns EOF) the dynamic storage area pointed to by this argument
must be freed, e.g. with "call dsfree (posn)".
.sp
The function return is EOF when the entire table has been scanned,
not EOF otherwise.
.im
If 'posn' is zero, 'sctabl' allocates two words of dynamic memory
and assigns their location to it.
These words are used to keep track of (1) the hash table bucket
currently in use and (2) the position in the bucket's list of the
next symbol.
If a symbol is available in the current list, 'sctabl'
returns its data and records the position of the next symbol in
the list;
otherwise, it moves to the next bucket and examines that list.
If there are no more buckets in the symbol table, the position
information pointed to by 'posn' is returned via a call to 'dsfree'
and EOF is returned as the function value.
Incidentally, 'posn' is set to zero when the end of the table is
encountered.
.am
symbol, info, posn
.ca
dsget, dsfree
.bu
A call to 'enter' must be made to update the information associated
with a symbol.
If new symbols are entered or old symbols deleted during a scan,
the results are unpredictable.
The argument order is bogus; all the other symbol table routines
have the table pointer as the last argument.
.sa
lookup (2), delete (2), mktabl (2), rmtabl (2), stlu (2),
dsget (2), dsfree (2), dsinit (2)
#-t-  sctabl                     2727  local   12/10/80  16:24:25
#-h-  sdrop                       880  local   12/10/80  16:24:26
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd SDROP 03/23/80
drop characters from a string (APL-style)
.sy
integer function sdrop (from, to, length)
character from (ARB), to (ARB)
integer length
.fs
'Sdrop' copies all but 'length' characters from the 'from' string
into the 'to' string and returns as its result the number of
characters copied.  If 'length' is positive, the omitted characters
are relative to the beginning of the 'from' string; if it is negative,
they are relative to the end of the string.
.am
to
.ca
ctoc, length
.sa
stake (2), index (2), substr (2)
#-t-  sdrop                       880  local   12/10/80  16:24:26
#-h-  seek                       1551  local   01/07/81  22:56:08
.bp 1
.in 0
.he 'SEEK (2)'11/13/78'SEEK (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
seek - move read/write pointer
.sp 1
.ti -7
SYNOPSIS
.br
call seek (offset, fd)
.sp
.br
.nf
integer offset(2)
filedes fd
integer stat returned as OK/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Seek moves the read/write pointer of the file specified
by "fd" to a (previously identified) spot
specified by "offset".
"Offset" must have been set by a call to "note", or its first
element must be set to one of the constants END_OF_FILE or
BEGINNING_OF_FILE (definitions available in the standard symbols
file).
.sp
Once the file is positioned by a call to seek,
reading can be done using the standard I/O calls
(getch, getlin, readf).

Seek
can also be used for seeking to the end of a file and
performing a write (thus extending the file).
.sp
Rewriting in place may not be allowed on some systems.
.sp 1
.ti -7
IMPLEMENTATION
.br
Seek
depends heavily upon the peculiarities of the operating system.
It can generally be used on files opened at READWRITE access.
.sp
The offset units are chosen to be whatever is most appropriate
for the system involved:
characters, words, records, block numbers, line numbers, etc.
Two words have been allotted for "offset" although some
systems may not need that much.

On some systems READWRITE access may have to be implemented by
opening the file twice, once at READ and once at WRITE access.

'Seek' should be made compatible with the standard reading
and writing routines.
.sp 1
.ti -7
SEE ALSO
.br
note
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  seek                       1551  local   01/07/81  22:56:08
#-h-  skipbl                      570  local   12/10/80  16:24:28
.bp 1
.in 0
.he 'SKIPBL (2)'11/13/78'SKIPBL (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
skipbl - skip blanks and tabs at str(i)
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call skipbl(str, i)

character str(ARB)
integer i              # i is incremented
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Starting at position 'i' of array 'str', increments i while
str(i) is a BLANK or TAB.
'Str' is an ascii character array terminated with an EOS marker.
.sp 1
.ti -7
SEE ALSO
.br
getwrd
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  skipbl                      570  local   12/10/80  16:24:28
#-h-  spawn                      3024  local   01/07/81  22:57:40
.bp 1
.in 0
.he 'SPAWN (2)'11/13/78'SPAWN (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
spawn - execute subtask
.sp 1
.ti -7
SYNOPSIS
.br
stat = spawn(command, args, desc, waitflg)
.sp
.nf
character command(ARB), args(ARB), desc(ARB), waitflg
integer stat returned as OK/ERR
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Spawn
is called to cause execution of a subtask.
'Command' is an ascii character array giving the (file)name of
the task to be executed.
 
'Args' is an ascii character array giving the command line
arguments to be passed to the subtask.
The arguments are separated by blanks and the entire string
is terminated with an EOS marker.
 
'Desc' is returned as a character array containing an ID for the
spawned subtask.
This ID may be passed to the 'pstat', 'suspnd', 'resume', and 'kill'
process control tools (if implemented).
 
'Waitflg' is a flag indicating whether or not spawn should return
before execution of the task is completed.
If WAIT is passed, spawn does not return until execution of
the task has completed (the situation for normal commands).
If NOWAIT is passed, spawn begins execution of the task and
immediately returns (for use with real pipes).
If BACKGROUND is passed, spawn executes the task as a background
process and immediately returns.
 
If the task cannot be executed, spawn returns ERR; otherwise it
returns OK.
 
Spawned tasks must be properly taught to read their command line
arguments in whatever manner spawn sends them.
.sp 1
.ti -7
IMPLEMENTATION
.br
Spawn is, by far, the most difficult primitive to implement.  A
few of the major obstacles which must be overcome are:
.sp
.in +5
.ti -3
1. Does the target operating system permit a running process
to spawn a subprocess?  If it provides a multi-user, interactive
environment, it most certainly does, but it may not be common
knowledge as to how to do it.  For example, the following DEC
implementations have been done by the LBL group:
.sp
.in +5
.ti -3
a) RSX11M - a loadable pseudo-driver is used to stuff MCR commands
into MCR's queue, via qio requests.
.sp
.ti -3
b) IAS - the TCS macros provided by the operating system for custom
CLI construction are used.  The only interface is from assembly
language, so that is the language used.
.sp
.ti -3
c) VMS - the sys$creprc system service, which is callable from any
supported language, is used.  In fact, the entire spawn primitive is
written in ratfor.
.sp
.in -5
.ti -3
2. Once one has determined how to spawn the process, it is necessary
to determine how to control it.  If the operating system does not
provide any synchronization methods, then they must be implemented.
.sp
.ti -3
3. Finally, one must determine how to communicate the arguments and
environment information to the subprocess.  This generally entails
an exploration of the system provided interprocess-communication
mechanisms, and often requires the invention of better ones.
.sp
.in -5
.sp 1
.ti -7
SEE ALSO
.br
.sp 1
.ti -7
DIAGNOSTICS
.br
A message 'Cannot spawn process' is printed if that situation occurs.
#-t-  spawn                      3024  local   01/07/81  22:57:40
#-h-  stake                       876  local   12/10/80  16:24:28
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd STAKE 03/23/80
take characters from a string (APL-style)
.sy
integer function stake (from, to, length)
character from (ARB), to (ARB)
integer length
.fs
'Stake' copies the number of characters specified by 'length'
from the 'from' string into the 'to' string and returns
as its result the number of characters copied.  If 'length' is
positive, the characters are copied from the beginning of
'from'; if it is negative, they are copied from the end of 'from'.
.am
to
.ca
ctoc, length
.sa
sdrop (2), index (2), substr (2)
#-t-  stake                       876  local   12/10/80  16:24:28
#-h-  stcopy                      741  local   12/10/80  16:24:30
.bp 1
.in 0
.he 'STCOPY (2)'6/6/79'STCOPY (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
stcopy - copy string at from(i) to to(j); increment j
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call stcopy(from, i, to, j)

character from(ARB), to(ARB)
integer i
integer j             # j is incremented
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Copies the (sub)string of 'from', starting in location 'i',
into array 'to', starting at 'j'.
'j' is incremented to point to the next available position in
'to' (i.e. the EOS marker inserted by the copy).
In all other respects, 'stcopy' is similar to 'scopy'.
.sp 1
.ti -7
SEE ALSO
.br
scopy, concat, addstr, addset
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  stcopy                      741  local   12/10/80  16:24:30
#-h-  strcmp                      604  local   12/10/80  16:24:31
.bp 1
.in 0
.he 'STRCMP (2)'7/23/80'STRCMP (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
strcmp - compare 2 strings
.sp 1
.ti -7
SYNOPSIS
.br
.nf
stat = strcmp (str1, str2)

character str1(ARB), str2(ARB)
integer stat is returned as -1, 0, or +1
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Strcmp compares its aguments and returns an integer greater than,
equal to, or less than 0, depending on whether str1 is
lexicographically greater than, equal to, or less than str2.
.sp 1
.ti -7
SEE ALSO
.br
equal
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  strcmp                      604  local   12/10/80  16:24:31
#-h-  strim                       900  local   12/10/80  16:24:32
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd STRIM 03/23/80
trim trailing blanks and tabs from a string
.sy
integer function strim (str)
character str (ARB)
.fs
'Strim' is used to trim trailing blanks and tabs from the EOS-terminated
string passed as its first argument.
The function return is the length of the trimmed string,
excluding EOS.
.im
One pass is made through the string, and the position of the last
non-blank, non-tab character remembered.
When the entire string has been scanned, an EOS is planted immediately
after the last non-blank.
.am
str
.sa
stake (2), sdrop (2), substr (2)
#-t-  strim                       900  local   12/10/80  16:24:32
#-h-  substr                     1338  local   12/10/80  16:24:32
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd SUBSTR 03/23/80
take a substring from a string
.sy
integer function substr (from, to, first, length)
character from (ARB), to (ARB)
integer first, length
.fs
'Substr' copies the portion of the 'from' string specified by
the 'first' and 'length' arguments into the 'to' string and
returns the length of 'to' string as its result.  'First' specifies
the starting character position in 'from'; if it is positive, it
indicates a position relative to the beginning of the string, whereas
if it is negative, the indicated position is relative to the end
of the string.
'Length' specifies the number of characters to be copied; if positive,
'length' characters
.ul
starting
with the one selected by 'first' are copied; if negative, 'length'
characters
.ul
ending
with the one selected by 'first' are copied.  If the specified
substring overlaps either the beginning or the end of 'from',
'to' will be shorter than 'length' characters.
.am
to
.ca
length
.sa
stake (2), sdrop (2), strim (2)
#-t-  substr                     1338  local   12/10/80  16:24:32
#-h-  type                        542  local   12/10/80  16:24:33
.bp 1
.in 0
.he 'TYPE (2)'11/13/78'TYPE (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
type - determine type of character
.sp 1
.ti -7
SYNOPSIS
.br
.nf
t = type(c)

character c
character t is returned as LETTER, DIGIT, or c
.fi
.sp 1
.ti -7
DESCRIPTION
.br
This function determines whether the character 'c' is a letter,
a digit, or something else; it returns LETTER, DIGIT, or the
character itself.
.sp 1
.ti -7
SEE ALSO
.br
index
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  type                        542  local   12/10/80  16:24:33
#-h-  upper                       580  local   12/10/80  16:24:34
.bp 1
.in 0
.he 'UPPER (2)'11/13/78'UPPER (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
upper - convert string to upper case
.sp 1
.ti -7
SYNOPSIS
.br
.nf
call upper(str)

character str(ARB)
.fi
.sp 1
.ti -7
DESCRIPTION
.br
Converts the array 'str' to upper case, if not already there.
If any characters are non-alphabetic, it leaves them unchanged.
'Str' is an ascii character array terminated with an EOS marker.
.sp 1
.ti -7
SEE ALSO
.br
cupper, fold, clower, lower
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  upper                       580  local   12/10/80  16:24:34
#-h-  wkday                       846  local   12/10/80  16:24:34
.de hd
.bp 1
.in 0
.he '$1 (2)'$2'$1 (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
$1 -
.en
.de sy
.sp 1
.ti -7
SYNOPSIS
.br
.nf
.en
.de fs
.fi
.sp
.ti -7
DESCRIPTION
.br
.en
.de im
.sp
.ti -7
IMPLEMENTATION
.br
.en
.de sa
.sp
.ti -7
SEE ALSO
.br
.en
.de am
.sp
.ti -7
ARGUMENTS MODIFIED
.br
.en
.de ca
.sp
.ti -7
CALLS
.br
.en
.de bu
.sp
.ti -7
BUGS
.br
.en
.hd WKDAY 03/23/80
get day-of-week corresponding to month, day, year
.sy
integer function wkday (month, day, year)
integer month, day, year
.fs
'Wkday' is used to return the day-of-the-week corresponding to a
given date.
The three arguments completely specify the date:
the month (1-12), day (1-28, 29, 30, or 31), and year (e.g. 1980).
The function return is the ordinal number of the day-of-the-week
(1 == Sunday, 7 == Saturday).
.im
Zeller's Congruence.
.sa
getnow (2), fmtdat (2), date (1)
#-t-  wkday                       846  local   12/10/80  16:24:34
#-h-  writef                     1093  local   01/07/81  22:56:10
.bp 1
.in 0
.he 'WRITEF (2)'6/30/78'WRITEF (2)'
.fo ''-#-''
.fi
.in 7
.ti -7
NAME
.br
writef - write to an opened file
.br
.sp
.ti -7
SYNOPSIS
.br
count = writef (buf, n, fd)
.sp
.nf
character buf(ARB)   or   integer buf(ARB)
integer n
filedes fd
integer count returned as count/ERR
.fi
.br
.sp 1
.ti -7
DESCRIPTION
.br
Writef writes "n" bytes from the array "buf" to the file
opened on file descriptor "fd".
Writef is the typical way of doing binary writes to files.
Whether buf is declared an integer or a character array is
dependent upon which is most appropriate for the host operating
system.
.sp
Writef returns the number of bytes/words actually written.
In most cases, this is equal to "n".
If, however, a write error occurs, writef returns ERR.
.sp 1
.ti -7
IMPLEMENTATION
.br
Writef is the typical way of implementing binary I/O.
Do whatever is necessary on your system to allow users
to get at the file directly.
.sp
If reasonable, design writef to work properly in conjunction
with putch and putlin.
.sp 1
.ti -7
SEE ALSO
.br
readf, putch, putlin
.sp 1
.ti -7
DIAGNOSTICS
.br
None
#-t-  writef                     1093  local   01/07/81  22:56:10
#-h-  sysdep                      234  local   12/10/80  16:24:35
.bp 1
.he ''''
.ce
3.  ADDITIONAL TOOLS AND SYSTEM-DEPENDENT INFORMATION
.sp 2
This section contains additional tools which may not be
implemented on every system, plus information about
using the tools on the local operating system.
#-t-  sysdep                      234  local   12/10/80  16:24:35
#-h-  primers                     205  local   12/10/80  16:24:42
.bp 1
.he ''''
.ce
4.  PRIMERS
.sp 2
This section contains more detailed help documents
for using some of the more complicated tools
It is anticipated that more primers will be written as
the need arises.
#-t-  primers                     205  local   12/10/80  16:24:42
#-h-  edit.prm                  36939  local   01/09/81  01:14:30
.bp 1
.in 5
.he 'ED Tutorial'10/28/80'ED Tutorial'
.fo ''-#-''
.sp 2
.ce
A Tutorial Introduction to the Software Tools TEXT EDITOR
.sp 2
.ce 2
B. Kernighan
Bell Laboratories
.sp
.ce
and
.sp
.ce 2
M.J. Gralia
Johns Hopkins University - Applied Physics Laboratory
.sp 3

.ti -5
INTRODUCTION
.br
.bd 1
Ed
is a "text editor", that is, an interactive program
for creating and modifying "text", using directions
provided by a user at a terminal.  The text is often
a document like this one, or a program or perhaps
data for a program.
.sp
This introduction is meant to simplify learning
.bd 1
ed.
The
recommended way to learn
.bd 1
ed
is to read this document,
simultaneously using
.bd 1
ed
to follow the examples,
then to read the description in section I of the Software Tools manual, all the
while experimenting with
.bd 1
ed.
(Solicitation of advice from
experienced users is also useful.)
.sp
Do the exercises!  They cover material not completely
discussed in the actual text.  An appendix summarizes the commands.

.ti -5
DISCLAIMER
.br
This is an introduction and a tutorial.
For this reason, no attempt is made to cover more than
a part of the facilities that
.bd 1
ed
offers (although
this fraction includes the most useful and
frequently used parts).  Also, there is not enough
space to explain basic Software Tools procedures.
We will assume
that you know how to log on and access the Software Tools, and that
you have at least a vague understanding of what a file is.
.sp
You must also know what character to type as the
end-of-line on your particular terminal.  It
is almost always a "return".
Throughout, we will refer to
this character, whatever it is, as "newline".

.ti -5
CASES
.br
And about case:  it is traditional to use both upper and
lower case characters when using the Software Tools, but
it is not required.  In describing
.bd 1
ed,
we will follow that
convention, but
.bd 1
ed
will work with either.
.sp
But a caution:
.bd 1
ed
differentiates cases.  If your files
contain both and your terminal is in upper case, you can
get into a "deadly embrace" situation in which you can see a
character but can't delete it.  The solution is simple -
always use both upper and lower case with Software Tools.

.ti -5
GETTING STARTED
.br
We'll assume that you have logged in.
The easiest way to get
.bd 1
ed
is to type
.sp
.nf
.ti +6
ed      (followed by a newline)
.fi
.sp
You are now ready to go -
.bd 1
ed
is waiting for you to tell it what to do.

.ti -5
CREATING TEXT - the Append command ``a''
.br
As our first problem, suppose we want to create some text
starting from scratch.  Perhaps we are typing the very first
draft of a paper; clearly it will have to start somewhere,
and undergo modifications later.  This section will show how
to get some text in, just to get started.  Later
we'll talk about how to change it.
.sp
When
.bd 1
ed
is first started, it is rather like working with a blank piece
of paper - there is no text or information present.  This must be
supplied by the person using
.bd 1
ed;
it is usually done by typing in the text, or by reading
it into
.bd 1
ed
from a file.  We will start by typing in some text, and
return shortly to how to read files.
.sp
First a bit of terminology.  In
.bd 1
ed
jargon, the text being marked on is said to be
"kept in a buffer."  Think of the buffer as a
work space, if you like, or simply as the
information that you are going to be editing.
In effect the buffer is like the piece of paper
on which we will write things, then change
some of them, and finally file the whole
thing away for another day.
.sp
The user tells
.bd 1
ed
what to do to his text by typing instructions
called "commands".  Most commands consist of a single letter.
Each command is typed on a separate line.  (Sometimes
the command is preceded by information about what
line or lines of text are to be
affected - we will discuss these shortly.)
.sp
The first command is
.bd 1
append,
written as the letter
.sp
.in +6
a
.in -6
.sp
all by itself.  It means
.bd 1
"append
(or add) text lines to the buffer,
as I type them in."  Appending is rather like writing fresh
material on a piece of paper.
.sp
So to enter lines of text into the buffer, we
just type an "a" followed by a newline,
followed by the lines of text we want, like this:
.sp
.nf
.in +6
.cc #
#nf
a
Now is the time
for all good men
to come to the aid of their party.
.
#fi
#cc .
.in -6
.fi
.sp
The only way to stop appending is to type a
line that contains only a period.  The "."
is used to tell
.bd 1
ed
that we have finished appending.  (Even
experienced users forget that terminating "."
sometimes.  If
.bd 1
ed
seems to be ignoring you, type an extra line with
just "." on it.  You may then find you've
added some garbage lines to your text, which you'll
have to take out later.)
.sp
After the append command has been done, the
buffer will contain the three lines
.sp
.nf
.in +6
Now is the time
for all good men
to come to the aid of their party.
.in -6
.fi
.sp
The "a" and "." aren't there, because they are not text.
.sp
To add more text to what we already have,
just issue another "a" command, and continue typing.
(Try it now - it won't always work right until
we explain about line numbers.)

.ti -5
ERROR MESSAGES - ``?''
.br
If at any time you make an error in the
commands you type to
.bd 1
ed,
it will tell you by typing
.sp
.in +6
.nf
?
.fi
.in -6
.sp
This is about as cryptic as it can be, but with
practice, you can usually figure out how you
goofed.

.ti -5
WRITING TEXT OUT AS A FILE - the Write command ``w''
.br
It's likely that we'll want to save our text for
later use.  To write out the contents of the buffer
onto a file, we use the
.bd 1
write
command
.sp
.ti +6
w
.sp
followed by the filename we want to write on.
This will copy the buffer's contents onto the
specified file (destroying any previous information on the
file).  To save the text on a file named "junk", for
example, type
.sp
.ti +6
w junk
.sp
Leave a space between "w" and the file name.
.bd 1
Ed
will respond by printing the number of lines it
wrote out.  In our case,
.bd 1
ed
would respond with
.sp
.ti +6
3
.sp
Writing a file just makes a copy
of the text - the buffer's contents are not disturbed,
so we can go on adding lines to it.  This is
an important point.
.bd 1
Ed
at all times works on a copy of a file, not the file itself.
No change in the contents of a file takes place until you give
a "w" command.  (Writing out the text onto a file from
time to time as it is being created is a good idea,
since if the system crashes or if you make some
horrible mistake, you will lose all the text in
the buffer, but any text that was written  onto a file
is relatively safe.)

.ti -5
LEAVING ED - the Quit command ``q''
.br
To terminate a session with
.bd 1
ed,
save the text you're working on by writing it onto a file
using the "w" command, and then type the command
.sp
.ti +6
q
.sp
which stands for
.bd 1
quit.
At this point your buffer vanishes,
with all its text, which is why you want to write it out
before quitting.

.ti -5
EXERCISE 1:
.br
Enter
.bd 1
ed
and create some text using
.sp
.in +6
.cc #
#nf
a
...text...
.
#fi
#cc .
.in -6
.sp
Write it out using "w".  Then leave
.bd 1
ed
with the "q" command, and print the file, to see that
everything worked.  (To print a file, say
.sp
.ti +6
cat filename
.sp
Also try
.sp
.ti +6
crt filename
.sp
Here, you need to enter a newline (to see the next page)
or "q" (to quit displaying the text).

.ti -5
READING TEXT FROM A FILE - the Edit command ``e''
.br
A common way to get text into the buffer is to
read it from a file in the file system.  This is
what you do to edit text that you saved with the "w"
command in a previous session.  The
.bd 1
edit
command "e" fetches the entire contents of a
file into the buffer.  So if we had saved the three
lines "Now is the time", etc., with a "w"
command in an earlier session, the
.bd 1
ed
command
.sp
.ti +6
e junk
.sp
would fetch the entire contents of the file "junk"
into the buffer, and respond
.sp
.ti +6
3
.sp
which is the number of lines in "junk".
If
anything was already in the buffer,
it is deleted first.
.sp
If we use the "e" command to read a file into the
buffer, then we need not use a file name after a
subsequent "w" command;
.bd 1
ed
remembers the last file name used in an "e" command, and
"w" will write on this file.  Thus a common way to
operate is
.sp
.nf
.in +6
ed
e file
[editing session]
w
q
.fi
.in -6
.sp
You can find out at any time what file named
.bd 1
ed
is remembering by typing the
.bd 1
file
command "f".  In our case, if we typed
.sp
.ti +6
f
.sp
.bd 1
ed
would reply
.sp
.ti +6
junk

.ti -5
READING TEXT FROM A FILE - the Read command ``r''
.br
Sometimes we want to read a file into the
buffer without destroying anything that is already
there.  This is done by the
.bd 1
read
command "r".
The command
.sp
.ti +6
r junk
.sp
will read the file "junk" into the buffer; it adds it
to the buffer (after the current line).  So if we do a
read after an edit:
.sp
.nf
.in +6
e junk
r junk
.in -6
.fi
.sp
the buffer will contain
.bd 1
two
copies
of the text (six lines).
.sp
.in +6
.nf
Now is the time
for all good men
to come to the aid of their party.
Now is the time
for all good men
to come to the aid of their party.
.fi
.in -6
.sp
.fi
Like the "w" and "e" commands, "r" prints the
number of newlines read in, after the reading
operation is complete.
.sp
Generally speaking, "r" is much less used than "e".

.ti -5
EXERCISE 2:
.br
Experiment with the "e" command - try reading
and printing various files.  You may get an
error "?.", typically because you spelled the file
name wrong.  Try alternately reading and appending
to see that they work similarly.  Verify that
.sp
.ti +6
ed filename
.sp
is exactly equivalent to
.sp
.in +6
.nf
ed
e filename
.fi
.in -6
.sp
What does
.sp
.ti +6
f filename
.sp
do?

.ti -5
PRINTING THE CONTENTS OF THE BUFFER - the Print command ``p''
.br
To
.bd 1
print
or list the contents of the buffer (or parts of
it) on the terminal, we use the print command
.sp
.ti +6
p
.sp
The way this is done is as follows.  We specify the
lines where we want printing to begin and where
we want it to end, separated by a comma, and
followed by the letter "p".  Thus to print the
first two lines of the buffer, for example, (that is,
lines 1 through 2) we say
.sp
.ti +6
1,2p
(starting line=1, ending line=2)
.sp
.bd 1
Ed
will respond with
.sp
.in +6
.nf
Now is the time
for all good men
.fi
.in -6
.sp
Suppose we want to print
.bd 1
all
the lines in the
buffer.  We could use "1,3p" as above if we knew
there were exactly 3 lines in the buffer.  But in
general, we don't know how many there are so what do we
use for the ending line number?
.bd 1
Ed
provides a shorthand
symbol for "line number of last line in buffer" - the dollar
sign "$".  Use it this way:
.sp
.ti +6
1,$p
.sp
This will print
.bd 1
all
the lines in the buffer
(line 1 to the last line.)
.sp
To print the
.bd 1
last
line of the buffer,
we could use
.sp
.ti +6
$,$p
.sp
but
.bd 1
ed
lets us abbreviate this to
.sp
.ti +6
$p
.sp
We can print any single line by typing the line
number followed by a "p".  Thus
.sp
.ti +6
1p
.sp
produces the response
.sp
.ti +6
Now is the time
.sp
which is the first line of the buffer.
.sp
In fact,
.bd 1
ed
lets us abbreviate even further:  we can
print any single line by typing
.bd 1
just
the line number - no need to type the letter "p".
So if we say
.sp
.ti +6
$
.sp
.bd 1
ed
will print the last line of the buffer for us.
.sp
We can also use "$" in combinations like
.sp
.ti +6
$-1,$p
.sp
which prints the last two lines of the buffer.
This helps when we want to see how far we got
in typing.

.ti -5
EXERCISE 3:
.br
As before, create some text using the append
command and experiment with the "p" command.
You will find, for example, that you can't print
line 0 or a line beyond the end of the
buffer, and that attempts to print a buffer in
reverse order by saying
.sp
.ti +6
3,1p
.sp
don't work.

.ti -5
THE CURRENT LINE - 'Dot' or '.'
.br
Suppose our buffer still contains the six
lines as above, that we have just typed
.sp
.ti +6
1,3p
.sp
and
.bd 1
ed
has printed the three lines for us.
Try typing just
.sp
.nf
.ti +6
p     (no line numbers).
.fi
.sp
This will print
.sp
.ti +6
to come to the aid of their party.
.sp
which is the third line of the buffer.  In fact
it is the last (most recent) line that we have done
anything with.  (We just printed it!)  We can
repeat this "p" command without line numbers,
and it will continue to print line 3.
.sp
The reason is that
.bd 1
ed
maintains a record of
the last line that we did anything to (in this case,
line 3, which we just printed) so that it can be
used instead of an explicit line number.  This
most recent line is referred to by the shorthand
symbol
.sp
.cc +
+ti +6
.     (pronounced "dot").
+cc .
.sp
Dot is a line number in the same way that "$"
is; it means exactly "the current line", or
loosely, "the line we most recently did something to."
We can use it in several ways - one possibility
is to say
.sp
.ti +6
.cc #
#nf
.,$p
#fi
#cc .
.sp
This will print all the lines from (including) the
current line to the end of the buffer.  In our case
these are lines 3 through 6.
.sp
Some commands change the value of dot, while others
do not.  The print command sets dot to the number of the
last line printed; by our last command, we would have
"." = "$" = 6.
.sp
Dot is most useful when used in combinations like this one:
.sp
.ti +6
.cc #
#nf
.+1     (or equivalently, .+1p)
#fi
#cc .
.sp
This means "print the next line" and gives us a
handy way to step slowly through a buffer.
We can also say
.sp
.ti +6
.nf
.cc #
.-1     (or .-1p)
#cc .
.fi
.sp
which means "print the line
.bd 1
before
the current
line." This enables us to go backwards if we
wish.  Another useful one is something like
.sp
.ti +6
.nf
.cc #
.-3,.-1p
#cc .
.fi
.sp
which prints the previous three lines.
.sp
Don't forget that all of these change the value
of dot.  You can find out what dot is at
any time by typing
.sp
.ti +6
.nf
.=
.fi
.sp
.bd 1
Ed
will respond by printing the value of dot.
.sp
Let's summarize some things about the "p"
command and dot.  Essentially "p" can be preceded by
0, 1, or 2 line numbers.  If there is no line
number given, it prints the "current line", the line
that dot refers to.  If there is one line number
given (with or without the letter "p"), it prints
that line (and dot is set there); and if there are two
line numbers, it prints all the lines in that range
(and sets dot to the last line printed.) If two line
numbers are specified the first can't be bigger than the
second (see Exercise 3.)
.sp
Typing a single newline will cause printing of the
next line - it's equivalent to ".+1p".  Try it.

.ti -5
DELETING LINES: the ``d'' command
.br
Suppose we want to get rid of the three extra
lines in the buffer.  This is done by the
.bd 1
delete
command
.sp
.ti +6
d
.sp
Except that "d" deletes lines instead of printing them,
its action is similar to that of "p".  The
lines to be deleted are specified for "d" exactly as
they are for "p":
.sp
.ti +6
starting-line, ending-line d
.sp
Thus the command
.sp
.ti +6
4,$d
.sp
deletes lines 4 through the end.  There are now
three lines left, as we can check by using
.sp
.ti +6
1,$p
.sp
And notice that "$" now is line 3!  Dot is set to the
next line after the last line deleted, unless the
last line deleted is the last line in the buffer.
In that case, dot is set to "$".

.ti -5
EXERCISE 4:
.br
Experiment with "a", "e", "r", "w", "p", and "d" until
you are sure that you know what they do, and until you understand
how dot, "$", and line numbers are used.
.sp
If you are adventurous, try using line numbers
with "a", "r", and "w" as well.  You will find that
"a" will append lines
.bd 1
after
the line number
that you specify (rather than after dot); that "r" reads
a file in
.bd 1
after
the line number you specify
(not necessarily at the end of the buffer); and that "w"
will write out exactly the lines you specify, not
necessarily the whole buffer.  These variations are
sometimes handy.  For instance you can insert a file
at the beginning of a buffer by saying
.sp
.ti +6
0r filename
.sp
and you can enter lines at the beginning of the
buffer by saying
.sp
.in +6
.cc #
#nf
0a
...text...
.
#fi
#cc .
.in -6
.sp
Notice that ".w" is
.bd 1
very
different from
.sp
.in +6
.nf
.cc #
.
w
#cc .
.fi
.in -6
.sp

.ti -5
MODIFYING TEXT: the Substitute command ``s''
.br
We are now ready to try one of the most important
of all commands - the substitute command
.sp
.ti +6
s
.sp
This is the command that is used to change
individual words or letters within a line or group of
lines.  It is what we use, for example, for correcting
spelling mistakes and typing errors.
.sp
Suppose that by a typing error, line 1 says
.sp
.ti +6
Now is th time
.sp
- the "e" has been left off "the".  We can use "s"
to fix this up as follows:
.sp
.ti +6
1s/th/the/
.sp
This says:  "in line 1, substitute for the characters
`th' the characters `the'.  To verify that it works
(
.bd 1
ed
will not print the result automatically)
we say
.sp
.ti +6
p
.sp
and get
.sp
.ti +6
Now is the time
.sp
which is what we wanted.  Notice that dot must have
been set to the line where the substitution took place,
since the "p" command printed that line.  Dot is always set
this way with the "s" command.
.sp
The general way to use the substitute command is
.sp
.ti +6
starting-line, ending-line s/change this/to this/
.sp
Whatever string of characters is between
the first pair of slashes is replaced by whatever
is between the second pair, in
.bd 1
all
the lines between
starting line and ending line.  Only the first occurrence on each line
is changed, however.  If you want to change
.bd 1
every
occurrence,
see Exercise 5.  The rules for
line numbers are the same as those for "p", except that dot
is set to the last line changed. (But there is a trap for the
unwary:  if no substitution took place, dot is
.bd 1
not
changed.  This causes an error "?" as a warning.)
.sp
Thus we can say
.sp
.ti +6
1,$s/speling/spelling/
.sp
and correct the first spelling mistake on each line in the text.
(This is useful for people who are consistent misspellers!)
.sp
If no line numbers are given, the "s" command assumes we
mean "make the substitution on line dot", so it changes things
only on the current line.  This leads to the very common sequence
.sp
.ti +6
s/something/something else/p
.sp
which makes some correction on the current line, and
then prints it, to make sure it worked out right.
If it didn't, we can try again.  (Notice that we put
a print command on the same line as the substitute.  With
few exceptions, "p" can follow any command; no other multi-command
lines are legal.)
.sp
It's also legal to say
.sp
.ti +6
s/something//
.sp
which means "change 'something' to
.bd 1
nothing,"
i.e., remove it.  This
is useful for deleting extra words in a line or
removing extra letters from words.  For instance,
if we had
.sp
.ti +6
Nowxx is the time
.sp
we can say
.sp
.ti +6
s/xx//p
.sp
to get
.sp
.ti +6
Now is the time
.sp
Notice that "//" here means "no characters", not
a blank.  There
.bd 1
is
a difference!  (See below
for another meaning of "//".)

.ti -5
EXERCISE 5:
.br
Experiment with the substitute command.  See what
happens if you substitute for some word on a line
with several occurrences of that word.  For
example, do this:
.sp
.in +6
.nf
.cc #
a
the other side of the coin
.
s/the/on the/p
#cc .
.fi
.in -6
.sp
You will get
.sp
.ti +6
on the other side of the coin
.sp
A substitute command changes only the first
occurrence of the first string.  You can change all
occurrences by adding a "g" (for "global") to
the "s" command, like this:
.sp
.ti +6
s/.../.../gp
.sp
Try other characters instead of slashes to delimit the two
sets of characters in the "s" command - anything should
work except blanks or tabs.
.sp
(If you get funny results using any of the characters
.sp
.nf
.ti +6
%  ?  $  [  *  @
.fi
.sp
read the section on "Special Characters".)

.ti -5
CONTEXT SEARCHING - ``/.../''
.br
With the substitute command mastered, we can move on
to another highly important idea of
.bd 1
ed
- context searching.
.sp
Suppose we have our original three line text in the buffer:
.sp
.in +6
.nf
Now is the time
for all good men
to come to the aid of their party.
.fi
.in -6
.sp
Suppose we want to find the line that contains "their"
so we can change it to "the". Now with only three lines in the buffer,
it's pretty easy to keep track of what line the word "their"
is on.  But if the buffer contained several hundred lines, and
we'd been making changes, deleting and rearranging
lines, and so on, we would no longer really know what
this line number would be.  Context searching is simply a method
of specifying the desired line, regardless of what its number is,
by specifying some context on it.
.sp
The way we say "search for a line that contains this
particular string of characters" is to type
.sp
.ti +6
/string of characters we want to find/
.sp
For example, the
.bd 1
ed
line
.sp
.ti +6
/their/
.sp
is a context search which is sufficient to find the
desired line - it will locate the next occurrence of the
characters between slashes ("their").  It also sets dot
to that line and prints the line for verification:
.sp
.ti +6
to come to the aid of their party.
.sp
"Next occurrence" means that
.bd 1
ed
starts looking for the
string at line ".+1", searches to the end of the buffer,
then continues at line 1 and searches to line dot.  (That is,
the search "wraps around" from "$" to 1.)  It scans all the
lines in the buffer until it either finds the desired line or
gets back to dot again.  If the given string of characters
can't be found in any line,
.bd 1
ed
types the error message
.sp
.ti +6
?
.sp
Otherwise it prints the line it found.
.sp
We can do both the search for the desired line
.bd 1
and
a substitution all at once, like this:
.sp
.ti +6
/their/s/their/the/p
.sp
which will yield
.sp
.ti +6
to come to the aid of the party.
.sp
There were three parts to that last command:  context search
for the desired line, make the substitution, print the line.
.sp
The expression "/their/" is a context search expression.
In their simplest form, all context search expressions are like this -
a string of characters surrounded by slashes.  Context searches are
interchangeable with line numbers, so they can be used by
themselves to find and print a desired line, or as line
numbers for some other command, like "s".  We used them both
ways in the examples above.
.sp
Suppose the buffer contains the three familiar lines
.in +6
.nf
.sp
Now is the time
for all good men
to come to the aid of their party.
.fi
.in -6
.sp
Then the
.bd 1
ed
line numbers
.sp
.in +6
.nf
/Now/+1
/good/
/party/-1
.fi
.in -6
.sp
are all context search expressions, and they all refer to the
same line (line 2).  To make a change in line 2, we could say
.sp
.ti +6
/Now/+1s/good/bad/
.sp
or
.sp
.ti +6
/good/s/good/bad/
.sp
or
.sp
.ti +6
/party/-1s/good/bad/
.sp
The choice is dictated only by convenience.  We could print
all three lines by, for instance
.sp
.ti +6
/Now/,/party/p
.sp
or
.sp
.ti +6
/Now/,/Now/+2p
.sp
or by any number of similar combinations.  The first one
of these might be better if we don't know how many lines
are involved.  (Of course, if there were only three lines
in the buffer, we could use
.sp
.ti +6
1,$p
.sp
but not if there were several hundred.)
.sp
The basic rule is:  a context search expression is
.bd 1
the
same as a line number, so it can be used wherever a
line number is needed.

.ti -5
EXERCISE 6:
.br
Experiment with context searching.  Try a body of text
with several occurrences of the same string of
characters, and scan through it using the same context search.
.sp
Try using context searches as line numbers for the
substitute, print and delete commands.  (They can also
be used with "r", "w", and "a".)
.sp
Try context searching using "\text\" instead of "/text/".
This scans lines in the buffer in reverse order rather than normal.
This is sometimes useful if you go too far while looking for
some string of characters - it's an easy way to back up.
.sp
(If you get funny results with any of the characters
.sp
.in +6
.nf
%  ?  $  [  *  @
.fi
.in -6
.sp
read the section on "Special Characters".)
.sp
.bd 1
Ed
provides a shorthand for repeating a context search
for the same string.  For example, the
.bd 1
ed
line number
.sp
.ti +6
/string/
.sp
will find the next occurrence of "string".  It often
happens that this is not the desired line, so the search
must be repeated.  This can be done by typing merely
.sp
.ti +6
//
.sp
This shorthand stands for "the most recently used context
search expression."  It can also be used as the first string
of the substitute command, as in
.sp
.ti +6
/string1/s//string2/
.sp
which will find the next occurrence of "string1" and
replace it by "string2".  This can save a lot of typing.
Similarly
.sp
.ti +6
\\
.sp
means "scan backwards for the same expression."

.ti -5
CHANGE and INSERT - ``c'' and ``i''
.br
This section discusses the
.bd 1
change
command
.sp
.ti +6
c
.sp
which is used to change or replace a group of one or more
lines, and the
.bd 1
insert
command
.sp
.ti +6
i
.sp
which is used for inserting a group of one or more lines.
.sp
.ne 5
"Change", written as
.sp
.ti +6
c
.sp
is used to replace a number of lines with different lines,
which are typed in at the terminal.  For example, to
change lines ".+1" through "$" to something else, type
.sp
.in +6
.cc #
#nf
.+1,$c
...type the lines of text you want here...
.
#fi
#cc .
.in -6
.sp
The lines you type between the "c" command and the "."
will take the place of the original lines between
start line and end line.  This is most useful in
replacing a line or several lines which have errors in them.
.sp
If only one line is specified in the "c" command, then
just that line is replaced.  (You can type in as many
replacement lines as you like.)  Notice the use of "." to end
the input - this works just like the "." in the append
command and must appear by itself on a new line.  If no line number
is given, line dot is replaced.  The value of dot is set to
the last line you typed in.
.sp
.ne 8
"Insert" is similar to append - for instance
.sp
.in +6
.cc #
#nf
/string/i
...type the lines to be inserted here...
.
#fi
#cc .
.in -6
.sp
will insert the given text
.bd 1
before
the next line that
contains "string".  The text between "i" and "." is
.bd 1
inserted
before the specified line.  If no line
number is specified dot is used.  Dot is set to the last line inserted.

.ne 16
.ti -5
EXERCISE 7:
.br
"Change" is rather like a combination of delete followed by
insert.  Experiment to verify that
.sp
.in +6
.cc #
#nf
start, end d
i
...text...
.
#fi
#cc .
.in -6
.sp
is almost the same as
.sp
.in +6
.cc #
#nf
start, end c
...text...
.
#fi
#cc .
.in -6
.sp
.fi
These are not
.bd 1
precisely
the same if line "$"
gets deleted.  Check this out.  What is dot?
.sp
Experiment with "a" and "i", to see that they are
similar, but not the same.
.ne 13
You will observe that
.sp
.in +6
.cc #
#nf
line-number a
...text..
.
#fi
#cc .
.in -6
.sp
.fi
appends
.bd 1
after
the given line, while
.sp
.in +6
.cc #
#nf
line-number i
...text...
.
#fi
#cc .
.in -6
.sp
inserts
.bd 1
before
it.  Observe that if no line number is
given, "i" inserts before line dot, while "a"
appends after line dot.

.ti -5
BROWSING: the ``b'' command
.br
Many times you want to look at several lines
of a large file
while you're using a video terminal.
If you said
.sp
.ti +6
1,$p
.sp
the whole buffer would flash on the screen, usually
too fast to read.  A better way is the browse
command "b".  It prints just enough lines (23)
to fill the CRT screen.  Browse has three major forms which control
what lines are displayed.  "b" or "b+" prints the current
line and the screen after it.  "b." prints the screen
centered on the current line and including it.
"b-" prints the screenful before the current line.

.ti -5
MOVING TEXT AROUND: the ``m'' command
.br
The move command "m" is used for cutting and pasting - it
lets you move a group of lines from one place to another
on the buffer.  Suppose we want to put the first three lines
of the buffer at the end instead.  We could do it by saying:
.sp
.in +6
.nf
1,3w temp
$r temp
1,3d
.fi
.in -6
.sp
(Do you see why?) but we can do it a lot easier with the "m"
command:
.sp
.ti +6
1,3m$
.sp
The general case is
.sp
.ti +6
start-line, end-line m after-this-line
.sp
Notice that there is a third line to be specified - the
place where the moved stuff gets put.  Of course the lines
to be moved can be specified by context searches; if we had
.sp
.in +6
.cc #
#nf
First paragraph
...
end of first paragraph.
Second paragraph
...
end of second paragraph.
#fi
#cc .
.in -6
.sp
we could reverse the two paragraphs like this:
.sp
.ti +6
/Second/,/second/m/First/-1
.sp
.fi
Notice the "-1" - the moved text goes
.bd 1
after
the
line mentioned.  Dot gets set to the last line moved.

.ti -5
THE GLOBAL COMMAND ``g''
.br
The
.bd 1
global
command "g" is used to execute an
.bd 1
ed
command on all those lines in the buffer that match some specified
string.  For example
.sp
.ti +6
g/peling/p
.sp
prints all lines that contain "peling".  More usefully,
.sp
.ti +6
g/peling/s//pelling/gp
.sp
makes the substitution everywhere on the line, then prints
each corrected line.  Compare this to
.sp
.ti +6
1,$s/peling/pelling/gp
.sp
which only prints the last line substituted.  Another subtle
difference is that the "g" command does not give a "?"
if "peling" is not found where the "s" command will.

.ti -5
SPECIAL CHARACTERS
.br
You may have noticed that things just don't work right
when you used some characters like "?", "*", "$", and others
in context searches and the substitute command.  The reason is
rather complex, although  the cure is simple.  Basically,
.bd 1
ed
treats these characters as special, with special meanings.
For instance,
.bd 1
in
a context search or the first
string of the substitute command only,
.sp
.ti +6
/x?y/
.sp
means "a line with an x,
.bd 1
any
character, and a y,"
.bd 1
not
just
"a line with an x, a question mark, and a y."
A complete list of the special characters that can
cause trouble is the following:
.sp
.ti +6
%   .   $   [   *   @   #   !
.sp
.bd 1
Warning:
The character @ is special to
.bd 1
ed.
For safety's sake, avoid it where possible.  If you have
to use one of the special characters in a
substitute command, you can turn off its magic meaning
temporarily by preceding it with the "at" sign.  Thus
.sp
.ti +6
s/@@@?@*/at quest star/
.sp
will change "@?*" into "at quest star".
.sp
Here is a hurried synopsis of the other special characters.
First, the percent "%" signifies the beginning
of a line.  Thus
.sp
.ti +6
/%string/
.sp
finds "string" only if it is at the beginning of a line:
it will find
.sp
.ti +6
string
.sp
.ne 3
but not
.sp
.ti +6
the string...
.sp
The dollar-sign "$" is just the opposite of the
percent sign; it means the end of a line:
.sp
.ti +6
/string$/
.sp
will only find an occurrence of "string" that is at
the end of some line.  This implies, of course,
that
.sp
.ti +6
/%string$/
.sp
will find only a line that contains just "string", and
.sp
.ti +6
/%?$/
.sp
finds a line containing exactly one character.
.sp
The character "?", as we mentioned above, matches anything;
.sp
.ti +6
/x?y/
.sp
matches any of
.sp
.in +6
.nf
xay
x1y
x+y
x-y
x y
x.y
.fi
.in -6
.sp
This is useful in conjunction with "*", which is a
repetition character; "a*" is shorthand for "any
number of a's", so "?*" matches any number of
anythings.  This is used like this:
.sp
.ti +6
s/?*/stuff/
.sp
which changes an entire line, or
.sp
.ti +6
s/?*,//
.sp
which deletes all characters in the line up to and
including the last comma.  (Since "?*" finds the longest
possible match, this goes up to the last comma.)
.sp
"[" is used with "]" to form "character classes";
for example,
.sp
.ti +6
/[1234567890]/
.sp
matches any single digit - any one of the characters
inside the braces will cause a match.
.sp
Finally, the "&" is another shorthand character - it is
used only on the right-hand part of a substitute command where
it means "whatever was matched on the left-hand side".  It is used
to save typing.  Suppose the current line contained
.sp
.ti +6
Now is the time
.sp
and we wanted to put parentheses around it.  We could
just retype the line, but this is tedious.  Or we could say
.sp
.in +6
.nf
s/%/(/
s/$/)/
.fi
.in -6
.sp
using our knowledge of "%" and "$".  But the easiest
way uses the "&":
.sp
.ti +6
s/?*/(&)/
.sp
This says "match the whole line, and replace it by itself
surrounded by parens."  The "&" can be used several times
in a line; consider using
.sp
.ti +6
s/?*/&. &!!/
.sp
to produce
.sp
.ti +6
Now is the time.  Now is the time!!
.sp
We don't have to match the whole line, of course:  if the
buffer contains
.sp
.ti +6
the end of the world
.sp
we could type
.sp
.ti +6
/world/s//& is at hand/
.sp
to produce
.sp
.ti +6
the end of the world is at hand
.sp
Observe this expression carefully, for it illustrates
how to take advantage of
.bd 1
ed
to save typing.  The
string "/world/" found the desired line; the
shorthand "//" found the same word in the line;
and the "&" saved us from typing it again.
.sp
The "&" is a special character only within the
replacement text of a substitute command, and has no
special meaning elsewhere.  We can turn off the special
meaning of "&" by preceding it with a "@":
.sp
.ti +6
s/ampersand/@&/
.sp
will convert the word "ampersand" into the literal
symbol "&" in the current line.

.ti -5
ACKNOWLEDGEMENT
.br
The majority of this document has been taken, with
the author's permission, from
"A Tutorial Introduction to
the UNIX Text Editor" by B. W. Kernighan.
It has been changed 
only to reflect
the differences between this editor and the UNIX version.

.ne 7
.ti -5
SUMMARY OF COMMANDS AND LINE NUMBERS
.br
The general form of
.bd 1
ed
commands is the command name,
perhaps preceded by one or two line numbers, and, in the
case of
.bd 1
e, r
and
.bd 1
w,
followed by a file name.
Only one command is allowed per line, but a
.bd 1
p
command may
follow any other command (except for
.bd 1
e, r, w
and
.bd 1
q).
.sp
.bd 1
a
(append) Add lines to the buffer (at line dot,
unless a different line is specified).  Appending continues
until "." is typed on a new line.  Dot is set
to the last line appended.
.sp
.bd 1
b
(browse) Display 23 lines of text, beginning at the current
line.  The current line will be centered if you use b.
("b dot").
Using b- will cause the previous 23 lines to be printed.
.sp
.bd 1
c
(change) Change the specified lines to the new
text which follows.  The new lines are terminated by a ".".
If no lines are specified, replace line dot.  Dot is set to last line
changed.
.sp
.bd 1
d
(delete) Delete the lines specified. If none are
specified, delete line dot.  Dot is set to the first undeleted
line, unless "$" is deleted, in which case dot is set to "$".
.sp
.bd 1
e
(edit) Edit new file.  Any previous contents of the buffer
are thrown away, so issue a
.bd 1
w
beforehand if you
want to save them.
.sp
.bd 1
f
(file) Print remembered filename.  If a name follows
.bd 1
f
the remembered name will be set to it.
.sp
.bd 1
g
(global) g/---/command will execute the command on
those lines that contain "---", which can be
any context search expression.
.sp
.bd 1
i
(insert) Insert lines before specified line (or dot)
until a "." is typed on a new line.  Dot is set to last line inserted.
.sp
.bd 1
m
(move) Move lines specified to after the line named after
.bd 1
m.
Dot is set to the last line moved.
.sp
.bd 1
p
(print) Print specified lines.  If none specified,
print line dot.  A single line number is equivalent to "line-number p".
A single newline prints ".+1", the next line.
.sp
.bd 1
q
(quit) Exit from ed.  Wipes out all text in buffer!!
.sp
.bd 1
r
(read) Read a file into buffer (at end unless specified
elsewhere.)  Dot set to last line read.
.sp
.bd 1
s
(substitute) s/string1/string2/ will substitute the
characters of `string2' for `string1' in specified lines.
If no line is specified, make substitution in line dot.
Dot is set to last line in which a substitution took place,
which means that if no substitution took place,
dot is not changed.
.bd 1
s
changes only the first occurrence
of string1 on a line;
to change all of them, type a "g" after the final slash.
.sp
.bd 1
w
(write) Write out buffer onto a file.  Dot is not changed.
.sp
.bd 1
.cc #
.=
#cc .
(dot value) Print value of dot.  ("=" by itself
prints the value of "$".)
.sp
.bd 1
/---/
Context search.  Search for next line which
contains this string of characters.  Print it.  Dot is set to
line where string found.  Search starts at ".+1", wraps around from
"$" to 1, and continues to dot, if necessary.
.sp
\---\ Context search in reverse direction.  Start search at
".-1", scan to 1, wrap around to "$".
#-t-  edit.prm                  36939  local   01/09/81  01:14:30
#-h-  ratfor.prm                17360  local   01/09/81  13:50:55
.bp 1
.rm 70
.in 0
.he 'RATFOR'4/4/78'RATFOR
.fo ''-#-''

.ce
RATFOR PRIMER

.ti +5
Ratfor is a preprocessor for Fortran.
Its primary purpose is to encourage readable and well-structured code
while taking advantage of the universality, portability, and
efficiency of Fortran.
This is done by providing the control structures not available in bare
Fortran, and by improving the "cosmetics" of the language.

.ti +5
Ratfor allows for all the features of normal Fortran, plus makes
available these control structures:
.br
.in +10
.nf

"if"-"else"
"while", "for", and "repeat"-"until" for looping
"break" and "next" for controlling loop exits
"switch" construct for allowing selection of alternatives
statement grouping with braces

.fi
.br
.in -10

.ti +5
The cosmetic aspects of Ratfor have been designed to make it concise
and reasonably pleasing to the eye:
.br
.in +10
.nf

free form input
unobtrusive comment convention
translation of >, <=, etc. into .GT., .LE., etc.
string data type
quoted character strings
"define" statement for symbolic constants
"include" statement for including source files
.fi
.in -10

.br

.ti +5
Ratfor is implemented as a preprocessor which translates the
above features into Fortran, which can then be fed into almost
any Fortran compiler.

.it +5
Each of the Ratfor features will now be discussed in more detail.
In the following, a "statement" is any legal statement in Fortran:
assignment, declaration, subroutine call, I/O, etc., or any of
the Ratfor statements themselves.
Any Fortran or Ratfor statement or group of these can be enclosed
in braces ({}) or brackets ([]) -- to make it a compound
statement, which is then
equivalent to a single statement and usable anywhere a single
statement can be used.

.bp
.ce
IF-ELSE

.ti +5
Ratfor provides an "else" statement to handle the construction
"if a condition is true, do this thing, otherwise do that thing".
The syntax is
.br
.in +10
.nf

if (legal Fortran condition)
               statement(s)
else
               statement(s)

.fi
.br
.in -10
where the else part is optional.  The "legal Fortran condition" is
anything that can legally go into a Fortran logical IF.
The Ratfor statements may be one or more valid Ratfor or Fortran
statements of any kind.
If more than one statement is desired, the statements must be
enclosed by braces.  For example,
.nf

.br
.in +10
if (a > b)
               {
               k = 1
               call remark (...)
               }
else if (a < b)
               {
               k = 2
               call remark (...)
               }
else
               return

.fi
.in -10

.bp
.ce
WHILE

.ti +5
Ratfor provides a while statement, which is simply a loop:
"while some condition is true, repeat this group of statements".
The syntax is
.nf

.br
.in +10
while (legal Fortran condition)
                 statement(s)

.fi
.in -10
As with the if, "legal Fortran condition" is something that can go
into a Fortran logical IF.
The condition is tested before execution of any of the Ratfor statements,
so if the condition is not met, the loop will be executed zero times.
Also, as with the IF, the Ratfor statements can be any valid Ratfor
or Fortran constructs.  If more than one statement is desired, the
statements must be enclosed by braces.  For example,
.nf

.br
.in +10
while (getc(c) != EOF)
               {
               c = cnvt (c)
               call putc (c)
               }

.fi
.in -10

.bp
.ce
FOR

.ti +5
The "for" statement is similar to the "while" except that it
allows explicit initialization and increment
steps as part of the statement.  The syntax is
.nf

.br
.in +10
for (init; condition; increment)
               statement(s)

.fi
.in -10
where "init" is any single Fortran statement which gets done once
before the loop begins.  "Increment" is any single Fortran statement
which gets done at the end of each pass through the loop, before the
test.
"Condition" is again anything that is legal in a logical IF.
Any of init, condition, and increment may be omitted, although
the semicolons must remain.  A non-existent condition is treated
as always true, so "for( ; ; )" is an indefinite repeat.
The "for" statement is particularly useful for backward loops,
chaining along lists, loops that might be done zero times, and
similar things which are hard to express with a DO statement.
Here are two examples of "for" loops:
.nf

.br
.in +10
for (i=1; getarg(i, file, MAXLINE) != EOF; i=i+1)
               {
               int = open (file, READ)
               while (getlin (line, int) != EOF)
                    {
                    for (j=80; j>0; j=j-1)
                       call putc (line(j))
                    }
               call close (int)
               }

.fi
.in -10
The above code simply reads cards from a list of files, reverses
the order of the characters, and writes the cards onto a standard
output file.
(The "!=" means .NE.)

.bp
.ce
REPEAT-UNTIL

The "repeat-until" statements allow for repetition of a group
of statements until a specified condition is met.
The syntax is:
.nf

.br
.in +10
repeat
               statement(s)
until
               condition

.fi
.in -10
The "until" is optional.
Once again, if more than one Ratfor statement is desired, the
statements must be enclosed by brackets.
If the "until" part is omitted, the result is an infinite loop
which must be broken with a "break" or "next" statement (see
below).
An example of a repeat-until loop is:
.br

.nf
.in +10
repeat
               {
               call putc (BLANK)
               col = col + 1
               }
               until (tabpos(col,tabs) == YES)

.br
.fi
.in -10

.bp
.ce
BREAK and NEXT

.ti +5
Ratfor provides statements for leaving a loop early and for
beginning the next iteration.

.ti +5
"Break" causes an immediate exit
from whatever loop it is contained in (which may be a "while",
"for", or "repeat").  Control resumes with the next statement
after the loop.
Only one loop is terminated by a "break", even if the "break"
is contained inside several nested loops.
For example:

.br
.nf
.in +10
repeat
               {
               if (getc(c) == EOF)  break
               ...
               }

.br
.fi
.in -10
.ti +5
"Next" is a branch to the bottom of the loop, so it causes the
next iteration to be done.
"Next" goes to the condition part of a "while" or "until",
to the top of an infinite "repeat" loop, and to the
reinitialize part of a "for".
For example:

.nf
.br
.in +10
for (i=1; i<10; i=i+1)
               {
               if (array(i) == BLANK)  next
               ...
               }

.fi
.in -10

.bp
.ce
SWITCH Construct
.sp
An assortment of alternatives may be specified using the switch
construct.
The syntax is:
.sp
.in +5
.nf
switch (expr):
        {
        case a: statement
        case b: statement
        case c: statement
        ....
        default: statement
        }
.sp
.fi
.in -5
The "default" case is optional.
An example of a switch/case construct is:
.sp
.in +5
.nf
switch (i):
        {
        case 25: do_this_stuff
        case -2: do_this_stuff
        default: otherwise do_this
        }
.bp
.ce
STATEMENT GROUPING AND NULL STATEMENTS

.ti +5
Ratfor allows a group of statements to be treated as a unit by
enclosing them in braces -- { and }.
This is true throughout the language:
wherever a single Ratfor statement can be used, there could also be
several enclosed in braces.
For example:

.nf
.br
.in +10
if (x > 100)
               {
               call error (...)
               err = 1
               return
               }
.in -10
.fi

If braces are not valid characters in the local operating system,
the characters "$(" and "$)" may be used instead of "{" and
"}" respectively.

.fi

.ti +5
Ratfor also allows for null statements, most useful after
"for" and "while" statements.  A semicolon alone indicates
a null statement.  For instance,
.br

.in +10
while (getlin(line, int) != EOF)  ;
.br

.in -10
would read lines from a file until the end-of-file was reached
and
.br

.in +10
for (i=1; line(i) == BLANK; i=i+1)  ;
.br

.in -10
positions after leading blanks in a line.
.bp
.ce
FREE-FORM INPUT

.ti +5
Statements may be placed anywhere on a line and several may
appear on one line if they are separated by semicolons.
No semicolon is needed at the end of each line because
Ratfor assumes there is one statement per line unless told
otherwise.
Ratfor will, however, continue lines when it seems obvious that they
are not yet done.

.ti +5
Any statement that begins with an all-numeric field
is assumed to be a Fortran label and is
placed in columns 1-5 upon output.

Statements may be passed through the Ratfor compiler unaltered
by inserting a percent sign (%) as the first character on
the line.
The percent will be removed, the rest of the line shifted
one position to the left, and the line sent out without
any changes.
This is a convenient way to pass regular Fortran or assembly
code through the ratfor compiler.
.bp
.ce
COMMENTS

.ti +5
A sharp character "#" in a line marks the beginning of a comment
and the rest of the line is considered to be that comment.
Comments and code can co-exist on the same line.  For example,

.nf
.br
.in +10
function dummy (x)
# I made up this function to show some comments
dummy = x         #I am simply returning the parameter
return
end

.fi
.in -10

.bp
.ce
CHARACTER TRANSLATION

.ti +5
Sometimes the characters >, <=, etc. are easier to read in
Fortran condition
statements than the
standard Fortran .EQ., .LT., etc..   Ratfor allows either
convention.   If the special characters are used, they are translated
in the following manner:

.nf
.br
.in +10
==          .EQ.
!= ^= ~=    .NE.
<           .LT.
>           .GT.
<=          .LE.
>=          .GE.
|           .OR.
&           .AND.

.fi
.in -10
For example,

.br
.in +10
.nf
for (i=1; i<= 5; i=i+1)
               ...

if (j != 100)
               ...

.in -10
.fi

.bp
.ce
STRING DATA TYPE
.sp
All character arrays in Ratfor are sequences of ASCII characters,
stored right-adjusted, one per array element, with the string
terminated with an EOS marker.
An automatic way to initialize string characters arrays is
provided.
The syntax is:
.sp
.ce
string name "characters"
.br
or
.ce
string name(n) "characters"
.sp
Ratfor will define name to be a character (or, more likely, integer)
array long enough to accomodate the ASCII codes for the
given character string, one per element.
The last word of name is initialized to EOS.
If a size is given, name is declared to be an integer array of
size 'n'.
If several string statements appear consecutively, the generated
declarations for the array will precede the data
statements that initialize them.
.sp
For example, the declarations:
.sp
.in +5
string errmsg "error"
.br
string done "bye"
.in -5
.sp
would be converted by ratfor into the Fortran:
.sp
.in +5
.nf
integer error(6)
integer done(4)
data error(1), error(2), error(3), error(4),
     error(5), error(6) /LETE, LETR, LETR, LETO, LETR, EOS/
data done(1), done(2), done(3), done(4) /LETD, LETO,
     LETN, LETE, EOS/
.in -5
.bp
.in 0
.ce
QUOTED CHARACTER STRINGS

.ti +5
Text enclosed in matching double or single quotes is converted to
nH... format, but is otherwise unaltered.  For instance,

.nf
.br
.in +10
call remark ("Error detected")
.ti -10
would translate to
call remark (14hError detected)

.ti -10
and
data string /"Can't find answer"/
.ti -10
would become
data string /17hCan't find answer/

.fi
.in -10
If the local operating system does not support both upper and lower
case hollerith strings, an escape mechanism is generally provided
to allow the user to indicate case.

.ti +5
Some operating systems are not capable of finding the end of a
fortran hollerith string.
In this case it may be necessary for the user to mark the end of
her quoted string with a specific character, such as a period.
.bp
.ce
DEFINE

.ti +5
Any string of alphanumeric characters can be defined as a name:
thereafter, whenever that name occurs in the input (delimited
by non-alphanumerics) it is replaced by the rest of the definition
line.
The syntax is:
.sp
.ce
define(name, replacement string)
.sp
which define "name" as a macro which will be replaced with
"replacement string" when encountered in the source files.
As a simple example:

.nf
.br
.in +10
define(ROW,10)
define(COLUMN,25)

dimension array (ROW, COLUMN)
.ti -10
and

define(EOF,-1)
if (getlin(line, fd) == EOF) ....

.in -10
.fi


.ti +5
Definitions may be included anywhere in the code, as long as they
appear before the defined name occurs.
The names of macro may contain letters, digits, periods, and
underline characters, but must start with a letter.
Upper and lower cases ARE significant (thus EOF is not the same
as eof).

Any occurrences of the strings
'$n' in the replacement text,
where 1 <= n <= 9, will be replaced with the
nth argument when the macro is actually invoked.  For example:

.ti +15
define(bump, $1 = $1 + 1)

will cause the source line

.ti +15
bump(i)

to be expanded into

.ti +15
i = i + 1



In addition to define, four other built-in macros are provided:

.in +17
.ti -16
arith(x,op,y)   performs the "integer" arithmetic specified by op (+,-,*,/)
on the two numeric operands and returns the result as its replacement.
.ti -16
incr(x)         converts the string x to a number, adds one to it, and returns
the value as its replacement (as a character string).
.ti -16
ifelse(a,b,c,d) compares a and b as character strings; if they are the same,
c is pushed back onto the input, else d is pushed back.
.ti -16
substr(s,m,n)   produces the substring of s which starts at position m
(with origin one), of length n.  If n is omitted or too big, the rest of
the string is used, while if m is out of range the result is a null string.
.in -17

.bp
.ce
INCLUDE

.ti +5
Files may be inserted into the input stream via the "include"
command.
The statement

.ti +10
include filename
.br
or
.ti +10
include "filename"

inserts the file found on input file "filename" into the
Ratfor input in place of the include statement.  This is
especially useful in inserting common blocks.  For example,

.nf
.br
.in +10
function exampl (x)
include comblk
exampl = x + z
return
end

.ti -10
might translate into

function exampl (x)
common /comblk/ q, r, z
exampl = x + z
return
end

.fi
.in -10


.bp
.ce
IMPLEMENTATION

.ti +5
Ratfor was originally written in C, a high-level language, on the
Unix operating system.
Our version is written in Ratfor itself, originally brought up
by a bootstrap written in Fortran.

.ti +5
Ratfor generates code by reading input files and translating any
Ratfor keywords into standard Fortran.  Thus, if the first
token (word) on a source line is not a keyword (like "for", "while",
etc.) the entire statement is simply copied to the output with
appropriate character translation and formatting.
Ratfor knows very little
Fortran and thus does not handle any Fortran error
detection.
Errors in Ratfor keyword syntax are generally noted by a message
to the user's terminal along with an indication of the source line number
which caused the problem.

.ti +5


.ce
CONCLUSIONS

.ti +5
Ratfor demonstrates that with modest effort Fortran-based
programmers can increase their productivity by using
a language that provides them with the control structures
and cosmetic features essential for structured programming
design.
Debugging and subsequent revision times are much faster
than the equivalent efforts in Fortran, mainly because
the code can be easily read.  Thus it becomes easier to
write code that is readable, reliable, and even esthetically
pleasing,
as well as being portable to other environments.
.bp
.in 0
.ce
EXAMPLE
.sp
.ti +5
The following is a sample Ratfor tool designed to show
some of the commonly-used Ratfor commands.  The routine
reads through a list of files, counting the lines as it goes.

.br
.in +10
.nf
# This is an example of a routine written in Ratfor
# Symbols such as EOF, ERR, MAXLINE, character and filedes are
# automatically defined (i.e. a file containing them is included)
# by the preprocessor

## count - counts lines in files
 DRIVER(count)

 include comblk     # this file contains a common block which
                    # contains a variable "linect"

 character file(FILENAMESIZE), line(MAXLINE)
 integer i
 filedes fd
 integer getarg, open, getlin
 string total "total lines: "

 call query ("usage:  count file.")
 linect = 0
                      #loop through the list of files
 for (i=1; getarg(i, file, FILENAMESIZE) != EOF; i=i+1)
      {
       fd = open (file, READ)      # open (attach) the file
       if (fd == ERR)              # file could not be located
            call cant (file)
       while (getlin(line, fd) != EOF)   # read and count lines
                linect = linect + 1
       call close (fd)              # close (unattach) the file
       }

 call putlin(total, STDOUT)
 call putint (linect, 5, STDOUT)
 call putch (NEWLINE, STDOUT)
 DRETURN
 end
 

.fi
.bp
.in -10

.ce
SEE ALSO

1)  Kernighan, Brian W., "Ratfor--a Preprocessor for a Rational
Fortran".
.ul
Software - Practice and Experience,
Vol. 5, 4 (Oct-Dec 75), pp. 395-406.

2)  Kernighan, Brian W. and P. J. Plauger, "Software Tools".
Addison-Wesley Publishing Company, Reading, Mass., 1976.

3)  The ratfor user document

4)  The Unix command "rc" in the Unix Manual (RC(I))
#-t-  ratfor.prm                17360  local   01/09/81  13:50:55
                                                                                                                                                                                            