Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.UUCP Posting-Version: version B 2.10.2 9/3/84; site genrad.UUCP Path: seismo!harvard!think!mit-eddie!genrad!sources-request From: sources-request@genrad.UUCP Newsgroups: mod.sources Subject: Software Tools in Pascal (Part 3 of 6) Message-ID: <940@genrad.UUCP> Date: 12 Jul 85 23:12:48 GMT Sender: john@genrad.UUCP Lines: 1590 Approved: john@genrad.UUCP Mod.sources: Volume 2, Issue 9 Submitted by: ihnp4!mnetor!clewis (Chris Lewis) #!/bin/sh echo 'Start of pack.out, part 03 of 06:' echo 'x - amatch.pascal' sed 's/^X//' > amatch.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ AMatch -- look for match of pat[i]... at lin[offset]... } Xsegment AMatch; X%include swtools X%include patdef X%include matchdef X%include metadef Xfunction RAMatch (var lin: StringType; offset: Integer; X var pat: StringType; j: Integer): Integer; X forward; Xfunction AMatch; Xvar X k: Integer; Xbegin X metaStackPointer := 1; X metaIndex := 1; X metaTable := nullMetaTable; X metaTable[0].first := offset; X k := RAMatch(lin, offset, pat, j); X metaTable[0].last := k; X AMatch := k; Xend; X{ RAMatch -- new AMatch with metas } Xfunction RAMatch; Xvar X i, k: Integer; X metaStackTemp: Integer; X done: Boolean; Xbegin X done := false; X while (not done) and (pat[j] <> ENDSTR) do X if (pat[j] = CLOSURE) then begin X metaStackTemp := metaStackPointer; X j := j + PatSize(pat, j); X i := offset; X {match as many as possible } X while (not done) and (lin[i] <> ENDSTR) do X if (not OMatch(lin, i, pat, j)) then begin X metaStackPointer := metaStackTemp; X done := true; X end X else X metaStackTemp := metaStackPointer; X { i points to input character that made us fail } X { match rest of pattern against rest of input } X { shrink closure by 1 after each failure } X done := false; X while (not done) and (i >= offset) do begin X metaStackTemp := metaStackPointer; X k := RAMatch(lin, i, pat, j+PatSize(pat, j)); X if (k > 0) then { matched rest of pattern} X done := true X else begin X metaStackPointer := metaStackTemp; X i := i - 1 X end X end; X offset := k; { if k = 0 failure, else success } X done := true X end X else if (not OMatch(lin, offset, pat, j)) then begin X offset := 0; X done := true X end X else { OMatch succeeded on this pattern element } X j := j + PatSize(pat, j); X RAMatch := offset Xend; / echo 'x - default.pascal' sed 's/^X//' > default.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ Default -- set Defaulted line numbers } Xsegment Default; X%include swtools X%include editcons X%include edittype X%include editproc X%include editref Xfunction Default; Xbegin X if (nLines = 0) then begin X line1 := def1; X line2 := def2 X end; X if (line1 > line2) or (line1 <= 0) then X status := ERR X else X status := OK; X Default := status Xend; / echo 'x - eval.pascal' sed 's/^X//' > eval.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ Eval -- expand args i..j: do built-in or push back defn } Xsegment Eval; X%include swtools X%include macdefs X%include macproc Xprocedure Eval; Xvar X argNo, k, t: Integer; X temp: StringType; X l,m,n: Integer; Xbegin X t := argStk[i]; X if traceing then begin X MPutStr('Traceing -$E', STDOUT); X case td of X DEFTYPE: X MPutStr('define($N$E', STDOUT); X EXPRTYPE: X MPutStr('expr($N$E', STDOUT); X SUBTYPE: X MPutStr('substr($N$E', STDOUT); X IFTYPE: X MPutStr('ifelse($N$E', STDOUT); X LENTYPE: X MPutStr('len($N$E', STDOUT); X CHQTYPE: X MPutStr('changeq($N$E', STDOUT) X otherwise X MPutStr('macro expansion:$N$E', STDOUT); X end {case}; X for l := i + 2 to j do begin X CsCopy(evalStk, argStk[l], temp); X PutStr(temp, STDOUT); X PutCF(NEWLINE, STDOUT) X end {for}; X MPutStr('<<<<<<$N$E', STDOUT); X end {if}; X X if (td = DEFTYPE) then X DoDef(argStk, i, j) X else if (td = EXPRTYPE) then X DoExpr(argStk, i, j) X else if (td = SUBTYPE) then X DoSub(argStk, i, j) X else if (td = IFTYPE) then X DoIf(argStk, i, j) X else if (td = LENTYPE) then X DoLen(argStk, i, j) X else if (td = CHQTYPE) then X DoChq(argStk, i, j) X else begin X k := t; X while (evalStk[k] <> ENDSTR) do X k := k + 1; X k := k - 1; { last character of data } X while (k > t) do begin X if (evalStk[k-1] <> ARGFLAG) then X PutBack(evalStk[k]) X else begin X argNo := Ord(evalStk[k]) - Ord(DIG0); X if (argNo >= 0) and (argNo < j-1) then begin X CsCopy(evalStk, argStk[i+argNo+1], temp); X PBStr(temp) X end {if}; X k := k - 1 { skip over $ } X end {if}; X k := k - 1 X end {while}; X if (k = t) then { do last character } X PutBack(evalStk[k]) X end {if} Xend {Eval}; / echo 'x - kwic.pascal' sed 's/^X//' > kwic.pascal << '/' X{ X Copyright (c) 1982 X By: Chris Lewis X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ Kwic -- make Keyword in Context index } Xprogram Kwic; X%include swtools X%include cms Xconst X FOLD = DOLLAR; Xvar X buf: StringType; X tempFile1: FileDesc; X tempFile2: FileDesc; X fileName: StringType; X RCode: Integer; X{ Rotate -- output rotated lines } Xprocedure Rotate (var buf: StringType; n: Integer); Xvar X i: Integer; Xbegin X i := n; X while (buf[i] <> NEWLINE) and (buf[i] <> ENDSTR) do begin X PutCF(buf[i], tempFile1); X i := i + 1 X end; X PutCF(FOLD, tempFile1); X for i := 1 to n - 1 do X PutCF(buf[i], tempFile1); X PutCF(NEWLINE, tempFile1) Xend; X{ PutRot -- create lines with keyword at front } Xprocedure PutRot(var buf: StringType); Xvar X i: Integer; Xbegin X i := 1; X while (buf[i] <> NEWLINE) and (buf[i] <> ENDSTR) do begin X if (IsAlphaNum(buf[i])) then begin X Rotate(buf, i); { token starts at "i" } X repeat X i := i + 1 X until (not IsAlphaNum(buf[i])) X end; X i := i + 1 X end Xend; X/* temporarily commented out until CMS cmd works X{ UnRotate -- Unrotate lines rotated by first half of KWIC } Xprocedure UnRotate; Xconst X MAXOUT = 80; X MIDDLE = 40; Xvar X inBuf, outBuf: StringType; X i, j, f: Integer; Xbegin X while (GetLine(inBuf, tempFile2, MAXSTR)) do begin X for i := 1 to MAXOUT -1 do X outBuf[i] := BLANK; X f := StrIndex(inBuf, FOLD); X j := MIDDLE - 1; X for i := StrLength(inBuf)-1 downto f+1 do begin X outBuf[j] := inBuf[i]; X j := j - 1; X if (j <= 0) then X j := MAXOUT - 1 X end; X j := MIDDLE + 3; X for i := 1 to f-1 do begin X outBuf[j] := inBuf[i]; X j := j mod (MAXOUT - 1) + 1 X end; X for j := 1 to MAXOUT - 1 do X if (outBuf[j] <> BLANK) then X i := j; X outBuf[i+1] := ENDSTR; X PutStr(outBuf, STDOUT); X PutC(NEWLINE) X end Xend; X*/ X{ Main program for Kwic } Xbegin X ToolInit; X/* Cannot get CMS to call sort properly X CvtSST('KWIC1 TEMP A', fileName); X tempFile1 := FOpen(fileName, IOWRITE); X if tempFile1 = IOERROR then X Error('Cannot open first KWIC temporary'); X*/ X/* */ X tempFile1 := STDOUT; X/* */ X while (GetLine(buf, STDIN, MAXSTR)) do X PutRot(buf); X/* X Cms('EXEC OSSORT KWIC1 TEMP A KWIC2 TEMP A 1 10', RCode); X if RCode <> 0 then X Error('KWIC: BNRSORT failed'); X CvtSST('KWIC2 TEMP A', fileName); X tempFile2 := FOpen(fileName, IOREAD); X if tempFile2 = IOERROR then X Error('KWIC: cannot open sorted rotated file'); X UnRotate X*/ Xend. / echo 'x - macro.pascal' sed 's/^X//' > macro.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ Macro -- expand macros with arguments } Xprogram Macro; X%include swtools X%include macdefs X%include macproc Xbegin X ToolInit; X InitMacro; X Install(defName, null, DEFTYPE); X Install(exprName, null, EXPRTYPE); X Install(subName, null, SUBTYPE); X Install(ifName, null, IFTYPE); X Install(lenName, null, LENTYPE); X Install(chqName, null, CHQTYPE); X X cp := 0; X ap := 1; X ep := 1; X while (GetTok(token, MAXTOK) <> ENDFILE) do X if (IsLetter(token[1])) then begin X if (not Lookup(token, defn, tokType)) then X PutTok(token) X else begin X cp := cp + 1; X if (cp > CALLSIZE) then X Error('Macro: call stack overflow'); X callStk[cp] := ap; X typeStk[cp] := tokType; X ap := Push(ep, argStk, ap); X PutTok(defn); { push definition } X PutChr(ENDSTR); X ap := Push(ep, argStk, ap); X PutTok(token); { stack name } X PutChr(ENDSTR); X ap := Push(ep, argStk, ap); X t := GetTok(token, MAXTOK); { peek at next } X PBStr(token); X if (t <> LPAREN) then begin { add () } X PutBack(RPAREN); X PutBack(LPAREN); X end; X pLev[cp] := 0 X end X end X else if (token[1] = lQuote) then begin { strip quotes } X nlPar := 1; X repeat X t := GetTok(token, MAXTOK); X if (t = rQuote) then X nlPar := nlPar - 1 X else if (t = lQuote) then X nlPar := nlPar + 1 X else if (t = ENDFILE) then X Error('Macro: missing right quote'); X if nlPar > 0 then X PutTok(token) X until (nlPar = 0) X end X else if (cp = 0) then { not in macro at all } X PutTok(token) X else if (token[1] = LPAREN) then begin X if (pLev[cp] > 0) then X PutTok(token); X pLev[cp] := pLev[cp] + 1 X end {then} X else if (token[1] = RPAREN) then begin X pLev[cp] := pLev[cp] - 1; X if (pLev[cp] > 0) then X PutTok(token) X else begin { end of argument list } X PutChr(ENDSTR); X Eval(argStk, typeStk[cp], callStk[cp], ap - 1); X ap := callStk[cp]; { pop eval stack } X ep := argStk[ap]; X cp := cp - 1 X end X end X else if (token[1] = COMMA) and (pLev[cp] = 1) then begin X PutChr(ENDSTR); { new argument } X ap := Push(ep, argStk, ap) X end {then} X else X PutTok(token); { just stack it } X if (cp <> 0) then X Error('Macro: unexpected end of input') Xend. / echo 'x - makepat.pascal' sed 's/^X//' > makepat.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ MakePat -- make pattern from arg[i], terminate at delim } Xsegment MakePat; X%include swtools X%include patdef X%include metadef Xfunction MakePat; Xvar X i,j, lastJ, lj: Integer; X k: Integer; X done, junk: Boolean; Xbegin X j := 1; { pat index} X i := start; { arg index} X metaStackPointer := 0; X metaIndex := 1; X done := false; X k := start; X while (arg[k] <> delim) and ((k + 2) <= MAXSTR) do X if (arg[k] = NEWLINE) or (arg[k] = ENDSTR) then begin X arg[k] := delim; X arg[k+1] := NEWLINE; X arg[k+2] := ENDSTR; X end X else X k := k + 1; X X while (not done) and (arg[i] <> delim) and X (arg[i] <> ENDSTR) do begin X lj := j; X if (arg[i] = ANY) then X junk := AddStr(ANY, pat, j, MAXPAT) X else if (arg[i] = BOL) and (i = start) then X junk := AddStr(BOL, pat, j, MAXPAT) X else if (arg[i] = BOM) then begin X junk := AddStr(BOM, pat, j, MAXPAT); X metaStackPointer := metaStackPointer + 1; X metaIndex := metaIndex + 1; X if (metaStackPointer > 9) or X (metaIndex > 9) then X done := true X end X else if (arg[i] = EOM) and (metaStackPointer > 0) then begin X junk := AddStr(EOM, pat, j, MAXPAT); X metaStackPointer := metaStackPointer - 1; X if (metaStackPointer < 0) then X done := true X end X else if (arg[i] = EOL) and (arg[i+1] = delim) then X junk := AddStr(EOL, pat, j, MAXPAT) X else if (arg[i] = CCL) then X done := (GetCCL(arg, i, pat, j) = false) X else if (arg[i] = CLOSURE) and (i > start) then begin X lj := lastJ; X if (pat[lj] in [BOL, EOL, CLOSURE]) then X done := true { force loop termination } X else X STClose(pat, j, lastJ) X end X else begin X junk := AddStr(LITCHAR, pat, j, MAXPAT); X junk := AddStr(Esc(arg,i), pat, j, MAXPAT) X end; X lastJ := lj; X if (not done) then X i := i + 1; X end; X if (done) or (arg[i] <> delim) or (metaStackPointer <> 0) then X MakePat := 0 X else if (not AddStr(ENDSTR, pat, j, MAXPAT)) then X MakePat := 0 { no room} X else X MakePat := i; Xend; / echo 'x - setbuf.pascal' sed 's/^X//' > setbuf.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ SetBuf -- set Buffer and other Buffer handlers (new-free) } Xsegment SetBuf; X%include swtools X%include editcons X%include edittype X%include editproc X%include editref Xconst X MAXLINES = 10000; Xtype X BufType = { in-memory new/free buffer handler } X record X txt: StringPtr; { text of line } X mark: Boolean; { mark for line } X end; Xref OUTOFSPACE: Boolean; Xstatic heapMark: @ Integer; Xstatic { This is a PRIVATE buffer } X intBuff: array [0..MAXLINES] of BufType; X{ SetBuf -- (new-free) initialize line storage Buffer } Xprocedure SetBuf; Xvar X i: 0..MAXLINES; Xbegin X Mark(heapMark); X for i := 0 to MAXLINES do X intBuff[i].txt := nil; X curLn := 0; X lastLn := 0 Xend; X{ ClrBuf -- (new-free) release storage } Xprocedure ClrBuf; Xvar i: 0..MAXLINES; Xbegin X Release(heapMark) Xend; X{ GetTxt -- (new-free) get text from line n into s } Xprocedure GetTxt; Xbegin X { note: the null is already there } X if intBuff[n].txt = nil then X s[1] := ENDSTR X else X s := intBuff[n].txt@; Xend; X{ PutTxt -- (new-free) put text from lin after curLn } Xfunction PutTxt; Xvar X sSize: Integer; Xbegin X PutTxt := ERR; X if (lastLn < MAXLINES) then begin X lastLn := lastLn + 1; X sSize := StrLength(lin) + 1; X if intBuff[lastLn].txt = nil then X New(intBuff[lastLn].txt, sSize) X else if (sSize > MaxLength(intBuff[lastLn].txt@)) then begin X Dispose(intBuff[lastLn].txt); X New(intBuff[lastLn].txt, sSize) X end; X { Check for New failing } X if OUTOFSPACE then begin X intBuff[lastLn].txt := nil; { insurance } X lastLn := lastLn - 1; { insurance } X OUTOFSPACE := false; X Message('out of space, write out and edit again'); X return { error } X end; X WriteStr(intBuff[lastLn].txt@, lin:sSize); X PutMark(lastLn, false); X BlkMove(lastLn, lastLn, curLn); X curLn := curLn + 1; X PutTxt := OK X end Xend; X{ GetMark -- get mark from nth line } Xfunction GetMark; Xbegin X GetMark := intBuff[n].mark Xend; X{ PutMark -- put mark m on nth line } Xprocedure PutMark; Xbegin X intBuff[n].mark := m Xend; X{ BlkMove -- move block of lines n1..n2 to after n3 } Xprocedure BlkMove; Xbegin X if (n3 < n1-1) then begin X Reverse (n3+1,n1-1); X Reverse (n1,n2); X Reverse (n3+1,n2) X end X else if (n3 > n2) then begin X Reverse(n1,n2); X Reverse(n2+1,n3); X Reverse(n1,n3) X end Xend; X{ Reverse -- reverse intBuff[n1]...intBuff[n2] } Xprocedure Reverse; Xvar temp: BufType; Xbegin X while (n1 < n2) do begin X temp := intBuff[n1]; X intBuff[n1] := intBuff[n2]; X intBuff[n2] := temp; X n1 := n1 + 1; X n2 := n2 - 1 X end Xend; / echo 'x - sortdriv.pascal' sed 's/^X//' > sortdriv.pascal << '/' X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ SortDriv -- Driver and Quick sort } Xprogram SortDriv; X%include SWTOOLS X%include ioref Xconst X inCoreSize = 500; Xtype X LineType = StringPtr; Xvar X notEof: Boolean; X inBuf: array [1..inCoreSize] of LineType; X i: Integer; X temp: StringType; Xprocedure PText (nLines: Integer; outFile: FileDesc); Xvar X i: Integer; Xbegin X for i := 1 to nLines do X PutStr (inBuf[i]@, outFile); Xend; {PText} Xfunction GText (var nLines: Integer; inFile: FileDesc): Boolean; Xvar X i: Integer; X temp: StringType; Xbegin X nLines := 0; X done := (GetLine(temp, inFile, MAXSTR) = false); X while (not done) and (nLines < inCoreSize) do begin X nLines := nLines + 1; X inBuf[nLines]@ := Str(temp); X done := (GetLine(temp, inFile, MAXSTR) = false); X end; {while} Xend; {GText} X Xprocedure QSort(l,r: integer); X var i,j: integer; X temp, hold: LineType; Xbegin X i := l; X j := r; X temp := inBuf[(i+j) div 2]; X repeat X while inBuf[i]@ < temp@ do X i := i+1; X while temp@ < inBuf[j]@ do X j := j-1; X if i <= j then begin X hold := inBuf[i]; X inBuf[i] := inBuf[j]; X inBuf[j] := hold; X i := i+1; X j := j-1 X end X until i > j; X if l < j then X QSort(l,j); X if i < r then X QSort(i,r) Xend {QSort} ; Xvar X done: Boolean; X nLines: Integer; X high: Integer; X outFile: FileDesc; Xbegin X ToolInit; X high := 0; X for i := 1 to inCoreSize do X New(inBuf[i], SizeOf(StringType)); X repeat { initial formation of runs } X done := GText (nLines, STDIN); X QSort(1, nLines); X high := high + 1; X outFile := MakeFile(high); X PText (nLines, outFile); X Close (outFile); X until (done); X low := 1; X while (low < high) do begin { merge runs } X lim := Min(low + MERGEORDER - 1, high); X GOpen (inFile, low, lim); X high := high + 1; X outFile := MakeFile(high); X Merge(inFile, lim-low+1, outFile); X Close (outFile); X GRemove (inFile, low, lim); X low := low + MERGEORDER; X end; {while} X GName (high, name) { final cleanup } X outFile := FOpen (name, IOREAD); X FCopy (outFile, STDOUT); X Close (outFile); X Remove (name); Xend. / echo 'x - swtools.copy' sed 's/^X//' > swtools.copy << '/' X*COPY NOTICE X{ X Copyright (c) 1981 X By: Bell Telephone Laboratories, Inc. and X Whitesmiths, Ltd., X X This software is derived from the book X "Software Tools In Pascal", by X Brian W. Kernighan and P.J. Plauger X Addison-Wesley, 1981 X ISBN 0-201-10342-7 X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X*COPY SWTOOLS X{ SWTOOLS -- Software Tools Environment Definitions } X%print off Xconst X IOERROR = 0; { status values for open files } X STDIN = 1; X STDOUT = 2; X STDERR = 3; X X{ other IO-related stuff } X X IOAVAIL = 1; X IOREAD = 2; X IOWRITE = 3; X MAXOPEN = 10; X MAXARG = 30; X X{ universal manifest constants } X X ENDFILE = Chr(1); X ENDSTR = Chr(0); X MAXSTR = 200; X X{ EBCDIC character set } X X BACKSPACE = Chr(8); X BACKSLASH = CHR(224); X TAB = Chr(5); X NEWLINE = Chr(10); X BLANK = ' '; X EXCLAM = '!'; X QUESTION = '?'; X DQUOTE = '"'; X SHARP = '#'; X DOLLAR = '$'; X PERCENT = '%'; X AMPER = '&'; X SQUOTE = ''''; X ACUTE = SQUOTE; X LPAREN = '('; X RPAREN = ')'; X STAR = '*'; X PLUS = '+'; X COMMA = ','; X MINUS = '-'; X DASH = MINUS; X PERIOD = '.'; X SLASH = '/'; X COLON = ':'; X SEMICOL = ';'; X LESS = '<'; X EQUALS = '='; X GREATER = '>'; X ATSIGN = '@'; X ESCAPE = ATSIGN; X LBRACK = Chr(173); X RBRACK = Chr(189); X CARET = '^'; X UNDERLINE = '_'; X GRAVE = '9C'XC; X LBRACE = Chr(139); X RBRACE = Chr(155); X BAR = '|'; X TILDE = '~'; X LETA = 'a'; X LETB = 'b'; X LETC = 'c'; X LETD = 'd'; X LETE = 'e'; X LETF = 'f'; X LETG = 'g'; X LETH = 'h'; X LETI = 'i'; X LETJ = 'j'; X LETK = 'k'; X LETL = 'l'; X LETM = 'm'; X LETN = 'n'; X LETO = 'o'; X LETP = 'p'; X LETQ = 'q'; X LETR = 'r'; X LETS = 's'; X LETT = 't'; X LETU = 'u'; X LETV = 'v'; X LETW = 'w'; X LETX = 'x'; X LETY = 'y'; X LETZ = 'z'; X BIGA = 'A'; X BIGB = 'B'; X BIGC = 'C'; X BIGD = 'D'; X BIGE = 'E'; X BIGF = 'F'; X BIGG = 'G'; X BIGH = 'H'; X BIGI = 'I'; X BIGJ = 'J'; X BIGK = 'K'; X BIGL = 'L'; X BIGM = 'M'; X BIGN = 'N'; X BIGO = 'O'; X BIGP = 'P'; X BIGQ = 'Q'; X BIGR = 'R'; X BIGS = 'S'; X BIGT = 'T'; X BIGU = 'U'; X BIGV = 'V'; X BIGW = 'W'; X BIGX = 'X'; X BIGY = 'Y'; X BIGZ = 'Z'; X DIG0 = '0'; X DIG1 = '1'; X DIG2 = '2'; X DIG3 = '3'; X DIG4 = '4'; X DIG5 = '5'; X DIG6 = '6'; X DIG7 = '7'; X DIG8 = '8'; X DIG9 = '9'; X X{ Standard types } X Xtype X FileDesc = IOERROR..MAXOPEN; X StringType = packed array [1..MAXSTR] of Char; X CharType = Char; X X{ Externally supplied primitive interfaces } X Xprocedure Error (s: String(MAXSTR)); X external; Xprocedure FClose (fd: FileDesc); X external; Xfunction FCreate (name: StringType; mode: Integer): FileDesc; X external; Xfunction FOpen (name: StringType; mode: Integer): FileDesc; X external; Xprocedure FSeek (recno: Integer; fd: FileDesc); X external; Xfunction GetArg (n: Integer; var str: StringType; X maxSize: Integer): Boolean; X external; Xfunction GetC (var c: CharType): CharType; X external; Xfunction GetCF (var c: CharType; fd: FileDesc): CharType; X external; Xfunction GetLine (var str: StringType; fd: FileDesc; X maxSize: Integer): Boolean; X external; Xprocedure Message (s: String(MAXSTR)); X external; Xfunction Nargs: Integer; X external; Xprocedure PutC (c: CharType); X external; Xprocedure PutCF (c: CharType; fd: FileDesc); X external; Xprocedure PutStr (const str: StringType; fd: FileDesc); X external; Xprocedure MPutStr (const str: StringType; fd: FileDesc); X external; Xprocedure Remove (var name: StringType); X external; Xprocedure SysExit (status: Integer); X external; Xprocedure ToolInit; X external; X X{ Externally supplied utilities } X Xfunction AddStr (c: CharType; var outSet: StringType; X var j: Integer; maxSet: Integer): Boolean; X external; Xfunction CToI (var s: StringType; var i: Integer): Integer; X external; Xprocedure CvtSST (src: String(MAXSTR); var dest: StringType); X external; Xprocedure CvtSTS (src: StringType; var dest: String(MAXSTR)); X external; Xfunction Equal (var str1, str2: StringType): Boolean; X external; Xfunction Esc (var s: StringType; var i: Integer): CharType; X external; Xprocedure FCopy (fin, fout: FileDesc); X external; Xfunction GetFid (var line: StringType; idx: Integer; X var fileName: StringType): Boolean; X external; Xfunction GetWord (var s: StringType; i: Integer; X var out: StringType): Integer; X external; Xfunction IsAlphaNum (c: CharType): Boolean; X external; Xfunction IsDigit (c: CharType): Boolean; X external; Xfunction IsLetter (c: CharType): Boolean; X external; Xfunction IsLower (c: CharType): Boolean; X external; Xfunction IsUpper (c: CharType): Boolean; X external; Xfunction IToC (n: Integer; var s: StringType; i: Integer): Integer; X external; Xfunction MustOpen (var fName: StringType; fMode: Integer): FileDesc; X external; Xprocedure PutDec (n, w: Integer); X external; Xprocedure SCopy (var src: StringType; i: Integer; X var dest: StringType; j: Integer); X external; Xfunction StrIndex (const s: StringType; c: CharType): Integer; X external; Xfunction StrLength (const s: StringType): Integer; X external; Xprocedure ProgExit (const returnCode: Integer); external; X%print on X*COPY EDITCONS X{ EditCons -- const declarations for edit } Xconst X CURLINE = PERIOD; X LASTLINE = DOLLAR; X SCAN = SLASH; X BACKSCAN = BACKSLASH; X ACMD = LETA; X CCMD = LETC; X DCMD = LETD; X ECMD = LETE; X EQCMD = EQUALS; X FCMD = LETF; X GCMD = LETG; X ICMD = LETI; X MCMD = LETM; X KCMD = LETK; X OCMD = LETO; X PCMD = LETP; X LCMD = LETL; X QCMD = LETQ; X RCMD = LETR; X SCMD = LETS; X WCMD = LETW; X XCMD = LETX; X promptFlag = 0; X verboseFlag = 1; X noMetaFlag = 2; X { insert more option flags here } X numFlag = 15; X*COPY EDITTYPE X{ EditType -- types for in-memory version of edit } Xtype X STCode = (ENDDATA, ERR, OK); { status returns } X*COPY EDITPROC X{ EditProc -- routine declarations for SW editor } Xfunction GetList (var lin: StringType; var i: Integer; X var status: STCode): STCode; external; Xfunction GetOne (var lin: StringType; var i, num: Integer; X var status: STCode): STCode; external; Xfunction GetNum (var lin: StringType; var i, num: integer; X var status: STCode): STCode; external; Xfunction OptPat (var lin: StringType; var i: Integer): STCode; external; Xfunction PatScan (way: CharType; var n: Integer): STCode; external; Xfunction NextLn (n: Integer): Integer; external; Xfunction PrevLn (n: Integer): Integer; external; Xfunction Default (def1, def2: Integer; X var status: STCode): STCode; external; Xfunction DoPrint (n1, n2: Integer): STCode; external; Xfunction DoLPrint (n1, n2: Integer): STCode; external; Xfunction DoCmd (var lin: StringType; var i: Integer; X glob: Boolean; var status: STCode): STCode; external; Xfunction Append (line: Integer; glob: Boolean): STCode; external; Xprocedure BlkMove (n1, n2, n3: Integer); external; Xprocedure Reverse (n1, n2: Integer); external; Xprocedure GetTxt (n: Integer; var s: StringType); external; Xprocedure SetBuf; external; Xfunction PutTxt (var lin: StringType): STCode; external; Xfunction CkP (var lin: StringType; i: Integer; X var pFlag: Boolean; var status: STCode): X STCode; external; Xfunction LnDelete (n1, n2: Integer; var status: STCode): X STCode; external; Xfunction Move (line3: Integer): STCode; external; Xfunction Kopy (line3: Integer): STCode; external; Xfunction GetRHS (var lin: StringType; var i: Integer; X var sub: StringType; var gFlag: Boolean): X STCode; external; Xfunction SubSt (var sub: StringType; gFlag, glob: Boolean): X STCode; external; Xprocedure SkipBl (var s: StringType; var i: Integer); X external; Xfunction GetFn(var lin: StringType; var i:Integer; X var fil: StringType): STCode; external; Xfunction DoRead (n: integer; var fil: StringType): STCode; external; Xfunction DoWrite (n1, n2: Integer; var fil: StringType): STCode; X external; Xfunction CkGlob (var lin: StringType; var i: Integer; X var status: STCode): STCode; external; Xfunction DoGlob (var lin: StringType; var i, curSave: Integer; X var status: STCode): STCode; external; Xprocedure ClrBuf; external; Xfunction GetMark(n: Integer): Boolean; external; Xprocedure PutMark(n: Integer; m: Boolean); external; Xfunction DoOption(var lin: STringType; var i: Integer): X STCode; external; Xfunction OptIsOn(flag: promptFlag..numFlag): Boolean; external; X*COPY IODEF Xtype X IOBlock = X record X fileVar: Text; X mode: IOERROR..IOWRITE X end; Xfunction FDAlloc: Integer; External; X*COPY IOREF X{ GlobRef -- standard global references (IO support mainly) } X%include iodef Xref openList: array [FileDesc] of IOBlock; Xref ERRORIO: Boolean; Xref ATTENTION: Boolean; Xref cmdLin: StringType; Xref cmdArgs: 0..MAXARG; Xref cmdIdx: array [1..MAXARG] of 1..MAXSTR; X*COPY EDITREF X{ EditRef -- external reference definitions for SW editor } Xref X line1: Integer; { first line number } X line2: Integer; { second line number } X nLines: Integer; { # of lines specified } X curLn: Integer; { current line } X lastLn: Integer; { last line in buffer } X pat: StringType; { pattern string } X lin: StringType; { input line } X saveFile: StringType; { current remembered file name } X*COPY MATCHDEF X{ MatchDef -- definitions of match and sub-fcns } Xfunction PatSize (var pat: StringType; n: Integer): Integer; X external; Xfunction OMatch (var lin: StringType; var i: Integer; X var pat: StringType; j: Integer): Boolean; X external; Xfunction Locate (c: CharType; var pat: StringType; X offset: Integer): Boolean; X external; Xfunction Match (var lin, pat: StringType): Boolean; X external; Xfunction AMatch (var lin: StringType; offset: Integer; X var pat: StringType; j: Integer): Integer; X external; X*COPY PATDEF X{ PatDef -- pattern constant declarations for GetPat } Xconst X MAXPAT = MAXSTR; X CLOSIZE = 1; { size of closure entry } X BOL = PERCENT; X EOL = DOLLAR; X ANY = QUESTION; X CCL = LBRACK; X CCLEND = RBRACK; X NEGATE = CARET; X NCCL = SHARP;{ cannot be the same as NEGATE } X LITCHAR = LETC; X NCHAR = EXCLAM; X CLOSURE = STAR; Xfunction GetCCL (var arg: StringType; var i: Integer; X var pat: StringType; var j: Integer) X :Boolean; X external; Xprocedure StClose(var pat: StringType; var j: Integer; X lastJ: Integer); X external; Xfunction GetPat (var arg, pat: StringType): Boolean; X external; Xfunction MakePat (var arg: StringType; start: Integer; X delim: CharType; var pat: StringType): Integer; X external; Xprocedure DoDash (delim: CharType; var src: StringType; X var i: Integer; var dest: StringType; X var j: Integer; maxSet: Integer); X external; Xfunction MakeSet (var inSet: StringType; k: Integer; X var outSet: StringType; maxSet: Integer): Boolean; X external; X*COPY SUBDEF X{ subdef -- definitions of substitution routines } Xconst X DITTO = Chr(255); Xprocedure SubLine (var lin, pat, sub: StringType); X external; Xprocedure CatSub (var lin: StringType; s1,s2: Integer; X var sub: StringType; var new: StringType; X var k: Integer; maxNew: Integer); X external; Xprocedure PutSub(var lin: StringType; s1, s2: Integer; X var sub: StringType); X external; Xfunction MakeSub (var arg: StringType; from: Integer; X delim: CharType; var sub: StringType): Integer; X external; Xfunction GetSub (var arg, sub: StringType): Boolean; X external; X*COPY DEFVAR X{ DefVar -- var declarations for define } Xdef X hashTab: array [1..HASHSIZE] of NDPtr; X NDTable: CharBuf; X nextTab: CharPos; { first free position in NDTable } X buf: array [1..BUFSIZE] of CharType; { for push back } X bp: 0..BUFSIZE; { next available character; init = 0 } X defn: StringType; X token: StringType; X tokType: STType; { type returned by lookup } X defName: StringType; { value is 'define' } X null: StringType; { value is '' } X*COPY DEFDEF X{ DefDef -- definitions needed for define } X{ DefCons -- const declarations for define } Xconst X BUFSIZE = 500; { size of push back buffer } X MAXCHARS = 5000; { size of name-defn table } X MAXDEF = MAXSTR; { max chars in a defn } X MAXTOK = MAXSTR; { max chars in a token } X HASHSIZE = 53; { size of hash table } X{ DefType -- type declarations for define } Xtype X CharPos = 1..MAXCHARS; X CharBuf = array [1..MAXCHARS] of CharType; X STType = (DEFTYPE, MACTYPE); { symbol table types } X NDPtr = -> NDBlock; { pointer to name-defn block } X NDBlock = X record X name: CharPos; X defn: CharPos; X kind: STType; X nextPtr: NDPtr; X end; X*COPY DEFPROC X{ DefProc -- procedures needed for define } Xprocedure CSCopy (var cb: CharBuf; i: CharPos; X var s: StringType); X external; Xprocedure SCCopy (var s: StringType; var cb: CharBuf; X i: CharPos); X external; Xprocedure PutBack (c: CharType); X external; Xfunction GetPBC (var c: CharType): CharType; X external; Xprocedure PBStr (var s: StringType); X external; Xfunction GetTok (var token: StringType; tokSize: Integer): CharType; X external; Xprocedure GetDef (var token: StringType; tokSize: Integer; X var defn: StringType; defSize: Integer); X external; Xprocedure InitHash; X external; Xfunction Hash (var name: StringType): Integer; X external; Xfunction HashFind (var name: StringType): NDPtr; X external; Xprocedure Install (var name, defn: StringType; t: STType); X external; Xfunction Lookup (var name, defn: StringType; var t: STType): Boolean; X external; Xprocedure InitDef; X external; X*COPY DEFREF Xdef X hashTab: array [1..HASHSIZE] of NDPtr; X NDTable: CharBuf; X nextTab: CharPos; { first free position in NDTable } X buf: array [1..BUFSIZE] of CharType; { for push back } X bp: 0..BUFSIZE; { next available character; init = 0 } X defn: StringType; X token: StringType; X tokType: STType; { type returned by lookup } X defName: StringType; { value is 'define' } X null: StringType; { value is '' } X*COPY METADEF X{ MetaDef -- definitions for Meta bracket implementation } Xconst X BOM = LBRACE; { start of meta bracket } X EOM = RBRACE; { end of meta bracket } Xtype X MetaIndexType = Integer; X MetaElementType = X record X first: Integer; X last: Integer; X end; X MetaTableType = array [0..9] of MetaElementType; X MetaStackType = array [0..9] of MetaIndexType; Xdef X metaIndex: MetaIndexType; X metaTable: MetaTableType; X nullMetaTable: MetaTableType; X metaStack: MetaStackType; X metaStackPointer: Integer; X*COPY CHARDEF Xconst X ChLetter = 0; X ChLower = 1; X ChUpper = 2; X ChDigit = 3; X ChSpecial = 4; Xtype X ChEntry = packed set of 0..7; X ChTable = array [0..255] of ChEntry; Xdef X CharTable: ChTable; Xfunction CharClass(const tIndex: CharType): ChEntry; external; X*COPY MACPROC X{ MacProc -- procedures needed for define } Xprocedure CSCopy (var cb: CharBuf; i: CharPos; X var s: StringType); X external; Xprocedure SCCopy (var s: StringType; var cb: CharBuf; X i: CharPos); X external; Xprocedure PutBack (c: CharType); X external; Xfunction GetPBC (var c: CharType): CharType; X external; Xprocedure PBStr (var s: StringType); X external; Xfunction GetTok (var token: StringType; tokSize: Integer): CharType; X external; Xprocedure GetDef (var token: StringType; tokSize: Integer; X var defn: StringType; defSize: Integer); X external; Xprocedure InitHash; X external; Xfunction Hash (var name: StringType): Integer; X external; Xfunction HashFind (var name: StringType): NDPtr; X external; Xprocedure Install (var name, defn: StringType; t: STType); X external; Xfunction Lookup (var name, defn: StringType; var t: STType): Boolean; X external; Xprocedure PutTok(var s: StringType); X external; Xprocedure PutChr(c: CharType); X external; Xprocedure InitMacro; X external; Xfunction Push (ep: Integer; var argStk: PosBuf; X ap: Integer): Integer; X external; Xprocedure Eval(var argStk: PosBuf; td: StType; X i,j: Integer); X external; Xprocedure DoDef (var argStk: PosBuf; i,j: Integer); X external; Xprocedure DoIf(var argStk: PosBuf; i,j: Integer); X external; Xprocedure DoExpr(var argStk: PosBuf; i,j: Integer); X external; Xfunction Expr(var s: StringType; var i: Integer): Integer; X external; Xfunction Term(var s: StringType; var i: Integer): Integer; X external; Xfunction Factor(var s: StringType; var i: Integer): Integer; X external; Xfunction GnbChar(var s: StringType; var i: Integer): CharType; X external; Xprocedure DoLen(var argStk: PosBuf; i,j: Integer); X external; Xprocedure DoSub(var argStk: PosBuf; i,j: Integer); X external; Xprocedure DoChq(var argStk: PosBuf; i,j: Integer); X external; Xprocedure PBNum(n: Integer); X external; X*COPY MACDEFS X{ Macdefs -- all definitions for Macro } Xconst X BUFSIZE = 1000; { size of pushback buffer } X MAXCHARS = 5000; { size of name-defn table } X MAXPOS = 500; X CALLSIZE = MAXPOS; X ARGSIZE = MAXPOS; X EVALSIZE = MAXCHARS; X MAXDEF = MAXSTR; { max chars in a defn } X MAXTOK = MAXSTR; { max length of a token } X HASHSIZE = 53; { size of hash table } X ARGFLAG = DOLLAR; { macro invocation character } X X{ MacType -- type declarations for Macro } Xtype X CharPos = 1..MAXCHARS; X CharBuf = packed array [1..MAXCHARS] of CharType; X PosBuf = packed array [1..MAXPOS] of CharPos; X Pos = 0..MAXPOS; X StType = (DEFTYPE, MACTYPE, IFTYPE, SUBTYPE, X EXPRTYPE, LENTYPE, CHQTYPE); { symbol table types } X NdPtr = ->NdBlock; X NdBlock = X record X name: CharPos; X defn: CharPos; X kind: StType; X nextPtr: NdPtr; X end {record}; X{ Macvar -- def declarations for macro } Xdef X traceing: Boolean; X buf: packed array [1..BUFSIZE] of CharType; { for pushback } X bp: 0..BUFSIZE; X hashTab: array [1..HASHSIZE] of NdPtr; X ndTable: CharBuf; X nextTab: CharPos; { first free position in ndTable } X callStk: PosBuf; X cp: Pos; { current call stack position } X typeStk: array [1..CALLSIZE] of StType; { type } X pLev: array [1..CALLSIZE] of Integer; { paren level } X argStk: PosBuf; { argument stack for this call } X ap: Pos; { current argument position } X evalStk: CharBuf; { evaluation stack } X ep: CharPos; { first character unused in evalStk } X { builtins } X defName: StringType; { 'define' } X exprName: StringType;{ 'expr' } X subName: StringType; { 'substr' } X ifName: StringType; { 'ifelse' } X lenName: StringType; { 'len' } X chqName: StringType; { 'changeq' } X null: StringType; { value is '' } X lQuote: CharType; { left quote character } X rQuote: CharType; { right quote character } X X defn: StringType; X token: StringType; X tokType: StType; X t: CharType; X nlPar: Integer; / echo 'x - toolinit.pascal' sed 's/^X//' > toolinit.pascal << '/' X{ X Copyright (c) 1982 X By: Chris Lewis X X Right is hereby granted to freely distribute or duplicate this X software, providing distribution or duplication is not for profit X or other commerical gain and that this copyright notice remains X intact. X} X{ ToolInit -- (CMS) standard program prologue } Xsegment ToolInit; X%include swtools X%include iodef Xdef openList: array [FileDesc] of IOBlock; Xdef cmdLin: StringType; Xdef cmdArgs: 0..MAXARG; Xdef cmdIdx: array [1..MAXARG] of 1..MAXSTR; Xdef termInput: Boolean; Xref ERRORIO: Boolean; Xvalue X termInput := false; Xprocedure ToolInit; Xvar X t: 1..MAXSTR; X i: FileDesc; X idx: 1..MAXSTR; X delim: CharType; X PARMSTRING: String(MAXSTR); X fileName: StringType; X cmdLength: 0..MAXSTR; X redirIn: Boolean; X j: 1..MAXSTR; X dummy: StringType; X okay: Boolean; X tempArgs: 0..MAXARG; X XFileName: String(MAXSTR); X k: 0..MAXSTR; X nextChar: 1..MAXSTR; Xbegin X TermIn(input); X TermOut(output); X for i := STDIN to MAXOPEN do X openList[i].mode := IOAVAIL; X openList[STDERR].mode := IOWRITE; X TermOut(openList[STDERR].fileVar); X PARMSTRING := PARMS; X if (Length(PARMSTRING) >= 1) and (PARMSTRING[1] = STAR) then begin X WriteLn('Input Command Parameters:'); X ReadLn(PARMSTRING); X PARMSTRING := PARMSTRING || SubStr(PARMS, 2, Length(PARMS)-1) X end; X for idx := 1 to Length(PARMSTRING) do X cmdLin[idx] := PARMSTRING[idx]; X cmdLin[Length(PARMSTRING) + 1] := NEWLINE; X cmdLin[Length(PARMSTRING) + 2] := ENDSTR; X idx := 1; X cmdArgs := 0; X while ((cmdLin[idx] <> ENDSTR) and X (cmdLin[idx] <> NEWLINE)) do begin X while (cmdLin[idx] = BLANK) do X idx := idx + 1; X if (cmdLin[idx] <> NEWLINE) then begin X delim := BLANK; X cmdArgs := cmdArgs + 1; X if (cmdLin[idx] = SQUOTE) or X (cmdLin[idx] = DQUOTE) then begin X cmdIdx[cmdArgs] := idx + 1; X delim := cmdLin[idx]; X idx := idx + 1 X end X else X cmdIdx[cmdArgs] := idx; X while ((cmdLin[idx] <> NEWLINE) and X (cmdLin[idx] <> delim)) do X idx := idx + 1; X cmdLin[idx] := ENDSTR; X idx := idx + 1; X end X end; X j := 1; X tempArgs := cmdArgs; X while (j <= cmdArgs) do begin X okay := GetArg(j, dummy, MAXSTR); X j := j + 1; X if (dummy[1] = LESS) or (dummy[1] = GREATER) then begin X if dummy[1] = LESS then X redirIn := true X else X redirIn := false; X SCopy(dummy, 2, fileName, 1); X nextChar := StrLength(fileName) + 1; X tempArgs := tempArgs - 1; X k := j; X while (k <= cmdArgs) do begin X okay := GetArg(k, dummy, MAXSTR); X k := k + 1; X if okay and (dummy[1] <> LESS) and X (dummy[1]<> GREATER) then begin X tempArgs := tempArgs - 1; X fileName[nextChar] := BLANK; X nextChar := nextChar + 1; X SCopy(dummy, 1, fileName, nextChar); X nextChar := StrLength(fileName) + 1; X j := j + 1; X end X else X k := cmdArgs + 1; X end; X t := 1; X okay := GetFid(fileName, t, fileName); X if not okay then X Error('Bad redirection file name'); X CvtSTS(fileName, XFileName); X if redirIn then begin X openList[STDIN].mode := IOREAD; X Reset(openList[STDIN].fileVar, 'NAME=' || X XFileName); X termInput := false; X if ERRORIO then begin X openList[STDIN].mode := IOAVAIL; X Error('Cannot open STDIN file'); X ERRORIO := false X end X end X else begin X openList[STDOUT].mode := IOWRITE; X Remove(fileName); X ReWrite(openList[STDOUT].fileVar, X 'LRECL=1000,NAME=' || XFileName); X if ERRORIO then begin X openList[STDOUT].mode := IOAVAIL; X ERRORIO := false X end X end X end X end; X cmdArgs := tempArgs; X if openList[STDIN].mode = IOAVAIL then begin X TermIn(openList[STDIN].fileVar); X openList[STDIN].mode := IOREAD; X termInput := true; X end; X if openList[STDOUT].mode = IOAVAIL then begin X TermOut(openList[STDOUT].fileVar); X openList[STDOUT].mode := IOWRITE; X end; Xend; / echo 'Part 03 of pack.out complete.' exit