xref: /plan9/sys/doc/sam/sam.html (revision 5d535f588fe0a7c7f04081512974c9c20b5d87a8)
1*5d535f58SDavid du Colombier<?xml version="1.0" encoding="utf-8"?>
2*5d535f58SDavid du Colombier<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
3*5d535f58SDavid du Colombier"http://www.w3.org/TR/html4/loose.dtd">
4*5d535f58SDavid du Colombier<html>
5*5d535f58SDavid du Colombier<head>
6*5d535f58SDavid du Colombier<meta http-equiv=Content-Type content="text/html; charset=utf8">
7*5d535f58SDavid du Colombier<title>The Text Editor sam</title>
8*5d535f58SDavid du Colombier</meta>
9*5d535f58SDavid du Colombier</head>
10*5d535f58SDavid du Colombier<body>
11*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.50in"></p>
12*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.21in"></p>
13*5d535f58SDavid du Colombier
14*5d535f58SDavid du Colombier<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
15*5d535f58SDavid du Colombier<span style="font-size: 12pt"><b>The Text Editor </b></span><span style="font-size: 12pt"><tt>sam</tt></span><span style="font-size: 12pt"><b></b></span></p>
16*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.21in"></p>
17*5d535f58SDavid du Colombier
18*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
19*5d535f58SDavid du Colombier<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
20*5d535f58SDavid du Colombier<span style="font-size: 10pt"><i>Rob Pike</i></span></p>
21*5d535f58SDavid du Colombier<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
22*5d535f58SDavid du Colombier<span style="font-size: 10pt"><i>rob@plan9.bell-labs.com</i></span></p>
23*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
24*5d535f58SDavid du Colombier
25*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
26*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.33in"></p>
27*5d535f58SDavid du Colombier<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
28*5d535f58SDavid du Colombier<span style="font-size: 10pt"><i>ABSTRACT</i></span></p>
29*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.19in"></p>
30*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
31*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.50in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
32*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
33*5d535f58SDavid du Colombieris an interactive multi-file text editor intended for
34*5d535f58SDavid du Colombierbitmap displays.
35*5d535f58SDavid du ColombierA textual command language
36*5d535f58SDavid du Colombiersupplements the mouse-driven, cut-and-paste interface
37*5d535f58SDavid du Colombierto make complex or
38*5d535f58SDavid du Colombierrepetitive editing tasks easy to specify.
39*5d535f58SDavid du ColombierThe language is characterized by the composition of regular expressions
40*5d535f58SDavid du Colombierto describe the structure of the text being modified.
41*5d535f58SDavid du ColombierThe treatment of files as a database, with changes logged
42*5d535f58SDavid du Colombieras atomic transactions, guides the implementation and
43*5d535f58SDavid du Colombiermakes a general &lsquo;undo&rsquo; mechanism straightforward.
44*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
45*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
46*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
47*5d535f58SDavid du Colombieris implemented as two processes connected by a low-bandwidth stream,
48*5d535f58SDavid du Colombierone process handling the display and the other the editing
49*5d535f58SDavid du Colombieralgorithms.  Therefore it can run with the display process
50*5d535f58SDavid du Colombierin a bitmap terminal and the editor on a local host,
51*5d535f58SDavid du Colombierwith both processes on a bitmap-equipped host, or with
52*5d535f58SDavid du Colombierthe display process in the terminal and the editor in a
53*5d535f58SDavid du Colombierremote host.
54*5d535f58SDavid du ColombierBy suppressing the display process,
55*5d535f58SDavid du Colombierit can even run without a bitmap terminal.
56*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
57*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
58*5d535f58SDavid du Colombier<span style="font-size: 10pt">This paper is reprinted from Software&mdash;Practice and Experience,
59*5d535f58SDavid du ColombierVol 17, number 11, pp. 813-845, November 1987.
60*5d535f58SDavid du ColombierThe paper has not been updated for the Plan 9 manuals.  Although
61*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
62*5d535f58SDavid du Colombierhas not changed much since the paper was written, the system around it certainly has.
63*5d535f58SDavid du ColombierNonetheless, the description here still stands as the best introduction to the editor.
64*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
65*5d535f58SDavid du Colombier
66*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
67*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
68*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.50in"></p>
69*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
70*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Introduction
71*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
72*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
73*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
74*5d535f58SDavid du Colombieris an interactive text editor that combines cut-and-paste interactive editing with
75*5d535f58SDavid du Colombieran unusual command language based on the composition of regular expressions.
76*5d535f58SDavid du ColombierIt is written as two programs: one, the &lsquo;host part,&rsquo; runs on a UNIX system
77*5d535f58SDavid du Colombierand implements the command language and provides file access; the other, the
78*5d535f58SDavid du Colombier&lsquo;terminal part,&rsquo; runs asynchronously
79*5d535f58SDavid du Colombieron a machine with a mouse and bitmap display
80*5d535f58SDavid du Colombierand supports the display and interactive editing.
81*5d535f58SDavid du ColombierThe host part may be even run in isolation on an ordinary terminal
82*5d535f58SDavid du Colombierto edit text using the command
83*5d535f58SDavid du Colombierlanguage, much like a traditional line editor,
84*5d535f58SDavid du Colombierwithout assistance from a mouse or display.
85*5d535f58SDavid du ColombierMost often,
86*5d535f58SDavid du Colombierthe terminal part runs on a Blit<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> terminal
87*5d535f58SDavid du Colombier(actually on a Teletype DMD 5620, the production version of the Blit), whose
88*5d535f58SDavid du Colombierhost connection is an ordinary 9600 bps RS232 link;
89*5d535f58SDavid du Colombieron the SUN computer the host and display processes run on a single machine,
90*5d535f58SDavid du Colombierconnected by a pipe.
91*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
92*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
93*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
94*5d535f58SDavid du Colombieredits uninterpreted
95*5d535f58SDavid du ColombierASCII text.
96*5d535f58SDavid du ColombierIt has no facilities for multiple fonts, graphics or tables,
97*5d535f58SDavid du Colombierunlike MacWrite,<sup></sup></span><sup><span style="font-size: 6pt">2</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> Bravo,<sup></sup></span><sup><span style="font-size: 6pt">3</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> Tioga<sup></sup></span><sup><span style="font-size: 6pt">4</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
98*5d535f58SDavid du Colombieror Lara.<sup></sup></span><sup><span style="font-size: 6pt">5</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
99*5d535f58SDavid du ColombierAlso unlike them, it has a rich command language.
100*5d535f58SDavid du Colombier(Throughout this paper, the phrase
101*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>command language
102*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">refers to
103*5d535f58SDavid du Colombiertextual commands; commands activated from the mouse form the
104*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>mouse</i></span><span style="font-size: 10pt">
105*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>language.</i></span><span style="font-size: 10pt">)
106*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
107*5d535f58SDavid du Colombierdeveloped as an editor for use by programmers, and tries to join
108*5d535f58SDavid du Colombierthe styles of the UNIX text editor
109*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">6,7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
110*5d535f58SDavid du Colombierwith that of interactive cut-and-paste editors by
111*5d535f58SDavid du Colombierproviding a comfortable mouse-driven interface
112*5d535f58SDavid du Colombierto a program with a solid command language driven by regular expressions.
113*5d535f58SDavid du ColombierThe command language developed more than the mouse language, and
114*5d535f58SDavid du Colombieracquired a notation for describing the structure of files
115*5d535f58SDavid du Colombiermore richly than as a sequence of lines,
116*5d535f58SDavid du Colombierusing a dataflow-like syntax for specifying changes.
117*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
118*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
119*5d535f58SDavid du Colombier<span style="font-size: 10pt">The interactive style was influenced by
120*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
121*5d535f58SDavid du Colombieran early cut-and-paste editor for the Blit, and by
122*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
123*5d535f58SDavid du Colombierthe Blit window system.
124*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Mux</tt></span><span style="font-size: 10pt">
125*5d535f58SDavid du Colombiermerges the original Blit window system,
126*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mpx</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
127*5d535f58SDavid du Colombierwith cut-and-paste editing, forming something like a
128*5d535f58SDavid du Colombiermultiplexed version of
129*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
130*5d535f58SDavid du Colombierthat edits the output of (and input to) command sessions rather than files.
131*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
132*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
133*5d535f58SDavid du Colombier<span style="font-size: 10pt">The first part of this paper describes the command language, then the mouse
134*5d535f58SDavid du Colombierlanguage, and explains how they interact.
135*5d535f58SDavid du ColombierThat is followed by a description of the implementation,
136*5d535f58SDavid du Colombierfirst of the host part, then of the terminal part.
137*5d535f58SDavid du ColombierA principle that influenced the design of
138*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
139*5d535f58SDavid du Colombieris that it should have no explicit limits, such as upper limits on
140*5d535f58SDavid du Colombierfile size or line length.
141*5d535f58SDavid du ColombierA secondary consideration is that it be efficient.
142*5d535f58SDavid du ColombierTo honor these two goals together requires a method for efficiently
143*5d535f58SDavid du Colombiermanipulating
144*5d535f58SDavid du Colombierhuge strings (files) without breaking them into lines,
145*5d535f58SDavid du Colombierperhaps while making thousands of changes
146*5d535f58SDavid du Colombierunder control of the command language.
147*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">&rsquo;s
148*5d535f58SDavid du Colombiermethod is to
149*5d535f58SDavid du Colombiertreat the file as a transaction database, implementing changes as atomic
150*5d535f58SDavid du Colombierupdates.  These updates may be unwound easily to &lsquo;undo&rsquo; changes.
151*5d535f58SDavid du ColombierEfficiency is achieved through a collection of caches that minimizes
152*5d535f58SDavid du Colombierdisc traffic and data motion, both within the two parts of the program
153*5d535f58SDavid du Colombierand between them.
154*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
155*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
156*5d535f58SDavid du Colombier<span style="font-size: 10pt">The terminal part of
157*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
158*5d535f58SDavid du Colombieris fairly straightforward.
159*5d535f58SDavid du ColombierMore interesting is how the two halves of the editor stay
160*5d535f58SDavid du Colombiersynchronized when either half may initiate a change.
161*5d535f58SDavid du ColombierThis is achieved through a data structure that organizes the
162*5d535f58SDavid du Colombiercommunications and is maintained in parallel by both halves.
163*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
164*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
165*5d535f58SDavid du Colombier<span style="font-size: 10pt">The last part of the paper chronicles the writing of
166*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
167*5d535f58SDavid du Colombierand discusses the lessons that were learned through its development and use.
168*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
169*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
170*5d535f58SDavid du Colombier<span style="font-size: 10pt">The paper is long, but is composed largely of two papers of reasonable length:
171*5d535f58SDavid du Colombiera description of the user interface of
172*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
173*5d535f58SDavid du Colombierand a discussion of its implementation.
174*5d535f58SDavid du ColombierThey are combined because the implementation is strongly influenced by
175*5d535f58SDavid du Colombierthe user interface, and vice versa.
176*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
177*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
178*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>The Interface
179*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
180*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
181*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
182*5d535f58SDavid du Colombieris a text editor for multiple files.
183*5d535f58SDavid du ColombierFile names may be provided when it is invoked:
184*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
185*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
186*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>sam file1 file2 ...</tt></span></p>
187*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
188*5d535f58SDavid du Colombier
189*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
190*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
191*5d535f58SDavid du Colombier<span style="font-size: 10pt">and there are commands
192*5d535f58SDavid du Colombierto add new files and discard unneeded ones.
193*5d535f58SDavid du ColombierFiles are not read until necessary
194*5d535f58SDavid du Colombierto complete some command.
195*5d535f58SDavid du ColombierEditing operations apply to an internal copy
196*5d535f58SDavid du Colombiermade when the file is read; the UNIX file associated with the copy
197*5d535f58SDavid du Colombieris changed only by an explicit command.
198*5d535f58SDavid du ColombierTo simplify the discussion, the internal copy is here called a
199*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>file</i></span><span style="font-size: 10pt">,
200*5d535f58SDavid du Colombierwhile the disc-resident original is called a
201*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>disc file.
202*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
203*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
204*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
205*5d535f58SDavid du Colombieris usually connected to a bitmap display that presents a cut-and-paste
206*5d535f58SDavid du Colombiereditor driven by the mouse.
207*5d535f58SDavid du ColombierIn this mode, the command language is still available:
208*5d535f58SDavid du Colombiertext typed in a special window, called the
209*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
210*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>window,</i></span><span style="font-size: 10pt">
211*5d535f58SDavid du Colombieris interpreted
212*5d535f58SDavid du Colombieras commands to be executed in the current file.
213*5d535f58SDavid du ColombierCut-and-paste editing may be used in any window &mdash; even in the
214*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
215*5d535f58SDavid du Colombierwindow to construct commands.
216*5d535f58SDavid du ColombierThe other mode of operation, invoked by starting
217*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
218*5d535f58SDavid du Colombierwith the option
219*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
220*5d535f58SDavid du Colombier(for &lsquo;no download&rsquo;),
221*5d535f58SDavid du Colombierdoes not use the mouse or bitmap display, but still permits
222*5d535f58SDavid du Colombierediting using the textual command language, even on an ordinary terminal,
223*5d535f58SDavid du Colombierinteractively or from a script.
224*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
225*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
226*5d535f58SDavid du Colombier<span style="font-size: 10pt">The following sections describe first the command language (under
227*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam\fP-d
228*5d535f58SDavid du Colombierand in the
229*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt"><tt>
230*5d535f58SDavid du Colombierwindow), and then the mouse interface.
231*5d535f58SDavid du ColombierThese two languages are nearly independent, but connect through the
232*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><i>current</i></span><span style="font-size: 10pt"><tt>
233*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><i>text,</i></span><span style="font-size: 10pt"><tt>
234*5d535f58SDavid du Colombierdescribed below.
235*5d535f58SDavid du Colombier</tt></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
236*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
237*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>The Command Language
238*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
239*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
240*5d535f58SDavid du Colombier<span style="font-size: 10pt">A file consists of its contents, which are an array of characters
241*5d535f58SDavid du Colombier(that is, a string); the
242*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>name</i></span><span style="font-size: 10pt">
243*5d535f58SDavid du Colombierof the associated disc file; the
244*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>modified bit
245*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">that states whether the contents match those of
246*5d535f58SDavid du Colombierthe disc file;
247*5d535f58SDavid du Colombierand a substring of the contents, called the
248*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>current text
249*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">or
250*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>dot</i></span><span style="font-size: 10pt">
251*5d535f58SDavid du Colombier(see Figures 1 and 2).
252*5d535f58SDavid du ColombierIf the current text is a null string, dot falls between characters.
253*5d535f58SDavid du ColombierThe
254*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>value</i></span><span style="font-size: 10pt">
255*5d535f58SDavid du Colombierof dot is the location of the current text; the
256*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>contents</i></span><span style="font-size: 10pt">
257*5d535f58SDavid du Colombierof dot are the characters it contains.
258*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
259*5d535f58SDavid du Colombierimparts to the text no two-dimensional interpretation such as columns
260*5d535f58SDavid du Colombieror fields; text is always one-dimensional.
261*5d535f58SDavid du ColombierEven the idea of a &lsquo;line&rsquo; of text as understood by most UNIX programs
262*5d535f58SDavid du Colombier&mdash; a sequence of characters terminated by a newline character &mdash;
263*5d535f58SDavid du Colombieris only weakly supported.
264*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
265*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
266*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
267*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>current file
268*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">is the file to which editing commands refer.
269*5d535f58SDavid du ColombierThe current text is therefore dot in the current file.
270*5d535f58SDavid du ColombierIf a command doesn&rsquo;t explicitly name a particular file or piece of text,
271*5d535f58SDavid du Colombierthe command is assumed to apply to the current text.
272*5d535f58SDavid du ColombierFor the moment, ignore the presence of multiple files and consider
273*5d535f58SDavid du Colombierediting a single file.
274*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="fig1.gif" /></center>
275*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
276*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 1. A typical
277*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
278*5d535f58SDavid du Colombierscreen, with the editing menu presented.
279*5d535f58SDavid du ColombierThe
280*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
281*5d535f58SDavid du Colombier(command language) window is in the middle, with file windows above and below.
282*5d535f58SDavid du Colombier(The user interface makes it easy to create these abutting windows.)
283*5d535f58SDavid du ColombierThe partially obscured window is a third file window.
284*5d535f58SDavid du ColombierThe uppermost window is that to which typing and mouse operations apply,
285*5d535f58SDavid du Colombieras indicated by its heavy border.
286*5d535f58SDavid du ColombierEach window has its current text highlighted in reverse video.
287*5d535f58SDavid du ColombierThe
288*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
289*5d535f58SDavid du Colombierwindow&rsquo;s current text is the null string on the last visible line,
290*5d535f58SDavid du Colombierindicated by a vertical bar.
291*5d535f58SDavid du ColombierSee also Figure 2.
292*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
293*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
294*5d535f58SDavid du Colombier
295*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
296*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
297*5d535f58SDavid du Colombier<span style="font-size: 10pt">Commands have one-letter names.
298*5d535f58SDavid du ColombierExcept for non-editing commands such as writing
299*5d535f58SDavid du Colombierthe file to disc, most commands make some change
300*5d535f58SDavid du Colombierto the text in dot and leave dot set to the text resulting from the change.
301*5d535f58SDavid du ColombierFor example, the delete command,
302*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>d</tt></span><span style="font-size: 10pt">,
303*5d535f58SDavid du Colombierdeletes the text in dot, replacing it by the null string and setting dot
304*5d535f58SDavid du Colombierto the result.
305*5d535f58SDavid du ColombierThe change command,
306*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">,
307*5d535f58SDavid du Colombierreplaces dot by text delimited by an arbitrary punctuation character,
308*5d535f58SDavid du Colombierconventionally
309*5d535f58SDavid du Colombiera slash.  Thus,
310*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
311*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
312*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>c/Peter/</tt></span></p>
313*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
314*5d535f58SDavid du Colombier
315*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
316*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
317*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces the text in dot by the string
318*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
319*5d535f58SDavid du ColombierSimilarly,
320*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
321*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
322*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>a/Peter/</tt></span></p>
323*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
324*5d535f58SDavid du Colombier
325*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
326*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
327*5d535f58SDavid du Colombier<span style="font-size: 10pt">(append) adds the string after dot, and
328*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
329*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
330*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>i/Peter/</tt></span></p>
331*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
332*5d535f58SDavid du Colombier
333*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
334*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
335*5d535f58SDavid du Colombier<span style="font-size: 10pt">(insert) inserts before dot.
336*5d535f58SDavid du ColombierAll three leave dot set to the new text,
337*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
338*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
339*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
340*5d535f58SDavid du Colombier<span style="font-size: 10pt">Newlines are part of the syntax of commands:
341*5d535f58SDavid du Colombierthe newline character lexically terminates a command.
342*5d535f58SDavid du ColombierWithin the inserted text, however, newlines are never implicit.
343*5d535f58SDavid du ColombierBut since it is often convenient to insert multiple lines of text,
344*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
345*5d535f58SDavid du Colombierhas a special
346*5d535f58SDavid du Colombiersyntax for that case:
347*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
348*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
349*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>a</tt></span></p>
350*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
351*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>some lines of text</tt></span></p>
352*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
353*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>to be inserted in the file,</tt></span></p>
354*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
355*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>terminated by a period</tt></span></p>
356*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
357*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>on a line by itself</tt></span></p>
358*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
359*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>.</tt></span></p>
360*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
361*5d535f58SDavid du Colombier
362*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
363*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
364*5d535f58SDavid du Colombier<span style="font-size: 10pt">In the one-line syntax, a newline character may be specified by a C-like
365*5d535f58SDavid du Colombierescape, so
366*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
367*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
368*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>c/\n/</tt></span></p>
369*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
370*5d535f58SDavid du Colombier
371*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
372*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
373*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces dot by a single newline character.
374*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
375*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
376*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
377*5d535f58SDavid du Colombieralso has a substitute command,
378*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">:
379*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
380*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
381*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>s/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/</tt></span><span style="font-size: 9pt"><i>replacement</i></span><span style="font-size: 9pt"><tt>/</tt></span></p>
382*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
383*5d535f58SDavid du Colombier
384*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
385*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
386*5d535f58SDavid du Colombier<span style="font-size: 10pt">substitutes the replacement text for the first match, in dot,
387*5d535f58SDavid du Colombierof the regular expression.
388*5d535f58SDavid du ColombierThus, if dot is the string
389*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
390*5d535f58SDavid du Colombierthe command
391*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
392*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
393*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>s/t/st/</tt></span></p>
394*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
395*5d535f58SDavid du Colombier
396*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
397*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
398*5d535f58SDavid du Colombier<span style="font-size: 10pt">changes it to
399*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Pester</tt></span><span style="font-size: 10pt">.
400*5d535f58SDavid du ColombierIn general,
401*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">
402*5d535f58SDavid du Colombieris unnecessary, but it was inherited from
403*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
404*5d535f58SDavid du Colombierand it has some convenient variations.
405*5d535f58SDavid du ColombierFor instance, the replacement text may include the matched text,
406*5d535f58SDavid du Colombierspecified by
407*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>&amp;</tt></span><span style="font-size: 10pt">:
408*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
409*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
410*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>s/Peter/Oh, &amp;, &amp;, &amp;, &amp;!/</tt></span></p>
411*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
412*5d535f58SDavid du Colombier
413*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
414*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
415*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
416*5d535f58SDavid du Colombier<span style="font-size: 10pt">There are also three commands that apply programs
417*5d535f58SDavid du Colombierto text:
418*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
419*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
420*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>&lt; </tt></span><span style="font-size: 9pt"><i>UNIX program</i></span><span style="font-size: 9pt"><tt></tt></span></p>
421*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
422*5d535f58SDavid du Colombier
423*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
424*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
425*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces dot by the output of the UNIX program.
426*5d535f58SDavid du ColombierSimilarly, the
427*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>&gt;</tt></span><span style="font-size: 10pt">
428*5d535f58SDavid du Colombiercommand
429*5d535f58SDavid du Colombierruns the program with dot as its standard input, and
430*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>|</tt></span><span style="font-size: 10pt">
431*5d535f58SDavid du Colombierdoes both.  For example,
432*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
433*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
434*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>| sort</tt></span></p>
435*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
436*5d535f58SDavid du Colombier
437*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
438*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
439*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces dot by the result of applying the standard sorting utility to it.
440*5d535f58SDavid du ColombierAgain, newlines have no special significance for these
441*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
442*5d535f58SDavid du Colombiercommands.
443*5d535f58SDavid du ColombierThe text acted upon and resulting from these commands is not necessarily
444*5d535f58SDavid du Colombierbounded by newlines, although for connection with UNIX programs,
445*5d535f58SDavid du Colombiernewlines may be necessary to obey conventions.
446*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
447*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
448*5d535f58SDavid du Colombier<span style="font-size: 10pt">One more command:
449*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
450*5d535f58SDavid du Colombierprints the contents of dot.
451*5d535f58SDavid du ColombierTable I summarizes
452*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
453*5d535f58SDavid du Colombiercommands.
454*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="sam0.png"></center>
455*5d535f58SDavid du Colombier</center>
456*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
457*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
458*5d535f58SDavid du Colombier
459*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
460*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
461*5d535f58SDavid du Colombier<span style="font-size: 10pt">The value of dot may be changed by
462*5d535f58SDavid du Colombierspecifying an
463*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>address</i></span><span style="font-size: 10pt">
464*5d535f58SDavid du Colombierfor the command.
465*5d535f58SDavid du ColombierThe simplest address is a line number:
466*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
467*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
468*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>3</tt></span></p>
469*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
470*5d535f58SDavid du Colombier
471*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
472*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
473*5d535f58SDavid du Colombier<span style="font-size: 10pt">refers to the third line of the file, so
474*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
475*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
476*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>3d</tt></span></p>
477*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
478*5d535f58SDavid du Colombier
479*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
480*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
481*5d535f58SDavid du Colombier<span style="font-size: 10pt">deletes the third line of the file, and implicitly renumbers
482*5d535f58SDavid du Colombierthe lines so the old line 4 is now numbered 3.
483*5d535f58SDavid du Colombier(This is one of the few places where
484*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
485*5d535f58SDavid du Colombierdeals with lines directly.)
486*5d535f58SDavid du ColombierLine
487*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>0</tt></span><span style="font-size: 10pt">
488*5d535f58SDavid du Colombieris the null string at the beginning of the file.
489*5d535f58SDavid du ColombierIf a command consists of only an address, a
490*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
491*5d535f58SDavid du Colombiercommand is assumed, so typing an unadorned
492*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>3</tt></span><span style="font-size: 10pt">
493*5d535f58SDavid du Colombierprints line 3 on the terminal.
494*5d535f58SDavid du ColombierThere are a couple of other basic addresses:
495*5d535f58SDavid du Colombiera period addresses dot itself; and
496*5d535f58SDavid du Colombiera dollar sign
497*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">)
498*5d535f58SDavid du Colombieraddresses the null string at the end of the file.
499*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
500*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
501*5d535f58SDavid du Colombier<span style="font-size: 10pt">An address is always a single substring of the file.
502*5d535f58SDavid du ColombierThus, the address
503*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>3</tt></span><span style="font-size: 10pt">
504*5d535f58SDavid du Colombieraddresses the characters
505*5d535f58SDavid du Colombierafter the second newline of
506*5d535f58SDavid du Colombierthe file through the third newline of the file.
507*5d535f58SDavid du ColombierA
508*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>compound address
509*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">is constructed by the comma operator
510*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
511*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
512*5d535f58SDavid du Colombier<span style="font-size: 9pt"><i>address1</i></span><span style="font-size: 9pt"><tt>,</tt></span><span style="font-size: 9pt"><i>address2</i></span><span style="font-size: 9pt"><tt></tt></span></p>
513*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
514*5d535f58SDavid du Colombier
515*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
516*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
517*5d535f58SDavid du Colombier<span style="font-size: 10pt">and addresses the substring of the file from the beginning of
518*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>address1</i></span><span style="font-size: 10pt">
519*5d535f58SDavid du Colombierto the end of
520*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>address2</i></span><span style="font-size: 10pt">.
521*5d535f58SDavid du ColombierFor example, the command
522*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>3,5p</tt></span><span style="font-size: 10pt">
523*5d535f58SDavid du Colombierprints the third through fifth lines of the file and
524*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.,$d</tt></span><span style="font-size: 10pt">
525*5d535f58SDavid du Colombierdeletes the text from the beginning of dot to the end of the file.
526*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
527*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
528*5d535f58SDavid du Colombier<span style="font-size: 10pt">These addresses are all absolute positions in the file, but
529*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
530*5d535f58SDavid du Colombieralso has relative addresses, indicated by
531*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
532*5d535f58SDavid du Colombieror
533*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">.
534*5d535f58SDavid du ColombierFor example,
535*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
536*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
537*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>$-3</tt></span></p>
538*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
539*5d535f58SDavid du Colombier
540*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
541*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
542*5d535f58SDavid du Colombier<span style="font-size: 10pt">is the third line before the end of the file and
543*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
544*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
545*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>.+1</tt></span></p>
546*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
547*5d535f58SDavid du Colombier
548*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
549*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
550*5d535f58SDavid du Colombier<span style="font-size: 10pt">is the line after dot.
551*5d535f58SDavid du ColombierIf no address appears to the left of the
552*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
553*5d535f58SDavid du Colombieror
554*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">,
555*5d535f58SDavid du Colombierdot is assumed;
556*5d535f58SDavid du Colombierif nothing appears to the right,
557*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>1</tt></span><span style="font-size: 10pt">
558*5d535f58SDavid du Colombieris assumed.
559*5d535f58SDavid du ColombierTherefore,
560*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.+1</tt></span><span style="font-size: 10pt">
561*5d535f58SDavid du Colombiermay be abbreviated to just a plus sign.
562*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
563*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
564*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
565*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
566*5d535f58SDavid du Colombieroperator acts relative to the end of its first argument, while the
567*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
568*5d535f58SDavid du Colombieroperator acts relative to the beginning.  Thus
569*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.+1</tt></span><span style="font-size: 10pt">
570*5d535f58SDavid du Colombieraddresses the first line after dot,
571*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.-</tt></span><span style="font-size: 10pt">
572*5d535f58SDavid du Colombieraddresses the first line before dot, and
573*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+-</tt></span><span style="font-size: 10pt">
574*5d535f58SDavid du Colombierrefers to the line containing the end of dot.  (Dot may span multiple lines, and
575*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
576*5d535f58SDavid du Colombierselects the line after the end of dot, then
577*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
578*5d535f58SDavid du Colombierbacks up one line.)
579*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
580*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
581*5d535f58SDavid du Colombier<span style="font-size: 10pt">The final type of address is a regular expression, which addresses the
582*5d535f58SDavid du Colombiertext matched by the expression.  The expression is enclosed in slashes, as in
583*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
584*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
585*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/</tt></span></p>
586*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
587*5d535f58SDavid du Colombier
588*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
589*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
590*5d535f58SDavid du Colombier<span style="font-size: 10pt">The expressions are the same as those in the UNIX program
591*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">6,7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
592*5d535f58SDavid du Colombierand include closures, alternations, and so on.
593*5d535f58SDavid du ColombierThey find the
594*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>leftmost longest
595*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">string that matches the expression, that is,
596*5d535f58SDavid du Colombierthe first match after the point where the search is started,
597*5d535f58SDavid du Colombierand if more than one match begins at the same spot, the longest such match.
598*5d535f58SDavid du Colombier(I assume familiarity with the syntax for regular expressions in UNIX programs.<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">)
599*5d535f58SDavid du ColombierFor example,
600*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
601*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
602*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>/x/</tt></span></p>
603*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
604*5d535f58SDavid du Colombier
605*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
606*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
607*5d535f58SDavid du Colombier<span style="font-size: 10pt">matches the next
608*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
609*5d535f58SDavid du Colombiercharacter in the file,
610*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
611*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
612*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>/xx*/</tt></span></p>
613*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
614*5d535f58SDavid du Colombier
615*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
616*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
617*5d535f58SDavid du Colombier<span style="font-size: 10pt">matches the next run of one or more
618*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">&rsquo;s,
619*5d535f58SDavid du Colombierand
620*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
621*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
622*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>/x|Peter/</tt></span></p>
623*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
624*5d535f58SDavid du Colombier
625*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
626*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
627*5d535f58SDavid du Colombier<span style="font-size: 10pt">matches the next
628*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
629*5d535f58SDavid du Colombieror
630*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
631*5d535f58SDavid du ColombierFor compatibility with other UNIX programs, the &lsquo;any character&rsquo; operator,
632*5d535f58SDavid du Colombiera period,
633*5d535f58SDavid du Colombierdoes not match a newline, so
634*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
635*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
636*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>/.*/</tt></span></p>
637*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
638*5d535f58SDavid du Colombier
639*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
640*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
641*5d535f58SDavid du Colombier<span style="font-size: 10pt">matches the text from dot to the end of the line, but excludes the newline
642*5d535f58SDavid du Colombierand so will not match across
643*5d535f58SDavid du Colombierthe line boundary.
644*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
645*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
646*5d535f58SDavid du Colombier<span style="font-size: 10pt">Regular expressions are always relative addresses.
647*5d535f58SDavid du ColombierThe direction is forwards by default,
648*5d535f58SDavid du Colombierso
649*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>/Peter/</tt></span><span style="font-size: 10pt">
650*5d535f58SDavid du Colombieris really an abbreviation for
651*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+/Peter/</tt></span><span style="font-size: 10pt">.
652*5d535f58SDavid du ColombierThe search can be reversed with a minus sign, so
653*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
654*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
655*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt></tt></span><span style="font-size: 9pt"><tt>-/Peter/</tt></span><span style="font-size: 9pt"><tt></tt></span></p>
656*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
657*5d535f58SDavid du Colombier
658*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
659*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
660*5d535f58SDavid du Colombier<span style="font-size: 10pt">finds the first
661*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
662*5d535f58SDavid du Colombierbefore dot.
663*5d535f58SDavid du ColombierRegular expressions may be used with other address forms, so
664*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>0+/Peter/</tt></span><span style="font-size: 10pt">
665*5d535f58SDavid du Colombierfinds the first
666*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
667*5d535f58SDavid du Colombierin the file and
668*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>$-/Peter/</tt></span><span style="font-size: 10pt">
669*5d535f58SDavid du Colombierfinds the last.
670*5d535f58SDavid du ColombierTable II summarizes
671*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
672*5d535f58SDavid du Colombieraddresses.
673*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="sam1.png"></center>
674*5d535f58SDavid du Colombier</center>
675*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
676*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
677*5d535f58SDavid du Colombier
678*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
679*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
680*5d535f58SDavid du Colombier<span style="font-size: 10pt">The language discussed so far will not seem novel
681*5d535f58SDavid du Colombierto people who use UNIX text editors
682*5d535f58SDavid du Colombiersuch as
683*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
684*5d535f58SDavid du Colombieror
685*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">.<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
686*5d535f58SDavid du ColombierMoreover, the kinds of editing operations these commands allow, with the exception
687*5d535f58SDavid du Colombierof regular expressions and line numbers,
688*5d535f58SDavid du Colombierare clearly more conveniently handled by a mouse-based interface.
689*5d535f58SDavid du ColombierIndeed,
690*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
691*5d535f58SDavid du Colombiermouse language (discussed at length below) is the means by which
692*5d535f58SDavid du Colombiersimple changes are usually made.
693*5d535f58SDavid du ColombierFor large or repetitive changes, however, a textual language
694*5d535f58SDavid du Colombieroutperforms a manual interface.
695*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
696*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
697*5d535f58SDavid du Colombier<span style="font-size: 10pt">Imagine that, instead of deleting just one occurrence of the string
698*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
699*5d535f58SDavid du Colombierwe wanted to eliminate every
700*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">.
701*5d535f58SDavid du ColombierWhat&rsquo;s needed is an iterator that runs a command for each occurrence of some
702*5d535f58SDavid du Colombiertext.
703*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">&rsquo;s
704*5d535f58SDavid du Colombieriterator is called
705*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
706*5d535f58SDavid du Colombierfor extract:
707*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
708*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
709*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>x/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
710*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
711*5d535f58SDavid du Colombier
712*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
713*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
714*5d535f58SDavid du Colombier<span style="font-size: 10pt">finds all matches in dot of the specified expression, and for each
715*5d535f58SDavid du Colombiersuch match, sets dot to the text matched and runs the command.
716*5d535f58SDavid du ColombierSo to delete all the
717*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peters:</tt></span><span style="font-size: 10pt">
718*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
719*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
720*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>0,$ x/Peter/ d</tt></span></p>
721*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
722*5d535f58SDavid du Colombier
723*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
724*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
725*5d535f58SDavid du Colombier<span style="font-size: 10pt">(Blanks in these examples are to improve readability;
726*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
727*5d535f58SDavid du Colombierneither requires nor interprets them.)
728*5d535f58SDavid du ColombierThis searches the entire file
729*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>0,$</tt></span><span style="font-size: 10pt">)
730*5d535f58SDavid du Colombierfor occurrences of the string
731*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
732*5d535f58SDavid du Colombierand runs the
733*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>d</tt></span><span style="font-size: 10pt">
734*5d535f58SDavid du Colombiercommand with dot set to each such occurrence.
735*5d535f58SDavid du Colombier(By contrast, the comparable
736*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
737*5d535f58SDavid du Colombiercommand would delete all
738*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>lines</i></span><span style="font-size: 10pt">
739*5d535f58SDavid du Colombiercontaining
740*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">;
741*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
742*5d535f58SDavid du Colombierdeletes only the
743*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peters</tt></span><span style="font-size: 10pt">.)
744*5d535f58SDavid du ColombierThe address
745*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>0,$</tt></span><span style="font-size: 10pt">
746*5d535f58SDavid du Colombieris commonly used, and may be abbreviated to just a comma.
747*5d535f58SDavid du ColombierAs another example,
748*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
749*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
750*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/Peter/ p</tt></span></p>
751*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
752*5d535f58SDavid du Colombier
753*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
754*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
755*5d535f58SDavid du Colombier<span style="font-size: 10pt">prints a list of
756*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peters,</tt></span><span style="font-size: 10pt">
757*5d535f58SDavid du Colombierone for each appearance in the file, with no intervening text (not even newlines
758*5d535f58SDavid du Colombierto separate the instances).
759*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
760*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
761*5d535f58SDavid du Colombier<span style="font-size: 10pt">Of course, the text extracted by
762*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
763*5d535f58SDavid du Colombiermay be selected by a regular expression,
764*5d535f58SDavid du Colombierwhich complicates deciding what set of matches is chosen &mdash;
765*5d535f58SDavid du Colombiermatches may overlap.  This is resolved by generating the matches
766*5d535f58SDavid du Colombierstarting from the beginning of dot using the leftmost-longest rule,
767*5d535f58SDavid du Colombierand searching for each match starting from the end of the previous one.
768*5d535f58SDavid du ColombierRegular expressions may also match null strings, but a null match
769*5d535f58SDavid du Colombieradjacent to a non-null match is never selected; at least one character
770*5d535f58SDavid du Colombiermust intervene.
771*5d535f58SDavid du ColombierFor example,
772*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
773*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
774*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, c/AAA/</tt></span></p>
775*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
776*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>x/B*/ c/-/</tt></span></p>
777*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
778*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, p</tt></span></p>
779*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
780*5d535f58SDavid du Colombier
781*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
782*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
783*5d535f58SDavid du Colombier<span style="font-size: 10pt">produces as output
784*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
785*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
786*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>-A-A-A-</tt></span></p>
787*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
788*5d535f58SDavid du Colombier
789*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
790*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
791*5d535f58SDavid du Colombier<span style="font-size: 10pt">because the pattern
792*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>B*</tt></span><span style="font-size: 10pt">
793*5d535f58SDavid du Colombiermatches the null strings separating the
794*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>A</tt></span><span style="font-size: 10pt">&rsquo;s.
795*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
796*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
797*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
798*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
799*5d535f58SDavid du Colombiercommand has a complement,
800*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">,
801*5d535f58SDavid du Colombierwith similar syntax, that executes the command with dot set to the text
802*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>between</i></span><span style="font-size: 10pt">
803*5d535f58SDavid du Colombierthe matches of the expression.
804*5d535f58SDavid du ColombierFor example,
805*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
806*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
807*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, c/AAA/</tt></span></p>
808*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
809*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>y/A/ c/-/</tt></span></p>
810*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
811*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, p</tt></span></p>
812*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
813*5d535f58SDavid du Colombier
814*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
815*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
816*5d535f58SDavid du Colombier<span style="font-size: 10pt">produces the same result as the example above.
817*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
818*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
819*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
820*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
821*5d535f58SDavid du Colombierand
822*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
823*5d535f58SDavid du Colombiercommands are looping constructs, and
824*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
825*5d535f58SDavid du Colombierhas a pair of conditional commands to go with them.
826*5d535f58SDavid du ColombierThey have similar syntax:
827*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
828*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
829*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>g/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
830*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
831*5d535f58SDavid du Colombier
832*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
833*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
834*5d535f58SDavid du Colombier<span style="font-size: 10pt">(guard)
835*5d535f58SDavid du Colombierruns the command exactly once if dot contains a match of the expression.
836*5d535f58SDavid du ColombierThis is different from
837*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
838*5d535f58SDavid du Colombierwhich runs the command for
839*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>each</i></span><span style="font-size: 10pt">
840*5d535f58SDavid du Colombiermatch:
841*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
842*5d535f58SDavid du Colombierloops;
843*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
844*5d535f58SDavid du Colombiermerely tests, without changing the value of dot.
845*5d535f58SDavid du ColombierThus,
846*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
847*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
848*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/Peter/ d</tt></span></p>
849*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
850*5d535f58SDavid du Colombier
851*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
852*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
853*5d535f58SDavid du Colombier<span style="font-size: 10pt">deletes all occurrences of
854*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
855*5d535f58SDavid du Colombierbut
856*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
857*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
858*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, g/Peter/ d</tt></span></p>
859*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
860*5d535f58SDavid du Colombier
861*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
862*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
863*5d535f58SDavid du Colombier<span style="font-size: 10pt">deletes the whole file (reduces it to a null string) if
864*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
865*5d535f58SDavid du Colombieroccurs anywhere in the text.
866*5d535f58SDavid du ColombierThe complementary conditional is
867*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>v</tt></span><span style="font-size: 10pt">,
868*5d535f58SDavid du Colombierwhich runs the command if there is
869*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>no</i></span><span style="font-size: 10pt">
870*5d535f58SDavid du Colombiermatch of the expression.
871*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
872*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
873*5d535f58SDavid du Colombier<span style="font-size: 10pt">These control-structure-like commands may be composed to construct more
874*5d535f58SDavid du Colombierinvolved operations.  For example, to print those lines of text that
875*5d535f58SDavid du Colombiercontain the string
876*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">:
877*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
878*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
879*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/.*\n/ g/Peter/ p</tt></span></p>
880*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
881*5d535f58SDavid du Colombier
882*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
883*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
884*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
885*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
886*5d535f58SDavid du Colombierbreaks the file into lines, the
887*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
888*5d535f58SDavid du Colombierselects those lines containing
889*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">,
890*5d535f58SDavid du Colombierand the
891*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>p</tt></span><span style="font-size: 10pt">
892*5d535f58SDavid du Colombierprints them.
893*5d535f58SDavid du ColombierThis command gives an address for the
894*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
895*5d535f58SDavid du Colombiercommand (the whole file), but because
896*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
897*5d535f58SDavid du Colombierdoes not have an explicit address, it applies to the value of
898*5d535f58SDavid du Colombierdot produced by the
899*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
900*5d535f58SDavid du Colombiercommand, that is, to each line.
901*5d535f58SDavid du ColombierAll commands in
902*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
903*5d535f58SDavid du Colombierexcept for the command to write a file to disc use dot for the
904*5d535f58SDavid du Colombierdefault address.
905*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
906*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
907*5d535f58SDavid du Colombier<span style="font-size: 10pt">Composition may be continued indefinitely.
908*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
909*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
910*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/.*\n/ g/Peterv/SaltPeter/ p</tt></span></p>
911*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
912*5d535f58SDavid du Colombier
913*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
914*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
915*5d535f58SDavid du Colombier<span style="font-size: 10pt">prints those lines containing
916*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Peter</tt></span><span style="font-size: 10pt">
917*5d535f58SDavid du Colombierbut
918*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>not</i></span><span style="font-size: 10pt">
919*5d535f58SDavid du Colombierthose containing
920*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>SaltPeter</tt></span><span style="font-size: 10pt">.
921*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
922*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
923*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Structural Regular Expressions
924*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
925*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
926*5d535f58SDavid du Colombier<span style="font-size: 10pt">Unlike other UNIX text editors,
927*5d535f58SDavid du Colombierincluding the non-interactive ones such as
928*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sed</tt></span><span style="font-size: 10pt">
929*5d535f58SDavid du Colombierand
930*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>awk</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
931*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
932*5d535f58SDavid du Colombieris good for manipulating files with multi-line &lsquo;records.&rsquo;
933*5d535f58SDavid du ColombierAn example is an on-line phone book composed of records,
934*5d535f58SDavid du Colombierseparated by blank lines, of the form
935*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
936*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
937*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>Herbert Tic</tt></span></p>
938*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
939*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>44 Turnip Ave., Endive, NJ</tt></span></p>
940*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
941*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>201-5555642</tt></span></p>
942*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.15in"></p>
943*5d535f58SDavid du Colombier
944*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
945*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>Norbert Twinge</tt></span></p>
946*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
947*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>16 Potato St., Cabbagetown, NJ</tt></span></p>
948*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
949*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>201-5553145</tt></span></p>
950*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.15in"></p>
951*5d535f58SDavid du Colombier
952*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
953*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>...</tt></span></p>
954*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
955*5d535f58SDavid du Colombier
956*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
957*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
958*5d535f58SDavid du Colombier<span style="font-size: 10pt">The format may be encoded as a regular expression:
959*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
960*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
961*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>(.+\n)+</tt></span></p>
962*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
963*5d535f58SDavid du Colombier
964*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
965*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
966*5d535f58SDavid du Colombier<span style="font-size: 10pt">that is, a sequence of one or more non-blank lines.
967*5d535f58SDavid du ColombierThe command to print Mr. Tic&rsquo;s entire record is then
968*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
969*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
970*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/(.+\n)+/ g/^Herbert Tic$/ p</tt></span></p>
971*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
972*5d535f58SDavid du Colombier
973*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
974*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
975*5d535f58SDavid du Colombier<span style="font-size: 10pt">and that to extract just the phone number is
976*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
977*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
978*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/(.+\n)+/ g/^Herbert Tic$/ x/^[0-9]*-[0-9]*\n/ p</tt></span></p>
979*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
980*5d535f58SDavid du Colombier
981*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
982*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
983*5d535f58SDavid du Colombier<span style="font-size: 10pt">The latter command breaks the file into records,
984*5d535f58SDavid du Colombierchooses Mr. Tic&rsquo;s record,
985*5d535f58SDavid du Colombierextracts the phone number from the record,
986*5d535f58SDavid du Colombierand finally prints the number.
987*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
988*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
989*5d535f58SDavid du Colombier<span style="font-size: 10pt">A more involved problem is that of
990*5d535f58SDavid du Colombierrenaming a particular variable, say
991*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">,
992*5d535f58SDavid du Colombierto
993*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>num</tt></span><span style="font-size: 10pt">
994*5d535f58SDavid du Colombierin a C program.
995*5d535f58SDavid du ColombierThe obvious first attempt,
996*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
997*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
998*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/n/ c/num/</tt></span></p>
999*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1000*5d535f58SDavid du Colombier
1001*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1002*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1003*5d535f58SDavid du Colombier<span style="font-size: 10pt">is badly flawed: it changes not only the variable
1004*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
1005*5d535f58SDavid du Colombierbut any letter
1006*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
1007*5d535f58SDavid du Colombierthat appears.
1008*5d535f58SDavid du ColombierWe need to extract all the variables, and select those that match
1009*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">
1010*5d535f58SDavid du Colombierand only
1011*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">:
1012*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1013*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1014*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
1015*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1016*5d535f58SDavid du Colombier
1017*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1018*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1019*5d535f58SDavid du Colombier<span style="font-size: 10pt">The pattern
1020*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>[A-Za-z_][A-Za-z_0-9]*</tt></span><span style="font-size: 10pt">
1021*5d535f58SDavid du Colombiermatches C identifiers.
1022*5d535f58SDavid du ColombierNext
1023*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g/n/</tt></span><span style="font-size: 10pt">
1024*5d535f58SDavid du Colombierselects those containing an
1025*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">.
1026*5d535f58SDavid du ColombierThen
1027*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>v/../</tt></span><span style="font-size: 10pt">
1028*5d535f58SDavid du Colombierrejects those containing two (or more) characters, and finally
1029*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>c/num/</tt></span><span style="font-size: 10pt">
1030*5d535f58SDavid du Colombierchanges the remainder (identifiers
1031*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">)
1032*5d535f58SDavid du Colombierto
1033*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>num</tt></span><span style="font-size: 10pt">.
1034*5d535f58SDavid du ColombierThis version clearly works much better, but there may still be problems.
1035*5d535f58SDavid du ColombierFor example, in C character and string constants, the sequence
1036*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\n</tt></span><span style="font-size: 10pt">
1037*5d535f58SDavid du Colombieris interpreted as a newline character, and we don&rsquo;t want to change it to
1038*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\num.</tt></span><span style="font-size: 10pt">
1039*5d535f58SDavid du ColombierThis problem can be forestalled with a
1040*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
1041*5d535f58SDavid du Colombiercommand:
1042*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1043*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1044*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>, y/\\n/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
1045*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1046*5d535f58SDavid du Colombier
1047*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1048*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1049*5d535f58SDavid du Colombier<span style="font-size: 10pt">(the second
1050*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\</tt></span><span style="font-size: 10pt">
1051*5d535f58SDavid du Colombieris necessary because of lexical conventions in regular expressions),
1052*5d535f58SDavid du Colombieror we could even reject character constants and strings outright:
1053*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1054*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1055*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>,y/&rsquo;[^&rsquo;]*&rsquo;/ y/"[^"]*"/ x/[A-Za-z_][A-Za-z_0-9]*/ g/n/ v/../ c/num/</tt></span></p>
1056*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1057*5d535f58SDavid du Colombier
1058*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1059*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1060*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
1061*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
1062*5d535f58SDavid du Colombiercommands in this version exclude from consideration all character constants
1063*5d535f58SDavid du Colombierand strings.
1064*5d535f58SDavid du ColombierThe only remaining problem is to deal with the possible occurrence of
1065*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\&rsquo;</tt></span><span style="font-size: 10pt">
1066*5d535f58SDavid du Colombieror
1067*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\"</tt></span><span style="font-size: 10pt">
1068*5d535f58SDavid du Colombierwithin these sequences, but it&rsquo;s easy to see how to resolve this difficulty.
1069*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1070*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1071*5d535f58SDavid du Colombier<span style="font-size: 10pt">The point of these composed commands is successive refinement.
1072*5d535f58SDavid du ColombierA simple version of the command is tried, and if it&rsquo;s not good enough,
1073*5d535f58SDavid du Colombierit can be honed by adding a clause or two.
1074*5d535f58SDavid du Colombier(Mistakes can be undone; see below.
1075*5d535f58SDavid du ColombierAlso, the mouse language makes it unnecessary to retype the command each time.)
1076*5d535f58SDavid du ColombierThe resulting chains of commands are somewhat reminiscent of
1077*5d535f58SDavid du Colombiershell pipelines.<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1078*5d535f58SDavid du ColombierUnlike pipelines, though, which pass along modified
1079*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>data</i></span><span style="font-size: 10pt">,
1080*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1081*5d535f58SDavid du Colombiercommands pass a
1082*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>view</i></span><span style="font-size: 10pt">
1083*5d535f58SDavid du Colombierof the data.
1084*5d535f58SDavid du ColombierThe text at each step of the command is the same, but which pieces
1085*5d535f58SDavid du Colombierare selected is refined step by step until the correct piece is
1086*5d535f58SDavid du Colombieravailable to the final step of the command line, which ultimately makes the change.
1087*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1088*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1089*5d535f58SDavid du Colombier<span style="font-size: 10pt">In other UNIX programs, regular expressions are used only for selection,
1090*5d535f58SDavid du Colombieras in the
1091*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1092*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
1093*5d535f58SDavid du Colombiercommand, never for extraction as in the
1094*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
1095*5d535f58SDavid du Colombieror
1096*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>y</tt></span><span style="font-size: 10pt">
1097*5d535f58SDavid du Colombiercommand.
1098*5d535f58SDavid du ColombierFor example, patterns in
1099*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>awk</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1100*5d535f58SDavid du Colombierare used to select lines to be operated on, but cannot be used
1101*5d535f58SDavid du Colombierto describe the format of the input text, or to handle newline-free text.
1102*5d535f58SDavid du ColombierThe use of regular expressions to describe the structure of a piece
1103*5d535f58SDavid du Colombierof text rather than its contents, as in the
1104*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
1105*5d535f58SDavid du Colombiercommand,
1106*5d535f58SDavid du Colombierhas been given a name:
1107*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>structural regular expressions.
1108*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">When they are composed, as in the above example,
1109*5d535f58SDavid du Colombierthey are pleasantly expressive.
1110*5d535f58SDavid du ColombierTheir use is discussed at greater length elsewhere.<sup></sup></span><sup><span style="font-size: 6pt">10</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1111*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1112*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1113*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1114*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Multiple files
1115*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1116*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1117*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
1118*5d535f58SDavid du Colombierhas a few other commands, mostly relating to input and output.
1119*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1120*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1121*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>e discfilename</tt></span></p>
1122*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1123*5d535f58SDavid du Colombier
1124*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1125*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1126*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces the contents and name of the current file with those of the named
1127*5d535f58SDavid du Colombierdisc file;
1128*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1129*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1130*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>w discfilename</tt></span></p>
1131*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1132*5d535f58SDavid du Colombier
1133*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1134*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1135*5d535f58SDavid du Colombier<span style="font-size: 10pt">writes the contents to the named disc file; and
1136*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1137*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1138*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>r discfilename</tt></span></p>
1139*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1140*5d535f58SDavid du Colombier
1141*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1142*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1143*5d535f58SDavid du Colombier<span style="font-size: 10pt">replaces dot with the contents of the named disc file.
1144*5d535f58SDavid du ColombierAll these commands use the current file&rsquo;s name if none is specified.
1145*5d535f58SDavid du ColombierFinally,
1146*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1147*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1148*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>f discfilename</tt></span></p>
1149*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1150*5d535f58SDavid du Colombier
1151*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1152*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1153*5d535f58SDavid du Colombier<span style="font-size: 10pt">changes the name associated with the file and displays the result:
1154*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1155*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1156*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>&rsquo;-. discfilename</tt></span></p>
1157*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1158*5d535f58SDavid du Colombier
1159*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1160*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1161*5d535f58SDavid du Colombier<span style="font-size: 10pt">This output is called the file&rsquo;s
1162*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>menu line,
1163*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">because it is the contents of the file&rsquo;s line in the button 3 menu (described
1164*5d535f58SDavid du Colombierin the
1165*5d535f58SDavid du Colombiernext section).
1166*5d535f58SDavid du ColombierThe first three characters are a concise notation for the state of the file.
1167*5d535f58SDavid du ColombierThe apostrophe signifies that the file is modified.
1168*5d535f58SDavid du ColombierThe minus sign indicates the number of windows
1169*5d535f58SDavid du Colombieropen on the file (see the next section):
1170*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-</tt></span><span style="font-size: 10pt">
1171*5d535f58SDavid du Colombiermeans none,
1172*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
1173*5d535f58SDavid du Colombiermeans one, and
1174*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>*</tt></span><span style="font-size: 10pt">
1175*5d535f58SDavid du Colombiermeans more than one.
1176*5d535f58SDavid du ColombierFinally, the period indicates that this is the current file.
1177*5d535f58SDavid du ColombierThese characters are useful for controlling the
1178*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">
1179*5d535f58SDavid du Colombiercommand, described shortly.
1180*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1181*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1182*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
1183*5d535f58SDavid du Colombiermay be started with a set of disc files (such as all the source for
1184*5d535f58SDavid du Colombiera program) by invoking it with a list of file names as arguments, and
1185*5d535f58SDavid du Colombiermore may be added or deleted on demand.
1186*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1187*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1188*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>B discfile1 discfile2 ...</tt></span></p>
1189*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1190*5d535f58SDavid du Colombier
1191*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1192*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1193*5d535f58SDavid du Colombier<span style="font-size: 10pt">adds the named files to
1194*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
1195*5d535f58SDavid du Colombierlist, and
1196*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1197*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1198*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>D discfile1 discfile2 ...</tt></span></p>
1199*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1200*5d535f58SDavid du Colombier
1201*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1202*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1203*5d535f58SDavid du Colombier<span style="font-size: 10pt">removes them from
1204*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
1205*5d535f58SDavid du Colombiermemory (without effect on associated disc files).
1206*5d535f58SDavid du ColombierBoth these commands have a syntax for using the shell<sup></sup></span><sup><span style="font-size: 6pt">7</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1207*5d535f58SDavid du Colombier(the UNIX command interpreter) to generate the lists:
1208*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1209*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1210*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>B &lt;echo *.c</tt></span></p>
1211*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1212*5d535f58SDavid du Colombier
1213*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1214*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1215*5d535f58SDavid du Colombier<span style="font-size: 10pt">will add all C source files, and
1216*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1217*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1218*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>B &lt;grep -l variable *.c</tt></span></p>
1219*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1220*5d535f58SDavid du Colombier
1221*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1222*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1223*5d535f58SDavid du Colombier<span style="font-size: 10pt">will add all C source files referencing a particular variable
1224*5d535f58SDavid du Colombier(the UNIX command
1225*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>grep\fP-l
1226*5d535f58SDavid du Colombierlists all files in its arguments that contain matches of
1227*5d535f58SDavid du Colombierthe specified regular expression).
1228*5d535f58SDavid du ColombierFinally,
1229*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt"><tt>
1230*5d535f58SDavid du Colombierwithout arguments deletes the current file.
1231*5d535f58SDavid du Colombier</tt></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1232*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1233*5d535f58SDavid du Colombier<span style="font-size: 10pt">There are two ways to change which file is current:
1234*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1235*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1236*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>b filename</tt></span></p>
1237*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1238*5d535f58SDavid du Colombier
1239*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1240*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1241*5d535f58SDavid du Colombier<span style="font-size: 10pt">makes the named file current.
1242*5d535f58SDavid du ColombierThe
1243*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>B</tt></span><span style="font-size: 10pt">
1244*5d535f58SDavid du Colombiercommand
1245*5d535f58SDavid du Colombierdoes the same, but also adds any new files to
1246*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
1247*5d535f58SDavid du Colombierlist.
1248*5d535f58SDavid du Colombier(In practice, of course, the current file
1249*5d535f58SDavid du Colombieris usually chosen by mouse actions, not by textual commands.)
1250*5d535f58SDavid du ColombierThe other way is to use a form of address that refers to files:
1251*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1252*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1253*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>"</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>" </tt></span><span style="font-size: 9pt"><i>address</i></span><span style="font-size: 9pt"><tt></tt></span></p>
1254*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1255*5d535f58SDavid du Colombier
1256*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1257*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1258*5d535f58SDavid du Colombier<span style="font-size: 10pt">refers to the address evaluated in the file whose menu line
1259*5d535f58SDavid du Colombiermatches the expression (there must be exactly one match).
1260*5d535f58SDavid du ColombierFor example,
1261*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1262*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1263*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>"peter.c" 3</tt></span></p>
1264*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1265*5d535f58SDavid du Colombier
1266*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1267*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1268*5d535f58SDavid du Colombier<span style="font-size: 10pt">refers to the third line of the file whose name matches
1269*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>peter.c</tt></span><span style="font-size: 10pt">.
1270*5d535f58SDavid du ColombierThis is most useful in the move
1271*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>m</tt></span><span style="font-size: 10pt">)
1272*5d535f58SDavid du Colombierand copy
1273*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>t</tt></span><span style="font-size: 10pt">)
1274*5d535f58SDavid du Colombiercommands:
1275*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1276*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1277*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>0,$ t "peter.c" 0</tt></span></p>
1278*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1279*5d535f58SDavid du Colombier
1280*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1281*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1282*5d535f58SDavid du Colombier<span style="font-size: 10pt">makes a copy of the current file at the beginning of
1283*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>peter.c</tt></span><span style="font-size: 10pt">.
1284*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1285*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1286*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
1287*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">
1288*5d535f58SDavid du Colombiercommand
1289*5d535f58SDavid du Colombieris a looping construct, like
1290*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">,
1291*5d535f58SDavid du Colombierthat refers to files instead of strings:
1292*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1293*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1294*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>X/</tt></span><span style="font-size: 9pt"><i>expression</i></span><span style="font-size: 9pt"><tt>/ </tt></span><span style="font-size: 9pt"><i>command</i></span><span style="font-size: 9pt"><tt></tt></span></p>
1295*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1296*5d535f58SDavid du Colombier
1297*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1298*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1299*5d535f58SDavid du Colombier<span style="font-size: 10pt">runs the command in all
1300*5d535f58SDavid du Colombierfiles whose menu lines match the expression.  The best example is
1301*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1302*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1303*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>X/&rsquo;/ w</tt></span></p>
1304*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1305*5d535f58SDavid du Colombier
1306*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1307*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1308*5d535f58SDavid du Colombier<span style="font-size: 10pt">which writes to disc all modified files.
1309*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Y</tt></span><span style="font-size: 10pt">
1310*5d535f58SDavid du Colombieris the complement of
1311*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>X</tt></span><span style="font-size: 10pt">:
1312*5d535f58SDavid du Colombierit runs the command on all files whose menu lines don&rsquo;t match the expression:
1313*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1314*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1315*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>Y/\.c/ D</tt></span></p>
1316*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1317*5d535f58SDavid du Colombier
1318*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1319*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1320*5d535f58SDavid du Colombier<span style="font-size: 10pt">deletes all files that don&rsquo;t have
1321*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.c</tt></span><span style="font-size: 10pt">
1322*5d535f58SDavid du Colombierin their names, that is, it keeps all C source files and deletes the rest.
1323*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1324*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1325*5d535f58SDavid du Colombier<span style="font-size: 10pt">Braces allow commands to be grouped, so
1326*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1327*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1328*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>{</tt></span></p>
1329*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1330*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    </tt></span><span style="font-size: 9pt"><i>command1</i></span><span style="font-size: 9pt"><tt></tt></span></p>
1331*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1332*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    </tt></span><span style="font-size: 9pt"><i>command2</i></span><span style="font-size: 9pt"><tt></tt></span></p>
1333*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1334*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}</tt></span></p>
1335*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1336*5d535f58SDavid du Colombier
1337*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1338*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1339*5d535f58SDavid du Colombier<span style="font-size: 10pt">is syntactically a single command that runs two commands.
1340*5d535f58SDavid du ColombierThus,
1341*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1342*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1343*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>X/\.c/ ,g/variable/ {</tt></span></p>
1344*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1345*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    f</tt></span></p>
1346*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1347*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    , x/.*\n/ g/variable/ p</tt></span></p>
1348*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1349*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}</tt></span></p>
1350*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1351*5d535f58SDavid du Colombier
1352*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1353*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1354*5d535f58SDavid du Colombier<span style="font-size: 10pt">finds all occurrences of
1355*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>variable</tt></span><span style="font-size: 10pt">
1356*5d535f58SDavid du Colombierin C source files, and prints
1357*5d535f58SDavid du Colombierout the file names and lines of each match.
1358*5d535f58SDavid du ColombierThe precise semantics of compound operations is discussed in the implementation
1359*5d535f58SDavid du Colombiersections below.
1360*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1361*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1362*5d535f58SDavid du Colombier<span style="font-size: 10pt">Finally,
1363*5d535f58SDavid du Colombierthe undo command,
1364*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>u</tt></span><span style="font-size: 10pt">,
1365*5d535f58SDavid du Colombierundoes the last command,
1366*5d535f58SDavid du Colombierno matter how many files were affected.
1367*5d535f58SDavid du ColombierMultiple undo operations move further back in time, so
1368*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1369*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1370*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>u</tt></span></p>
1371*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1372*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>u</tt></span></p>
1373*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1374*5d535f58SDavid du Colombier
1375*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1376*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1377*5d535f58SDavid du Colombier<span style="font-size: 10pt">(which may be abbreviated
1378*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>u2</tt></span><span style="font-size: 10pt">)
1379*5d535f58SDavid du Colombierundoes the last two commands.  An undo may not be undone, however, nor
1380*5d535f58SDavid du Colombiermay any command that adds or deletes files.
1381*5d535f58SDavid du ColombierEverything else is undoable, though, including for example
1382*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>e</tt></span><span style="font-size: 10pt">
1383*5d535f58SDavid du Colombiercommands:
1384*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1385*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1386*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>e filename</tt></span></p>
1387*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1388*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>u</tt></span></p>
1389*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1390*5d535f58SDavid du Colombier
1391*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1392*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1393*5d535f58SDavid du Colombier<span style="font-size: 10pt">restores the state of the file completely, including its name, dot,
1394*5d535f58SDavid du Colombierand modified bit.  Because of the undo, potentially dangerous commands
1395*5d535f58SDavid du Colombierare not guarded by confirmations.  Only
1396*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">,
1397*5d535f58SDavid du Colombierwhich destroys the information necessary to restore itself, is protected.
1398*5d535f58SDavid du ColombierIt will not delete a modified file, but a second
1399*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">
1400*5d535f58SDavid du Colombierof the same file will succeed regardless.
1401*5d535f58SDavid du ColombierThe
1402*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>q</tt></span><span style="font-size: 10pt">
1403*5d535f58SDavid du Colombiercommand, which exits
1404*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
1405*5d535f58SDavid du Colombieris similarly guarded.
1406*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1407*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1408*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Mouse Interface
1409*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1410*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1411*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
1412*5d535f58SDavid du Colombieris most commonly run
1413*5d535f58SDavid du Colombierconnected to a bitmap display and mouse for interactive editing.
1414*5d535f58SDavid du ColombierThe only difference in the command language
1415*5d535f58SDavid du Colombierbetween regular, mouse-driven
1416*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1417*5d535f58SDavid du Colombierand
1418*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam\fP-d
1419*5d535f58SDavid du Colombieris that if an address
1420*5d535f58SDavid du Colombieris provided without a command,
1421*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><tt>sam\fP-d
1422*5d535f58SDavid du Colombierwill print the text referenced by the address, but
1423*5d535f58SDavid du Colombierregular
1424*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt"><tt>
1425*5d535f58SDavid du Colombierwill highlight it on the screen &mdash; in fact,
1426*5d535f58SDavid du Colombierdot is always highlighted (see Figure 2).
1427*5d535f58SDavid du Colombier</tt></span><span style="font-size: 10pt"></span></p><center><img src="fig3.gif" /></center>
1428*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1429*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 2. A
1430*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>sam</tt></span><span style="font-size: 8pt"><i>
1431*5d535f58SDavid du Colombierwindow.  The scroll bar down the left
1432*5d535f58SDavid du Colombierrepresents the file, with the bubble showing the fraction
1433*5d535f58SDavid du Colombiervisible in the window.
1434*5d535f58SDavid du ColombierThe scroll bar may be manipulated by the mouse for convenient browsing.
1435*5d535f58SDavid du ColombierThe current text,
1436*5d535f58SDavid du Colombierwhich is highlighted, need not fit on a line.  Here it consists of one partial
1437*5d535f58SDavid du Colombierline, one complete line, and final partial line.
1438*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1439*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
1440*5d535f58SDavid du Colombier
1441*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
1442*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1443*5d535f58SDavid du Colombier<span style="font-size: 10pt">Each file may have zero or more windows open on the display.
1444*5d535f58SDavid du ColombierAt any time, only one window in all of
1445*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1446*5d535f58SDavid du Colombieris the
1447*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>current window,
1448*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">that is, the window to which typing and mouse actions refer;
1449*5d535f58SDavid du Colombierthis may be the
1450*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1451*5d535f58SDavid du Colombierwindow (that in which commands may be typed)
1452*5d535f58SDavid du Colombieror one of the file windows.
1453*5d535f58SDavid du ColombierWhen a file has multiple windows, the image of the file in each window
1454*5d535f58SDavid du Colombieris always kept up to date.
1455*5d535f58SDavid du ColombierThe current file is the last file affected by a command,
1456*5d535f58SDavid du Colombierso if the
1457*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1458*5d535f58SDavid du Colombierwindow is current,
1459*5d535f58SDavid du Colombierthe current window is not a window on the current file.
1460*5d535f58SDavid du ColombierHowever, each window on a file has its own value of dot,
1461*5d535f58SDavid du Colombierand when switching between windows on a single file,
1462*5d535f58SDavid du Colombierthe file&rsquo;s value of dot is changed to that of the window.
1463*5d535f58SDavid du ColombierThus, flipping between windows behaves in the obvious, convenient way.
1464*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1465*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1466*5d535f58SDavid du Colombier<span style="font-size: 10pt">The mouse on the Blit has three buttons, numbered left to right.
1467*5d535f58SDavid du ColombierButton 3 has a list of commands to manipulate windows,
1468*5d535f58SDavid du Colombierfollowed by a list of &lsquo;menu lines&rsquo; exactly as printed by the
1469*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>f</tt></span><span style="font-size: 10pt">
1470*5d535f58SDavid du Colombiercommand, one per file (not one per window).
1471*5d535f58SDavid du ColombierThese menu lines are sorted by file name.
1472*5d535f58SDavid du ColombierIf the list is long, the Blit menu software will make it more manageable
1473*5d535f58SDavid du Colombierby generating a scrolling menu instead of an unwieldy long list.
1474*5d535f58SDavid du ColombierUsing the menu to select a file from the list makes that file the current
1475*5d535f58SDavid du Colombierfile, and the most recently current window in that file the current window.
1476*5d535f58SDavid du ColombierBut if that file is already current, selecting it in the menu cycles through
1477*5d535f58SDavid du Colombierthe windows on the file; this simple trick avoids a special menu to
1478*5d535f58SDavid du Colombierchoose windows on a file.
1479*5d535f58SDavid du ColombierIf there is no window open on the file,
1480*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1481*5d535f58SDavid du Colombierchanges the mouse cursor to prompt the user to create one.
1482*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1483*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1484*5d535f58SDavid du Colombier<span style="font-size: 10pt">The commands on the button 3 menu are straightforward (see Figure 3), and
1485*5d535f58SDavid du Colombierare like the commands to manipulate windows in
1486*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1487*5d535f58SDavid du Colombierthe Blit&rsquo;s window system.
1488*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>New</tt></span><span style="font-size: 10pt">
1489*5d535f58SDavid du Colombiermakes a new file, and gives it one empty window, whose size is determined
1490*5d535f58SDavid du Colombierby a rectangle swept by the mouse.
1491*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Zerox</tt></span><span style="font-size: 10pt">
1492*5d535f58SDavid du Colombierprompts for a window to be selected, and
1493*5d535f58SDavid du Colombiermakes a clone of that window; this is how multiple windows are created on one file.
1494*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Reshape</tt></span><span style="font-size: 10pt">
1495*5d535f58SDavid du Colombierchanges the size of the indicated window, and
1496*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>close</tt></span><span style="font-size: 10pt">
1497*5d535f58SDavid du Colombierdeletes it.  If that is the last window open on the file,
1498*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>close</tt></span><span style="font-size: 10pt">
1499*5d535f58SDavid du Colombierfirst does a
1500*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>D</tt></span><span style="font-size: 10pt">
1501*5d535f58SDavid du Colombiercommand on the file.
1502*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Write</tt></span><span style="font-size: 10pt">
1503*5d535f58SDavid du Colombieris identical to a
1504*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>w</tt></span><span style="font-size: 10pt">
1505*5d535f58SDavid du Colombiercommand on the file; it is in the menu purely for convenience.
1506*5d535f58SDavid du ColombierFinally,
1507*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>~~sam~~</tt></span><span style="font-size: 10pt">
1508*5d535f58SDavid du Colombieris a menu item that appears between the commands and the file names.
1509*5d535f58SDavid du ColombierSelecting it makes the
1510*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1511*5d535f58SDavid du Colombierwindow the current window,
1512*5d535f58SDavid du Colombiercausing subsequent typing to be interpreted as commands.
1513*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="fig2.gif" /></center>
1514*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1515*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 3. The menu on button 3.
1516*5d535f58SDavid du ColombierThe black rectangle on the left is a scroll bar; the menu is limited to
1517*5d535f58SDavid du Colombierthe length shown to prevent its becoming unwieldy.
1518*5d535f58SDavid du ColombierAbove the
1519*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>~~sam~~</tt></span><span style="font-size: 8pt"><i>
1520*5d535f58SDavid du Colombierline is a list of commands;
1521*5d535f58SDavid du Colombierbeneath it is a list of files, presented exactly as with the
1522*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>f</tt></span><span style="font-size: 8pt"><i>
1523*5d535f58SDavid du Colombiercommand.
1524*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1525*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
1526*5d535f58SDavid du Colombier
1527*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
1528*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1529*5d535f58SDavid du Colombier<span style="font-size: 10pt">When
1530*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1531*5d535f58SDavid du Colombierrequests that a window be swept, in response to
1532*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>new</tt></span><span style="font-size: 10pt">,
1533*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>zerox</tt></span><span style="font-size: 10pt">
1534*5d535f58SDavid du Colombieror
1535*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>reshape</tt></span><span style="font-size: 10pt">,
1536*5d535f58SDavid du Colombierit changes the mouse cursor from the usual arrow to a box with
1537*5d535f58SDavid du Colombiera small arrow.
1538*5d535f58SDavid du ColombierIn this state, the mouse may be used to indicate an arbitrary rectangle by
1539*5d535f58SDavid du Colombierpressing button 3 at one corner and releasing it at the opposite corner.
1540*5d535f58SDavid du ColombierMore conveniently,
1541*5d535f58SDavid du Colombierbutton 3 may simply be clicked,
1542*5d535f58SDavid du Colombierwhereupon
1543*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1544*5d535f58SDavid du Colombiercreates the maximal rectangle that contains the cursor
1545*5d535f58SDavid du Colombierand abuts the
1546*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1547*5d535f58SDavid du Colombierwindow.
1548*5d535f58SDavid du ColombierBy placing the
1549*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1550*5d535f58SDavid du Colombierwindow in the middle of the screen, the user can define two regions (one above,
1551*5d535f58SDavid du Colombierone below) in which stacked fully-overlapping
1552*5d535f58SDavid du Colombierwindows can be created with minimal fuss (see Figure 1).
1553*5d535f58SDavid du ColombierThis simple user interface trick makes window creation noticeably easier.
1554*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1555*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1556*5d535f58SDavid du Colombier<span style="font-size: 10pt">The cut-and-paste editor is essentially the same as that in Smalltalk-80.<sup></sup></span><sup><span style="font-size: 6pt">11</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1557*5d535f58SDavid du ColombierThe text in dot is always highlighted on the screen.
1558*5d535f58SDavid du ColombierWhen a character is typed it replaces dot, and sets dot to the null
1559*5d535f58SDavid du Colombierstring after the character.  Thus, ordinary typing inserts text.
1560*5d535f58SDavid du ColombierButton 1 is used for selection:
1561*5d535f58SDavid du Colombierpressing the button, moving the mouse, and lifting the button
1562*5d535f58SDavid du Colombierselects (sets dot to) the text between the points where the
1563*5d535f58SDavid du Colombierbutton was pressed and released.
1564*5d535f58SDavid du ColombierPressing and releasing at the same point selects a null string; this
1565*5d535f58SDavid du Colombieris called clicking.  Clicking twice quickly, or
1566*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>double clicking,
1567*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">selects larger objects;
1568*5d535f58SDavid du Colombierfor example, double clicking in a word selects the word,
1569*5d535f58SDavid du Colombierdouble clicking just inside an opening bracket selects the text
1570*5d535f58SDavid du Colombiercontained in the brackets (handling nested brackets correctly),
1571*5d535f58SDavid du Colombierand similarly for
1572*5d535f58SDavid du Colombierparentheses, quotes, and so on.
1573*5d535f58SDavid du ColombierThe double-clicking rules reflect a bias toward
1574*5d535f58SDavid du Colombierprogrammers.
1575*5d535f58SDavid du ColombierIf
1576*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1577*5d535f58SDavid du Colombierwere intended more for word processing, double-clicks would probably
1578*5d535f58SDavid du Colombierselect linguistic structures such as sentences.
1579*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1580*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1581*5d535f58SDavid du Colombier<span style="font-size: 10pt">If button 1 is pressed outside the current window, it makes the indicated
1582*5d535f58SDavid du Colombierwindow current.
1583*5d535f58SDavid du ColombierThis is the easiest way to switch between windows and files.
1584*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1585*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1586*5d535f58SDavid du Colombier<span style="font-size: 10pt">Pressing button 2 brings up a menu of editing functions (see Figure 4).
1587*5d535f58SDavid du ColombierThese mostly apply to the selected text:
1588*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>cut</tt></span><span style="font-size: 10pt">
1589*5d535f58SDavid du Colombierdeletes the selected text, and remembers it in a hidden buffer called the
1590*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>snarf buffer,
1591*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>paste</tt></span><span style="font-size: 10pt">
1592*5d535f58SDavid du Colombierreplaces the selected text by the contents of the snarf buffer,
1593*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>snarf</tt></span><span style="font-size: 10pt">
1594*5d535f58SDavid du Colombierjust copies the selected text to the snarf buffer,
1595*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>look</tt></span><span style="font-size: 10pt">
1596*5d535f58SDavid du Colombiersearches forward for the next literal occurrence of the selected text, and
1597*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>&lt;mux&gt;</tt></span><span style="font-size: 10pt">
1598*5d535f58SDavid du Colombierexchanges snarf buffers with the window system in which
1599*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1600*5d535f58SDavid du Colombieris running.
1601*5d535f58SDavid du ColombierFinally, the last regular expression used appears as a menu entry
1602*5d535f58SDavid du Colombierto search
1603*5d535f58SDavid du Colombierforward for the next occurrence of a match for the expression.
1604*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="fig4.gif" /></center>
1605*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1606*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 4. The menu on button 2.
1607*5d535f58SDavid du ColombierThe bottom entry tracks the most recently used regular expression, which may
1608*5d535f58SDavid du Colombierbe literal text.
1609*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1610*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
1611*5d535f58SDavid du Colombier
1612*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
1613*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1614*5d535f58SDavid du Colombier<span style="font-size: 10pt">The relationship between the command language and the mouse language is
1615*5d535f58SDavid du Colombierentirely due to the equality of dot and the selected text chosen
1616*5d535f58SDavid du Colombierwith button 1 on the mouse.
1617*5d535f58SDavid du ColombierFor example, to make a set of changes in a C subroutine, dot can be
1618*5d535f58SDavid du Colombierset by double clicking on the left brace that begins the subroutine,
1619*5d535f58SDavid du Colombierwhich sets dot for the command language.
1620*5d535f58SDavid du ColombierAn address-free command then typed in the
1621*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1622*5d535f58SDavid du Colombierwindow will apply only to the text between the opening and closing
1623*5d535f58SDavid du Colombierbraces of the function.
1624*5d535f58SDavid du ColombierThe idea is to select what you want, and then say what you want
1625*5d535f58SDavid du Colombierto do with it, whether invoked by a menu selection or by a typed command.
1626*5d535f58SDavid du ColombierAnd of course, the value of dot is highlighted on
1627*5d535f58SDavid du Colombierthe display after the command completes.
1628*5d535f58SDavid du ColombierThis relationship between mouse interface and command language
1629*5d535f58SDavid du Colombieris clumsy to explain, but comfortable, even natural, in practice.
1630*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1631*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1632*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>The Implementation
1633*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1634*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1635*5d535f58SDavid du Colombier<span style="font-size: 10pt">The next few sections describe how
1636*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1637*5d535f58SDavid du Colombieris put together, first the host part,
1638*5d535f58SDavid du Colombierthen the inter-component communication,
1639*5d535f58SDavid du Colombierthen the terminal part.
1640*5d535f58SDavid du ColombierAfter explaining how the command language is implemented,
1641*5d535f58SDavid du Colombierthe discussion follows (roughly) the path of a character
1642*5d535f58SDavid du Colombierfrom the temporary file on disc to the screen.
1643*5d535f58SDavid du ColombierThe presentation centers on the data structures,
1644*5d535f58SDavid du Colombierbecause that is how the program was designed and because
1645*5d535f58SDavid du Colombierthe algorithms are easy to provide, given the right data
1646*5d535f58SDavid du Colombierstructures.
1647*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1648*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1649*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Parsing and execution
1650*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1651*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1652*5d535f58SDavid du Colombier<span style="font-size: 10pt">The command language is interpreted by parsing each command with a
1653*5d535f58SDavid du Colombiertable-driven recursive
1654*5d535f58SDavid du Colombierdescent parser, and when a complete command is assembled, invoking a top-down
1655*5d535f58SDavid du Colombierexecutor.
1656*5d535f58SDavid du ColombierMost editors instead employ a simple character-at-a-time
1657*5d535f58SDavid du Colombierlexical scanner.
1658*5d535f58SDavid du ColombierUse of a parser makes it
1659*5d535f58SDavid du Colombiereasy and unambiguous to detect when a command is complete,
1660*5d535f58SDavid du Colombierwhich has two advantages.
1661*5d535f58SDavid du ColombierFirst, escape conventions such as backslashes to quote
1662*5d535f58SDavid du Colombiermultiple-line commands are unnecessary;  if the command isn&rsquo;t finished,
1663*5d535f58SDavid du Colombierthe parser keeps reading.  For example, a multiple-line append driven by an
1664*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
1665*5d535f58SDavid du Colombiercommand is straightforward:
1666*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1667*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1668*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>x/.*\n/ g/Peter/ a</tt></span></p>
1669*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1670*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>one line about Peter</tt></span></p>
1671*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1672*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>another line about Peter</tt></span></p>
1673*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1674*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>.</tt></span></p>
1675*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1676*5d535f58SDavid du Colombier
1677*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1678*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1679*5d535f58SDavid du Colombier<span style="font-size: 10pt">Other UNIX editors would require a backslash after all but the last line.
1680*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1681*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1682*5d535f58SDavid du Colombier<span style="font-size: 10pt">The other advantage is specific to the two-process structure of
1683*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
1684*5d535f58SDavid du ColombierThe host process must decide when a command is completed so the
1685*5d535f58SDavid du Colombiercommand interpreter can be called.  This problem is easily resolved
1686*5d535f58SDavid du Colombierby having the lexical analyzer read the single stream of events from the
1687*5d535f58SDavid du Colombierterminal, directly executing all typing and mouse commands,
1688*5d535f58SDavid du Colombierbut passing to the parser characters typed to the
1689*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1690*5d535f58SDavid du Colombiercommand window.
1691*5d535f58SDavid du ColombierThis scheme is slightly complicated by the availability of cut-and-paste
1692*5d535f58SDavid du Colombierediting in the
1693*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1694*5d535f58SDavid du Colombierwindow, but that difficulty is resolved by applying the rules
1695*5d535f58SDavid du Colombierused in
1696*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">:
1697*5d535f58SDavid du Colombierwhen a newline is typed to the
1698*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1699*5d535f58SDavid du Colombierwindow, all text between the newline and the previously typed newline
1700*5d535f58SDavid du Colombieris made available to the parser.
1701*5d535f58SDavid du ColombierThis permits arbitrary editing to be done to a command before
1702*5d535f58SDavid du Colombiertyping newline and thereby requesting execution.
1703*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1704*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1705*5d535f58SDavid du Colombier<span style="font-size: 10pt">The parser is driven by a table because the syntax of addresses
1706*5d535f58SDavid du Colombierand commands is regular enough
1707*5d535f58SDavid du Colombierto be encoded compactly.  There are few special cases, such as the
1708*5d535f58SDavid du Colombierreplacement text in a substitution, so the syntax of almost all commands
1709*5d535f58SDavid du Colombiercan be encoded with a few flags.
1710*5d535f58SDavid du ColombierThese include whether the command allows an address (for example,
1711*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>e</tt></span><span style="font-size: 10pt">
1712*5d535f58SDavid du Colombierdoes not), whether it takes a regular expression (as in
1713*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
1714*5d535f58SDavid du Colombierand
1715*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">),
1716*5d535f58SDavid du Colombierwhether it takes replacement text (as in
1717*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">
1718*5d535f58SDavid du Colombieror
1719*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>i</tt></span><span style="font-size: 10pt">),
1720*5d535f58SDavid du Colombierwhich may be multi-line, and so on.
1721*5d535f58SDavid du ColombierThe internal syntax of regular expressions is handled by a separate
1722*5d535f58SDavid du Colombierparser; a regular expression is a leaf of the command parse tree.
1723*5d535f58SDavid du ColombierRegular expressions are discussed fully in the next section.
1724*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1725*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1726*5d535f58SDavid du Colombier<span style="font-size: 10pt">The parser table also has information about defaults, so the interpreter
1727*5d535f58SDavid du Colombieris always called with a complete tree.  For example, the parser fills in
1728*5d535f58SDavid du Colombierthe implicit
1729*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>0</tt></span><span style="font-size: 10pt">
1730*5d535f58SDavid du Colombierand
1731*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">
1732*5d535f58SDavid du Colombierin the abbreviated address
1733*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>,</tt></span><span style="font-size: 10pt">
1734*5d535f58SDavid du Colombier(comma),
1735*5d535f58SDavid du Colombierinserts a
1736*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>+</tt></span><span style="font-size: 10pt">
1737*5d535f58SDavid du Colombierto the left of an unadorned regular expression in an address,
1738*5d535f58SDavid du Colombierand provides the usual default address
1739*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.</tt></span><span style="font-size: 10pt">
1740*5d535f58SDavid du Colombier(dot) for commands that expect an address but are not given one.
1741*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1742*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1743*5d535f58SDavid du Colombier<span style="font-size: 10pt">Once a complete command is parsed, the evaluation is easy.
1744*5d535f58SDavid du ColombierThe address is evaluated left-to-right starting from the value of dot,
1745*5d535f58SDavid du Colombierwith a mostly ordinary expression evaluator.
1746*5d535f58SDavid du ColombierAddresses, like many of the data structures in
1747*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
1748*5d535f58SDavid du Colombierare held in a C structure and passed around by value:
1749*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1750*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1751*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>typedef long Posn;    /* Position in a file */</tt></span></p>
1752*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1753*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>typedef struct Range{</tt></span></p>
1754*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1755*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        Posn    p1, p2;</tt></span></p>
1756*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1757*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}Range;</tt></span></p>
1758*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1759*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>typedef struct Address{</tt></span></p>
1760*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1761*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        Range   r;</tt></span></p>
1762*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1763*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        File    *f;</tt></span></p>
1764*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1765*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}Address;</tt></span></p>
1766*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1767*5d535f58SDavid du Colombier
1768*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1769*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1770*5d535f58SDavid du Colombier<span style="font-size: 10pt">An address is encoded as a substring (character positions
1771*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>p1</tt></span><span style="font-size: 10pt">
1772*5d535f58SDavid du Colombierto
1773*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>p2</tt></span><span style="font-size: 10pt">)
1774*5d535f58SDavid du Colombierin a file
1775*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>f</tt></span><span style="font-size: 10pt">.
1776*5d535f58SDavid du Colombier(The data type
1777*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
1778*5d535f58SDavid du Colombieris described in detail below.)
1779*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1780*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1781*5d535f58SDavid du Colombier<span style="font-size: 10pt">The address interpreter is an
1782*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Address</tt></span><span style="font-size: 10pt">-valued
1783*5d535f58SDavid du Colombierfunction that traverses the parse tree describing an address (the
1784*5d535f58SDavid du Colombierparse tree for the address has type
1785*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Addrtree</tt></span><span style="font-size: 10pt">):
1786*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1787*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1788*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>Address</tt></span></p>
1789*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1790*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>address(ap, a, sign)</tt></span></p>
1791*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1792*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    Addrtree *ap;</tt></span></p>
1793*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1794*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    Address a;</tt></span></p>
1795*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1796*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    int sign;</tt></span></p>
1797*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1798*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>{</tt></span></p>
1799*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1800*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    Address a2;</tt></span></p>
1801*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1802*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    do</tt></span></p>
1803*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1804*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        switch(ap-&gt;type){</tt></span></p>
1805*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1806*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        case &rsquo;.&rsquo;:</tt></span></p>
1807*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1808*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a=a.f-&gt;dot;</tt></span></p>
1809*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1810*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            break;</tt></span></p>
1811*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1812*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        case &rsquo;$&rsquo;:</tt></span></p>
1813*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1814*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a.r.p1=a.r.p2=a.f-&gt;nbytes;</tt></span></p>
1815*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1816*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            break;</tt></span></p>
1817*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1818*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        case &rsquo;"&rsquo;:   </tt></span></p>
1819*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1820*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a=matchfile(a, ap-&gt;aregexp)-&gt;dot; </tt></span></p>
1821*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1822*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            break;</tt></span></p>
1823*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1824*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        case &rsquo;,&rsquo;:</tt></span></p>
1825*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1826*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a2=address(ap-&gt;right, a, 0);</tt></span></p>
1827*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1828*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a=address(ap-&gt;left, a, 0);</tt></span></p>
1829*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1830*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            if(a.f!=a2.f || a2.r.p2&lt;a.r.p1)</tt></span></p>
1831*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1832*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>                error(Eorder);</tt></span></p>
1833*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1834*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            a.r.p2=a2.r.p2;</tt></span></p>
1835*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1836*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>            return a;</tt></span></p>
1837*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1838*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        /* and so on */</tt></span></p>
1839*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1840*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        }</tt></span></p>
1841*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1842*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    while((ap=ap-&gt;right)!=0);</tt></span></p>
1843*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1844*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    return a;</tt></span></p>
1845*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1846*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}</tt></span></p>
1847*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1848*5d535f58SDavid du Colombier
1849*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1850*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
1851*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1852*5d535f58SDavid du Colombier<span style="font-size: 10pt">Throughout, errors are handled by a non-local
1853*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>goto</tt></span><span style="font-size: 10pt">
1854*5d535f58SDavid du Colombier(a
1855*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>setjmp/longjmp</tt></span><span style="font-size: 10pt">
1856*5d535f58SDavid du Colombierin C terminology)
1857*5d535f58SDavid du Colombierhidden in a routine called
1858*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>error</tt></span><span style="font-size: 10pt">
1859*5d535f58SDavid du Colombierthat immediately aborts the execution, retracts any
1860*5d535f58SDavid du Colombierpartially made changes (see the section below on &lsquo;undoing&rsquo;), and
1861*5d535f58SDavid du Colombierreturns to the top level of the parser.
1862*5d535f58SDavid du ColombierThe argument to
1863*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>error</tt></span><span style="font-size: 10pt">
1864*5d535f58SDavid du Colombieris an enumeration type that
1865*5d535f58SDavid du Colombieris translated to a terse but possibly helpful
1866*5d535f58SDavid du Colombiermessage such as &lsquo;?addresses out of order.&rsquo;
1867*5d535f58SDavid du ColombierVery common messages are kept short; for example the message for
1868*5d535f58SDavid du Colombiera failed regular expression search is &lsquo;?search.&rsquo;
1869*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1870*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1871*5d535f58SDavid du Colombier<span style="font-size: 10pt">Character addresses such as
1872*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>#3</tt></span><span style="font-size: 10pt">
1873*5d535f58SDavid du Colombierare trivial to implement, as the
1874*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
1875*5d535f58SDavid du Colombierdata structure is accessible by character number.
1876*5d535f58SDavid du ColombierHowever,
1877*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1878*5d535f58SDavid du Colombierkeeps no information about the position of newlines &mdash; it is too
1879*5d535f58SDavid du Colombierexpensive to track dynamically &mdash; so line addresses are computed by reading
1880*5d535f58SDavid du Colombierthe file, counting newlines.  Except in very large files, this has proven
1881*5d535f58SDavid du Colombieracceptable: file access is fast enough to make the technique practical,
1882*5d535f58SDavid du Colombierand lines are not central to the structure of the command language.
1883*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1884*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1885*5d535f58SDavid du Colombier<span style="font-size: 10pt">The command interpreter, called
1886*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>cmdexec</tt></span><span style="font-size: 10pt">,
1887*5d535f58SDavid du Colombieris also straightforward.  The parse table includes a
1888*5d535f58SDavid du Colombierfunction to call to interpret a particular command.  That function
1889*5d535f58SDavid du Colombierreceives as arguments
1890*5d535f58SDavid du Colombierthe calculated address
1891*5d535f58SDavid du Colombierfor the command
1892*5d535f58SDavid du Colombierand the command tree (of type
1893*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Cmdtree</tt></span><span style="font-size: 10pt">),
1894*5d535f58SDavid du Colombierwhich may contain information such as the subtree for compound commands.
1895*5d535f58SDavid du ColombierHere, for example, is the function for the
1896*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
1897*5d535f58SDavid du Colombierand
1898*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>v</tt></span><span style="font-size: 10pt">
1899*5d535f58SDavid du Colombiercommands:
1900*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1901*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1902*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>int</tt></span></p>
1903*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1904*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>g_cmd(a, cp)</tt></span></p>
1905*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1906*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    Address a;</tt></span></p>
1907*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1908*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    Cmdtree *cp;</tt></span></p>
1909*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1910*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>{</tt></span></p>
1911*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1912*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    compile(cp-&gt;regexp);</tt></span></p>
1913*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1914*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    if(execute(a.fa.r.p1a.r.p2)!=(cp-&gt;cmdchar==&rsquo;v&rsquo;)){</tt></span></p>
1915*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1916*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        a.f-&gt;dot=a;</tt></span></p>
1917*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1918*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        return cmdexec(a, cp-&gt;subcmd);</tt></span></p>
1919*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1920*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    }</tt></span></p>
1921*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1922*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>    return TRUE;    /* cause execution to continue */</tt></span></p>
1923*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1924*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}</tt></span></p>
1925*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
1926*5d535f58SDavid du Colombier
1927*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
1928*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1929*5d535f58SDavid du Colombier<span style="font-size: 10pt">(</span><span style="font-size: 10pt"><tt>Compile</tt></span><span style="font-size: 10pt">
1930*5d535f58SDavid du Colombierand
1931*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
1932*5d535f58SDavid du Colombierare part of the regular expression code, described in the next section.)
1933*5d535f58SDavid du ColombierBecause the parser and the
1934*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
1935*5d535f58SDavid du Colombierdata structure do most of the work, most commands
1936*5d535f58SDavid du Colombierare similarly brief.
1937*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
1938*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1939*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Regular expressions
1940*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1941*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1942*5d535f58SDavid du Colombier<span style="font-size: 10pt">The regular expression code in
1943*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1944*5d535f58SDavid du Colombieris an interpreted, rather than compiled on-the-fly, implementation of Thompson&rsquo;s
1945*5d535f58SDavid du Colombiernon-deterministic finite automaton algorithm.<sup></sup></span><sup><span style="font-size: 6pt">12</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1946*5d535f58SDavid du ColombierThe syntax and semantics of the expressions are as in the UNIX program
1947*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,
1948*5d535f58SDavid du Colombierincluding alternation, closures, character classes, and so on.
1949*5d535f58SDavid du ColombierThe only changes in the notation are two additions:
1950*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>\n</tt></span><span style="font-size: 10pt">
1951*5d535f58SDavid du Colombieris translated to, and matches, a newline character, and
1952*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>@</tt></span><span style="font-size: 10pt">
1953*5d535f58SDavid du Colombiermatches any character.  In
1954*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">,
1955*5d535f58SDavid du Colombierthe character
1956*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.</tt></span><span style="font-size: 10pt">
1957*5d535f58SDavid du Colombiermatches any character except newline, and in
1958*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
1959*5d535f58SDavid du Colombierthe same rule seemed safest, to prevent idioms like
1960*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>.*</tt></span><span style="font-size: 10pt">
1961*5d535f58SDavid du Colombierfrom spanning newlines.
1962*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Egrep</tt></span><span style="font-size: 10pt">
1963*5d535f58SDavid du Colombierexpressions are arguably too complicated for an interactive editor &mdash;
1964*5d535f58SDavid du Colombiercertainly it would make sense if all the special characters were two-character
1965*5d535f58SDavid du Colombiersequences, so that most of the punctuation characters wouldn&rsquo;t have
1966*5d535f58SDavid du Colombierpeculiar meanings &mdash; but for an interesting command language, full
1967*5d535f58SDavid du Colombierregular expressions are necessary, and
1968*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">
1969*5d535f58SDavid du Colombierdefines the full regular expression syntax for UNIX programs.
1970*5d535f58SDavid du ColombierAlso, it seemed superfluous to define a new syntax, since various UNIX programs
1971*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">,
1972*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>egrep</tt></span><span style="font-size: 10pt">
1973*5d535f58SDavid du Colombierand
1974*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">)
1975*5d535f58SDavid du Colombierdefine too many already.
1976*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1977*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1978*5d535f58SDavid du Colombier<span style="font-size: 10pt">The expressions are compiled by a routine,
1979*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>compile</tt></span><span style="font-size: 10pt">,
1980*5d535f58SDavid du Colombierthat generates the description of the non-deterministic finite state machine.
1981*5d535f58SDavid du ColombierA second routine,
1982*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">,
1983*5d535f58SDavid du Colombierinterprets the machine to generate the leftmost-longest match of the
1984*5d535f58SDavid du Colombierexpression in a substring of the file.
1985*5d535f58SDavid du ColombierThe algorithm is described elsewhere.<sup></sup></span><sup><span style="font-size: 6pt">12,13</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
1986*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Execute</tt></span><span style="font-size: 10pt">
1987*5d535f58SDavid du Colombierreports
1988*5d535f58SDavid du Colombierwhether a match was found, and sets a global variable,
1989*5d535f58SDavid du Colombierof type
1990*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Range</tt></span><span style="font-size: 10pt">,
1991*5d535f58SDavid du Colombierto the substring matched.
1992*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
1993*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1994*5d535f58SDavid du Colombier<span style="font-size: 10pt">A trick is required to evaluate the expression in reverse, such as when
1995*5d535f58SDavid du Colombiersearching backwards for an expression.
1996*5d535f58SDavid du ColombierFor example,
1997*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
1998*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
1999*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>-/P.*r/</tt></span></p>
2000*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
2001*5d535f58SDavid du Colombier
2002*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
2003*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2004*5d535f58SDavid du Colombier<span style="font-size: 10pt">looks backwards through the file for a match of the expression.
2005*5d535f58SDavid du ColombierThe expression, however, is defined for a forward search.
2006*5d535f58SDavid du ColombierThe solution is to construct a machine identical to the machine
2007*5d535f58SDavid du Colombierfor a forward search except for a reversal of all the concatenation
2008*5d535f58SDavid du Colombieroperators (the other operators are symmetric under direction reversal),
2009*5d535f58SDavid du Colombierto exchange the meaning of the operators
2010*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>^</tt></span><span style="font-size: 10pt">
2011*5d535f58SDavid du Colombierand
2012*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt">,
2013*5d535f58SDavid du Colombierand then to read the file backwards, looking for the
2014*5d535f58SDavid du Colombierusual earliest longest match.
2015*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2016*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2017*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Execute</tt></span><span style="font-size: 10pt">
2018*5d535f58SDavid du Colombiergenerates only one match each time it is called.
2019*5d535f58SDavid du ColombierTo interpret looping constructs such as the
2020*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
2021*5d535f58SDavid du Colombiercommand,
2022*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2023*5d535f58SDavid du Colombiermust therefore synchronize between
2024*5d535f58SDavid du Colombiercalls of
2025*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
2026*5d535f58SDavid du Colombierto avoid
2027*5d535f58SDavid du Colombierproblems with null matches.
2028*5d535f58SDavid du ColombierFor example, even given the leftmost-longest rule,
2029*5d535f58SDavid du Colombierthe expression
2030*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>a*</tt></span><span style="font-size: 10pt">
2031*5d535f58SDavid du Colombiermatches three times in the string
2032*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ab</tt></span><span style="font-size: 10pt">
2033*5d535f58SDavid du Colombier(the character
2034*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">,
2035*5d535f58SDavid du Colombierthe null string between the
2036*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">
2037*5d535f58SDavid du Colombierand
2038*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>b</tt></span><span style="font-size: 10pt">,
2039*5d535f58SDavid du Colombierand the final null string).
2040*5d535f58SDavid du ColombierAfter returning a match for the
2041*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>a</tt></span><span style="font-size: 10pt">,
2042*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2043*5d535f58SDavid du Colombiermust not match the null string before the
2044*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>b</tt></span><span style="font-size: 10pt">.
2045*5d535f58SDavid du ColombierThe algorithm starts
2046*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>execute</tt></span><span style="font-size: 10pt">
2047*5d535f58SDavid du Colombierat the end of its previous match, and
2048*5d535f58SDavid du Colombierif the match it returns
2049*5d535f58SDavid du Colombieris null and abuts the previous match, rejects the match and advances
2050*5d535f58SDavid du Colombierthe initial position one character.
2051*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2052*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2053*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Memory allocation
2054*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2055*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2056*5d535f58SDavid du Colombier<span style="font-size: 10pt">The C language has no memory allocation primitives, although a standard
2057*5d535f58SDavid du Colombierlibrary routine,
2058*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>malloc</tt></span><span style="font-size: 10pt">,
2059*5d535f58SDavid du Colombierprovides adequate service for simple programs.
2060*5d535f58SDavid du ColombierFor specific uses, however,
2061*5d535f58SDavid du Colombierit can be better to write a custom allocator.
2062*5d535f58SDavid du ColombierThe allocator (or rather, pair of allocators) described here
2063*5d535f58SDavid du Colombierwork in both the terminal and host parts of
2064*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
2065*5d535f58SDavid du ColombierThey are designed for efficient manipulation of strings,
2066*5d535f58SDavid du Colombierwhich are allocated and freed frequently and vary in length from essentially
2067*5d535f58SDavid du Colombierzero to 32 Kbytes (very large strings are written to disc).
2068*5d535f58SDavid du ColombierMore important, strings may be large and change size often,
2069*5d535f58SDavid du Colombierso to minimize memory usage it is helpful to reclaim and to coalesce the
2070*5d535f58SDavid du Colombierunused portions of strings when they are truncated.
2071*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2072*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2073*5d535f58SDavid du Colombier<span style="font-size: 10pt">Objects to be allocated in
2074*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2075*5d535f58SDavid du Colombierare of two flavors:
2076*5d535f58SDavid du Colombierthe first is C
2077*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>structs</tt></span><span style="font-size: 10pt">,
2078*5d535f58SDavid du Colombierwhich are small and often addressed by pointer variables;
2079*5d535f58SDavid du Colombierthe second is variable-sized arrays of characters
2080*5d535f58SDavid du Colombieror integers whose
2081*5d535f58SDavid du Colombierbase pointer is always used to access them.
2082*5d535f58SDavid du ColombierThe memory allocator in
2083*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2084*5d535f58SDavid du Colombieris therefore in two parts:
2085*5d535f58SDavid du Colombierfirst, a traditional first-fit allocator that provides fixed storage for
2086*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>structs</tt></span><span style="font-size: 10pt">;
2087*5d535f58SDavid du Colombierand second, a garbage-compacting allocator that reduces storage
2088*5d535f58SDavid du Colombieroverhead for variable-sized objects, at the cost of some bookkeeping.
2089*5d535f58SDavid du ColombierThe two types of objects are allocated from adjoining arenas, with
2090*5d535f58SDavid du Colombierthe garbage-compacting allocator controlling the arena with higher addresses.
2091*5d535f58SDavid du ColombierSeparating into two arenas simplifies compaction and prevents fragmentation due
2092*5d535f58SDavid du Colombierto immovable objects.
2093*5d535f58SDavid du ColombierThe access rules for garbage-compactable objects
2094*5d535f58SDavid du Colombier(discussed in the next paragraph) allow them to be relocated, so when
2095*5d535f58SDavid du Colombierthe first-fit arena needs space, it moves the garbage-compacted arena
2096*5d535f58SDavid du Colombierto higher addresses to make room.  Storage is therefore created only
2097*5d535f58SDavid du Colombierat successively higher addresses, either when more garbage-compacted
2098*5d535f58SDavid du Colombierspace is needed or when the first-fit arena pushes up the other arena.
2099*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2100*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2101*5d535f58SDavid du Colombier<span style="font-size: 10pt">Objects that may be compacted declare to the
2102*5d535f58SDavid du Colombierallocator a cell that is guaranteed to be the sole repository of the
2103*5d535f58SDavid du Colombieraddress of the object whenever a compaction can occur.
2104*5d535f58SDavid du ColombierThe compactor can then update the address when the object is moved.
2105*5d535f58SDavid du ColombierFor example, the implementation of type
2106*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
2107*5d535f58SDavid du Colombier(really a variable-length array)
2108*5d535f58SDavid du Colombieris:
2109*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
2110*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2111*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>typedef struct List{</tt></span></p>
2112*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2113*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        int     nused;</tt></span></p>
2114*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2115*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>        long    *ptr;</tt></span></p>
2116*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2117*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>}List;</tt></span></p>
2118*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
2119*5d535f58SDavid du Colombier
2120*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
2121*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2122*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2123*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ptr</tt></span><span style="font-size: 10pt">
2124*5d535f58SDavid du Colombiercell must always be used directly, and never copied.  When a
2125*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
2126*5d535f58SDavid du Colombieris to be created the
2127*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">
2128*5d535f58SDavid du Colombierstructure is allocated in the ordinary first-fit arena
2129*5d535f58SDavid du Colombierand its
2130*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ptr</tt></span><span style="font-size: 10pt">
2131*5d535f58SDavid du Colombieris allocated in the garbage-compacted arena.
2132*5d535f58SDavid du ColombierA similar data type for strings, called
2133*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">,
2134*5d535f58SDavid du Colombierstores variable-length character arrays of up to 32767 elements.
2135*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2136*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2137*5d535f58SDavid du Colombier<span style="font-size: 10pt">A related matter of programming style:
2138*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2139*5d535f58SDavid du Colombierfrequently passes structures by value, which
2140*5d535f58SDavid du Colombiersimplifies the code.
2141*5d535f58SDavid du ColombierTraditionally, C programs have
2142*5d535f58SDavid du Colombierpassed structures by reference, but implicit allocation on
2143*5d535f58SDavid du Colombierthe stack is easier to use.
2144*5d535f58SDavid du ColombierStructure passing is a relatively new feature of C
2145*5d535f58SDavid du Colombier(it is not in the
2146*5d535f58SDavid du Colombierstandard reference manual for C<sup></sup></span><sup><span style="font-size: 6pt">14</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">), and is poorly supported in most
2147*5d535f58SDavid du Colombiercommercial C compilers.
2148*5d535f58SDavid du ColombierIt&rsquo;s convenient and expressive, though,
2149*5d535f58SDavid du Colombierand simplifies memory management by
2150*5d535f58SDavid du Colombieravoiding the allocator altogether
2151*5d535f58SDavid du Colombierand eliminating pointer aliases.
2152*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2153*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2154*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Data structures for manipulating files
2155*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2156*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2157*5d535f58SDavid du Colombier<span style="font-size: 10pt">Experience with
2158*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
2159*5d535f58SDavid du Colombiershowed that the requirements
2160*5d535f58SDavid du Colombierof the file data structure were few, but strict.
2161*5d535f58SDavid du ColombierFirst, files need to be read and written quickly;
2162*5d535f58SDavid du Colombieradding a fresh file must be painless.
2163*5d535f58SDavid du ColombierSecond, the implementation must place no arbitrary upper limit on
2164*5d535f58SDavid du Colombierthe number or sizes of files.  (It should be practical to edit many files,
2165*5d535f58SDavid du Colombierand files up to megabytes in length should be handled gracefully.)
2166*5d535f58SDavid du ColombierThis implies that files be stored on disc, not in main memory.
2167*5d535f58SDavid du Colombier(Aficionados of virtual memory may argue otherwise, but the
2168*5d535f58SDavid du Colombierimplementation of virtual
2169*5d535f58SDavid du Colombiermemory in our system is not something to depend on
2170*5d535f58SDavid du Colombierfor good performance.)
2171*5d535f58SDavid du ColombierThird, changes to files need be made by only two primitives:
2172*5d535f58SDavid du Colombierdeletion and insertion.
2173*5d535f58SDavid du ColombierThese are inverses of each other,
2174*5d535f58SDavid du Colombierwhich simplifies the implementation of the undo operation.
2175*5d535f58SDavid du ColombierFinally,
2176*5d535f58SDavid du Colombierit must be easy and efficient to access the file, either
2177*5d535f58SDavid du Colombierforwards or backwards, a byte at a time.
2178*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2179*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2180*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2181*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2182*5d535f58SDavid du Colombierdata type is constructed from three simpler data structures that hold arrays
2183*5d535f58SDavid du Colombierof characters.
2184*5d535f58SDavid du ColombierEach of these types has an insertion and deletion operator, and the
2185*5d535f58SDavid du Colombierinsertion and deletion operators of the
2186*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2187*5d535f58SDavid du Colombiertype itself are constructed from them.
2188*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2189*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2190*5d535f58SDavid du Colombier<span style="font-size: 10pt">The simplest type is the
2191*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">,
2192*5d535f58SDavid du Colombierwhich is used to hold strings in main memory.
2193*5d535f58SDavid du ColombierThe code that manages
2194*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
2195*5d535f58SDavid du Colombierguarantees that they will never be longer
2196*5d535f58SDavid du Colombierthan some moderate size, and in practice they are rarely larger than 8 Kbytes.
2197*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
2198*5d535f58SDavid du Colombierhave two purposes: they hold short strings like file names with little overhead,
2199*5d535f58SDavid du Colombierand because they are deliberately small, they are efficient to modify.
2200*5d535f58SDavid du ColombierThey are therefore used as the data structure for in-memory caches.
2201*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2202*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2203*5d535f58SDavid du Colombier<span style="font-size: 10pt">The disc copy of the file is managed by a data structure called a
2204*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">,
2205*5d535f58SDavid du Colombierwhich corresponds to a temporary file.  A
2206*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2207*5d535f58SDavid du Colombierhas no storage in main memory other than bookkeeping information;
2208*5d535f58SDavid du Colombierthe actual data being held is all on the disc.
2209*5d535f58SDavid du ColombierTo reduce the number of open files needed,
2210*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2211*5d535f58SDavid du Colombieropens a dozen temporary UNIX files and multiplexes the
2212*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Discs</tt></span><span style="font-size: 10pt">
2213*5d535f58SDavid du Colombierupon them.
2214*5d535f58SDavid du ColombierThis permits many files to
2215*5d535f58SDavid du Colombierbe edited; the entire
2216*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2217*5d535f58SDavid du Colombiersource (48 files) may be edited comfortably with a single
2218*5d535f58SDavid du Colombierinstance of
2219*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
2220*5d535f58SDavid du ColombierAllocating one temporary file per
2221*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2222*5d535f58SDavid du Colombierwould strain the operating system&rsquo;s limit on the number of open files.
2223*5d535f58SDavid du ColombierAlso, spreading the traffic among temporary files keeps the files shorter,
2224*5d535f58SDavid du Colombierand shorter files are more efficiently implemented by the UNIX
2225*5d535f58SDavid du ColombierI/O subsystem.
2226*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2227*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2228*5d535f58SDavid du Colombier<span style="font-size: 10pt">A
2229*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2230*5d535f58SDavid du Colombieris an array of fixed-length blocks, each of which contains
2231*5d535f58SDavid du Colombierbetween 1 and 4096 characters of active data.
2232*5d535f58SDavid du Colombier(The block size of our UNIX file system is 4096 bytes.)
2233*5d535f58SDavid du ColombierThe block addresses within the temporary file and the length of each
2234*5d535f58SDavid du Colombierblock are stored in a
2235*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>List</tt></span><span style="font-size: 10pt">.
2236*5d535f58SDavid du ColombierWhen changes are made the live part of blocks may change size.
2237*5d535f58SDavid du ColombierBlocks are created and coalesced when necessary to try to keep the sizes
2238*5d535f58SDavid du Colombierbetween 2048 and 4096 bytes.
2239*5d535f58SDavid du ColombierAn actively changing part of the
2240*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2241*5d535f58SDavid du Colombiertherefore typically has about a kilobyte of slop that can be
2242*5d535f58SDavid du Colombierinserted or deleted
2243*5d535f58SDavid du Colombierwithout changing more than one block or affecting the block order.
2244*5d535f58SDavid du ColombierWhen an insertion would overflow a block, the block is split, a new one
2245*5d535f58SDavid du Colombieris allocated to receive the overflow, and the memory-resident list of blocks
2246*5d535f58SDavid du Colombieris rearranged to reflect the insertion of the new block.
2247*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2248*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2249*5d535f58SDavid du Colombier<span style="font-size: 10pt">Obviously, going to the disc for every modification to the file is
2250*5d535f58SDavid du Colombierprohibitively expensive.
2251*5d535f58SDavid du ColombierThe data type
2252*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
2253*5d535f58SDavid du Colombierconsists of a
2254*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2255*5d535f58SDavid du Colombierto hold the data and a
2256*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">
2257*5d535f58SDavid du Colombierthat acts as a cache.
2258*5d535f58SDavid du ColombierThis is the first of a series of caches throughout the data structures in
2259*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam.</tt></span><span style="font-size: 10pt">
2260*5d535f58SDavid du ColombierThe caches not only improve performance, they provide a way to organize
2261*5d535f58SDavid du Colombierthe flow of data, particularly in the communication between the host
2262*5d535f58SDavid du Colombierand terminal.
2263*5d535f58SDavid du ColombierThis idea is developed below, in the section on communications.
2264*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2265*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2266*5d535f58SDavid du Colombier<span style="font-size: 10pt">To reduce disc traffic, changes to a
2267*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
2268*5d535f58SDavid du Colombierare mediated by a variable-length string, in memory, that acts as a cache.
2269*5d535f58SDavid du ColombierWhen an insertion or deletion is made to a
2270*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
2271*5d535f58SDavid du Colombierif the change can be accommodated by the cache, it is done there.
2272*5d535f58SDavid du ColombierIf the cache becomes bigger than a block because of an insertion,
2273*5d535f58SDavid du Colombiersome of it is written to the
2274*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2275*5d535f58SDavid du Colombierand deleted from the cache.
2276*5d535f58SDavid du ColombierIf the change does not intersect the cache, the cache is flushed.
2277*5d535f58SDavid du ColombierThe cache is only loaded at the new position if the change is smaller than a block;
2278*5d535f58SDavid du Colombierotherwise, it is sent directly to the
2279*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">.
2280*5d535f58SDavid du ColombierThis is because
2281*5d535f58SDavid du Colombierlarge changes are typically sequential,
2282*5d535f58SDavid du Colombierwhereupon the next change is unlikely to overlap the current one.
2283*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2284*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2285*5d535f58SDavid du Colombier<span style="font-size: 10pt">A
2286*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2287*5d535f58SDavid du Colombiercomprises a
2288*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>String</tt></span><span style="font-size: 10pt">
2289*5d535f58SDavid du Colombierto hold the file name and some ancillary data such as dot and the modified bit.
2290*5d535f58SDavid du ColombierThe most important components, though, are a pair of
2291*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffers</tt></span><span style="font-size: 10pt">,
2292*5d535f58SDavid du Colombierone called the transcript and the other the contents.
2293*5d535f58SDavid du ColombierTheir use is described in the next section.
2294*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2295*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2296*5d535f58SDavid du Colombier<span style="font-size: 10pt">The overall structure is shown in Figure 5.
2297*5d535f58SDavid du ColombierAlthough it may seem that the data is touched many times on its
2298*5d535f58SDavid du Colombierway from the
2299*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">,
2300*5d535f58SDavid du Colombierit is read (by one UNIX system call) directly into the cache of the
2301*5d535f58SDavid du Colombierassociated
2302*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">;
2303*5d535f58SDavid du Colombierno extra copy is done.
2304*5d535f58SDavid du ColombierSimilarly, when flushing the cache, the text is written
2305*5d535f58SDavid du Colombierdirectly from the cache to disc.
2306*5d535f58SDavid du ColombierMost operations act directly on the text in the cache.
2307*5d535f58SDavid du ColombierA principle applied throughout
2308*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2309*5d535f58SDavid du Colombieris that the fewer times the data is copied, the faster the program will run
2310*5d535f58SDavid du Colombier(see also the paper by Waite<sup></sup></span><sup><span style="font-size: 6pt">15</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">).
2311*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="sam2.png"></center>
2312*5d535f58SDavid du Colombier</center>
2313*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2314*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 5. File data structures.
2315*5d535f58SDavid du ColombierThe temporary files are stored in the standard repository for such files
2316*5d535f58SDavid du Colombieron the host system.
2317*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2318*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
2319*5d535f58SDavid du Colombier
2320*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
2321*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2322*5d535f58SDavid du Colombier<span style="font-size: 10pt">The contents of a
2323*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2324*5d535f58SDavid du Colombierare accessed by a routine that
2325*5d535f58SDavid du Colombiercopies to a buffer a substring of a file starting at a specified offset.
2326*5d535f58SDavid du ColombierTo read a byte at a time, a
2327*5d535f58SDavid du Colombierper-</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2328*5d535f58SDavid du Colombierarray is loaded starting from a specified initial position,
2329*5d535f58SDavid du Colombierand bytes may then be read from the array.
2330*5d535f58SDavid du ColombierThe implementation is done by a macro similar to the C standard I/O
2331*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>getc</tt></span><span style="font-size: 10pt">
2332*5d535f58SDavid du Colombiermacro.<sup></sup></span><sup><span style="font-size: 6pt">14</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2333*5d535f58SDavid du ColombierBecause the reading may be done at any address, a minor change to the
2334*5d535f58SDavid du Colombiermacro allows the file to be read backwards.
2335*5d535f58SDavid du ColombierThis array is read-only; there is no
2336*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>putc</tt></span><span style="font-size: 10pt">.
2337*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2338*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2339*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Doing and undoing
2340*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2341*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2342*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2343*5d535f58SDavid du Colombierhas an unusual method for managing changes to files.
2344*5d535f58SDavid du ColombierThe command language makes it easy to specify multiple variable-length changes
2345*5d535f58SDavid du Colombierto a file millions of bytes long, and such changes
2346*5d535f58SDavid du Colombiermust be made efficiently if the editor is to be practical.
2347*5d535f58SDavid du ColombierThe usual techniques for inserting and deleting strings
2348*5d535f58SDavid du Colombierare inadequate under these conditions.
2349*5d535f58SDavid du ColombierThe
2350*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
2351*5d535f58SDavid du Colombierand
2352*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
2353*5d535f58SDavid du Colombierdata structures are designed for efficient random access to long strings,
2354*5d535f58SDavid du Colombierbut care must be taken to avoid super-linear behavior when making
2355*5d535f58SDavid du Colombiermany changes simultaneously.
2356*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2357*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2358*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2359*5d535f58SDavid du Colombieruses a two-pass algorithm for making changes, and treats each file as a database
2360*5d535f58SDavid du Colombieragainst which transactions are registered.
2361*5d535f58SDavid du ColombierChanges are not made directly to the contents.
2362*5d535f58SDavid du ColombierInstead, when a command is started, a &lsquo;mark&rsquo; containing
2363*5d535f58SDavid du Colombiera sequence number is placed in the transcript
2364*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
2365*5d535f58SDavid du Colombierand each change made to the file, either an insertion or deletion
2366*5d535f58SDavid du Colombieror a change to the file name,
2367*5d535f58SDavid du Colombieris appended to the end of the transcript.
2368*5d535f58SDavid du ColombierWhen the command is complete, the transcript is rewound to the
2369*5d535f58SDavid du Colombiermark and applied to the contents.
2370*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2371*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2372*5d535f58SDavid du Colombier<span style="font-size: 10pt">One reason for separating evaluation from
2373*5d535f58SDavid du Colombierapplication in this way is to simplify tracking the addresses of changes
2374*5d535f58SDavid du Colombiermade in the middle of a long sequence.
2375*5d535f58SDavid du ColombierThe two-pass algorithm also allows all changes to apply to the
2376*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>original</i></span><span style="font-size: 10pt">
2377*5d535f58SDavid du Colombierdata: no change can affect another change made in the same command.
2378*5d535f58SDavid du ColombierThis is particularly important when evaluating an
2379*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
2380*5d535f58SDavid du Colombiercommand because it prevents regular expression matches
2381*5d535f58SDavid du Colombierfrom stumbling over changes made earlier in the execution.
2382*5d535f58SDavid du ColombierAlso, the two-pass
2383*5d535f58SDavid du Colombieralgorithm is cleaner than the way other UNIX editors allow changes to
2384*5d535f58SDavid du Colombieraffect each other;
2385*5d535f58SDavid du Colombierfor example,
2386*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s
2387*5d535f58SDavid du Colombieridioms to do things like delete every other line
2388*5d535f58SDavid du Colombierdepend critically on the implementation.
2389*5d535f58SDavid du ColombierInstead,
2390*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
2391*5d535f58SDavid du Colombiersimple model, in which all changes in a command occur effectively
2392*5d535f58SDavid du Colombiersimultaneously, is easy to explain and to understand.
2393*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2394*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2395*5d535f58SDavid du Colombier<span style="font-size: 10pt">The records in the transcript are of the form &lsquo;&lsquo;delete substring from
2396*5d535f58SDavid du Colombierlocations
2397*5d535f58SDavid du Colombier123 to 456&rsquo;&rsquo; and &lsquo;&lsquo;insert 11 characters &lsquo;hello there&rsquo; at location 789.&rsquo;&rsquo;
2398*5d535f58SDavid du Colombier(It is an error if the changes are not at monotonically greater
2399*5d535f58SDavid du Colombierpositions through the file.)
2400*5d535f58SDavid du ColombierWhile the update is occurring, these numbers must be
2401*5d535f58SDavid du Colombieroffset by earlier changes, but that is straightforward and
2402*5d535f58SDavid du Colombierlocal to the update routine;
2403*5d535f58SDavid du Colombiermoreover, all the numbers have been computed
2404*5d535f58SDavid du Colombierbefore the first is examined.
2405*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2406*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2407*5d535f58SDavid du Colombier<span style="font-size: 10pt">Treating the file as a transaction system has another advantage:
2408*5d535f58SDavid du Colombierundo is trivial.
2409*5d535f58SDavid du ColombierAll it takes is to invert the transcript after it has been
2410*5d535f58SDavid du Colombierimplemented, converting insertions
2411*5d535f58SDavid du Colombierinto deletions and vice versa, and saving them in a holding
2412*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">.
2413*5d535f58SDavid du ColombierThe &lsquo;do&rsquo; transcript can then be deleted from
2414*5d535f58SDavid du Colombierthe transcript
2415*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
2416*5d535f58SDavid du Colombierand replaced by the &lsquo;undo&rsquo; transcript.
2417*5d535f58SDavid du ColombierIf an undo is requested, the transcript is rewound and the undo transcript
2418*5d535f58SDavid du Colombierexecuted.
2419*5d535f58SDavid du ColombierBecause the transcript
2420*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">
2421*5d535f58SDavid du Colombieris not truncated after each command, it accumulates
2422*5d535f58SDavid du Colombiersuccessive changes.
2423*5d535f58SDavid du ColombierA sequence of undo commands
2424*5d535f58SDavid du Colombiercan therefore back up the file arbitrarily,
2425*5d535f58SDavid du Colombierwhich is more helpful than the more commonly implemented self-inverse form of undo.
2426*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2427*5d535f58SDavid du Colombierprovides no way to undo an undo, but if it were desired,
2428*5d535f58SDavid du Colombierit would be easy to provide by re-interpreting the &lsquo;do&rsquo; transcript.)
2429*5d535f58SDavid du ColombierEach mark in the transcript contains a sequence number and the offset into
2430*5d535f58SDavid du Colombierthe transcript of the previous mark, to aid in unwinding the transcript.
2431*5d535f58SDavid du ColombierMarks also contain the value of dot and the modified bit so these can be
2432*5d535f58SDavid du Colombierrestored easily.
2433*5d535f58SDavid du ColombierUndoing multiple files is easy; it merely demands undoing all files whose
2434*5d535f58SDavid du Colombierlatest change has the same sequence number as the current file.
2435*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2436*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2437*5d535f58SDavid du Colombier<span style="font-size: 10pt">Another benefit of having a transcript is that errors encountered in the middle
2438*5d535f58SDavid du Colombierof a complicated command need not leave the files in an intermediate state.
2439*5d535f58SDavid du ColombierBy rewinding the transcript to the mark beginning the command,
2440*5d535f58SDavid du Colombierthe partial command can be trivially undone.
2441*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2442*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2443*5d535f58SDavid du Colombier<span style="font-size: 10pt">When the update algorithm was first implemented, it was unacceptably slow,
2444*5d535f58SDavid du Colombierso a cache was added to coalesce nearby changes,
2445*5d535f58SDavid du Colombierreplacing multiple small changes by a single larger one.
2446*5d535f58SDavid du ColombierThis reduced the number
2447*5d535f58SDavid du Colombierof insertions into the transaction
2448*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
2449*5d535f58SDavid du Colombierand made a dramatic improvement in performance,
2450*5d535f58SDavid du Colombierbut made it impossible
2451*5d535f58SDavid du Colombierto handle changes in non-monotonic order in the file; the caching method
2452*5d535f58SDavid du Colombieronly works if changes don&rsquo;t overlap.
2453*5d535f58SDavid du ColombierBefore the cache was added, the transaction could in principle be sorted
2454*5d535f58SDavid du Colombierif the changes were out of order, although
2455*5d535f58SDavid du Colombierthis was never done.
2456*5d535f58SDavid du ColombierThe current status is therefore acceptable performance with a minor
2457*5d535f58SDavid du Colombierrestriction on global changes, which is sometimes, but rarely, an annoyance.
2458*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2459*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2460*5d535f58SDavid du Colombier<span style="font-size: 10pt">The update algorithm obviously paws the data more than simpler
2461*5d535f58SDavid du Colombieralgorithms, but it is not prohibitively expensive;
2462*5d535f58SDavid du Colombierthe caches help.
2463*5d535f58SDavid du Colombier(The principle of avoiding copying the data is still honored here,
2464*5d535f58SDavid du Colombieralthough not as piously:
2465*5d535f58SDavid du Colombierthe data is moved from contents&rsquo; cache to
2466*5d535f58SDavid du Colombierthe transcript&rsquo;s all at once and through only one internal buffer.)
2467*5d535f58SDavid du ColombierPerformance figures confirm the efficiency.
2468*5d535f58SDavid du ColombierTo read from a dead start a hundred kilobyte file on a VAX-11/750
2469*5d535f58SDavid du Colombiertakes 1.4 seconds of user time, 2.5 seconds of system time,
2470*5d535f58SDavid du Colombierand 5 seconds of real time.
2471*5d535f58SDavid du ColombierReading the same file in
2472*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
2473*5d535f58SDavid du Colombiertakes 6.0 seconds of user time, 1.7 seconds of system time,
2474*5d535f58SDavid du Colombierand 8 seconds of real time.
2475*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2476*5d535f58SDavid du Colombieruses about half the CPU time.
2477*5d535f58SDavid du ColombierA more interesting example is the one stated above:
2478*5d535f58SDavid du Colombierinserting a character between every pair of characters in the file.
2479*5d535f58SDavid du ColombierThe
2480*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2481*5d535f58SDavid du Colombiercommand is
2482*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
2483*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2484*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>,y/@/ a/x/</tt></span></p>
2485*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
2486*5d535f58SDavid du Colombier
2487*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
2488*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2489*5d535f58SDavid du Colombier<span style="font-size: 10pt">and takes 3 CPU seconds per kilobyte of input file, of which
2490*5d535f58SDavid du Colombierabout a third is spent in the regular expression code.
2491*5d535f58SDavid du ColombierThis translates to about 500 changes per second.
2492*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Ed</tt></span><span style="font-size: 10pt">
2493*5d535f58SDavid du Colombiertakes 1.5 seconds per kilobyte to make a similar change (ignoring newlines),
2494*5d535f58SDavid du Colombierbut cannot undo it.
2495*5d535f58SDavid du ColombierThe same example in
2496*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ex</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">9</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2497*5d535f58SDavid du Colombiera variant of
2498*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
2499*5d535f58SDavid du Colombierdone at the University of California at Berkeley,
2500*5d535f58SDavid du Colombierwhich allows one level of undoing, again takes 3 seconds.
2501*5d535f58SDavid du ColombierIn summary,
2502*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
2503*5d535f58SDavid du Colombierperformance is comparable to that of other UNIX editors, although it solves
2504*5d535f58SDavid du Colombiera harder problem.
2505*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2506*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2507*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Communications
2508*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2509*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2510*5d535f58SDavid du Colombier<span style="font-size: 10pt">The discussion so far has described the implementation of the host part of
2511*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">;
2512*5d535f58SDavid du Colombierthe next few sections explain how a machine with mouse and bitmap display
2513*5d535f58SDavid du Colombiercan be engaged to improve interaction.
2514*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2515*5d535f58SDavid du Colombieris not the first editor to be written as two processes,<sup></sup></span><sup><span style="font-size: 6pt">16</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2516*5d535f58SDavid du Colombierbut its implementation
2517*5d535f58SDavid du Colombierhas some unusual aspects.
2518*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2519*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2520*5d535f58SDavid du Colombier<span style="font-size: 10pt">There are several ways
2521*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
2522*5d535f58SDavid du Colombierhost and terminal parts may be connected.
2523*5d535f58SDavid du ColombierThe first and simplest is to forgo the terminal part and use the host
2524*5d535f58SDavid du Colombierpart&rsquo;s command language to edit text on an ordinary terminal.
2525*5d535f58SDavid du ColombierThis mode is invoked by starting
2526*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2527*5d535f58SDavid du Colombierwith the
2528*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
2529*5d535f58SDavid du Colombieroption.
2530*5d535f58SDavid du ColombierWith no options,
2531*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2532*5d535f58SDavid du Colombierruns separate host and terminal programs,
2533*5d535f58SDavid du Colombiercommunicating with a message protocol over the physical
2534*5d535f58SDavid du Colombierconnection that joins them.
2535*5d535f58SDavid du ColombierTypically, the connection is an RS-232 link between a Blit
2536*5d535f58SDavid du Colombier(the prototypical display for
2537*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">)
2538*5d535f58SDavid du Colombierand a host running
2539*5d535f58SDavid du Colombierthe Ninth Edition of the UNIX operating system.<sup></sup></span><sup><span style="font-size: 6pt">8</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2540*5d535f58SDavid du Colombier(This is the version of the system used in the Computing Sciences Research
2541*5d535f58SDavid du ColombierCenter at AT&amp;T Bell Laboratories [now Lucent Technologies, Bell Labs], where I work.  Its relevant
2542*5d535f58SDavid du Colombieraspects are discussed in the Blit paper.<sup></sup></span><sup><span style="font-size: 6pt">1</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">)
2543*5d535f58SDavid du ColombierThe implementation of
2544*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2545*5d535f58SDavid du Colombierfor the SUN computer runs both processes on the same machine and
2546*5d535f58SDavid du Colombierconnects them by a pipe.
2547*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2548*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2549*5d535f58SDavid du Colombier<span style="font-size: 10pt">The low bandwidth of an RS-232 link
2550*5d535f58SDavid du Colombiernecessitated the split between
2551*5d535f58SDavid du Colombierthe two programs.
2552*5d535f58SDavid du ColombierThe division is a mixed blessing:
2553*5d535f58SDavid du Colombiera program in two parts is much harder to write and to debug
2554*5d535f58SDavid du Colombierthan a self-contained one,
2555*5d535f58SDavid du Colombierbut the split makes several unusual configurations possible.
2556*5d535f58SDavid du ColombierThe terminal may be physically separated from the host, allowing the conveniences
2557*5d535f58SDavid du Colombierof a mouse and bitmap display to be taken home while leaving the files at work.
2558*5d535f58SDavid du ColombierIt is also possible to run the host part on a remote machine:
2559*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
2560*5d535f58SDavid du Colombier<p style="line-height: 1.1em; margin-left: 1.28in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2561*5d535f58SDavid du Colombier<span style="font-size: 9pt"><tt>sam -r host</tt></span></p>
2562*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
2563*5d535f58SDavid du Colombier
2564*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
2565*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2566*5d535f58SDavid du Colombier<span style="font-size: 10pt">connects to the terminal in the usual way, and then makes a call
2567*5d535f58SDavid du Colombieracross the network to establish the host part of
2568*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2569*5d535f58SDavid du Colombieron the named machine.
2570*5d535f58SDavid du ColombierFinally, it cross-connects the I/O to join the two parts.
2571*5d535f58SDavid du ColombierThis allows
2572*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2573*5d535f58SDavid du Colombierto be run on machines that do not support bitmap displays;
2574*5d535f58SDavid du Colombierfor example,
2575*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2576*5d535f58SDavid du Colombieris the editor of choice on our Cray X-MP/24.
2577*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2578*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-r</tt></span><span style="font-size: 10pt">
2579*5d535f58SDavid du Colombierinvolves
2580*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>three</i></span><span style="font-size: 10pt">
2581*5d535f58SDavid du Colombiermachines: the remote host, the terminal, and the local host.
2582*5d535f58SDavid du ColombierThe local host&rsquo;s job is simple but vital: it passes the data
2583*5d535f58SDavid du Colombierbetween the remote host and terminal.
2584*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2585*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2586*5d535f58SDavid du Colombier<span style="font-size: 10pt">The host and terminal exchange messages asynchronously
2587*5d535f58SDavid du Colombier(rather than, say, as remote procedure calls) but there is no
2588*5d535f58SDavid du Colombiererror detection or correction
2589*5d535f58SDavid du Colombierbecause, whatever the configuration, the connection is reliable.
2590*5d535f58SDavid du ColombierBecause the terminal handles mundane interaction tasks such as
2591*5d535f58SDavid du Colombierpopping up menus and interpreting the responses, the messages are about
2592*5d535f58SDavid du Colombierdata, not actions.
2593*5d535f58SDavid du ColombierFor example, the host knows nothing about what is displayed on the screen,
2594*5d535f58SDavid du Colombierand when the user types a character, the message sent to the host says
2595*5d535f58SDavid du Colombier&lsquo;&lsquo;insert a one-byte string at location 123 in file 7,&rsquo;&rsquo; not &lsquo;&lsquo;a character
2596*5d535f58SDavid du Colombierwas typed at the current position in the current file.&rsquo;&rsquo;
2597*5d535f58SDavid du ColombierIn other words, the messages look very much like the transaction records
2598*5d535f58SDavid du Colombierin the transcripts.
2599*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2600*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2601*5d535f58SDavid du Colombier<span style="font-size: 10pt">Either the host or terminal part of
2602*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2603*5d535f58SDavid du Colombiermay initiate a change to a file.
2604*5d535f58SDavid du ColombierThe command language operates on the host, while typing and some
2605*5d535f58SDavid du Colombiermouse operations are executed directly in the terminal to optimize response.
2606*5d535f58SDavid du ColombierChanges initiated by the host program must be transmitted to the terminal,
2607*5d535f58SDavid du Colombierand
2608*5d535f58SDavid du Colombiervice versa.
2609*5d535f58SDavid du Colombier(A token is exchanged to determine which end is in control,
2610*5d535f58SDavid du Colombierwhich means that characters typed while a time-consuming command runs
2611*5d535f58SDavid du Colombiermust be buffered and do not appear until the command is complete.)
2612*5d535f58SDavid du ColombierTo maintain consistent information,
2613*5d535f58SDavid du Colombierthe host and terminal track changes through a per-file
2614*5d535f58SDavid du Colombierdata structure that records what portions of the file
2615*5d535f58SDavid du Colombierthe terminal has received.
2616*5d535f58SDavid du ColombierThe data structure, called a
2617*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2618*5d535f58SDavid du Colombier(a weak pun: it&rsquo;s a file with holes)
2619*5d535f58SDavid du Colombieris held and updated by both the host and terminal.
2620*5d535f58SDavid du ColombierA
2621*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2622*5d535f58SDavid du Colombieris a list of
2623*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Strings</tt></span><span style="font-size: 10pt">
2624*5d535f58SDavid du Colombierholding those parts of the file known to the terminal,
2625*5d535f58SDavid du Colombierseparated by counts of the number of bytes in the interstices.
2626*5d535f58SDavid du ColombierOf course, the host doesn&rsquo;t keep a separate copy of the data (it only needs
2627*5d535f58SDavid du Colombierthe lengths of the various pieces),
2628*5d535f58SDavid du Colombierbut the structure is the same on both ends.
2629*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2630*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2631*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2632*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2633*5d535f58SDavid du Colombierin the terminal doubles as a cache.
2634*5d535f58SDavid du ColombierSince the terminal keeps the text for portions of the file it has displayed,
2635*5d535f58SDavid du Colombierit need not request data from the host when revisiting old parts of the file
2636*5d535f58SDavid du Colombieror redrawing obscured windows, which speeds things up considerably
2637*5d535f58SDavid du Colombierover low-speed links.
2638*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2639*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2640*5d535f58SDavid du Colombier<span style="font-size: 10pt">It&rsquo;s trivial for the terminal to maintain its
2641*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">,
2642*5d535f58SDavid du Colombierbecause all changes made on the terminal apply to parts of the file
2643*5d535f58SDavid du Colombieralready loaded there.
2644*5d535f58SDavid du ColombierChanges made by the host are compared against the
2645*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2646*5d535f58SDavid du Colombierduring the update sequence after each command.
2647*5d535f58SDavid du ColombierSmall changes to pieces of the file loaded in the terminal
2648*5d535f58SDavid du Colombierare sent in their entirety.
2649*5d535f58SDavid du ColombierLarger changes, and changes that fall entirely in the holes,
2650*5d535f58SDavid du Colombierare transmitted as messages without literal data:
2651*5d535f58SDavid du Colombieronly the lengths of the deleted and inserted strings are transmitted.
2652*5d535f58SDavid du ColombierWhen a command is completed, the terminal examines its visible
2653*5d535f58SDavid du Colombierwindows to see if any holes in their
2654*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasps</tt></span><span style="font-size: 10pt">
2655*5d535f58SDavid du Colombierintersect the visible portion of the file.
2656*5d535f58SDavid du ColombierIt then requests the missing data from the host,
2657*5d535f58SDavid du Colombieralong with up to 512 bytes of surrounding data, to minimize
2658*5d535f58SDavid du Colombierthe number of messages when visiting a new portion of the file.
2659*5d535f58SDavid du ColombierThis technique provides a kind of two-level lazy evaluation for the terminal.
2660*5d535f58SDavid du ColombierThe first level sends a minimum of information about
2661*5d535f58SDavid du Colombierparts of the file not being edited interactively;
2662*5d535f58SDavid du Colombierthe second level waits until a change is displayed before
2663*5d535f58SDavid du Colombiertransmitting the new data.
2664*5d535f58SDavid du ColombierOf course,
2665*5d535f58SDavid du Colombierperformance is also helped by having the terminal respond immediately to typing
2666*5d535f58SDavid du Colombierand simple mouse requests.
2667*5d535f58SDavid du ColombierExcept for small changes to active pieces of the file, which are
2668*5d535f58SDavid du Colombiertransmitted to the terminal without negotiation,
2669*5d535f58SDavid du Colombierthe terminal is wholly responsible for deciding what is displayed;
2670*5d535f58SDavid du Colombierthe host uses the
2671*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2672*5d535f58SDavid du Colombieronly to tell the terminal what might be relevant.
2673*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2674*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2675*5d535f58SDavid du Colombier<span style="font-size: 10pt">When a change is initiated by the host,
2676*5d535f58SDavid du Colombierthe messages to the terminal describing the change
2677*5d535f58SDavid du Colombierare generated by the routine that applies the transcript of the changes
2678*5d535f58SDavid du Colombierto the contents of the
2679*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">.
2680*5d535f58SDavid du ColombierSince changes are undone by the same update routine,
2681*5d535f58SDavid du Colombierundoing requires
2682*5d535f58SDavid du Colombierno extra code in the communications;
2683*5d535f58SDavid du Colombierthe usual messages describing changes to the file are sufficient
2684*5d535f58SDavid du Colombierto back up the screen image.
2685*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2686*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2687*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2688*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2689*5d535f58SDavid du Colombieris a particularly good example of the way caches are used in
2690*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
2691*5d535f58SDavid du ColombierFirst, it facilitates access to the active portion of the text by placing
2692*5d535f58SDavid du Colombierthe busy text in main memory.
2693*5d535f58SDavid du ColombierIn so doing, it provides efficient access
2694*5d535f58SDavid du Colombierto a large data structure that does not fit in memory.
2695*5d535f58SDavid du ColombierSince the form of data is to be imposed by the user, not by the program,
2696*5d535f58SDavid du Colombierand because characters will frequently be scanned sequentially,
2697*5d535f58SDavid du Colombierfiles are stored as flat objects.
2698*5d535f58SDavid du ColombierCaches help keep performance good and linear when working with such
2699*5d535f58SDavid du Colombierdata.
2700*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2701*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2702*5d535f58SDavid du Colombier<span style="font-size: 10pt">Second, the
2703*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2704*5d535f58SDavid du Colombierand several of the other caches have some
2705*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>read-ahead;</i></span><span style="font-size: 10pt">
2706*5d535f58SDavid du Colombierthat is, the cache is loaded with more information than is needed for
2707*5d535f58SDavid du Colombierthe job immediately at hand.
2708*5d535f58SDavid du ColombierWhen manipulating linear structures, the accesses are usually sequential,
2709*5d535f58SDavid du Colombierand read-ahead can significantly reduce the average time to access the
2710*5d535f58SDavid du Colombiernext element of the object.
2711*5d535f58SDavid du ColombierSequential access is a common mode for people as well as programs;
2712*5d535f58SDavid du Colombierconsider scrolling through a document while looking for something.
2713*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2714*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2715*5d535f58SDavid du Colombier<span style="font-size: 10pt">Finally, like any good data structure,
2716*5d535f58SDavid du Colombierthe cache guides the algorithm, or at least the implementation.
2717*5d535f58SDavid du ColombierThe
2718*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2719*5d535f58SDavid du Colombierwas actually invented to control the communications between the host and
2720*5d535f58SDavid du Colombierterminal parts, but I realized very early that it was also a form of
2721*5d535f58SDavid du Colombiercache.  Other caches were more explicitly intended to serve a double
2722*5d535f58SDavid du Colombierpurpose: for example, the caches in
2723*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Files</tt></span><span style="font-size: 10pt">
2724*5d535f58SDavid du Colombierthat coalesce updates not only reduce traffic to the
2725*5d535f58SDavid du Colombiertranscript and contents
2726*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffers</tt></span><span style="font-size: 10pt">,
2727*5d535f58SDavid du Colombierthey also clump screen updates so that complicated changes to the
2728*5d535f58SDavid du Colombierscreen are achieved in
2729*5d535f58SDavid du Colombierjust a few messages to the terminal.
2730*5d535f58SDavid du ColombierThis saved me considerable work: I did not need to write special
2731*5d535f58SDavid du Colombiercode to optimize the message traffic to the
2732*5d535f58SDavid du Colombierterminal.
2733*5d535f58SDavid du ColombierCaches pay off in surprising ways.
2734*5d535f58SDavid du ColombierAlso, they tend to be independent, so their performance improvements
2735*5d535f58SDavid du Colombierare multiplicative.
2736*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2737*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2738*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Data structures in the terminal
2739*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2740*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2741*5d535f58SDavid du Colombier<span style="font-size: 10pt">The terminal&rsquo;s job is to display and to maintain a consistent image of
2742*5d535f58SDavid du Colombierpieces of the files being edited.
2743*5d535f58SDavid du ColombierBecause the text is always in memory, the data structures are
2744*5d535f58SDavid du Colombierconsiderably simpler than those in the host part.
2745*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2746*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2747*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
2748*5d535f58SDavid du Colombiertypically has far more windows than does
2749*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
2750*5d535f58SDavid du Colombierthe window system within which its Blit implementation runs.
2751*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Mux</tt></span><span style="font-size: 10pt">
2752*5d535f58SDavid du Colombierhas a fairly small number of asynchronously updated windows;
2753*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2754*5d535f58SDavid du Colombierneeds a large number of synchronously updated windows that are
2755*5d535f58SDavid du Colombierusually static and often fully obscured.
2756*5d535f58SDavid du ColombierThe different tradeoffs guided
2757*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2758*5d535f58SDavid du Colombieraway from the memory-intensive implementation of windows, called
2759*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">,<sup></sup></span><sup><span style="font-size: 6pt">17</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2760*5d535f58SDavid du Colombierused in
2761*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux.</tt></span><span style="font-size: 10pt">
2762*5d535f58SDavid du ColombierRather than depending on a complete bitmap image of the display for each window,
2763*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2764*5d535f58SDavid du Colombierregenerates the image from its in-memory text
2765*5d535f58SDavid du Colombier(stored in the
2766*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">)
2767*5d535f58SDavid du Colombierwhen necessary, although it will use such an image if it is available.
2768*5d535f58SDavid du ColombierLike
2769*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">,
2770*5d535f58SDavid du Colombierthough,
2771*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2772*5d535f58SDavid du Colombieruses the screen bitmap as active storage in which to update the image using
2773*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">.<sup></sup></span><sup><span style="font-size: 6pt">18,19</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2774*5d535f58SDavid du ColombierThe resulting organization, pictured in Figure 6,
2775*5d535f58SDavid du Colombierhas a global array of windows, called
2776*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">,
2777*5d535f58SDavid du Colombiereach of which holds an image of a piece of text held in a data structure
2778*5d535f58SDavid du Colombiercalled a
2779*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">,
2780*5d535f58SDavid du Colombierwhich in turn represents
2781*5d535f58SDavid du Colombiera rectangular window full of text displayed in some
2782*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">.
2783*5d535f58SDavid du ColombierEach
2784*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
2785*5d535f58SDavid du Colombierappears in a global list that orders them all front-to-back
2786*5d535f58SDavid du Colombieron the display, and simultaneously as an element of a per-file array
2787*5d535f58SDavid du Colombierthat holds all the open windows for that file.
2788*5d535f58SDavid du ColombierThe complement in the terminal of the
2789*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>File</tt></span><span style="font-size: 10pt">
2790*5d535f58SDavid du Colombieron the host is called a
2791*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Text</tt></span><span style="font-size: 10pt">;
2792*5d535f58SDavid du Colombiereach connects its
2793*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">
2794*5d535f58SDavid du Colombierto the associated
2795*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">.
2796*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="sam3.png"></center>
2797*5d535f58SDavid du Colombier</center>
2798*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2799*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 6. Data structures in the terminal.
2800*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>Flayers</tt></span><span style="font-size: 8pt"><i>
2801*5d535f58SDavid du Colombierare also linked together into a front-to-back list.
2802*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>
2803*5d535f58SDavid du Colombierare discussed in the next section.
2804*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
2805*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
2806*5d535f58SDavid du Colombier
2807*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
2808*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2809*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2810*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2811*5d535f58SDavid du Colombierfor a
2812*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2813*5d535f58SDavid du Colombiercontains the image of the text.
2814*5d535f58SDavid du ColombierFor a fully visible window, the
2815*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2816*5d535f58SDavid du Colombierwill be the screen (or at least the
2817*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Layer</tt></span><span style="font-size: 10pt">
2818*5d535f58SDavid du Colombierin which
2819*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2820*5d535f58SDavid du Colombieris being run),
2821*5d535f58SDavid du Colombierwhile for partially obscured windows the
2822*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2823*5d535f58SDavid du Colombierwill be off-screen.
2824*5d535f58SDavid du ColombierIf the window is fully obscured, the
2825*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2826*5d535f58SDavid du Colombierwill be null.
2827*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2828*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2829*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2830*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2831*5d535f58SDavid du Colombieris a kind of cache.
2832*5d535f58SDavid du ColombierWhen making changes to the display, most of the original image will
2833*5d535f58SDavid du Colombierlook the same in the final image, and the update algorithms exploit this.
2834*5d535f58SDavid du ColombierThe
2835*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2836*5d535f58SDavid du Colombiersoftware updates the image in the
2837*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2838*5d535f58SDavid du Colombierincrementally; the
2839*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2840*5d535f58SDavid du Colombieris not just an image, it is a data structure.<sup></sup></span><sup><span style="font-size: 6pt">18,19</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2841*5d535f58SDavid du ColombierThe job of the software that updates the display is therefore
2842*5d535f58SDavid du Colombierto use as much as possible of the existing image (converting the
2843*5d535f58SDavid du Colombiertext from ASCII characters to pixels is expensive) in a sort of two-dimensional
2844*5d535f58SDavid du Colombierstring insertion algorithm.
2845*5d535f58SDavid du ColombierThe details of this process are described in the next section.
2846*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2847*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2848*5d535f58SDavid du Colombier<span style="font-size: 10pt">The
2849*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2850*5d535f58SDavid du Colombiersoftware has no code to support overlapping windows;
2851*5d535f58SDavid du Colombierits job is to keep a single
2852*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2853*5d535f58SDavid du Colombierup to date.
2854*5d535f58SDavid du ColombierIt falls to the
2855*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
2856*5d535f58SDavid du Colombiersoftware to multiplex the various
2857*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
2858*5d535f58SDavid du Colombieronto the screen.
2859*5d535f58SDavid du ColombierThe problem of maintaining overlapping
2860*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">
2861*5d535f58SDavid du Colombieris easier than for
2862*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt"><sup></sup></span><sup><span style="font-size: 6pt">17</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt">
2863*5d535f58SDavid du Colombierbecause changes are made synchronously and because the contents of the window
2864*5d535f58SDavid du Colombiercan be reconstructed from the data stored in the
2865*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">;
2866*5d535f58SDavid du Colombierthe
2867*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Layers</tt></span><span style="font-size: 10pt">
2868*5d535f58SDavid du Colombiersoftware
2869*5d535f58SDavid du Colombiermakes no such assumptions.
2870*5d535f58SDavid du ColombierIn
2871*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">,
2872*5d535f58SDavid du Colombierthe window being changed is almost always fully visible, because the current
2873*5d535f58SDavid du Colombierwindow is always fully visible, by construction.
2874*5d535f58SDavid du ColombierHowever, when multi-file changes are being made, or when
2875*5d535f58SDavid du Colombiermore than one window is open on a file,
2876*5d535f58SDavid du Colombierit may be necessary to update partially obscured windows.
2877*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2878*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2879*5d535f58SDavid du Colombier<span style="font-size: 10pt">There are three cases: the window is
2880*5d535f58SDavid du Colombierfully visible, invisible (fully obscured), or partially visible.
2881*5d535f58SDavid du ColombierIf fully visible, the
2882*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2883*5d535f58SDavid du Colombieris part of the screen, so when the
2884*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
2885*5d535f58SDavid du Colombierupdate routine calls the
2886*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2887*5d535f58SDavid du Colombierupdate routine, the screen will be updated directly.
2888*5d535f58SDavid du ColombierIf the window is invisible,
2889*5d535f58SDavid du Colombierthere is no associated
2890*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">,
2891*5d535f58SDavid du Colombierand all that is necessary is to update the
2892*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2893*5d535f58SDavid du Colombierdata structure, not the image.
2894*5d535f58SDavid du ColombierIf the window is partially visible, the
2895*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2896*5d535f58SDavid du Colombierroutine is called to update the image in the off-screen
2897*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">,
2898*5d535f58SDavid du Colombierwhich may require regenerating it from the text of the window.
2899*5d535f58SDavid du ColombierThe
2900*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayer</tt></span><span style="font-size: 10pt">
2901*5d535f58SDavid du Colombiercode then clips this
2902*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
2903*5d535f58SDavid du Colombieragainst the
2904*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
2905*5d535f58SDavid du Colombierof all
2906*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frames</tt></span><span style="font-size: 10pt">
2907*5d535f58SDavid du Colombierin front of the
2908*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2909*5d535f58SDavid du Colombierbeing modified, and the remainder is copied to the display.
2910*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2911*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2912*5d535f58SDavid du Colombier<span style="font-size: 10pt">This is much faster than recreating the image off-screen
2913*5d535f58SDavid du Colombierfor every change, or clipping all the changes made to the image
2914*5d535f58SDavid du Colombierduring its update.
2915*5d535f58SDavid du ColombierUnfortunately, these caches can also consume prohibitive amounts of
2916*5d535f58SDavid du Colombiermemory, so they are freed fairly liberally &mdash; after every change to the
2917*5d535f58SDavid du Colombierfront-to-back order of the
2918*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Flayers</tt></span><span style="font-size: 10pt">.
2919*5d535f58SDavid du ColombierThe result is that
2920*5d535f58SDavid du Colombierthe off-screen
2921*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmaps</tt></span><span style="font-size: 10pt">
2922*5d535f58SDavid du Colombierexist only while multi-window changes are occurring,
2923*5d535f58SDavid du Colombierwhich is the only time the performance improvement they provide is needed.
2924*5d535f58SDavid du ColombierAlso, the user interface causes fully-obscured windows to be the
2925*5d535f58SDavid du Colombiereasiest to make &mdash;
2926*5d535f58SDavid du Colombiercreating a canonically sized and placed window requires only a button click
2927*5d535f58SDavid du Colombier&mdash; which reduces the need for caching still further.
2928*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2929*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.17in"></p>
2930*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2931*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Screen update
2932*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2933*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2934*5d535f58SDavid du Colombier<span style="font-size: 10pt">Only two low-level primitives are needed for incremental update:
2935*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">,
2936*5d535f58SDavid du Colombierwhich copies rectangles of pixels, and
2937*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
2938*5d535f58SDavid du Colombier(which in turn calls
2939*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">),
2940*5d535f58SDavid du Colombierwhich draws a null-terminated character string in a
2941*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">.
2942*5d535f58SDavid du ColombierA
2943*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
2944*5d535f58SDavid du Colombiercontains a list of
2945*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">,
2946*5d535f58SDavid du Colombiereach of which defines a horizontal strip of text in the window
2947*5d535f58SDavid du Colombier(see Figure 7).
2948*5d535f58SDavid du ColombierA
2949*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
2950*5d535f58SDavid du Colombierhas a character string
2951*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">,
2952*5d535f58SDavid du Colombierand a
2953*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rectangle</tt></span><span style="font-size: 10pt">
2954*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">
2955*5d535f58SDavid du Colombierthat defines the location of the strip in the window.
2956*5d535f58SDavid du Colombier(The text in
2957*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">
2958*5d535f58SDavid du Colombieris stored in the
2959*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
2960*5d535f58SDavid du Colombierseparately from the
2961*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
2962*5d535f58SDavid du Colombierassociated with the window&rsquo;s file, so
2963*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
2964*5d535f58SDavid du Colombierare self-contained.)
2965*5d535f58SDavid du ColombierThe invariant is that
2966*5d535f58SDavid du Colombierthe image of the
2967*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
2968*5d535f58SDavid du Colombiercan be reproduced by calling
2969*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
2970*5d535f58SDavid du Colombierwith argument
2971*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>str</tt></span><span style="font-size: 10pt">
2972*5d535f58SDavid du Colombierto draw the string in
2973*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">,
2974*5d535f58SDavid du Colombierand the resulting picture fits perfectly within
2975*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>rect</tt></span><span style="font-size: 10pt">.
2976*5d535f58SDavid du ColombierIn other words, the
2977*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
2978*5d535f58SDavid du Colombierdefine the tiling of the window.
2979*5d535f58SDavid du ColombierThe tiling may be complicated by long lines of text, which
2980*5d535f58SDavid du Colombierare folded onto the next line.
2981*5d535f58SDavid du ColombierSome editors use horizontal scrolling to avoid this complication,
2982*5d535f58SDavid du Colombierbut to be comfortable this technique requires that lines not be
2983*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>too</i></span><span style="font-size: 10pt">
2984*5d535f58SDavid du Colombierlong;
2985*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
2986*5d535f58SDavid du Colombierhas no such restriction.
2987*5d535f58SDavid du ColombierAlso, and perhaps more importantly, UNIX programs and terminals traditionally fold
2988*5d535f58SDavid du Colombierlong lines to make their contents fully visible.
2989*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
2990*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
2991*5d535f58SDavid du Colombier<span style="font-size: 10pt">Two special kinds of
2992*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
2993*5d535f58SDavid du Colombiercontain a single
2994*5d535f58SDavid du Colombiercharacter: either a newline or a tab.
2995*5d535f58SDavid du ColombierNewlines and tabs are white space.
2996*5d535f58SDavid du ColombierA newline
2997*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
2998*5d535f58SDavid du Colombieralways extends to the right edge of the window,
2999*5d535f58SDavid du Colombierforcing the following
3000*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3001*5d535f58SDavid du Colombierto the next line.
3002*5d535f58SDavid du ColombierThe width of a tab depends on where it is located:
3003*5d535f58SDavid du Colombierit forces the next
3004*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3005*5d535f58SDavid du Colombierto begin at a tab location.
3006*5d535f58SDavid du ColombierTabs also
3007*5d535f58SDavid du Colombierhave a minimum width equivalent to a blank (blanks are
3008*5d535f58SDavid du Colombierdrawn by
3009*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>string</tt></span><span style="font-size: 10pt">
3010*5d535f58SDavid du Colombierand are not treated specially); newlines have a minimum width of zero.
3011*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"></span></p><center><img src="sam4.png"></center>
3012*5d535f58SDavid du Colombier</center>
3013*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.08in"></p>
3014*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3015*5d535f58SDavid du Colombier<span style="font-size: 8pt"><i>Figure 7. A line of text showing its
3016*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>.
3017*5d535f58SDavid du ColombierThe first two blank
3018*5d535f58SDavid du Colombier</i></span><span style="font-size: 8pt"><tt>Boxes</tt></span><span style="font-size: 8pt"><i>
3019*5d535f58SDavid du Colombiercontain tabs; the last contains a newline.
3020*5d535f58SDavid du ColombierSpaces are handled as ordinary characters.
3021*5d535f58SDavid du Colombier</i></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3022*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.02in"></p>
3023*5d535f58SDavid du Colombier
3024*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
3025*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3026*5d535f58SDavid du Colombier<span style="font-size: 10pt">The update algorithms always use the
3027*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">
3028*5d535f58SDavid du Colombierimage of the text (either the display or cache
3029*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Bitmap</tt></span><span style="font-size: 10pt">);
3030*5d535f58SDavid du Colombierthey never examine the characters within a
3031*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3032*5d535f58SDavid du Colombierexcept when the
3033*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3034*5d535f58SDavid du Colombierneeds to be split in two.
3035*5d535f58SDavid du ColombierBefore a change, the window consists of a tiling of
3036*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">;
3037*5d535f58SDavid du Colombierafter the change the window is tiled differently.
3038*5d535f58SDavid du ColombierThe update algorithms rearrange the tiles in place, without
3039*5d535f58SDavid du Colombierbackup storage.
3040*5d535f58SDavid du ColombierThe algorithms are not strictly optimal &mdash; for example, they can
3041*5d535f58SDavid du Colombierclear a pixel that is later going to be written upon &mdash;
3042*5d535f58SDavid du Colombierbut they never move a tile that doesn&rsquo;t need to be moved,
3043*5d535f58SDavid du Colombierand they move each tile at most once.
3044*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frinsert</tt></span><span style="font-size: 10pt">
3045*5d535f58SDavid du Colombieron a Blit can absorb over a thousand characters a second if the strings
3046*5d535f58SDavid du Colombierbeing inserted are a few tens of characters long.
3047*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3048*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3049*5d535f58SDavid du Colombier<span style="font-size: 10pt">Consider
3050*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">.
3051*5d535f58SDavid du ColombierIts job is to delete a substring from a
3052*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
3053*5d535f58SDavid du Colombierand restore the image of the
3054*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">.
3055*5d535f58SDavid du ColombierThe image of a substring has a peculiar shape (see Figure 2) comprising
3056*5d535f58SDavid du Colombierpossibly a partial line,
3057*5d535f58SDavid du Colombierzero or more full lines,
3058*5d535f58SDavid du Colombierand possibly a final partial line.
3059*5d535f58SDavid du ColombierFor reference, call this the
3060*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Z-shape.
3061*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Frdelete</tt></span><span style="font-size: 10pt">
3062*5d535f58SDavid du Colombierbegins by splitting, if necessary, the
3063*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
3064*5d535f58SDavid du Colombiercontaining the ends of
3065*5d535f58SDavid du Colombierthe substring so the substring begins and ends on
3066*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3067*5d535f58SDavid du Colombierboundaries.
3068*5d535f58SDavid du ColombierBecause the substring is being deleted, its image is not needed,
3069*5d535f58SDavid du Colombierso the Z-shape is then cleared.
3070*5d535f58SDavid du ColombierThen, tiles (that is, the images of
3071*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">)
3072*5d535f58SDavid du Colombierare copied, using
3073*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblt</tt></span><span style="font-size: 10pt">,
3074*5d535f58SDavid du Colombierfrom immediately after the Z-shape to
3075*5d535f58SDavid du Colombierthe beginning of the Z-shape,
3076*5d535f58SDavid du Colombierresulting in a new Z-shape.
3077*5d535f58SDavid du Colombier(</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
3078*5d535f58SDavid du Colombierwhose contents would span two lines in the new position must first be split.)
3079*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3080*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3081*5d535f58SDavid du Colombier<span style="font-size: 10pt">Copying the remainder of the
3082*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frame</tt></span><span style="font-size: 10pt">
3083*5d535f58SDavid du Colombiertile by tile
3084*5d535f58SDavid du Colombierthis way will clearly accomplish the deletion but eventually,
3085*5d535f58SDavid du Colombiertypically when the copying algorithm encounters a tab or newline,
3086*5d535f58SDavid du Colombierthe old and new
3087*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
3088*5d535f58SDavid du Colombiercoordinates of the tile
3089*5d535f58SDavid du Colombierto be copied are the same.
3090*5d535f58SDavid du ColombierThis correspondence implies
3091*5d535f58SDavid du Colombierthat the Z-shape has its beginning and ending edges aligned
3092*5d535f58SDavid du Colombiervertically, and a sequence of at most two
3093*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblts</tt></span><span style="font-size: 10pt">
3094*5d535f58SDavid du Colombiercan be used to copy the remaining tiles.
3095*5d535f58SDavid du ColombierThe last step is to clear out the resulting empty space at the bottom
3096*5d535f58SDavid du Colombierof the window;
3097*5d535f58SDavid du Colombierthe number of lines to be cleared is the number of complete lines in the
3098*5d535f58SDavid du ColombierZ-shape closed by the final
3099*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>bitblts.</tt></span><span style="font-size: 10pt">
3100*5d535f58SDavid du ColombierThe final step is to merge horizontally adjacent
3101*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
3102*5d535f58SDavid du Colombierof plain text.
3103*5d535f58SDavid du ColombierThe complete source to
3104*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">
3105*5d535f58SDavid du Colombieris less than 100 lines of C.
3106*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3107*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3108*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>frinsert</tt></span><span style="font-size: 10pt">
3109*5d535f58SDavid du Colombieris more complicated because it must do four passes:
3110*5d535f58SDavid du Colombierone to construct the
3111*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Box</tt></span><span style="font-size: 10pt">
3112*5d535f58SDavid du Colombierlist for the inserted string,
3113*5d535f58SDavid du Colombierone to reconnoitre,
3114*5d535f58SDavid du Colombierone to copy (in opposite order to
3115*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">)
3116*5d535f58SDavid du Colombierthe
3117*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Boxes</tt></span><span style="font-size: 10pt">
3118*5d535f58SDavid du Colombierto make the hole for the new text,
3119*5d535f58SDavid du Colombierand finally one to copy the new text into place.
3120*5d535f58SDavid du ColombierOverall, though,
3121*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>frinsert</tt></span><span style="font-size: 10pt">
3122*5d535f58SDavid du Colombierhas a similar flavor to
3123*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>frdelete</tt></span><span style="font-size: 10pt">,
3124*5d535f58SDavid du Colombierand needn&rsquo;t be described further.
3125*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Frinsert</tt></span><span style="font-size: 10pt">
3126*5d535f58SDavid du Colombierand its subsidiary routines comprise 211 lines of C.
3127*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3128*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3129*5d535f58SDavid du Colombier<span style="font-size: 10pt">The terminal source code is 3024 lines of C,
3130*5d535f58SDavid du Colombierand the host source is 5797 lines.
3131*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3132*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3133*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Discussion
3134*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3135*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3136*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>History
3137*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3138*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3139*5d535f58SDavid du Colombier<span style="font-size: 10pt">The immediate ancestor of
3140*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3141*5d535f58SDavid du Colombierwas the original text editor for the Blit, called
3142*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">.
3143*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3144*5d535f58SDavid du Colombierinherited
3145*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">&rsquo;s
3146*5d535f58SDavid du Colombiertwo-process structure and mouse language almost unchanged, but
3147*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3148*5d535f58SDavid du Colombiersuffered from several drawbacks that were addressed in the design of
3149*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">.
3150*5d535f58SDavid du ColombierThe most important of these was the lack of a command language.
3151*5d535f58SDavid du ColombierAlthough
3152*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3153*5d535f58SDavid du Colombierwas easy to use for simple editing, it provided no direct help with
3154*5d535f58SDavid du Colombierlarge or repetitive editing tasks.  Instead, it provided a command to pass
3155*5d535f58SDavid du Colombierselected text through a shell pipeline,
3156*5d535f58SDavid du Colombierbut this was no more satisfactory than could be expected of a stopgap measure.
3157*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3158*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3159*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Jim</tt></span><span style="font-size: 10pt">
3160*5d535f58SDavid du Colombierwas written primarily as a vehicle for experimenting with a mouse-based
3161*5d535f58SDavid du Colombierinterface to text, and the experiment was successful.
3162*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Jim</tt></span><span style="font-size: 10pt">
3163*5d535f58SDavid du Colombierhad some spin-offs:
3164*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
3165*5d535f58SDavid du Colombierthe second window system for the Blit, is essentially a multiplexed
3166*5d535f58SDavid du Colombierversion of the terminal part of
3167*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">;
3168*5d535f58SDavid du Colombierand the debugger
3169*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>pi</tt></span><span style="font-size: 10pt">&rsquo;s
3170*5d535f58SDavid du Colombieruser interface<sup></sup></span><sup><span style="font-size: 6pt">20</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> was closely modeled on
3171*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">&rsquo;s.
3172*5d535f58SDavid du ColombierBut after a couple of years,
3173*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3174*5d535f58SDavid du Colombierhad become difficult to maintain and limiting to use,
3175*5d535f58SDavid du Colombierand its replacement was overdue.
3176*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3177*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3178*5d535f58SDavid du Colombier<span style="font-size: 10pt">I began the design of
3179*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3180*5d535f58SDavid du Colombierby asking
3181*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3182*5d535f58SDavid du Colombiercustomers what they wanted.
3183*5d535f58SDavid du ColombierThis was probably a mistake; the answers were essentially a list of features
3184*5d535f58SDavid du Colombierto be found in other editors, which did not provide any of the
3185*5d535f58SDavid du Colombierguiding principles I was seeking.
3186*5d535f58SDavid du ColombierFor instance, one common request was for a &lsquo;&lsquo;global substitute,&rsquo;&rsquo;
3187*5d535f58SDavid du Colombierbut no one suggested how to provide it within a cut-and-paste editor.
3188*5d535f58SDavid du ColombierI was looking for a scheme that would
3189*5d535f58SDavid du Colombiersupport such specialized features comfortably in the context of some
3190*5d535f58SDavid du Colombiergeneral command language.
3191*5d535f58SDavid du ColombierIdeas were not forthcoming, though, particularly given my insistence
3192*5d535f58SDavid du Colombieron removing all limits on file sizes, line lengths and so on.
3193*5d535f58SDavid du ColombierEven worse, I recognized that, since the mouse could easily
3194*5d535f58SDavid du Colombierindicate a region of the screen that was not an integral number of lines,
3195*5d535f58SDavid du Colombierthe command language would best forget about newlines altogether,
3196*5d535f58SDavid du Colombierand that meant the command language had to treat the file as a single
3197*5d535f58SDavid du Colombierstring, not an array of lines.
3198*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3199*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3200*5d535f58SDavid du Colombier<span style="font-size: 10pt">Eventually, I decided that thinking was not getting me very far and it was
3201*5d535f58SDavid du Colombiertime to try building.
3202*5d535f58SDavid du ColombierI knew that the terminal part could be built easily &mdash;
3203*5d535f58SDavid du Colombierthat part of
3204*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3205*5d535f58SDavid du Colombierbehaved acceptably well &mdash; and that most of the hard work was going
3206*5d535f58SDavid du Colombierto be in the host part: the file interface, command interpreter and so on.
3207*5d535f58SDavid du ColombierMoreover, I had some ideas about how the architecture of
3208*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3209*5d535f58SDavid du Colombiercould be improved without destroying its basic structure, which I liked
3210*5d535f58SDavid du Colombierin principle but which hadn&rsquo;t worked out as well as I had hoped.
3211*5d535f58SDavid du ColombierSo I began by designing the file data structure,
3212*5d535f58SDavid du Colombierstarting with the way
3213*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3214*5d535f58SDavid du Colombierworked &mdash; comparable to a single structure merging
3215*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Disc</tt></span><span style="font-size: 10pt">
3216*5d535f58SDavid du Colombierand
3217*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Buffer</tt></span><span style="font-size: 10pt">,
3218*5d535f58SDavid du Colombierwhich I split to make the cache more general
3219*5d535f58SDavid du Colombier&mdash; and thinking about how global substitute could be implemented.
3220*5d535f58SDavid du ColombierThe answer was clearly that it had to be done in two passes,
3221*5d535f58SDavid du Colombierand the transcript-oriented implementation fell out naturally.
3222*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3223*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3224*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3225*5d535f58SDavid du Colombierwas written bottom-up,
3226*5d535f58SDavid du Colombierstarting from the data structures and algorithms for manipulating text,
3227*5d535f58SDavid du Colombierthrough the command language and up to the code for maintaining
3228*5d535f58SDavid du Colombierthe display.
3229*5d535f58SDavid du ColombierIn retrospect, it turned out well, but this implementation method is
3230*5d535f58SDavid du Colombiernot recommended in general.
3231*5d535f58SDavid du ColombierThere were several times when I had a large body of interesting code
3232*5d535f58SDavid du Colombierassembled and no clue how to proceed with it.
3233*5d535f58SDavid du ColombierThe command language, in particular, took almost a year to figure out,
3234*5d535f58SDavid du Colombierbut can be implemented (given what was there at the beginning of that year)
3235*5d535f58SDavid du Colombierin a day or two.  Similarly, inventing the
3236*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
3237*5d535f58SDavid du Colombierdata structure delayed the
3238*5d535f58SDavid du Colombierconnection of the host and terminal pieces by another few months.
3239*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3240*5d535f58SDavid du Colombiertook about two years to write, although only about four months were
3241*5d535f58SDavid du Colombierspent actually working on it.
3242*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3243*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3244*5d535f58SDavid du Colombier<span style="font-size: 10pt">Part of the design process was unusual:
3245*5d535f58SDavid du Colombierthe subset of the protocol that maintains the
3246*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
3247*5d535f58SDavid du Colombierwas simulated, debugged
3248*5d535f58SDavid du Colombierand verified by an automatic protocol analyzer,<sup></sup></span><sup><span style="font-size: 6pt">21</span><span style="font-size: 10pt"></span></sup><span style="font-size: 10pt"> and was bug-free
3249*5d535f58SDavid du Colombierfrom the start.
3250*5d535f58SDavid du ColombierThe rest of the protocol, concerned mostly
3251*5d535f58SDavid du Colombierwith keeping menus up to date,
3252*5d535f58SDavid du Colombierwas unfortunately too unwieldy for such analysis,
3253*5d535f58SDavid du Colombierand was debugged by more traditional methods, primarily
3254*5d535f58SDavid du Colombierby logging in a file all messages in and out of the host.
3255*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3256*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3257*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Reflections
3258*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3259*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3260*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3261*5d535f58SDavid du Colombieris essentially the only interactive editor used by the sixty or so members of
3262*5d535f58SDavid du Colombierthe computing science research center in which I work.
3263*5d535f58SDavid du ColombierThe same could not be said of
3264*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">;
3265*5d535f58SDavid du Colombierthe lack of a command language kept some people from adopting it.
3266*5d535f58SDavid du ColombierThe union of a user interface as comfortable as
3267*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">&rsquo;s
3268*5d535f58SDavid du Colombierwith a command language as powerful as
3269*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s&dagger;
3270*5d535f58SDavid du Colombier</span></p><p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3271*5d535f58SDavid du Colombier<span style="font-size: 10pt">is essential to
3272*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3273*5d535f58SDavid du Colombiersuccess.
3274*5d535f58SDavid du ColombierWhen
3275*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3276*5d535f58SDavid du Colombierwas first made available to the
3277*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3278*5d535f58SDavid du Colombiercommunity,
3279*5d535f58SDavid du Colombieralmost everyone switched to it within two or three days.
3280*5d535f58SDavid du ColombierIn the months that followed, even people who had never adopted
3281*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>jim</tt></span><span style="font-size: 10pt">
3282*5d535f58SDavid du Colombierstarted using
3283*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3284*5d535f58SDavid du Colombierexclusively.
3285*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3286*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3287*5d535f58SDavid du Colombier<span style="font-size: 10pt">To be honest,
3288*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
3289*5d535f58SDavid du Colombierstill gets occasional use, but usually when
3290*5d535f58SDavid du Colombiersomething quick needs to be done and the overhead of
3291*5d535f58SDavid du Colombierdownloading the terminal part of
3292*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3293*5d535f58SDavid du Colombierisn&rsquo;t worth the trouble.
3294*5d535f58SDavid du ColombierAlso, as a &lsquo;line&rsquo; editor,
3295*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3296*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>-d</tt></span><span style="font-size: 10pt">
3297*5d535f58SDavid du Colombieris a bit odd;
3298*5d535f58SDavid du Colombierwhen using a good old ASCII terminal, it&rsquo;s comforting to have
3299*5d535f58SDavid du Colombiera true line editor.
3300*5d535f58SDavid du ColombierBut it is fair to say that
3301*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3302*5d535f58SDavid du Colombiercommand language has displaced
3303*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s
3304*5d535f58SDavid du Colombierfor most of the complicated editing that has kept line editors
3305*5d535f58SDavid du Colombier(that is, command-driven editors) with us.
3306*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3307*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3308*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">&rsquo;s
3309*5d535f58SDavid du Colombiercommand language is even fancier than
3310*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s,
3311*5d535f58SDavid du Colombierand most
3312*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3313*5d535f58SDavid du Colombiercustomers don&rsquo;t come near to using all its capabilities.
3314*5d535f58SDavid du ColombierDoes it need to be so sophisticated?
3315*5d535f58SDavid du ColombierI think the answer is yes, for two reasons.
3316*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3317*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3318*5d535f58SDavid du Colombier<span style="font-size: 10pt">First, the
3319*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>model</i></span><span style="font-size: 10pt">
3320*5d535f58SDavid du Colombierfor
3321*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3322*5d535f58SDavid du Colombiercommand language is really relatively simple, and certainly simpler than that of
3323*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">.
3324*5d535f58SDavid du ColombierFor instance, there is only one kind of textual loop in
3325*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3326*5d535f58SDavid du Colombier&mdash; the
3327*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt">
3328*5d535f58SDavid du Colombiercommand &mdash;
3329*5d535f58SDavid du Colombierwhile
3330*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
3331*5d535f58SDavid du Colombierhas three (the
3332*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>g</tt></span><span style="font-size: 10pt">
3333*5d535f58SDavid du Colombiercommand, the global flag on substitutions, and the implicit loop over
3334*5d535f58SDavid du Colombierlines in multi-line substitutions).
3335*5d535f58SDavid du ColombierAlso,
3336*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s
3337*5d535f58SDavid du Colombiersubstitute command is necessary to make changes within lines, but in
3338*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3339*5d535f58SDavid du Colombierthe
3340*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>s</tt></span><span style="font-size: 10pt">
3341*5d535f58SDavid du Colombiercommand is more of a familiar convenience than a necessity;
3342*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>c</tt></span><span style="font-size: 10pt">
3343*5d535f58SDavid du Colombierand
3344*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>t</tt></span><span style="font-size: 10pt">
3345*5d535f58SDavid du Colombiercan do all the work.
3346*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3347*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3348*5d535f58SDavid du Colombier<span style="font-size: 10pt">Second,
3349*5d535f58SDavid du Colombiergiven a community that expects an editor to be about as powerful as
3350*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">,
3351*5d535f58SDavid du Colombierit&rsquo;s hard to see how
3352*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3353*5d535f58SDavid du Colombiercould really be much simpler and still satisfy that expectation.
3354*5d535f58SDavid du ColombierPeople want to do &lsquo;&lsquo;global substitutes,&rsquo;&rsquo; and most are content
3355*5d535f58SDavid du Colombierto have the recipe for that and a few other fancy changes.
3356*5d535f58SDavid du ColombierThe sophistication of the command language is really just a veneer
3357*5d535f58SDavid du Colombierover a design that makes it possible to do global substitutes
3358*5d535f58SDavid du Colombierin a screen editor.
3359*5d535f58SDavid du ColombierSome people will always want something more, however, and it&rsquo;s gratifying to
3360*5d535f58SDavid du Colombierbe able to provide it.
3361*5d535f58SDavid du ColombierThe real power of
3362*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3363*5d535f58SDavid du Colombiercommand language comes from composability of the operators, which is by
3364*5d535f58SDavid du Colombiernature orthogonal to the underlying model.
3365*5d535f58SDavid du ColombierIn other words,
3366*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3367*5d535f58SDavid du Colombieris not itself complex, but it makes complex things possible.
3368*5d535f58SDavid du ColombierIf you don&rsquo;t want to do anything complex, you can ignore the
3369*5d535f58SDavid du Colombiercomplexity altogether, and many people do so.
3370*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3371*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3372*5d535f58SDavid du Colombier<span style="font-size: 10pt">Sometimes I am asked the opposite question: why didn&rsquo;t I just make
3373*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3374*5d535f58SDavid du Colombiera real programmable editor, with macros and variables and so on?
3375*5d535f58SDavid du ColombierThe main reason is a matter of taste: I like the editor
3376*5d535f58SDavid du Colombierto be the same every time I use it.
3377*5d535f58SDavid du ColombierThere is one technical reason, though:
3378*5d535f58SDavid du Colombierprogrammability in editors is largely a workaround for insufficient
3379*5d535f58SDavid du Colombierinteractivity.
3380*5d535f58SDavid du ColombierProgrammable editors are used to make particular, usually short-term,
3381*5d535f58SDavid du Colombierthings easy to do, such as by providing shorthands for common actions.
3382*5d535f58SDavid du ColombierIf things are generally easy to do in the first place,
3383*5d535f58SDavid du Colombiershorthands are not as helpful.
3384*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3385*5d535f58SDavid du Colombiermakes common editing operations very easy, and the solutions to
3386*5d535f58SDavid du Colombiercomplex editing problems seem commensurate with the problems themselves.
3387*5d535f58SDavid du ColombierAlso, the ability to edit the
3388*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3389*5d535f58SDavid du Colombierwindow makes it easy to repeat commands &mdash; it only takes a mouse button click
3390*5d535f58SDavid du Colombierto execute a command again.
3391*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3392*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3393*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Pros and cons
3394*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3395*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3396*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3397*5d535f58SDavid du Colombierhas several other good points,
3398*5d535f58SDavid du Colombierand its share of problems.
3399*5d535f58SDavid du ColombierAmong the good things is the idea of
3400*5d535f58SDavid du Colombierstructural regular expressions,
3401*5d535f58SDavid du Colombierwhose usefulness has only begun to be explored.
3402*5d535f58SDavid du ColombierThey were arrived at serendipitously when I attempted to distill the essence of
3403*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s
3404*5d535f58SDavid du Colombierway of doing global substitution and recognized that the looping command in
3405*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
3406*5d535f58SDavid du Colombierwas implicitly imposing a structure (an array of lines) on the file.
3407*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3408*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3409*5d535f58SDavid du Colombier<span style="font-size: 10pt">Another of
3410*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3411*5d535f58SDavid du Colombiergood things is its undo capability.
3412*5d535f58SDavid du ColombierI had never before used an editor with a true undo,
3413*5d535f58SDavid du Colombierbut I would never go back now.
3414*5d535f58SDavid du ColombierUndo
3415*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>must</i></span><span style="font-size: 10pt">
3416*5d535f58SDavid du Colombierbe done well, but if it is, it can be relied on.
3417*5d535f58SDavid du ColombierFor example,
3418*5d535f58SDavid du Colombierit&rsquo;s safe to experiment if you&rsquo;re not sure how to write some intricate command,
3419*5d535f58SDavid du Colombierbecause if you make a mistake, it can be fixed simply and reliably.
3420*5d535f58SDavid du ColombierI learned two things about undo from writing
3421*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">:
3422*5d535f58SDavid du Colombierfirst, it&rsquo;s easy to provide if you design it in from the beginning, and
3423*5d535f58SDavid du Colombiersecond, it&rsquo;s necessary, particularly if the system has some subtle
3424*5d535f58SDavid du Colombierproperties that may be unfamiliar or error-prone for users.
3425*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3426*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3427*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">&rsquo;s
3428*5d535f58SDavid du Colombierlack of internal limits and sizes is a virtue.
3429*5d535f58SDavid du ColombierBecause it avoids all fixed-size tables and data structures,
3430*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3431*5d535f58SDavid du Colombieris able to make global changes to files that some of our other
3432*5d535f58SDavid du Colombiertools cannot even read.
3433*5d535f58SDavid du ColombierMoreover, the design keeps the performance linear when doing such
3434*5d535f58SDavid du Colombieroperations, although I must admit
3435*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3436*5d535f58SDavid du Colombierdoes get slow when editing a huge file.
3437*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3438*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3439*5d535f58SDavid du Colombier<span style="font-size: 10pt">Now, the problems.
3440*5d535f58SDavid du ColombierExternally, the most obvious is that it is poorly integrated into the
3441*5d535f58SDavid du Colombiersurrounding window system.
3442*5d535f58SDavid du ColombierBy design, the user interface in
3443*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3444*5d535f58SDavid du Colombierfeels almost identical to that of
3445*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">,
3446*5d535f58SDavid du Colombierbut a thick wall separates text in
3447*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3448*5d535f58SDavid du Colombierfrom the programs running in
3449*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">.
3450*5d535f58SDavid du ColombierFor instance, the &lsquo;snarf buffer&rsquo; in
3451*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3452*5d535f58SDavid du Colombiermust be maintained separately from that in
3453*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>mux</tt></span><span style="font-size: 10pt">.
3454*5d535f58SDavid du ColombierThis is regrettable, but probably necessary given the unusual configuration
3455*5d535f58SDavid du Colombierof the system, with a programmable terminal on the far end of an RS-232 link.
3456*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3457*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3458*5d535f58SDavid du Colombier<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Sam</tt></span><span style="font-size: 10pt">
3459*5d535f58SDavid du Colombieris reliable; otherwise, people wouldn&rsquo;t use it.
3460*5d535f58SDavid du ColombierBut it was written over such a long time, and has so many new (to me)
3461*5d535f58SDavid du Colombierideas in it, that I would like to see it done over again to clean
3462*5d535f58SDavid du Colombierup the code and remove many of the lingering problems in the implementation.
3463*5d535f58SDavid du ColombierThe worst part is in the interconnection of the host and terminal parts,
3464*5d535f58SDavid du Colombierwhich might even be able to go away in a redesign for a more
3465*5d535f58SDavid du Colombierconventional window system.
3466*5d535f58SDavid du ColombierThe program must be split in two to use the terminal effectively,
3467*5d535f58SDavid du Colombierbut the low bandwidth of the connection forces the separation to
3468*5d535f58SDavid du Colombieroccur in an inconvenient part of the design if performance is to be acceptable.
3469*5d535f58SDavid du ColombierA simple remote procedure call
3470*5d535f58SDavid du Colombierprotocol driven by the host, emitting only graphics
3471*5d535f58SDavid du Colombiercommands, would be easy to write but wouldn&rsquo;t have nearly the
3472*5d535f58SDavid du Colombiernecessary responsiveness.  On the other hand, if the terminal were in control
3473*5d535f58SDavid du Colombierand requested much simpler file services from the host, regular expression
3474*5d535f58SDavid du Colombiersearches would require that the terminal read the entire file over its RS-232
3475*5d535f58SDavid du Colombierlink, which would be unreasonably slow.
3476*5d535f58SDavid du ColombierA compromise in which either end can take control is necessary.
3477*5d535f58SDavid du ColombierIn retrospect, the communications protocol should have been
3478*5d535f58SDavid du Colombierdesigned and verified formally, although I do not know of any tool
3479*5d535f58SDavid du Colombierthat can adequately relate the protocol to
3480*5d535f58SDavid du Colombierits implementation.
3481*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3482*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3483*5d535f58SDavid du Colombier<span style="font-size: 10pt">Not all of
3484*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3485*5d535f58SDavid du Colombierusers are comfortable with its command language, and few are adept.
3486*5d535f58SDavid du ColombierSome (venerable) people use a sort of
3487*5d535f58SDavid du Colombier&lsquo;&lsquo;</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
3488*5d535f58SDavid du Colombiersubset&rsquo;&rsquo; of
3489*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3490*5d535f58SDavid du Colombiercommand language,
3491*5d535f58SDavid du Colombierand even ask why
3492*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3493*5d535f58SDavid du Colombiercommand language is not exactly
3494*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s.
3495*5d535f58SDavid du Colombier(The reason, of course, is that
3496*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3497*5d535f58SDavid du Colombiermodel for text does not include newlines, which are central to
3498*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">.
3499*5d535f58SDavid du ColombierMaking the text an array of newlines to the command language would
3500*5d535f58SDavid du Colombierbe too much of a break from the seamless model provided by the mouse.
3501*5d535f58SDavid du ColombierSome editors, such as
3502*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>vi</tt></span><span style="font-size: 10pt">,
3503*5d535f58SDavid du Colombierare willing to make this break, though.)
3504*5d535f58SDavid du ColombierThe difficulty is that
3505*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">&rsquo;s
3506*5d535f58SDavid du Colombiersyntax is so close to
3507*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">&rsquo;s
3508*5d535f58SDavid du Colombierthat people believe it
3509*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>should</i></span><span style="font-size: 10pt">
3510*5d535f58SDavid du Colombierbe the same.
3511*5d535f58SDavid du ColombierI thought, with some justification in hindsight,
3512*5d535f58SDavid du Colombierthat making
3513*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3514*5d535f58SDavid du Colombiersimilar to
3515*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt">
3516*5d535f58SDavid du Colombierwould make it easier to learn and to accept.
3517*5d535f58SDavid du ColombierBut I may have overstepped and raised the users&rsquo;
3518*5d535f58SDavid du Colombierexpectations too much.
3519*5d535f58SDavid du ColombierIt&rsquo;s hard to decide which way to resolve this problem.
3520*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3521*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3522*5d535f58SDavid du Colombier<span style="font-size: 10pt">Finally, there is a tradeoff in
3523*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3524*5d535f58SDavid du Colombierthat was decided by the environment in which it runs:
3525*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">
3526*5d535f58SDavid du Colombieris a multi-file editor, although in a different system there might instead be
3527*5d535f58SDavid du Colombiermultiple single-file editors.
3528*5d535f58SDavid du ColombierThe decision was made primarily because starting a new program in a Blit is
3529*5d535f58SDavid du Colombiertime-consuming.
3530*5d535f58SDavid du ColombierIf the choice could be made freely, however, I would
3531*5d535f58SDavid du Colombierstill choose the multi-file architecture, because it allows
3532*5d535f58SDavid du Colombiergroups of files to be handled as a unit;
3533*5d535f58SDavid du Colombierthe usefulness of the multi-file commands is incontrovertible.
3534*5d535f58SDavid du ColombierIt is delightful to have the source to an entire program
3535*5d535f58SDavid du Colombieravailable at your fingertips.
3536*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3537*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3538*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>Acknowledgements
3539*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3540*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3541*5d535f58SDavid du Colombier<span style="font-size: 10pt">Tom Cargill suggested the idea behind the
3542*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>Rasp</tt></span><span style="font-size: 10pt">
3543*5d535f58SDavid du Colombierdata structure.
3544*5d535f58SDavid du ColombierNorman Wilson and Ken Thompson influenced the command language.
3545*5d535f58SDavid du ColombierThis paper was improved by comments from
3546*5d535f58SDavid du ColombierAl Aho,
3547*5d535f58SDavid du ColombierJon Bentley,
3548*5d535f58SDavid du ColombierChris Fraser,
3549*5d535f58SDavid du ColombierGerard Holzmann,
3550*5d535f58SDavid du ColombierBrian Kernighan,
3551*5d535f58SDavid du ColombierTed Kowalski,
3552*5d535f58SDavid du ColombierDoug McIlroy
3553*5d535f58SDavid du Colombierand
3554*5d535f58SDavid du ColombierDennis Ritchie.
3555*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
3556*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3557*5d535f58SDavid du Colombier<span style="font-size: 10pt"><b>REFERENCES
3558*5d535f58SDavid du Colombier</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3559*5d535f58SDavid du Colombier<p style="margin-top: 0; margin-bottom: 0.05in"></p>
3560*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3561*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 1.    R. Pike,
3562*5d535f58SDavid du Colombier&lsquo;The Blit: a multiplexed graphics terminal,&rsquo;
3563*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>AT&amp;T Bell Labs. Tech. J.,
3564*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>63</b></span><span style="font-size: 10pt">,
3565*5d535f58SDavid du Colombier(8),
3566*5d535f58SDavid du Colombier1607-1631 (1984).
3567*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3568*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3569*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 2.    L. Johnson,
3570*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>MacWrite,</i></span><span style="font-size: 10pt">
3571*5d535f58SDavid du ColombierApple Computer Inc., Cupertino, Calif. 1983.
3572*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3573*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3574*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 3.    B. Lampson,
3575*5d535f58SDavid du Colombier&lsquo;Bravo Manual,&rsquo;
3576*5d535f58SDavid du Colombierin
3577*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Alto User&rsquo;s Handbook,
3578*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">pp. 31-62,
3579*5d535f58SDavid du ColombierXerox Palo Alto Research Center,
3580*5d535f58SDavid du ColombierPalo Alto, Calif.
3581*5d535f58SDavid du Colombier1979.
3582*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3583*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3584*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 4.    W. Teitelman,
3585*5d535f58SDavid du Colombier&lsquo;A tour through Cedar,&rsquo;
3586*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>IEEE Software,
3587*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>1</b></span><span style="font-size: 10pt">
3588*5d535f58SDavid du Colombier(2), 44-73 (1984).
3589*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3590*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3591*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 5.    J. Gutknecht,
3592*5d535f58SDavid du Colombier&lsquo;Concepts of the text editor Lara,&rsquo;
3593*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Comm. ACM,
3594*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>28</b></span><span style="font-size: 10pt">,
3595*5d535f58SDavid du Colombier(9),
3596*5d535f58SDavid du Colombier942-960 (1985).
3597*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3598*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3599*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 6.    Bell Telephone Laboratories,
3600*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>UNIX Programmer&rsquo;s Manual,
3601*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Holt, Rinehart and Winston, New York 1983.
3602*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3603*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3604*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 7.    B. W. Kernighan and R. Pike,
3605*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>The Unix Programming Environment,
3606*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Prentice-Hall, Englewood Cliffs, New Jersey 1984.
3607*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3608*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3609*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 8.    </span><span style="font-size: 10pt"><i>Unix Time-Sharing System Programmer&rsquo;s Manual, Research Version, Ninth Edition,
3610*5d535f58SDavid du ColombierVolume 1,
3611*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">AT&amp;T Bell Laboratories, Murray Hill, New Jersey 1986.
3612*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3613*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3614*5d535f58SDavid du Colombier<span style="font-size: 10pt"> 9.    </span><span style="font-size: 10pt"><i>Unix Time-Sharing System Programmer&rsquo;s Manual, 4.1 Berkeley Software Distribution,
3615*5d535f58SDavid du ColombierVolumes 1 and 2C,
3616*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">University of California, Berkeley, Calif. 1981.
3617*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3618*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3619*5d535f58SDavid du Colombier<span style="font-size: 10pt">10.    R. Pike,
3620*5d535f58SDavid du Colombier&lsquo;Structural Regular Expressions,&rsquo;
3621*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Proc. EUUG Spring Conf., Helsinki 1987,
3622*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Eur. Unix User&rsquo;s Group, Buntingford, Herts, UK 1987.
3623*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3624*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3625*5d535f58SDavid du Colombier<span style="font-size: 10pt">11.    A. Goldberg,
3626*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Smalltalk-80 &ndash; The Interactive Programming Environment,
3627*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Addison-Wesley, Reading, Mass. 1984.
3628*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3629*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3630*5d535f58SDavid du Colombier<span style="font-size: 10pt">12.    K. Thompson,
3631*5d535f58SDavid du Colombier&lsquo;Regular expression search algorithm,&rsquo;
3632*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Comm. ACM,
3633*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>11</b></span><span style="font-size: 10pt">,
3634*5d535f58SDavid du Colombier(6),
3635*5d535f58SDavid du Colombier419-422 (1968).
3636*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3637*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3638*5d535f58SDavid du Colombier<span style="font-size: 10pt">13.    A. V. Aho, J. E. Hopcroft and J. D. Ullman,
3639*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>The Design and Analysis of Computer Algorithms,
3640*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Addison-Wesley, Reading, Mass. 1974.
3641*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3642*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3643*5d535f58SDavid du Colombier<span style="font-size: 10pt">14.    B. W. Kernighan and D. M. Ritchie,
3644*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>The C Programming Language,
3645*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">Prentice-Hall, Englewood Cliffs, New Jersey 1978.
3646*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3647*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3648*5d535f58SDavid du Colombier<span style="font-size: 10pt">15.    W. M. Waite,
3649*5d535f58SDavid du Colombier&lsquo;The cost of lexical analysis,&rsquo;
3650*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Softw. Pract. Exp.,
3651*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>16</b></span><span style="font-size: 10pt">,
3652*5d535f58SDavid du Colombier(5),
3653*5d535f58SDavid du Colombier473-488 (1986).
3654*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3655*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3656*5d535f58SDavid du Colombier<span style="font-size: 10pt">16.    C. W. Fraser,
3657*5d535f58SDavid du Colombier&lsquo;A generalized text editor,&rsquo;
3658*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Comm. ACM,
3659*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>23</b></span><span style="font-size: 10pt">,
3660*5d535f58SDavid du Colombier(3),
3661*5d535f58SDavid du Colombier154-158 (1980).
3662*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3663*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3664*5d535f58SDavid du Colombier<span style="font-size: 10pt">17.    R. Pike,
3665*5d535f58SDavid du Colombier&lsquo;Graphics in overlapping bitmap layers,&rsquo;
3666*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>ACM Trans. on Graph.,
3667*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>2</b></span><span style="font-size: 10pt">,
3668*5d535f58SDavid du Colombier(2)
3669*5d535f58SDavid du Colombier135-160 (1983).
3670*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3671*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3672*5d535f58SDavid du Colombier<span style="font-size: 10pt">18.    L. J. Guibas and J. Stolfi,
3673*5d535f58SDavid du Colombier&lsquo;A language for bitmap manipulation,&rsquo;
3674*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>ACM Trans. on Graph.,
3675*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>1</b></span><span style="font-size: 10pt">,
3676*5d535f58SDavid du Colombier(3),
3677*5d535f58SDavid du Colombier191-214 (1982).
3678*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3679*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3680*5d535f58SDavid du Colombier<span style="font-size: 10pt">19.    R. Pike, B. Locanthi and J. Reiser,
3681*5d535f58SDavid du Colombier&lsquo;Hardware/software trade-offs for bitmap graphics on the Blit,&rsquo;
3682*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Softw. Pract. Exp.,
3683*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>15</b></span><span style="font-size: 10pt">,
3684*5d535f58SDavid du Colombier(2),
3685*5d535f58SDavid du Colombier131-151 (1985).
3686*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3687*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3688*5d535f58SDavid du Colombier<span style="font-size: 10pt">20.    T. A. Cargill,
3689*5d535f58SDavid du Colombier&lsquo;The feel of Pi,&rsquo;
3690*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Winter USENIX Conference Proceedings,
3691*5d535f58SDavid du ColombierDenver 1986,
3692*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">62-71,
3693*5d535f58SDavid du ColombierUSENIX Assoc., El Cerrito, CA.
3694*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
3695*5d535f58SDavid du Colombier<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
3696*5d535f58SDavid du Colombier<span style="font-size: 10pt">21.    G. J. Holzmann,
3697*5d535f58SDavid du Colombier&lsquo;Tracing protocols,&rsquo;
3698*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>AT&amp;T Tech. J.,
3699*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>64</b></span><span style="font-size: 10pt">,
3700*5d535f58SDavid du Colombier(10),
3701*5d535f58SDavid du Colombier2413-2434 (1985).
3702*5d535f58SDavid du Colombier</span></p><p style="margin-top: 0; margin-bottom: 0.50in"></p>
3703*5d535f58SDavid du Colombier</body>
3704*5d535f58SDavid du Colombier</html>
3705*5d535f58SDavid du Colombier
3706