lib/rvc/fs.rb in rvc-1.2.2 vs lib/rvc/fs.rb in rvc-1.3.0
- old
+ new
@@ -18,128 +18,92 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
module RVC
-class Location
- attr_reader :stack
-
- def initialize root
- @stack = [['', root]]
- end
-
- def initialize_copy src
- super
- @stack = @stack.dup
- end
-
- def push name, obj
- @stack << [name, obj]
- end
-
- def pop
- @stack.pop
- end
-
- def obj
- @stack.empty? ? nil : @stack[-1][1]
- end
-
- def path
- @stack.map { |name,obj| name }
- end
-end
-
class FS
- attr_reader :root, :loc, :marks
+ attr_reader :root, :cur, :marks
MARK_PATTERN = /^~(?:([\d\w]*|~|@))$/
REGEX_PATTERN = /^%/
GLOB_PATTERN = /\*/
def initialize root
+ fail unless root.is_a? RVC::InventoryObject
@root = root
- @loc = Location.new root
+ @cur = root
@marks = {}
end
- def cur
- @loc.obj
- end
-
def display_path
- @loc.path * '/'
+ @cur.rvc_path.map { |arc,obj| arc } * '/'
end
- def cd new_loc
- mark '~', @loc
- @loc = new_loc
+ def cd dst
+ fail unless dst.is_a? RVC::InventoryObject
+ mark '~', [@cur]
+ @cur = dst
end
def lookup path
- lookup_loc(path).map(&:obj)
+ arcs, absolute, trailing_slash = Path.parse path
+ base = absolute ? @root : @cur
+ traverse(base, arcs)
end
- def lookup_loc path
- els, absolute, trailing_slash = Path.parse path
- base_loc = absolute ? Location.new(@root) : @loc
- traverse(base_loc, els)
+ # Starting from base, traverse each path element in arcs. Since the path
+ # may contain wildcards, this function returns a list of matches.
+ def traverse base, arcs
+ objs = [base]
+ arcs.each_with_index do |arc,i|
+ objs.map! { |obj| traverse_one obj, arc, i==0 }
+ objs.flatten!
+ end
+ objs
end
- def traverse_one loc, el, first
- case el
+ def traverse_one cur, arc, first
+ case arc
when '.'
- [loc]
+ [cur]
when '..'
- loc.pop unless loc.obj == @root
- [loc]
+ [cur.rvc_parent ? cur.rvc_parent : cur]
when '...'
- loc.push(el, loc.obj.parent) unless loc.obj == @root
- [loc]
+ # XXX shouldnt be nil
+ [(cur.respond_to?(:parent) && cur.parent) ? cur.parent : (cur.rvc_parent || cur)]
when MARK_PATTERN
- return unless first
- loc = @marks[$1] or return []
- [loc.dup]
+ if first and objs = @marks[$1]
+ objs
+ else
+ []
+ end
when REGEX_PATTERN
regex = Regexp.new($')
- loc.obj.children.
- select { |k,v| k =~ regex }.
- map { |k,v| loc.dup.tap { |x| x.push(k, v) } }
+ cur.children.select { |k,v| k =~ regex }.map { |k,v| v.rvc_link(cur, k); v }
when GLOB_PATTERN
- regex = glob_to_regex el
- loc.obj.children.
- select { |k,v| k =~ regex }.
- map { |k,v| loc.dup.tap { |x| x.push(k, v) } }
+ regex = glob_to_regex arc
+ cur.children.select { |k,v| k =~ regex }.map { |k,v| v.rvc_link(cur, k); v }
else
# XXX check for ambiguous child
- if first and el =~ /^\d+$/ and @marks.member? el
- loc = @marks[el].dup
+ if first and arc =~ /^\d+$/ and objs = @marks[arc]
+ objs
else
- x = loc.obj.traverse_one(el) or return []
- loc.push el, x
+ if child = cur.traverse_one(arc)
+ child.rvc_link cur, arc
+ [child]
+ else
+ []
+ end
end
- [loc]
end
end
- # Starting from base_loc, traverse each path element in els. Since the path
- # may contain wildcards, this function returns a list of matches.
- def traverse base_loc, els
- locs = [base_loc.dup]
- els.each_with_index do |el,i|
- locs.map! { |loc| traverse_one loc, el, i==0 }
- locs.flatten!
- end
- locs
+ def mark key, objs
+ fail "not an array" unless objs.is_a? Array
+ @marks[key] = objs
end
- def mark key, loc
- if loc == nil
- @marks.delete key
- else
- @marks[key] = loc
- end
- end
+private
def glob_to_regex str
Regexp.new "^#{Regexp.escape(str.gsub('*', "\0")).gsub("\0", ".*")}$"
end
end