home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # File: patch.icn
- #
- # Subject: Procedures for UNIX-like patch(1)
- #
- # Author: Rich Morin
- #
- # Date: June 18, 1990
- #
- ###########################################################################
- #
- # This procedure produces a sequence of edited items, reading a source
- # stream (from) and a stream of difference records (diffs), as generated
- # by dif.icn.
- #
- # An optional parameter (rev) causes the edits to be made in reverse.
- # This allows an old stream to be regenerated from a new stream and an
- # appropriate stream of difference records.
- #
- # The original patch(1) utility was written by Larry Wall, and is used
- # widely in the UNIX community. See also diffu.icn and patchu.icn, the
- # utility program versions of dif.icn and patch.icn.
- #
- # Usage: patch(old, diff) # patch old to new via diff
- # patch(new, diff, rev) # patch new to old via diff
- #
- ############################################################################
- #
- # Requires: co-expressions
- #
- ############################################################################
-
- procedure patch(from, diff, rev)
- local c_diff, c_from, cnte, cnti, i, item, ldr, o
-
- initial {
- i := 1
- o := 2
- if \rev then
- i :=: o
-
- c_diff := create !diff
- c_from := create !from
-
- cnti := item := 0
- ldr := @c_diff
- cnte := ldr[i].pos
- }
-
- repeat {
-
- while /ldr | cnti < cnte-1 do { # copy old items
- cnti +:= 1
- if item := @c_from then
- suspend item
- else {
- item := &null
- break
- }
- }
-
- if \ldr then { # still have edits
- every 1 to *ldr[i].diffs do { # discard items
- cnti +:= 1
- @c_from | zot_patch("unexpected end of stream")
- }
-
- if *ldr[o].diffs > 0 then # copy new items
- suspend !ldr[o].diffs
-
- if ldr := @c_diff then # get next edit
- cnte := ldr[i].pos
- else
- ldr := &null
- }
-
- if /item & /ldr then
- fail
- }
-
- end
-
-
- procedure zot_patch(msg) # exit w/ message
- write(&errout, "patch: ", msg)
- exit(1)
- end
-