diff options
Diffstat (limited to 'ipl/procs/patch.icn')
-rw-r--r-- | ipl/procs/patch.icn | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/ipl/procs/patch.icn b/ipl/procs/patch.icn new file mode 100644 index 0000000..88e023c --- /dev/null +++ b/ipl/procs/patch.icn @@ -0,0 +1,92 @@ +############################################################################ +# +# File: patch.icn +# +# Subject: Procedures for UNIX-like patch(1) +# +# Author: Rich Morin +# +# Date: June 18, 1990 +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ +# +# 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 |