home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / progs / patchu.icn < prev    next >
Text File  |  2000-07-29  |  4KB  |  154 lines

  1. ############################################################################
  2. #
  3. #    File:     patchu.icn
  4. #
  5. #    Subject:  Program to implement UNIX-like patch
  6. #
  7. #    Author:   Rich Morin
  8. #
  9. #    Date:     June 18, 1990
  10. #
  11. ############################################################################
  12. #
  13. #   This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  This program reads a source file and a diff file, producing an
  18. #  updated file.  The diff file may be generated by the UNIX diff(1)
  19. #  utility, or by diffu.icn, which uses dif.icn for the hard work.
  20. #
  21. #  The original patch(1) utility, written by Larry Wall, is widely
  22. #  used in the UNIX community.
  23. #
  24. #  The diff file contains edit lines, separators, and text lines.
  25. #  Edit lines may take the forms:
  26. #
  27. #    #a#[,#]            <- add    lines
  28. #    #[,#]c#[,#]        <- change lines
  29. #    #[,#]d#            <- delete lines
  30. #
  31. #  Change lines contain only the string "---".  All other lines are
  32. #  text lines.  See diff(1) in any UNIX manual for more details.
  33. #
  34. ############################################################################
  35. #
  36. #  Requires:  co-expressions
  37. #
  38. ############################################################################
  39. #
  40. #  Links:  options, patch
  41. #
  42. ############################################################################
  43.  
  44. link options, patch
  45.  
  46. record diff_rec(pos, diffs)
  47.  
  48. global n1, n2, n3, n4
  49.  
  50. procedure main(arg)
  51.    local t, rev, source, dfile, diffs
  52.  
  53.   t := options(arg, "r")
  54.   rev := t["r"]
  55.  
  56.   if *arg ~= 2 then
  57.     zot("usage: patchu source diffs")
  58.  
  59.   source := open(arg[1]) | zot("cannot open " || arg[1])
  60.   dfile  := open(arg[2]) | zot("cannot open " || arg[2])
  61.  
  62. # every write(patch(source, get_diff(dfile))) # ? shouldn't need diffs ?
  63.  
  64.   diffs := []
  65.   every put(diffs, get_diff(dfile))
  66.   every write(patch(source, diffs, rev))
  67.  
  68. end
  69.  
  70.  
  71. procedure get_diff(dfile)        # get diff record
  72.   local ef, i1, i2, l1, l2, i, line
  73.  
  74.   repeat {
  75.     if ef := get_edit(dfile) then {
  76. #     write(">>> ",n1,", ",n2,", ",ef,", ",n3,", ",n4)
  77.       if ef == "a" then i1 := n1+1 else i1 := n1
  78.       if ef == "d" then i2 := n3+1 else i2 := n3
  79.       l1 := []
  80.       l2 := []
  81.       if ef == !"cd" then {
  82.         every i := n1 to n2 do {
  83.           line := !dfile | zot("unexpected end of edit data(1)")
  84.           if line[1:3] ~== "< " then
  85.             zot("bad edit data(1): " || line)
  86.           put(l1, line[3:0])
  87.         }
  88.       }
  89.  
  90.       if ef == "c" then {
  91.         line := !dfile | zot("unexpected end of edit data(2)")
  92.         if line ~== "---" then
  93.           zot("bad edit data(2): " || line)
  94.       }
  95.  
  96.       if ef == !"ac" then {
  97.         every i := n3 to n4 do {
  98.           line := !dfile | zot("unexpected end of edit data(3)")
  99.           if line[1:3] ~== "> " then
  100.             zot("bad edit data(3): " || line)
  101.           put(l2, line[3:0])
  102.         }
  103.       }
  104.       suspend [diff_rec(i1,l1), diff_rec(i2,l2)]
  105.     }
  106.     else
  107.       fail
  108.   }
  109.  
  110. end
  111.  
  112.  
  113. procedure get_edit(dfile)        # get edit parameters
  114.   local edit, i1, i2, ef, i3, i4
  115.  
  116.   edit := !dfile | fail
  117.   i1 := i2 := many(&digits, edit) | zot("bad edit spec(1): " || edit)
  118.   n1 := n2 := edit[1:i1]
  119.   if edit[i1] == "," then {
  120.     i2 := many(&digits, edit, i1+1) | zot("bad edit spec(2): " || edit)
  121.     n2 := edit[i1+1:i2]
  122.   }
  123.  
  124.   if edit[i2] == !"acd" then {
  125.     ef := edit[i2]
  126.     i3 := i4 := many(&digits, edit, i2+1) | zot("bad edit spec(3): " || edit)
  127.     n3 := n4 := edit[i2+1:i3]
  128.     if edit[i3] == "," then {
  129.       i4 := many(&digits, edit, i3+1) | zot("bad edit spec(4): " || edit)
  130.       n4 := edit[i3+1:i4]
  131.     }
  132.   }
  133.   else
  134.     zot("bad edit spec(5): " || edit)
  135.  
  136.   if i4 ~= *edit+1 then 
  137.     zot("bad edit spec(6): " || edit)
  138.  
  139.   if not 0 <= n3 <= n4 then
  140.     zot("bad edit spec(7): " || edit)
  141.  
  142.   if not 0 <= n1 <= n2 then
  143.     zot("bad edit spec(8): " || edit)
  144.  
  145.   return ef
  146.  
  147. end    
  148.  
  149.  
  150. procedure zot(msg)                # exit w/message
  151.   write(&errout, "patchu: " || msg)
  152.   exit(1)
  153. end
  154.