def PrependPath(curpath, path): if not curpath: curpath = [] elif atmake.IsString(curpath): curpath = curpath.split(os.pathsep) elif atmake.IsList(curpath): pass else: atmake.Error('Invalid current PATH type !') if not path: path = [] elif atmake.IsString(path): path = path.split(os.pathsep) elif atmake.IsList(path): pass else: atmake.Error('Invalid PATH type !') for p in path: if p and not p in curpath: curpath.insert(0, str(p)) return string.join(curpath, os.pathsep)
def ToListPath(path, sep=None): """ ['A','B','C','D'] -> ['A','B','C','D'] 'A/B/C/D' -> ['A','B','C','D'] 'A B C D' -> ['A','B','C','D'] """ if sep is None: sep = os.sep if atmake.IsList(path): return path if not atmake.IsString(path): atmake.Error("Invalid path : %s !" % str(path)) if path.find(os.sep) >= 0: # 'A/B/C/D' -> ['A','B','C','D'] drive, path = os.path.splitdrive(path) p = [] while len(path): path, base = os.path.split(path) if len(base): p = [base] + p # prevent os.path.split('\\\') looping if len(path) and path[-1] == sep: break if len(drive): p = [drive] + p return p # 'A B C D' return path.split()
def RelativeFile(refdir, path): if not refdir or len(refdir) == 0: return path if not IsAbsPath(path): atmake.Error("File pathname <%s> must be absolute !" % path) if not IsAbsPath(refdir): atmake.Error("Reference directory <%s> must be absolute !" % refdir) n0 = os.path.normpath(path) n1 = os.path.normpath(refdir) p0 = ToListPath(n0.lower()) p1 = ToListPath(n1.lower()) ret = [] if p0: # if p0[:len(p1)] != p1 : # atmake.Error( "File <%s> isn't in base directory <%s> !" % (path,refdir) ) p0 = ToListPath(n0) ret.extend(p0[len(p1):]) return ToStringPath(ret)
def GetSourceTarget(self, fw, source, target=None): """ Framework fw str source str target """ if self.one2one: # one source, one target _trg = self.GetSourceTmpTarget(fw, source) if target and (target != _trg): atmake.Error( "One2One builder can't use the specific target <%s> !" % target) else: # multi sources to one target if not target: atmake.Error("Target file is missing !") _trg = fw.ToTargetFile(target) return _trg
def __fmt_source_ext(self, ext): if atmake.IsString(ext): extl = ext.split() else: extl = atmake.ToList(ext) extr = [] for e in extl: if not atmake.IsString(e): atmake.Error("Source extension must be a string !") if e.startswith('.'): extr.append(e[1:]) else: extr.append(e) return extr
def Spawn ( cmdline, cwd=None, env=None, showcl=None ) : """ returns : ( exec_success, exit_code, stdout lines, stderr lines ) """ def __readlines( ilines ) : olines = [] ol = '' for il in ilines : if il==ord('\r') : continue if il==ord('\n') : olines.append( ol+'\r\n' ) ol = '' else : ol += chr(il) return olines if atmake.IsString(cmdline) : cmdlist = cmdline_to_list( cmdline ) elif atmake.IsList(cmdline) : cmdlist = cmdline else : atmake.Error( "Command-line must be a string or a list of strings !" ) if showcl : print(cmdlist) # disable cl.exe direct redirection to visual IDE output window ! if env and 'VS_UNICODE_OUTPUT' in env : env['VS_UNICODE_OUTPUT'] = '' oo = ee = '' try : p = subprocess.Popen( cmdlist, stdout = subprocess.PIPE, stderr = subprocess.PIPE, cwd = cwd, env = env) oo, ee = p.communicate() oo = __readlines( oo ) ee = __readlines( ee ) retcode = p.returncode return ( True, retcode, oo, ee ) except OSError as e : print(oo) print(ee) return ( False, 0, None, None )
def processFiles(template, searchpath, extlist=[ '.h', '.c', '.cpp', '.cxx', '.vupp', '.vsmpp', '.vcl', '.vsa', '.psa' ]): """ Update file's header recursively. <template> The template header lines <searchpath> The root search path <extlist> List of file extensions to match """ # read header file header_lines = open(template, 'r').readlines() if header_lines == None: atmake.Error("Template header file <%s> is not found !\n" % template) for ext in extList: atmake.tools.header.processFiles(searchpath, ext, header_lines)
def ToStringPath(path, sep=None): """ 'A/B/C/D' -> 'A/B/C/D' 'A B C D' -> 'A/B/C/D' ['A','B','C','D'] -> 'A/B/C/D' """ if sep is None: sep = os.sep if atmake.IsString(path): if path.find(sep) >= 0: return path path = str(path).split() if not atmake.IsList(path) or len(path) == 0: atmake.Error("Invalid path : %s !" % str(path)) j = '' for p in path: if len(str(p)): j += sep + str(p) return j[1:]
def __fmt_target_ext(self, ext): if not atmake.IsString(ext): atmake.Error("Target extension must be a string !") if ext.startswith('.'): return ext[1:] else: return ext
def sort_by_rules(in_list, in_rules): # sort strings according to a list of rules # rule is a string 'pattern0 < pattern1' such as strings matching pattern0 # always occur in list before strings matching pattern1 def __id(li, it): if it in li: return li.index(it) else: li.append(it) return len(li) - 1 def __add(d, lid, rid): if lid in d: d[lid].append(rid) else: d[lid] = [rid] if rid not in d: d[rid] = [] def __extdict(d, r, k): for i in d[k]: r[i] = True __extdict(d, r, i) def __extlist(d, k): r = {} __extdict(d, r, k) return r.keys() def __fnmatch(li, path): d = {} for i in range(len(li)): pi = li[i] if fnmatch.fnmatch(path, pi): d[pi] = i return [d[k] for k in sorted(d.keys())] def __rcmp(r, r0, r1): if len(r0) == 0 and len(r1) == 0: return 0 if r0[0] == r1[0]: return __rcmp(r, r0[1:], r1[1:]) c = 0 for i0 in r0: for i1 in r1: if i1 in r[i0]: _c = -1 # i0 before i1 elif i0 in r[i1]: _c = +1 # i0 after i1 else: _c = 0 if _c != 0: atmake.Assert(c == 0 or (_c == c), 'Circular rules found !') c = _c return c show_dbg = False patterns = [] rules = {} for r in in_rules: if r.find('<') > 0: left, sep, right = r.partition('<') elif r.find('>') > 0: right, sep, left = r.partition('>') else: atmake.Error('Invalid rule "%s" !' % r) left, right = left.strip().lower(), right.strip().lower() atmake.Assert(left, 'Invalid rule "%s" !' % r) atmake.Assert(right, 'Invalid rule "%s" !' % r) lid = __id(patterns, left) rid = __id(patterns, right) __add(rules, lid, rid) if show_dbg: print(r, lid, rid, patterns, rules) def __cmp(s0, s1): c = __rcmp(rules, s0[1], s1[1]) if show_dbg: if c < 0: print('(%s) < (%s)' % (s0[0], s1[0])) elif c > 0: print('(%s) > (%s)' % (s0[0], s1[0])) else: print('(%s) = (%s)' % (s0[0], s1[0])) return c # items is list of preprocessed ( path, path-pattern-ids ) items = [(i, __fnmatch(patterns, i.lower())) for i in in_list] sitems = sorted(items, cmp=__cmp) out_list = [i[0] for i in sitems] if show_dbg: print("Before ....") for s in in_list: print(s) print("After ...") for s in out_list: print(s) return out_list
def AbsoluteFile(basedir, path): if not IsAbsPath(basedir): atmake.Error("Base directory <%s> must be absolute !" % basedir) if IsAbsPath(path): atmake.Error("File pathname <%s> must be relative !" % path) return os.path.normpath(os.path.join(basedir, path))
def __cache_error(self): RmFile(self.sfile) atmake.Error( "\n\n** The cache file <%s> seems to be corrupted !!!\n** This file has been automatically removed.\n** Please restart the whole operation to complete.\n\n\n\n" % self.sfile, 0)