Software Tools in Pascal 6/8
jp at lanl.ARPA
jp at lanl.ARPA
Sun Oct 6 15:02:25 AEST 1985
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Rot -- Rotate a file 90 degrees clockwise }
program Rot;
%include swtools
const
maxWidth = 2000;
maxHeight = 130;
var
buffers: array [1..maxHeight] of array
[1..maxWidth] of Char;
i: Integer;
j: Integer;
maxReadWidth: Integer;
maxReadHeight: Integer;
begin
ToolInit;
i := 1;
j := 1;
maxReadWidth := 0;
while (GetC(buffers[i,j]) <> ENDFILE) do begin
if (buffers[i,j] = NEWLINE) then begin
maxReadWidth := Max(maxReadWidth,j);
for j := j to maxWidth do
buffers[i,j] := BLANK;
j := 1;
i := i + 1;
end
else
j := j + 1;
if (i > maxHeight) or (j > maxWidth) then begin
Message('input file too big');
leave
end
end;
maxReadHeight := i - 1;
for i := 1 to maxReadWidth do begin
for j := maxReadHeight downto 1 do
PutC (buffers[j,i]);
PutC (NEWLINE)
end;
end.
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SCCopy -- copy string s to cb[i] }
segment SCCopy;
%include swtools
%include defdef
%include defref
%include defproc
procedure SCCopy;
var
j: Integer;
begin
j := 1;
while (s[j] <> ENDSTR) do begin
cb[i] := s[j];
j := j + 1;
i := i + 1
end;
cb[i] := ENDSTR
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SCopy (CMS) -- copy strings }
segment SCopy;
%include swtools
procedure SCopy;
begin
while(src[i] <> ENDSTR) do begin
dest[j] := src[i];
i := i + 1;
j := j + 1;
end;
dest[j] := ENDSTR;
end;
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Screen -- line printer character test }
program Screen;
%include swtools
%include ioref
var i: Integer;
first: Integer;
begin
ToolInit;
WriteLn(openList[STDOUT].fileVar, ' C H A R A C T E R S E T');
PutC(NEWLINE);
WriteLn(openList[STDOUT].FileVar,
' 0 1 2 3 4 5 6 7 8 9 A B C D E F');
for i := 0 to 255 do begin
if i mod 16 = 0 then begin
PutC(NEWLINE);
PutC(NEWLINE);
first := i div 16;
if first >= 10 then
PutC(Chr(first + Ord(BIGA) - 10))
else
PutC(Chr(i div 16 + Ord(DIG0)));
PutC(DIG0);
PutC(BLANK);
PutC(BLANK);
end;
Write(openList[STDOUT].fileVar, ' ', Chr(i))
end
end.
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SetBuf -- set Buffer and other Buffer handlers (new-free) }
segment SetBuf;
%include swtools
%include editcons
%include edittype
%include editproc
%include editref
const
MAXLINES = 10000;
type
BufType = { in-memory new/free buffer handler }
record
txt: StringPtr; { text of line }
mark: Boolean; { mark for line }
end;
ref OUTOFSPACE: Boolean;
static heapMark: @ Integer;
static { This is a PRIVATE buffer }
intBuff: array [0..MAXLINES] of BufType;
{ SetBuf -- (new-free) initialize line storage Buffer }
procedure SetBuf;
var
i: 0..MAXLINES;
begin
Mark(heapMark);
for i := 0 to MAXLINES do
intBuff[i].txt := nil;
curLn := 0;
lastLn := 0
end;
{ ClrBuf -- (new-free) release storage }
procedure ClrBuf;
var i: 0..MAXLINES;
begin
Release(heapMark)
end;
{ GetTxt -- (new-free) get text from line n into s }
procedure GetTxt;
begin
{ note: the null is already there }
if intBuff[n].txt = nil then
s[1] := ENDSTR
else
s := intBuff[n].txt@;
end;
{ PutTxt -- (new-free) put text from lin after curLn }
function PutTxt;
var
sSize: Integer;
begin
PutTxt := ERR;
if (lastLn < MAXLINES) then begin
lastLn := lastLn + 1;
sSize := StrLength(lin) + 1;
if intBuff[lastLn].txt = nil then
New(intBuff[lastLn].txt, sSize)
else if (sSize > MaxLength(intBuff[lastLn].txt@)) then begin
Dispose(intBuff[lastLn].txt);
New(intBuff[lastLn].txt, sSize)
end;
{ Check for New failing }
if OUTOFSPACE then begin
intBuff[lastLn].txt := nil; { insurance }
lastLn := lastLn - 1; { insurance }
OUTOFSPACE := false;
Message('out of space, write out and edit again');
return { error }
end;
WriteStr(intBuff[lastLn].txt@, lin:sSize);
PutMark(lastLn, false);
BlkMove(lastLn, lastLn, curLn);
curLn := curLn + 1;
PutTxt := OK
end
end;
{ GetMark -- get mark from nth line }
function GetMark;
begin
GetMark := intBuff[n].mark
end;
{ PutMark -- put mark m on nth line }
procedure PutMark;
begin
intBuff[n].mark := m
end;
{ BlkMove -- move block of lines n1..n2 to after n3 }
procedure BlkMove;
begin
if (n3 < n1-1) then begin
Reverse (n3+1,n1-1);
Reverse (n1,n2);
Reverse (n3+1,n2)
end
else if (n3 > n2) then begin
Reverse(n1,n2);
Reverse(n2+1,n3);
Reverse(n1,n3)
end
end;
{ Reverse -- reverse intBuff[n1]...intBuff[n2] }
procedure Reverse;
var temp: BufType;
begin
while (n1 < n2) do begin
temp := intBuff[n1];
intBuff[n1] := intBuff[n2];
intBuff[n2] := temp;
n1 := n1 + 1;
n2 := n2 - 1
end
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SkipBl -- skip blanks and tabs s[i] ... }
segment SkipBl;
%include swtools
%include editcons
%include edittype
%include editproc
procedure SkipBl;
begin
while (s[i] = BLANK) or (s[i] = TAB) do
i := i + 1
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SortDriv -- Driver and Quick sort }
program Sort;
%include SWTOOLS
%include ioref
const
inCoreSize = 500;
MERGEORDER = 5;
type
LineType = -> StringType;
fdBufType = array [1..MERGEORDER] of FileDesc;
var
notEof: Boolean;
inBuf: array [1..inCoreSize] of LineType;
inFile: fdBufType;
i: Integer;
temp: StringType;
depth: Integer;
maxDepth: Integer;
procedure GName (n: Integer; var name: StringType);
var
junk: Integer;
temp: String(30);
begin
WriteStr(temp, 'STEMP',n:1,' TEMP A');
name := temp;
end; {GName}
procedure GOpen (var inFile: fdBufType; f1, f2: Integer);
var
name: StringType;
i: 1..MERGEORDER;
begin
for i := 1 to f2-f1+1 do begin
GName (f1+i-1, name);
inFile[i] := MustOpen(name, IOREAD);
end; {for}
end; {GOpen}
procedure GRemove (var inFile: fdBufType; f1, f2: Integer);
var
name: StringType;
i: 1..MERGEORDER;
begin
for i := 1 to f2-f1+1 do begin
FClose (inFile[i]);
GName (f1+i-1, name);
Remove (name);
end; {for}
end; {GRemove}
function MakeFile (n: Integer): FileDesc;
var
name: StringType;
temp: FileDesc;
begin
GName (n, name);
temp := FCreate (name, IOWRITE);
if temp = IOERROR then
Error('Could not create temporary file' || Str(name));
MakeFile := temp;
end; {MakeFile}
procedure PText (nLines: Integer; outFile: FileDesc);
var
i: Integer;
begin
for i := 1 to nLines do begin
PutStr(inBuf[i]@, outFile);
end; {for}
end; {PText}
function GText (var nLines: Integer; inFile: FileDesc): Boolean;
var
temp: StringType;
done: Boolean;
begin
nLines := 1;
done := (GetLine(inBuf[nLines]@, inFile, MAXSTR) = false);
while (not done) do begin
nLines := nLines + 1;
if nLines > inCoreSize then leave;
done := (GetLine(inBuf[nLines]@, inFile, MAXSTR) = false);
end; {while}
nLines := nLines - 1;
GText := done;
end; {GText}
procedure QSort(l,r: integer);
var i,j: integer;
temp, hold: LineType;
begin
if l >= r then return;
depth := depth + 1;
maxDepth := Max (maxDepth, depth);
i := l;
j := r;
temp := inBuf[(i+j) div 2];
repeat
while inBuf[i]@ < temp@ do
i := i+1;
while temp@ < inBuf[j]@ do
j := j-1;
if i <= j then begin
hold := inBuf[i];
inBuf[i] := inBuf[j];
inBuf[j] := hold;
i := i+1;
j := j-1
end
until i > j;
{ if left smaller do: }
if (j - l) < (r - i) then begin
QSort(l,j); {left side first}
QSort(i,r);
end
else begin
QSort(i,r); {right side first}
QSort(l,j);
end; {if}
depth := depth - 1;
end {QSort} ;
{ Merge -- Merge infile[1] .. infile[nf] into outfile }
procedure Merge(var inFile: fdBufType; nf: Integer; outFile: FileDesc);
var
i,j: Integer;
lbp: Integer;
temp: LineType;
fromArray: array [1..MERGEORDER] of Integer;
procedure ReHeap (nf: Integer);
var
i,j,k: Integer;
temp: LineType;
begin
i := 1;
j := 2 * i;
while (j <= nf) do begin
if (j < nf) then { find smaller child }
if inBuf[j]@ > inBuf[j+1]@ then
j := j + 1;
if inBuf[i]@ <= inBuf[j]@ then
i := nf { proper position found, terminate loop }
else begin
k := fromArray[i];
fromArray[i] := fromArray[j];
fromArray[j] := k;
temp := inBuf[i];
inBuf[i] := inBuf[j];
inBuf[j] := temp;
end; {if}
i := j;
j := 2 * i;
end; {while}
end; {while}
procedure PermSort(l,r: Integer);
var
i,j,k: Integer;
temp: LineType;
begin
for i := 1 to r do
fromArray[i] := i;
for i := r downto 2 do
for j := 1 to i-1 do
if inBuf[j]@ > inBuf[j + 1]@ then begin
k := fromArray[j];
fromArray[j] := fromArray[j + 1];
fromArray[j + 1] := k;
temp := inBuf[j];
inBuf[j] := inBuf[j + 1];
inBuf[j + 1] := temp;
end; {if}
end; {PermSort}
begin
j := 1;
for i := 1 to nf do { get one line from each file }
if GetLine(inBuf[j]@, inFile[i], MAXSTR) then
j := j + 1;
nf := j - 1;
PermSort (1, nf); { make initial heap }
while (nf > 0) do begin
PutStr(inBuf[1]@, outFile);
if not
(GetLine(inBuf[1]@, inFile[fromArray[1]], MAXSTR))
then begin
temp := inBuf[1];
inBuf[1] := inBuf[nf];
inBuf[nf] := temp;
fromArray[1] := fromArray[nf];
nf := nf - 1;
end; {if}
ReHeap(nf);
end; {while}
end; {Merge}
var
done: Boolean;
nLines: Integer;
highMark: Integer;
lowMark: Integer;
lim: Integer;
outFile: FileDesc;
name: StringType;
begin
ToolInit;
highMark := 0;
for i := 1 to inCoreSize do
New(inBuf[i]);
repeat { initial formation of runs }
done := GText (nLines, STDIN);
depth := 0;
maxDepth := 0;
QSort(1, nLines);
highMark := highMark + 1;
outFile := MakeFile(highMark);
PText (nLines, outFile);
FClose (outFile);
until (done);
lowMark := 1;
while (lowMark < highMark) do begin { merge runs }
lim := Min(lowMark + MERGEORDER - 1, highMark);
GOpen (inFile, lowMark, lim);
highMark := highMark + 1;
outFile := MakeFile(highMark);
Merge(inFile, lim-lowMark+1, outFile);
FClose (outFile);
GRemove (inFile, lowMark, lim);
lowMark := lowMark + MERGEORDER;
end; {while}
GName (highMark, name); { final cleanup }
outFile := FOpen (name, IOREAD);
FCopy (outFile, STDOUT);
FClose (outFile);
Remove (name);
end.
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SortDriv -- Driver and Quick sort }
program SortDriv;
%include SWTOOLS
%include ioref
const
inCoreSize = 500;
type
LineType = StringPtr;
var
notEof: Boolean;
inBuf: array [1..inCoreSize] of LineType;
i: Integer;
temp: StringType;
procedure PText (nLines: Integer; outFile: FileDesc);
var
i: Integer;
begin
for i := 1 to nLines do
PutStr (inBuf[i]@, outFile);
end; {PText}
function GText (var nLines: Integer; inFile: FileDesc): Boolean;
var
i: Integer;
temp: StringType;
begin
nLines := 0;
done := (GetLine(temp, inFile, MAXSTR) = false);
while (not done) and (nLines < inCoreSize) do begin
nLines := nLines + 1;
inBuf[nLines]@ := Str(temp);
done := (GetLine(temp, inFile, MAXSTR) = false);
end; {while}
end; {GText}
procedure QSort(l,r: integer);
var i,j: integer;
temp, hold: LineType;
begin
i := l;
j := r;
temp := inBuf[(i+j) div 2];
repeat
while inBuf[i]@ < temp@ do
i := i+1;
while temp@ < inBuf[j]@ do
j := j-1;
if i <= j then begin
hold := inBuf[i];
inBuf[i] := inBuf[j];
inBuf[j] := hold;
i := i+1;
j := j-1
end
until i > j;
if l < j then
QSort(l,j);
if i < r then
QSort(i,r)
end {QSort} ;
var
done: Boolean;
nLines: Integer;
high: Integer;
outFile: FileDesc;
begin
ToolInit;
high := 0;
for i := 1 to inCoreSize do
New(inBuf[i], SizeOf(StringType));
repeat { initial formation of runs }
done := GText (nLines, STDIN);
QSort(1, nLines);
high := high + 1;
outFile := MakeFile(high);
PText (nLines, outFile);
Close (outFile);
until (done);
low := 1;
while (low < high) do begin { merge runs }
lim := Min(low + MERGEORDER - 1, high);
GOpen (inFile, low, lim);
high := high + 1;
outFile := MakeFile(high);
Merge(inFile, lim-low+1, outFile);
Close (outFile);
GRemove (inFile, low, lim);
low := low + MERGEORDER;
end; {while}
GName (high, name) { final cleanup }
outFile := FOpen (name, IOREAD);
FCopy (outFile, STDOUT);
Close (outFile);
Remove (name);
end.
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ StClose -- insert closure entry at pat[j] }
segment STClose;
%include swtools
%include patdef
procedure StClose;
var
jp, jt: Integer;
junk: Boolean;
begin
for jp := j-1 downto lastJ do begin
jt := jp + CLOSIZE;
junk := AddStr(pat[jp], pat, jt, MAXPAT)
end;
j := j + CLOSIZE;
pat[lastJ] := CLOSURE { where original pattern began }
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ StrIndex -- find position of character c in string s }
segment StrIndex;
%include swtools
function StrIndex;
var
i: Integer;
begin
i := 1;
while (s[i] <> c) and (s[i] <> ENDSTR) do
i := i + 1;
if (s[i] = ENDSTR) then
StrIndex := 0
else
StrIndex := i
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ StrLength -- determine length of swtools string }
segment StrLength;
%include swtools
function StrLength;
var
i: Integer;
begin
i := LBound(s);
while (s[i] <> ENDSTR) and (i < MAXSTR) do
i := i + 1;
StrLength := i - LBound(s)
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SubLine -- substitute sub for pat in lin and print }
segment SubLine;
%include swtools
%include patdef
%include subdef
%include matchdef
procedure SubLine;
var
i, lastm, m: Integer;
junk: Boolean;
begin
lastm := 0;
i := 1;
while (lin[i] <> ENDSTR) do begin
m := AMatch(lin, i, pat, 1);
if (m > 0) and (lastm <> m) then begin
{ replace substituted text }
PutSub(lin, i, m, sub);
lastm := m
end;
if (m = 0) or (m = i) then begin
{ no match or null match }
PutC(lin[i]);
i := i + 1
end
else { skip matched text }
i := m
end
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SubSt -- substitute "sub" for occurrences of pattern }
segment SubSt;
%include swtools
%include editcons
%include edittype
%include editproc
%include editref
%include matchdef
%include subdef
function SubSt;
var
new, old: StringType;
j, k, lastm, line, m: Integer;
stat: STCode;
done, subbed, junk: Boolean;
begin
if (glob) then
stat := OK
else
stat := ERR;
done := (line1 <= 0);
line := line1;
while (not done) and (line <= line2) do begin
j := 1;
subbed := false;
GetTxt(line, old);
lastm := 0;
k := 1;
while (old[k] <> ENDSTR) do begin
if (gFlag) or (not subbed) then
m := AMatch(old, k, pat, 1)
else
m := 0;
if (m > 0) and (lastm <> m) then begin
{ replace matched text }
subbed := true;
CatSub(old, k, m, sub, new, j, MAXSTR);
lastm := m
end;
if (m = 0) or (m = k) then begin
{ no match or null match }
junk := AddStr(old[k], new, j, MAXSTR);
k := k + 1
end
else
{ skip matched text }
k := m
end;
if (subbed) then begin
if (not AddStr(ENDSTR, new, j, MAXSTR)) then begin
stat := ERR;
done := true
end
else begin
stat := LnDelete(line, line, stat);
stat := PutTxt(new);
line2 := line2 + curLn - line;
line := curLn;
if (stat = ERR) then
done := true
else
stat := OK
end
end;
line := line + 1
end;
SubSt := stat
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ SW[edit] -- main routine for text editor }
program SW;
%include swtools
%include editcons
%include edittype
%include editproc
var
curSave, i: Integer;
status: STCode;
more: Boolean;
argIndex: Integer;
def line1: Integer; { first line number }
def line2: Integer; { second line number }
def nLines: Integer; { # lines in buffer }
def curLn: Integer; { current line: value of dot }
def lastLn: Integer; { last line: value of $ }
def pat: StringType; { pattern }
def lin: StringType; { input line }
def saveFile: StringType; { file name }
value
line1 := 0;
line2 := 0;
nLines := 0;
begin
ToolInit;
SetBuf;
pat[1] := ENDSTR;
saveFile[1] := ENDSTR;
i := 1;
for argIndex := 1 to Nargs do
if GetArg(argIndex, lin, MAXSTR) then begin
SCopy (lin, 1, saveFile, i);
i := StrLength(saveFile) + 2;
saveFile[i-1] := BLANK
end;
i := 1;
if saveFile[1] <> ENDSTR then
if (not GetFid(saveFile, i, saveFile)) then
saveFile[1] := ENDSTR;
if saveFile[1] <> ENDSTR then
if (DoRead(0, saveFile) = ERR) then
Message('Cannot open input file');
if (OptIsOn(promptFlag)) then begin
PutC(COLON);
PutC(NEWLINE)
end;
more := GetLine(lin, STDIN, MAXSTR);
while (more) do begin
i := 1;
curSave := curLn;
if (GetList(lin, i, Status) = OK) then begin
if (CKGlob(lin, i, status) = OK) then
status := DoGlob(lin, i, curSave, status)
else if (status <> ERR) then
status := DoCmd(lin, i, false, status)
{ else error - do nothing }
end;
if (status = ERR) then begin
Message('eh?');
curLn := Min(curSave, lastLn)
end
else if (status = ENDDATA) then
more := false;
{ else ok }
if (more) then begin
if OptIsOn(promptFlag) then begin
PutC(COLON);
PutC(NEWLINE)
end;
more := GetLine(lin, STDIN, MAXSTR)
end
end;
ClrBuf
end.
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Change -- change "from" into "to" on each line }
program swch;
%include swtools
%include patdef
%include matchdef
%include subdef
var
lin, pat, sub, arg: StringType;
begin
ToolInit;
if (not GetArg(1, arg, MAXSTR)) then
Error('usage: change from <to>');
if (not GetPat(arg, pat)) then
Error('change: illegal "from" pattern');
if (not GetArg(2, arg, MAXSTR)) then
arg[1] := ENDSTR;
if (not GetSub(arg, sub)) then
Error('change: illegal "to" string');
while (GetLine(lin, STDIN, MAXSTR)) do
SubLine(lin, pat, sub)
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Translit -- map characters }
program SWTr;
%include swtools
%include patdef
var
arg, fromSet, toSet: StringType;
c: CharType;
i, lastTo: 0..MAXSTR;
allBut, squash: Boolean;
{ XIndex -- conditionally invert value from strindex }
function XIndex (var inSet: StringType; c: CharType;
allBut: Boolean; lastTo: Integer): Integer;
begin
if (c = ENDFILE) then
XIndex := 0
else if (not allBut) then
XIndex := StrIndex(inSet,c)
else if (StrIndex(inSet,c) > 0) then
XIndex := 0
else
XIndex := lastTo + 1
end;
begin
ToolInit;
if (not GetArg(1, arg, MAXSTR)) then
Error('usage: translit from to');
allBut := (arg[1] = NEGATE);
if allBut then
i := 2
else
i := 1;
if (not MakeSet(arg, i, fromSet, MaxStr)) then
Error('translit: "from" set too large');
if (not GetArg(2,arg, MAXSTR)) then
toSet[1] := ENDSTR
else if (not MakeSet(arg, 1, toSet, MAXSTR)) then
Error('translit: "to" set too large')
else if (StrLength(fromSet) < StrLength(toSet)) then
Error('Translit: "from" shorter than "to"');
lastTo := StrLength(toSet);
squash := (StrLength(fromSet) > lastTo) or (allBut);
repeat
i := XIndex(fromSet, GetC(c), allBut, lastTo);
if (squash) and (i >= lastTo) and (lastTo > 0) then begin
PutC(toSet[lastTo]);
repeat
i := XIndex(fromSet, GetC(c), allBut, lastTo)
until (i < lastTo)
end;
if (c <> ENDFILE) then begin
if (i > 0) and (lastTo > 0) then { translate }
PutC(toSet[i])
else if (i = 0) then { copy }
PutC(c)
{ else delete (don't print) }
end
until (c = ENDFILE)
end;
{
Copyright (c) 1981
By: Bell Telephone Laboratories, Inc. and
Whitesmiths, Ltd.,
This software is derived from the book
"Software Tools In Pascal", by
Brian W. Kernighan and P.J. Plauger
Addison-Wesley, 1981
ISBN 0-201-10342-7
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Term -- Evaluate term of arithmetic expression }
segment Term;
%include swtools
%include macdefs
%include macproc
function Term;
var
v: Integer;
t: CharType;
begin
v := Factor(s, i);
t := GNBChar(s, i);
while (t in [STAR, SLASH, PERCENT]) do begin
i := i + 1;
case t of
STAR:
v := v * Factor(s, i);
SLASH:
v := v div Factor(s, i);
PERCENT:
v := v mod Factor(s, i)
end {case};
t := GNBChar(s, i)
end {while};
Term := v
end { Term };
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ ToolInit -- (CMS) standard program prologue }
segment ToolInit;
%include swtools
%include iodef
def openList: array [FileDesc] of IOBlock;
def cmdLin: StringType;
def cmdArgs: 0..MAXARG;
def cmdIdx: array [1..MAXARG] of 1..MAXSTR;
def termInput: Boolean;
ref ERRORIO: Boolean;
value
termInput := false;
procedure ToolInit;
var
t: 1..MAXSTR;
i: FileDesc;
idx: 1..MAXSTR;
delim: CharType;
PARMSTRING: String(MAXSTR);
fileName: StringType;
cmdLength: 0..MAXSTR;
redirIn: Boolean;
j: 1..MAXSTR;
dummy: StringType;
okay: Boolean;
tempArgs: 0..MAXARG;
XFileName: String(MAXSTR);
k: 0..MAXSTR;
nextChar: 1..MAXSTR;
begin
TermIn(input);
TermOut(output);
for i := STDIN to MAXOPEN do
openList[i].mode := IOAVAIL;
openList[STDERR].mode := IOWRITE;
TermOut(openList[STDERR].fileVar);
PARMSTRING := PARMS;
if (Length(PARMSTRING) >= 1) and (PARMSTRING[1] = STAR) then begin
WriteLn('Input Command Parameters:');
ReadLn(PARMSTRING);
PARMSTRING := PARMSTRING || SubStr(PARMS, 2, Length(PARMS)-1)
end;
for idx := 1 to Length(PARMSTRING) do
cmdLin[idx] := PARMSTRING[idx];
cmdLin[Length(PARMSTRING) + 1] := NEWLINE;
cmdLin[Length(PARMSTRING) + 2] := ENDSTR;
idx := 1;
cmdArgs := 0;
while ((cmdLin[idx] <> ENDSTR) and
(cmdLin[idx] <> NEWLINE)) do begin
while (cmdLin[idx] = BLANK) do
idx := idx + 1;
if (cmdLin[idx] <> NEWLINE) then begin
delim := BLANK;
cmdArgs := cmdArgs + 1;
if (cmdLin[idx] = SQUOTE) or
(cmdLin[idx] = DQUOTE) then begin
cmdIdx[cmdArgs] := idx + 1;
delim := cmdLin[idx];
idx := idx + 1
end
else
cmdIdx[cmdArgs] := idx;
while ((cmdLin[idx] <> NEWLINE) and
(cmdLin[idx] <> delim)) do
idx := idx + 1;
cmdLin[idx] := ENDSTR;
idx := idx + 1;
end
end;
j := 1;
tempArgs := cmdArgs;
while (j <= cmdArgs) do begin
okay := GetArg(j, dummy, MAXSTR);
j := j + 1;
if (dummy[1] = LESS) or (dummy[1] = GREATER) then begin
if dummy[1] = LESS then
redirIn := true
else
redirIn := false;
SCopy(dummy, 2, fileName, 1);
nextChar := StrLength(fileName) + 1;
tempArgs := tempArgs - 1;
k := j;
while (k <= cmdArgs) do begin
okay := GetArg(k, dummy, MAXSTR);
k := k + 1;
if okay and (dummy[1] <> LESS) and
(dummy[1]<> GREATER) then begin
tempArgs := tempArgs - 1;
fileName[nextChar] := BLANK;
nextChar := nextChar + 1;
SCopy(dummy, 1, fileName, nextChar);
nextChar := StrLength(fileName) + 1;
j := j + 1;
end
else
k := cmdArgs + 1;
end;
t := 1;
okay := GetFid(fileName, t, fileName);
if not okay then
Error('Bad redirection file name');
CvtSTS(fileName, XFileName);
if redirIn then begin
openList[STDIN].mode := IOREAD;
Reset(openList[STDIN].fileVar, 'NAME=' ||
XFileName);
termInput := false;
if ERRORIO then begin
openList[STDIN].mode := IOAVAIL;
Error('Cannot open STDIN file');
ERRORIO := false
end
end
else begin
openList[STDOUT].mode := IOWRITE;
Remove(fileName);
ReWrite(openList[STDOUT].fileVar,
'LRECL=1000,NAME=' || XFileName);
if ERRORIO then begin
openList[STDOUT].mode := IOAVAIL;
ERRORIO := false
end
end
end
end;
cmdArgs := tempArgs;
if openList[STDIN].mode = IOAVAIL then begin
TermIn(openList[STDIN].fileVar);
openList[STDIN].mode := IOREAD;
termInput := true;
end;
if openList[STDOUT].mode = IOAVAIL then begin
TermOut(openList[STDOUT].fileVar);
openList[STDOUT].mode := IOWRITE;
end;
end;
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Unique -- strip adjacent duplicate lines in a file }
program Unique;
%include swtools
var
buffer: array [0..1] of StringType;
bufNum: 0..1;
sameRecCount: Integer;
counts: Boolean;
lastRec: StringType;
begin
ToolInit;
buffer[1,1] := ENDSTR;
buffer[0,1] := NEWLINE; { just so's they're different }
lastRec := buffer[1];
counts := NArgs > 0;
bufNum := 0;
sameRecCount := 0;
while(GetLine(buffer[bufNum], STDIN, MAXSTR)) do begin
if (not Equal(buffer[0], buffer[1])) then begin
if counts and (sameRecCount <> 0) then begin
PutDec(sameRecCount, 6);
PutC(BLANK)
end;
if sameRecCount <> 0 then
PutStr(lastRec, STDOUT);
lastRec := buffer[bufNum];
sameRecCount := 1
end
else
sameRecCount := sameRecCount + 1;
bufNum := (1 - bufNum)
end;
if sameRecCount <> 0 then begin
if counts then begin
PutDec(sameRecCount, 6);
PutC(BLANK)
end;
PutStr(lastRec, STDOUT)
end
end.
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ UnRotate -- Unrotate lines rotated by first half of KWIC }
Program UnRotate;
%include swtools
const
MAXOUT = 80;
MIDDLE = 40;
FOLD = DOLLAR;
var
inBuf, outBuf: StringType;
tempFile2: FileDesc;
i, j, f: Integer;
begin
ToolInit;
tempFile2 := STDIN;
while (GetLine(inBuf, tempFile2, MAXSTR)) do begin
for i := 1 to MAXOUT -1 do
outBuf[i] := BLANK;
f := StrIndex(inBuf, FOLD);
j := MIDDLE - 1;
for i := StrLength(inBuf)-1 downto f+1 do begin
outBuf[j] := inBuf[i];
j := j - 1;
if (j <= 0) then
j := MAXOUT - 1
end;
j := MIDDLE + 3;
for i := 1 to f-1 do begin
outBuf[j] := inBuf[i];
j := j mod (MAXOUT - 1) + 1
end;
for j := 1 to MAXOUT - 1 do
if (outBuf[j] <> BLANK) then
i := j;
outBuf[i+1] := ENDSTR;
PutStr(outBuf, STDOUT);
PutC(NEWLINE)
end
end;
{
Copyright (c) 1982
By: Chris Lewis
Right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commerical gain and that this copyright notice remains
intact.
}
{ Wc -- Word Counting program }
program Wc;
%include SWTOOLS
var
buffer: StringType;
numChars: Integer;
numWords: Integer;
numLines: Integer;
i: Integer;
lineLength: Integer;
inWord: Boolean;
begin
ToolInit;
numChars := 0;
numWords := 0;
numLines := 0;
while (GetLine(buffer, STDIN, MAXSTR)) do begin
inWord := false;
numLines := numLines + 1;
lineLength := StrLength (buffer);
numChars := numChars + lineLength;
for i := 1 to lineLength do
if (buffer[i] = BLANK) then
inWord := false
else if (not inWord) then begin
inWord := true;
numWords := numWords + 1;
end; {if}
end; {while}
PutDec(numChars, 7);
PutDec(numWords, 7);
PutDec(numLines, 7);
end; {Wc}
More information about the Comp.sources.unix
mailing list