• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# common python utility routines for the Bionic tool scripts
2
3import sys, os, commands, string, commands
4
5# basic debugging trace support
6# call D_setlevel to set the verbosity level
7# and D(), D2(), D3(), D4() to add traces
8#
9verbose = 0
10
11def panic(msg):
12    sys.stderr.write( find_program_name() + ": error: " )
13    sys.stderr.write( msg )
14    sys.exit(1)
15
16def D(msg):
17    global verbose
18    if verbose > 0:
19        print msg
20
21def D2(msg):
22    global verbose
23    if verbose >= 2:
24        print msg
25
26def D3(msg):
27    global verbose
28    if verbose >= 3:
29        print msg
30
31def D4(msg):
32    global verbose
33    if verbose >= 4:
34        print msg
35
36def D_setlevel(level):
37    global verbose
38    verbose = level
39
40
41#  other stuff
42#
43#
44def find_program_name():
45    return os.path.basename(sys.argv[0])
46
47def find_program_dir():
48    return os.path.dirname(sys.argv[0])
49
50class StringOutput:
51    def __init__(self):
52        self.line = ""
53
54    def write(self,msg):
55        self.line += msg
56        D2("write '%s'" % msg)
57
58    def get(self):
59        return self.line
60
61
62def create_file_path(path):
63    dirs = []
64    while 1:
65        parent = os.path.dirname(path)
66        #print "parent: %s <- %s" % (parent, path)
67        if parent == "/" or parent == "":
68            break
69        dirs.append(parent)
70        path = parent
71
72    dirs.reverse()
73    for dir in dirs:
74        #print "dir %s" % dir
75        if os.path.isdir(dir):
76            continue
77        os.mkdir(dir)
78
79def walk_source_files(paths,callback,args,excludes=[]):
80    """recursively walk a list of paths and files, only keeping the source files in directories"""
81    for path in paths:
82        if len(path) > 0 and path[0] == '@':
83            # this is the name of another file, include it and parse it
84            path = path[1:]
85            if os.path.exists(path):
86                for line in open(path):
87                    if len(line) > 0 and line[-1] == '\n':
88                        line = line[:-1]
89                    walk_source_files([line],callback,args,excludes)
90            continue
91        if not os.path.isdir(path):
92            callback(path,args)
93        else:
94            for root, dirs, files in os.walk(path):
95                #print "w-- %s (ex: %s)" % (repr((root,dirs)), repr(excludes))
96                if len(excludes):
97                    for d in dirs[:]:
98                        if os.path.join(root,d) in excludes:
99                            dirs.remove(d)
100                for f in files:
101                    r, ext = os.path.splitext(f)
102                    if ext in [ ".h", ".c", ".cpp", ".S" ]:
103                        callback( "%s/%s" % (root,f), args )
104
105def cleanup_dir(path):
106    """create a directory if needed, and ensure that it is totally empty
107       by removing any existing content in it"""
108    if not os.path.exists(path):
109        os.mkdir(path)
110    else:
111        for root, dirs, files in os.walk(path, topdown=False):
112            if root.endswith("kernel_headers/"):
113                # skip 'kernel_headers'
114                continue
115            for name in files:
116                os.remove(os.path.join(root, name))
117            for name in dirs:
118                os.rmdir(os.path.join(root, name))
119
120
121class BatchFileUpdater:
122    """a class used to edit several files at once"""
123    def __init__(self):
124        self.old_files = set()
125        self.new_files = set()
126        self.new_data  = {}
127
128    def readFile(self,path):
129        #path = os.path.realpath(path)
130        if os.path.exists(path):
131            self.old_files.add(path)
132
133    def readDir(self,path):
134        #path = os.path.realpath(path)
135        for root, dirs, files in os.walk(path):
136            for f in files:
137                dst = "%s/%s" % (root,f)
138                self.old_files.add(dst)
139
140    def editFile(self,dst,data):
141        """edit a destination file. if the file is not mapped from a source,
142           it will be added. return 0 if the file content wasn't changed,
143           1 if it was edited, or 2 if the file is new"""
144        #dst = os.path.realpath(dst)
145        result = 1
146        if os.path.exists(dst):
147            f = open(dst, "r")
148            olddata = f.read()
149            f.close()
150            if olddata == data:
151                self.old_files.remove(dst)
152                return 0
153        else:
154            result = 2
155
156        self.new_data[dst] = data
157        self.new_files.add(dst)
158        return result
159
160    def getChanges(self):
161        """determine changes, returns (adds, deletes, edits)"""
162        adds    = set()
163        edits   = set()
164        deletes = set()
165
166        for dst in self.new_files:
167            if not (dst in self.old_files):
168                adds.add(dst)
169            else:
170                edits.add(dst)
171
172        for dst in self.old_files:
173            if not dst in self.new_files:
174                deletes.add(dst)
175
176        return (adds, deletes, edits)
177
178    def _writeFile(self,dst):
179        if not os.path.exists(os.path.dirname(dst)):
180            create_file_path(dst)
181        f = open(dst, "w")
182        f.write(self.new_data[dst])
183        f.close()
184
185    def updateFiles(self):
186        adds, deletes, edits = self.getChanges()
187
188        for dst in sorted(adds):
189            self._writeFile(dst)
190
191        for dst in sorted(edits):
192            self._writeFile(dst)
193
194        for dst in sorted(deletes):
195            os.remove(dst)
196
197    def updateGitFiles(self):
198        adds, deletes, edits = self.getChanges()
199
200        if adds:
201            for dst in sorted(adds):
202                self._writeFile(dst)
203            commands.getoutput("git add " + " ".join(adds))
204
205        if deletes:
206            commands.getoutput("git rm " + " ".join(deletes))
207
208        if edits:
209            for dst in sorted(edits):
210                self._writeFile(dst)
211            commands.getoutput("git add " + " ".join(edits))
212