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 ‘undo’ 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—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 ‘host part,’ runs on a UNIX system 77*5d535f58SDavid du Colombierand implements the command language and provides file access; the other, the 78*5d535f58SDavid du Colombier‘terminal part,’ 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">’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 ‘undo’ 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 — 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 ‘no download’), 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 ‘line’ of text as understood by most UNIX programs 262*5d535f58SDavid du Colombier— a sequence of characters terminated by a newline character — 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’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’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>&</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, &, &, &, &!/</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>< </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>></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">’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">’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 ‘any character’ 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">’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">’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’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">’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 — 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">’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/Peter/ v/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 ‘records.’ 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’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’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’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/’[^’]*’/ 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>\’</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’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’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’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>’-. 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’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’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">’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">’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 <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 <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">’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/’/ 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’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’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 — 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’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 ‘menu lines’ 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’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><mux></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’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->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 ’.’:</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->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 ’$’:</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->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 ’"’: </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->aregexp)->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 ’,’:</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->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->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<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->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 ‘undoing’), 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 ‘?addresses out of order.’ 1867*5d535f58SDavid du ColombierVery common messages are kept short; for example the message for 1868*5d535f58SDavid du Colombiera failed regular expression search is ‘?search.’ 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 — it is too 1879*5d535f58SDavid du Colombierexpensive to track dynamically — 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->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.f, a.r.p1, a.r.p2)!=(cp->cmdchar==’v’)){</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->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->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’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 — 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’t have 1966*5d535f58SDavid du Colombierpeculiar meanings — 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’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’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 ‘mark’ 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">’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">’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 ‘‘delete substring from 2396*5d535f58SDavid du Colombierlocations 2397*5d535f58SDavid du Colombier123 to 456’’ and ‘‘insert 11 characters ‘hello there’ at location 789.’’ 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 ‘do’ 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 ‘undo’ 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 ‘do’ 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’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’ cache to 2466*5d535f58SDavid du Colombierthe transcript’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">’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">’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’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&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’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‘‘insert a one-byte string at location 123 in file 7,’’ not ‘‘a character 2596*5d535f58SDavid du Colombierwas typed at the current position in the current file.’’ 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’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’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’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’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 — 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 — 2926*5d535f58SDavid du Colombiercreating a canonically sized and placed window requires only a button click 2927*5d535f58SDavid du Colombier— 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’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 — for example, they can 3041*5d535f58SDavid du Colombierclear a pixel that is later going to be written upon — 3042*5d535f58SDavid du Colombierbut they never move a tile that doesn’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’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">’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">’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">’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 ‘‘global substitute,’’ 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 — 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 — 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’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 — 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— 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">’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">’s† 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">’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’t worth the trouble. 3294*5d535f58SDavid du ColombierAlso, as a ‘line’ 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’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">’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">’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">’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">’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’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">’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— the 3327*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>x</tt></span><span style="font-size: 10pt"> 3328*5d535f58SDavid du Colombiercommand — 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">’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’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 ‘‘global substitutes,’’ 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’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">’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’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’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 — 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">’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">’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’s safe to experiment if you’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’s easy to provide if you design it in from the beginning, and 3423*5d535f58SDavid du Colombiersecond, it’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">’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 ‘snarf buffer’ 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’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’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">’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‘‘</span><span style="font-size: 10pt"><tt>ed</tt></span><span style="font-size: 10pt"> 3488*5d535f58SDavid du Colombiersubset’’ of 3489*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><tt>sam</tt></span><span style="font-size: 10pt">’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">’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">’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">’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">’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">’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’ 3518*5d535f58SDavid du Colombierexpectations too much. 3519*5d535f58SDavid du ColombierIt’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‘The Blit: a multiplexed graphics terminal,’ 3563*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>AT&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‘Bravo Manual,’ 3576*5d535f58SDavid du Colombierin 3577*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>Alto User’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‘A tour through Cedar,’ 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‘Concepts of the text editor Lara,’ 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’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’s Manual, Research Version, Ninth Edition, 3610*5d535f58SDavid du ColombierVolume 1, 3611*5d535f58SDavid du Colombier</i></span><span style="font-size: 10pt">AT&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’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‘Structural Regular Expressions,’ 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’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 – 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‘Regular expression search algorithm,’ 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‘The cost of lexical analysis,’ 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‘A generalized text editor,’ 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‘Graphics in overlapping bitmap layers,’ 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‘A language for bitmap manipulation,’ 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‘Hardware/software trade-offs for bitmap graphics on the Blit,’ 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‘The feel of Pi,’ 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‘Tracing protocols,’ 3698*5d535f58SDavid du Colombier</span><span style="font-size: 10pt"><i>AT&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