From 1df83e027bef7a1d16ad9e05555103da028a49d9 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Sat, 30 Jul 2011 01:31:34 +0200 Subject: Need to rework how the automakefile scan works. So I can get the correct -I flags when I scan the files --- filetypes/acif.py | 17 +++++---- filetypes/autoconf.py | 27 ++++++++++---- filetypes/automake.py | 99 +++++++++++++++++++++++++++++++++---------------- filetypes/ctypefiles.py | 14 ++++++- scanfiles.py | 50 +++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 49 deletions(-) diff --git a/filetypes/acif.py b/filetypes/acif.py index 3da4ecb..1d3ed29 100644 --- a/filetypes/acif.py +++ b/filetypes/acif.py @@ -122,14 +122,15 @@ def parseif(ifoptions): | NONZERO OPT | OPT """ - if p[2] == "=": - varstr = p[1].split("$") - p[0] = [varstr[1],p[3][len(varstr[0]):]] - #[VARIABLEname,value to pass test] - - elif p[2] == "!=": - varstr = p[1].split("$") - p[0] = [varstr[1],"!" + p[3][len(varstr[0]):]] + if len(p) == 4: + if p[2] == "=": + varstr = p[1].split("$") + p[0] = [varstr[1],p[3][len(varstr[0]):]] + #[VARIABLEname,value to pass test] + + elif p[2] == "!=": + varstr = p[1].split("$") + p[0] = [varstr[1],"!" + p[3][len(varstr[0]):]] else: varstr = p[len(p)-1].split("$")[1] diff --git a/filetypes/autoconf.py b/filetypes/autoconf.py index debbd75..9b9dba0 100644 --- a/filetypes/autoconf.py +++ b/filetypes/autoconf.py @@ -355,7 +355,7 @@ def scanacfile(acfile): items = yacc.parse(acfile) return items -from acif import parseif +from filetypes.acif import parseif def output(inputlst): variables = dict() @@ -372,6 +372,7 @@ def output(inputlst): #remember to convert chars in the name of "item[1]" that is not #alfanumeric char to underscores _ + #Done with convnames! elif item[0] == "AC_ARG_WITH": name = convnames(item[1][0]) @@ -385,12 +386,22 @@ def output(inputlst): for variable in variables: for pattern in item[0][1]: if variable in pattern: - iflst += [parseif(item[0][1]),ifs(item[1],{})] + iflst += [[parseif(item[0][1]),ifs(item[1],{})]] + + elif item[0] == "AM_CONDITIONAL": + var = item[1][0].strip("[]") + cond = parseif(item[1][1].strip("[]").split()) + for if_state in iflst: + if cond[0] in if_state[1]: + if cond[1] == "!" or cond[1] == if_state[1][cond[0]]: + #"!" == not zero/defined, "" zero/not defined + if_state[1][var] = "true" #for variable in variables: #print(variable) #print(variables[variable]) - print(iflst) + #print(iflst) + return variables,iflst def ifs(inputlst,variables): @@ -400,6 +411,8 @@ def ifs(inputlst,variables): ac_check = 1 elif item[0] == "AC_CHECK_LIB": ac_check = 2 + elif item[0] == "PKG_CHECK_MODULES": + ac_check = 3 if ac_check: if not isinstance(item[1][0],list): @@ -433,6 +446,7 @@ def ifs(inputlst,variables): elif "=" in item: (var,items) = item.split("=") compitems = [] + #Fix "ยด" aka exec shell commad comments! for itm in items.strip('"').strip("'").split(): if itm[0] == "$": if itm[1:] in variables: @@ -451,7 +465,6 @@ def convnames(string): #strip none alfanumeric chars and replace them with "_" newstr = re.sub(pattern, "_", string) return newstr -file="configure.in" - -with open(file, encoding="utf-8", errors="replace") as inputfile: - output(scanacfile(inputfile.read())) +#this is no a good name, come up with a better one! +def scanac(acfile): + return output(scanacfile(acfile)) diff --git a/filetypes/automake.py b/filetypes/automake.py index f7e6a91..d338b71 100644 --- a/filetypes/automake.py +++ b/filetypes/automake.py @@ -72,7 +72,6 @@ def scanamfile(amfile): def t_CVAR(t): #configure variable r"@.*?@" #not greedy - t.value = t.value.strip("@") return t def t_MVAR(t): #makefile variable @@ -252,38 +251,74 @@ def scanamfile(amfile): variables = yacc.parse(amfile) return variables - -def scan(amfile): - curdir = os.path.split(amfile)[0] + "/" - amlist = scanamfile(openfile(amfile)) - print(amfile) - return sources_to_scan(amlist,curdir) - -def sources_to_scan(amlist,curdir): - sources = [] - #perhaps use set() here to eliminate the possibilty of duplicates? - for variable in amlist[0]: - if variable.split("_")[-1] == "SOURCES": - sources += amlist[0][variable] - - if "SUBDIRS" in amlist[0]: - for dir in amlist[0]["SUBDIRS"]: - sources += scan(curdir + dir + "/Makefile.am") - - for lst in amlist[1]: - if lst[0] == "SUBDIRS": - for dir in lst[1]: - sources += scan(curdir + dir + "/Makefile.am") - - for ifstatement in amlist[2]: - #don't care about if statements ATM! - sources += sources_to_scan(amlist[2][ifstatement],curdir) - - return sources +def initscan(amfile,iflst): + useflag_sources = {} #{source: [useflag, value]} + + def scan(amfile): + curdir = os.path.split(amfile)[0] + "/" + amlist = scanamfile(openfile(amfile)) + #print(amfile) + + def sources_to_scan(amlist,curdir): + sources = [] + extra_sources = [] + #perhaps use set() here to eliminate the possibilty of duplicates? + for variable in amlist[0]: + if variable.split("_")[-1] == "SOURCES": + if variable.split("_")[0] == "EXTRA": + extra_sources += amlist[0][variable] + else: + sources += amlist[0][variable] + + if variable.split("_")[-1] == "LDADD": + for item in amlist[0][variable]: + if item[0] == "@" and item[-1] == "@": + for ifstate in iflst: + if item.strip("@") in ifstate[1]: + for file in ifstate[1][item.strip("@")]: + for src in extra_sources: + if file.split(".")[0] == src.split(".")[0]: + useflag_sources.update({curdir + src : ifstate[0]}) + + for src in extra_sources: + if item.split(".")[0] == src.split(".")[0]: + sources += [src] + + if "SUBDIRS" in amlist[0]: + for dir in amlist[0]["SUBDIRS"]: + sources += scan(curdir + dir + "/Makefile.am") + + for lst in amlist[1]: + if lst[0] == "SUBDIRS": + for dir in lst[1]: + sources += scan(curdir + dir + "/Makefile.am") + + for ifstatement in amlist[2]: + #print(ifstatement) + for item in iflst: + if ifstatement.lstrip("!") in item[1]: + if ifstatement[0] == "!": + if item[1][ifstatement.lstrip("!")] == "false": + for src in sources_to_scan(amlist[2][ifstatement],curdir): + useflag_sources.update({src : item[0]}) + + elif item[1][ifstatement] == "true": + for src in sources_to_scan(amlist[2][ifstatement],curdir): + useflag_sources.update({src : item[0]}) + + #add filepath + dirsources = [] + for source in sources: + if os.path.split(source)[0] == "": + dirsources += [curdir + source] + else: + dirsources += [source] + + return dirsources + + return sources_to_scan(amlist,curdir) + return scan(amfile),useflag_sources def openfile(ofile): with open(ofile, encoding="utf-8", errors="replace") as inputfile: return inputfile.read() - -scan("/usr/portage/distfiles/svn-src/moc/trunk/Makefile.am") - diff --git a/filetypes/ctypefiles.py b/filetypes/ctypefiles.py index 32cb32d..ef6cbc5 100644 --- a/filetypes/ctypefiles.py +++ b/filetypes/ctypefiles.py @@ -122,6 +122,16 @@ def scanincludes(string,inclst,curdir): ifdef[p[1]] = p[2] p[0] = [set(),set(),ifdef] + def p_ifdefempty(p): + """ + includes : includes IFDEF ENDIF + | IFDEF ENDIF + """ + if len(p) == 4: + p[0] = p[1] + else: + p[0] = [set(),set(),{}] + def p_ginc(p): "includes : ginc" globinc = set() @@ -146,7 +156,7 @@ def scanincludes(string,inclst,curdir): p[0] = p[1] def p_error(p): - #print("syntax error at '%s'" % p.type) + print("syntax error at '%s'" % p.type) pass yacc.yacc() @@ -161,7 +171,7 @@ def scanincludes(string,inclst,curdir): def islocalinc(inc, curdir): """Checks if this is a local include - Checks if the file can be found with the path the is supplied. + Checks if the file can be found with the path that is supplied. If not this is probably a global include and thus return False """ diff --git a/scanfiles.py b/scanfiles.py index af4895e..a14200f 100644 --- a/scanfiles.py +++ b/scanfiles.py @@ -3,6 +3,8 @@ import glob from filetypes.ctypefiles import scanincludes from filetypes.makefiles import scanmakefile from filetypes.makefilecom import expand +from filetypes.autoconf import scanac +from filetypes.automake import initscan def scandirfor(dir, filetypes): """Scans recursivly the supplied dir for provided filetypes. @@ -65,6 +67,50 @@ def scanmakefiledeps(makefile): os.chdir(olddir) return filestoscan,binaries,incflags,targets +def scanautotoolsdeps(acfile,amfile): + """Scans autoconf file for useflags and the automake file in the same dir. + + Scans the provided autoconf file and then looks for a automakefile in the + same dir. Autoconf scan returns a dict with useflags and a list with variables + that gets defined by those useflags. + + Call the automake scan with the am file (that is in the same dir as the ac file) + and the list of variables from the autoconf scan and it will return a list of + default source files and a dict of files that gets pulled in by the useflag it + returns. + """ + #these are not really useflags yet. So perhaps change name? + useflags, iflst = scanac(openfile(acfile)) + srcfiles, src_useflag = initscan(amfile, iflst) + + #standard includes + includes = scanfilelist(srcfiles) + + def inter_useflag(uselst): + if uselst[1] == "yes" or uselst[1] == "!no": + usearg = uselst[0] + elif uselst[1] == "no" or uselst[1] == "!yes": + usearg = "!" + uselst[1] + else: + usearg = uselst[0] + "=" + uselst[1] + + return usearg + + #useflag includes + useargs = {} + for src in src_useflag: + usearg = inter_useflag(src_useflag[src]) + if usearg in useargs: + useargs[usearg] += [src] + else: + useargs[usearg] = [src] + + for usearg in useargs: + useargs[usearg] = scanfilelist(useargs[usearg]) + + print(useargs) + #print(includes) + def scanfilelist(filelist): """ Scan files in filelist for #includes @@ -79,6 +125,7 @@ def scanfilelist(filelist): inclst = [global_hfiles,local_hfiles,{}] for file in filelist: + #print(file) filestring = openfile(file) if not filestring == None: inclst = scanincludes(filestring,inclst,os.path.split(file)[0]) @@ -111,3 +158,6 @@ def openfile(file): return inputfile.read() except IOError: print('cannot open', file) + +#scanautotoolsdeps("/usr/portage/distfiles/svn-src/moc/trunk/configure.in","/usr/portage/distfiles/svn-src/moc/trunk/Makefile.am") +print(scanfilelist(["/usr/portage/distfiles/svn-src/moc/trunk/decoder_plugins/sidplay2/sidplay2.h"])) -- cgit v1.2.3-65-gdbad