|
|
1.1 ! root 1: # FSET(1) ! 2: # ! 3: # Perform set operations on file specifications ! 4: # ! 5: # Thomas R. Hicks ! 6: # ! 7: # Last modified 8/14/84 ! 8: # ! 9: ! 10: procedure main(args) ! 11: local i, fyls, arglist ! 12: if not find("sets",&options) then ! 13: stop("Set extensions must be enabled to run this program.") ! 14: if *args = 0 then return ! 15: if *args > 1 then ! 16: every i := 2 to *args do ! 17: args[1] ||:= (" " || args[i]) ! 18: (arglist := parse(args[1])) | ! 19: stop("Invalid file specification expression") ! 20: case type(arglist) of { ! 21: "string" : fyls := mkfset(arglist) ! 22: "list" : fyls := exec(arglist) ! 23: default : stop("Main: bad type -can't happen") ! 24: } ! 25: fyls := sort(fyls) ! 26: every write(!fyls," ") ! 27: end ! 28: ! 29: procedure Exp() # file spec expression parser ! 30: local a ! 31: suspend (a := [Factor(),=Op(),Factor()] & [a[2],a[1],a[3]]) | ! 32: Factor() | ! 33: (a := [="(",Exp(),=")"] & .a[2]) ! 34: end ! 35: ! 36: procedure Factor() # file spec expression parser ! 37: local a ! 38: suspend (a := [Term(),=Op(),Term()] & [a[2],a[1],a[3]]) | ! 39: Term() | ! 40: (a := [="(",Factor(),=")"] & .a[2]) ! 41: end ! 42: ! 43: procedure Name() # file spec name matcher ! 44: static valid ! 45: initial valid := ~'()' ! 46: suspend (any(~valid) || fail) | tab(find(Op()) | many(valid)) ! 47: end ! 48: ! 49: procedure Non() # file spec expression parser ! 50: local a ! 51: suspend a := [Name(),=Op(),Name()] & [a[2],a[1],a[3]] ! 52: end ! 53: ! 54: procedure Op() # file spec operation matcher ! 55: suspend !["++","--","&&"] ! 56: end ! 57: ! 58: procedure Term() # file spec expression parser ! 59: local a ! 60: suspend (a := [="(",Non(),=")"] & .a[2]) | ! 61: Name() ! 62: end ! 63: ! 64: procedure bldfset(arg) # build file set, excluding . and .. ! 65: local line ! 66: static dotfiles ! 67: initial dotfiles := set([".",".."]) ! 68: line := read(open("echo " || arg,"rp")) ! 69: return str2set(line,' ') -- dotfiles ! 70: end ! 71: ! 72: procedure exec(lst) # process file spec list recursively ! 73: return setops(lst[1])(exec2(lst[2]),exec2(lst[3])) ! 74: end ! 75: ! 76: procedure exec2(arg) # helping procedure for exec ! 77: case type(arg) of { ! 78: "string" : return mkfset(arg) ! 79: "list" : return exec(arg) ! 80: default : stop("exec2: can't happen") ! 81: } ! 82: end ! 83: ! 84: procedure mkfset(fspec) # make file list from specification ! 85: if fspec == "*" then ! 86: fspec := "* .*" ! 87: return bldfset(fspec) ! 88: end ! 89: ! 90: procedure parse(str) # top level of parsing procedures ! 91: local res ! 92: str ? (res := Exp() & pos(0)) | fail ! 93: return res ! 94: end ! 95: ! 96: procedure sdiff(f1,f2) # set difference ! 97: return f1 -- f2 ! 98: end ! 99: ! 100: procedure setops(op) # return correct set operaton ! 101: case op of { ! 102: "++" : return sunion ! 103: "&&" : return sinter ! 104: "--" : return sdiff ! 105: } ! 106: end ! 107: ! 108: procedure sinter(f1,f2) # set intersection ! 109: return f1 ** f2 ! 110: end ! 111: ! 112: procedure str2set(str,delim) # convert delimited string into a set ! 113: local fset, f ! 114: fset := set([]) ! 115: str ? { ! 116: while f := (tab(upto(delim))) do { ! 117: insert(fset,f) ! 118: move(1) ! 119: } ! 120: if "" ~== (f := tab(0)) then ! 121: insert(fset,f) ! 122: } ! 123: return fset ! 124: end ! 125: ! 126: procedure sunion(f1,f2) # set union ! 127: return f1 ++ f2 ! 128: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.