1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
"""scons.Node.FS
File system nodes.
"""
__revision__ = "Node/FS.py __REVISION__ __DATE__ __DEVELOPER__"
import os
import os.path
from scons.Node import Node
Top = None
Root = {}
def init(path = None):
"""Initialize the Node.FS subsystem.
The supplied path is the top of the source tree, where we
expect to find the top-level build file. If no path is
supplied, the current directory is the default.
"""
global Top
if path == None:
path = os.getcwd()
Top = lookup(Dir, path, directory = None)
Top.path = '.'
def lookup(fsclass, name, directory = Top):
"""Look up a file system node for a path name. If the path
name is relative, it will be looked up relative to the
specified directory node, or to the top-level directory
if no node was specified. An initial '#' specifies that
the name will be looked up relative to the top-level directory,
regardless of the specified directory argument. Returns the
existing or newly-created node for the specified path name.
The node returned will be of the specified fsclass (Dir or
File).
"""
global Top
head, tail = os.path.split(name)
if not tail:
drive, path = os.path.splitdrive(head)
if not Root.has_key(drive):
Root[drive] = Dir(head, None)
Root[drive].abspath = head
Root[drive].path = head
return Root[drive]
if tail[0] == '#':
directory = Top
tail = tail[1:]
elif directory is None:
directory = Top
if head:
directory = lookup(Dir, head, directory)
try:
self = directory.entries[tail]
except AttributeError:
# There was no "entries" attribute on the directory,
# which essentially implies that it was a file.
# Return it as a more descriptive exception.
raise TypeError, directory
except KeyError:
# There was to entry for "tail," so create the new
# node and link it in to the existing structure.
self = fsclass(tail, directory)
self.name = tail
if self.path[0:2] == "./":
self.path = self.path[2:]
directory.entries[tail] = self
except:
raise
if self.__class__.__name__ != fsclass.__name__:
# Here, we found an existing node for this path,
# but it was the wrong type (a File when we were
# looking for a Dir, or vice versa).
raise TypeError, self
return self
# XXX TODO?
# Annotate with the creator
# is_under
# rel_path
# srcpath / srcdir
# link / is_linked
# linked_targets
# is_accessible
class Dir(Node):
"""A class for directories in a file system.
"""
def __init__(self, name, directory):
self.entries = {}
self.entries['.'] = self
self.entries['..'] = directory
if not directory is None:
self.abspath = os.path.join(directory.abspath, name, '')
self.path = os.path.join(directory.path, name, '')
def up(self):
return self.entries['..']
# XXX TODO?
# rfile
# precious
# no_rfile
# rpath
# rsrcpath
# source_exists
# derived_exists
# is_on_rpath
# local
# base_suf
# suffix
# addsuffix
# accessible
# ignore
# build
# bind
# is_under
# relpath
class File(Node):
"""A class for files in a file system.
"""
def __init__(self, name, directory):
self.abspath = os.path.join(directory.abspath, name)
self.path = os.path.join(directory.path, name)
|