aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2011-07-14 23:22:34 +0200
committerSebastian Parborg <darkdefende@gmail.com>2011-07-14 23:22:34 +0200
commit11cc610aee0455ba23c5a7182d599fcad523e9ca (patch)
tree4f565d570496658b805ebb36648071698622cd23
parentThe autoconf parser now parser whole files (diff)
downloadebuildgen-11cc610aee0455ba23c5a7182d599fcad523e9ca.tar.gz
ebuildgen-11cc610aee0455ba23c5a7182d599fcad523e9ca.tar.bz2
ebuildgen-11cc610aee0455ba23c5a7182d599fcad523e9ca.zip
More work on autotools
-rw-r--r--TODO1
-rw-r--r--filetypes/acif.py144
-rw-r--r--filetypes/autoconf.py55
-rw-r--r--filetypes/automake.py77
4 files changed, 264 insertions, 13 deletions
diff --git a/TODO b/TODO
index 5db51b6..729cd86 100644
--- a/TODO
+++ b/TODO
@@ -12,3 +12,4 @@ Handle zip,tar for unpacking
Handle $(foo)_test = ... variable assingment
Add more filetypes to search for in the implicid makefile ".c" search
Have ply write the parser.out to different files for different filetypes so that is doesn't overwrite other parsers
+Properly handle names of AC_ARG_WITH (convert stuff to underscores)
diff --git a/filetypes/acif.py b/filetypes/acif.py
new file mode 100644
index 0000000..3da4ecb
--- /dev/null
+++ b/filetypes/acif.py
@@ -0,0 +1,144 @@
+from ply import lex
+from ply import yacc
+
+def parseif(ifoptions):
+ optstr = ""
+ for option in ifoptions:
+ optstr += option + " "
+
+ tokens = (
+ "NOT",
+ "AND",
+ "OR",
+ "EQ",
+ "NEQ",
+ "NONZERO",
+ "SEMICOL",
+ "LBRAC",
+ "RPRAC",
+ "OPT",
+ "TEST",
+ )
+
+ def t_TEST(t):
+ r"test"
+ return t
+
+ def t_AND(t):
+ r"(\-a|\&\&)"
+ return t
+
+ def t_OR(t):
+ r"(\-o|\|\|)"
+ return t
+
+ def t_EQ(t):
+ r"="
+ return t
+
+ def t_NEQ(t):
+ r"\!="
+ return t
+
+ def t_NOT(t):
+ r"\!"
+ return t
+
+ def t_NONZERO(t):
+ r"\-n"
+ return t
+
+ def t_SEMICOL(t):
+ r";"
+ pass
+
+ def t_LBRAC(t):
+ r"\{"
+ return t
+
+ def t_RPRAC(t):
+ r"\}"
+ return t
+
+ def t_space(t):
+ r"[ \t\n]"
+ pass
+
+ def t_quote(t):
+ r"[\"\']"
+ pass
+
+ def t_OPT(t):
+ r"[^ \t\n;\"\']+"
+ return t
+
+ def t_ANY_error(t):
+ print("Illegal character '%s'" % t.value[0],t.lexer.lineno)
+ t.lexer.skip(1)
+
+ lexer = lex.lex()
+
+ #lexer.input(optstr)
+ #for tok in lexer:
+ # print(tok)
+
+ #YACC
+ #Add more cases!
+
+ def p_exp(p):
+ """
+ exp : NOT TEST expopt
+ | TEST expopt
+ """
+ if len(p) == 4:
+ newlst = []
+ while len(newlst) < len(p[3]):
+ if p[3][len(newlst)+1][0] == "!":
+ newresult = p[3][len(newlst)+1][1:]
+ else:
+ newresult = "!" + p[3][len(newlst)+1]
+
+ newlst += [p[3][len(newlst)],newresult]
+
+ p[0] = newlst
+
+ else:
+ p[0] = p[2]
+
+ def p_expopt(p):
+ """
+ expopt : expopt AND expopt
+ | expopt OR expopt
+ """
+ if p[2] == "-a":
+ p[0] = p[1] + p[3]
+ else: #come up with something better
+ p[0] = p[1] + p[3]
+
+ def p_expopt2(p):
+ """
+ expopt : OPT EQ OPT
+ | OPT NEQ OPT
+ | 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]):]]
+
+ else:
+ varstr = p[len(p)-1].split("$")[1]
+ p[0] = [varstr, "!"] #req that the variable is nonzero to be True
+
+ def p_error(p):
+ print("syntax error at '%s'" % p.type,p.value)
+ pass
+
+ yacc.yacc()
+ return yacc.parse(optstr)
+
diff --git a/filetypes/autoconf.py b/filetypes/autoconf.py
index 09bf87d..98555ce 100644
--- a/filetypes/autoconf.py
+++ b/filetypes/autoconf.py
@@ -188,6 +188,7 @@ def scanacfile(acfile):
return t
def t_TEXT(t): #most likely commands like "AM_INIT_AUTOMAKE" etc.
+ #Fix this so I can handle variables like the one above as that is NOT a text string
r"([^ ;,\t\n\(\)]+|\([^() \t\n]*\))"
return t
@@ -352,10 +353,56 @@ def scanacfile(acfile):
yacc.yacc()
items = yacc.parse(acfile)
- #for item in items:
- # print(item)
+ return items
+
+from acif import parseif
+
+def output(inputlst):
+ variables = dict()
+ ifs = []
+ for item in inputlst:
+ if item[0] == "AC_ARG_ENABLE":
+ name = convnames(item[1][0])
+ if len(item[1]) == 2:
+ variables["enable_" + name] = [[],[]]
+ elif len(item[1]) == 3:
+ variables["enable_" + name] = [item[1][2],[]]
+ else:
+ variables["enable_" + name] = [item[1][2],item[1][3]]
+
+ #remember to convert chars in the name of "item[1]" that is not
+ #alfanumeric char to underscores _
-file="configure.ac"
+ if item[0] == "AC_ARG_WITH":
+ name = convnames(item[1][0])
+ if len(item[1]) == 2:
+ variables["with_" + name] = [[],[]]
+ elif len(item[1]) == 3:
+ variables["with_" + name] = [item[1][2],[]]
+ else:
+ variables["with_" + name] = [item[1][2],item[1][3]]
+ elif isinstance(item[0],list): #if statements
+ for variable in variables:
+ for pattern in item[0][1]:
+ if variable in pattern:
+ ifs += [parseif(item[0][1])]
+ elif "=" in item:
+ #print(item)
+ b = 0
+
+ #for variable in variables:
+ #print(variable)
+ #print(variables[variable])
+ print(ifs)
+
+import re
+def convnames(string): #strip none alfanumeric chars and replace them with "_"
+ string = string.strip("[]") #remove quotes
+ pattern = re.compile("\W")
+ newstr = re.sub(pattern, "_", string)
+ return newstr
+
+file="configure.in"
with open(file, encoding="utf-8", errors="replace") as inputfile:
- scanacfile(inputfile.read())
+ output(scanacfile(inputfile.read()))
diff --git a/filetypes/automake.py b/filetypes/automake.py
index e9e31a2..1eaa765 100644
--- a/filetypes/automake.py
+++ b/filetypes/automake.py
@@ -18,11 +18,15 @@ def scanamfile(amfile):
"TEXT",
"ENDTAB",
"SPACE",
+ "IF",
+ "ELSE",
+ "ENDIF",
)
states = (
("com", "exclusive"), #comment
("var", "inclusive"),
+ ("if", "exclusive"),
)
def t_begin_com(t):
@@ -42,6 +46,29 @@ def scanamfile(amfile):
t.lexer.lineno += 1
pass
+ def t_ifbegin(t):
+ #ugly hack to ensure that this is at the begining of the line and keep the newline token.
+ #PLY doesn't support the "^" beginning of line regexp :,(
+ r"\nif"
+ t.type = "END"
+ t.lexer.push_state("if")
+ return t
+
+ def t_if_IF(t):
+ #http://www.gnu.org/s/hello/manual/automake/Usage-of-Conditionals.html#Usage-of-Conditionals
+ r"[ \t]+[^ \n\t]*"
+ t.value = t.value.strip() #take the variable to test
+ t.lexer.pop_state()
+ return t
+
+ def t_ELSE(t):
+ r"\nelse"
+ return t
+
+ def t_ENDIF(t):
+ r"\nendif"
+ return t
+
def t_CVAR(t): #configure variable
r"@.*?@" #not greedy
t.value = t.value.strip("@")
@@ -60,11 +87,13 @@ def scanamfile(amfile):
def t_EQ(t):
r"[ \t]*=[ \t]*"
t.lexer.begin("var")
+ t.value = t.value.strip()
return t
def t_PEQ(t):
r"[ \t]*\+=[ \t]*"
t.lexer.begin("var")
+ t.value = t.value.strip()
return t
def t_contline(t):
@@ -101,15 +130,19 @@ def scanamfile(amfile):
return t
def t_END(t):
- r"[ \t]*\n+"
+ r"[ \t]*\n"
t.lexer.lineno += t.value.count('\n')
t.lexer.begin('INITIAL')
return t
- def t_SPACE(t):
+ def t_var_SPACE(t):
r"[ \t]+"
return t
+ def t_space(t):
+ r"[ \t]"
+ pass
+
def t_var_special(t):
r"\$[^({]"
t.type = "TEXT"
@@ -128,26 +161,46 @@ def scanamfile(amfile):
#YACC stuff begins here
def p_done(p):
- "done : vars END"
+ "done : vars end"
p[0] = p[1]
def p_vars(p):
"""
- vars : vars END var
- | END var
+ vars : vars end var
+ | end var
"""
if len(p) == 4:
- p[1].update(p[3])
- p[0] = p[1]
+ p[1][0].update(p[3][0])
+ p[1][2].update(p[3][2])
+ p[0] = [p[1][0], p[1][1] + p[3][1], p[1][2]]
+
else:
p[0] = p[2]
+ def p_if(p):
+ """
+ var : IF vars ENDIF
+ | IF vars ELSE vars ENDIF
+ """
+ if len(p) == 4:
+ p[0] = [{},[],{p[1]:p[2]}]
+
+ else:
+ p[0] = [{},[],{p[1]:p[2],"!"+p[1]:p[4]}]
+
def p_var(p):
"""
var : textstr EQ textlst
+ | textstr EQ
| textstr PEQ textlst
"""
- p[0] = {p[1]:p[3]}
+ if p[2] == "=":
+ if len(p) == 4:
+ p[0] = [{p[1]: p[3]},[],{}]
+ else:
+ p[0] = [{p[1]: []},[],{}]
+ else:
+ p[0] = [{},[[p[1], p[3]]],{}]
def p_textlst(p):
"""
@@ -183,6 +236,12 @@ def scanamfile(amfile):
else:
p[0] = p[1]
+ def p_end(p):
+ """
+ end : end END
+ | END
+ """
+
def p_error(p):
print("syntax error at '%s'" % p.type,p.value)
pass
@@ -192,7 +251,7 @@ def scanamfile(amfile):
variables = yacc.parse(amfile)
print(variables)
-file="/usr/portage/distfiles/svn-src/moc/trunk/Makefile.am"
+file="/usr/portage/distfiles/svn-src/moc/trunk/decoder_plugins/Makefile.am"
with open(file, encoding="utf-8", errors="replace") as inputfile:
scanamfile(inputfile.read())