summaryrefslogtreecommitdiffstats
path: root/util/cmake/pro2cmake.py
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2019-02-11 18:02:22 +0100
committerTobias Hunger <tobias.hunger@qt.io>2019-02-27 16:02:45 +0000
commit35f23a3dad20e09bada4e8fcdcc0de16b8a6af2f (patch)
tree6a6e3d10cbf5896d908a594bba093d2708fe9f9e /util/cmake/pro2cmake.py
parentb1fa25e7b8974fd9ce4b6d1283b9a43da532992e (diff)
CMake: pro2cmake.py: Better parsing of scopes with else
Parse conditions more exactly as before, enabling proper handling of else scopes. Change-Id: Icb5dcc73010be4833b2d1cbc1396191992df1ee4 Reviewed-by: Albert Astals Cid <albert.astals.cid@kdab.com>
Diffstat (limited to 'util/cmake/pro2cmake.py')
-rwxr-xr-xutil/cmake/pro2cmake.py123
1 files changed, 66 insertions, 57 deletions
diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py
index 5537ba38dc..63938d75c8 100755
--- a/util/cmake/pro2cmake.py
+++ b/util/cmake/pro2cmake.py
@@ -32,6 +32,7 @@ from __future__ import annotations
from argparse import ArgumentParser
import copy
+from itertools import chain
import os.path
import re
import io
@@ -509,10 +510,12 @@ class QmakeParser:
# Define grammar:
pp.ParserElement.setDefaultWhitespaceChars(' \t')
- LC = pp.Suppress(pp.Literal('\\') + pp.LineEnd())
- EOL = pp.Suppress(pp.Optional(pp.pythonStyleComment()) + pp.LineEnd())
-
+ LC = pp.Suppress(pp.Literal('\\\n'))
+ EOL = pp.Suppress(pp.Literal('\n'))
+ Else = pp.Keyword('else')
+ DefineTest = pp.Keyword('defineTest')
Identifier = pp.Word(pp.alphas + '_', bodyChars=pp.alphanums+'_-./')
+
Substitution \
= pp.Combine(pp.Literal('$')
+ (((pp.Literal('$') + Identifier
@@ -525,32 +528,31 @@ class QmakeParser:
| (pp.Literal('$') + pp.Literal('[') + Identifier
+ pp.Literal(']'))
)))
- # Do not match word ending in '\' since that breaks line
- # continuation:-/
LiteralValuePart = pp.Word(pp.printables, excludeChars='$#{}()')
SubstitutionValue \
= pp.Combine(pp.OneOrMore(Substitution | LiteralValuePart
| pp.Literal('$')))
- Value = (pp.QuotedString(quoteChar='"', escChar='\\')
- | SubstitutionValue)
+ Value = pp.NotAny(Else | pp.Literal('}') | EOL | pp.Literal('\\')) \
+ + (pp.QuotedString(quoteChar='"', escChar='\\')
+ | SubstitutionValue)
- Values = pp.ZeroOrMore(Value)('value')
+ Values = pp.ZeroOrMore(Value + pp.Optional(LC))('value')
Op = pp.Literal('=') | pp.Literal('-=') | pp.Literal('+=') \
| pp.Literal('*=')
- Operation = Identifier('key') + Op('operation') + Values('value')
- Load = pp.Keyword('load') + pp.Suppress('(') \
- + Identifier('loaded') + pp.Suppress(')')
- Include = pp.Keyword('include') + pp.Suppress('(') \
- + pp.CharsNotIn(':{=}#)\n')('included') + pp.Suppress(')')
- Option = pp.Keyword('option') + pp.Suppress('(') \
- + Identifier('option') + pp.Suppress(')')
- DefineTest = pp.Suppress(pp.Keyword('defineTest')
- + pp.Suppress('(') + Identifier
- + pp.Suppress(')')
- + pp.nestedExpr(opener='{', closer='}')
- + pp.LineEnd()) # ignore the whole thing...
+ Key = Identifier
+
+ Operation = Key('key') + pp.Optional(LC) \
+ + Op('operation') + pp.Optional(LC) \
+ + Values('value')
+ CallArgs = pp.nestedExpr()
+ CallArgs.setParseAction(lambda x: ' '.join(chain(*x)))
+ Load = pp.Keyword('load') + CallArgs('loaded')
+ Include = pp.Keyword('include') + CallArgs('included')
+ Option = pp.Keyword('option') + CallArgs('option')
+ DefineTestDefinition = pp.Suppress(DefineTest + CallArgs \
+ + pp.nestedExpr(opener='{', closer='}')) # ignore the whole thing...
ForLoop = pp.Suppress(pp.Keyword('for') + pp.nestedExpr()
+ pp.nestedExpr(opener='{', closer='}',
ignoreExpr=None)
@@ -559,45 +561,54 @@ class QmakeParser:
Scope = pp.Forward()
- Statement = pp.Group(Load | Include | Option | DefineTest
- | ForLoop | FunctionCall | Operation)
- StatementLine = Statement + EOL
- StatementGroup = pp.ZeroOrMore(StatementLine | Scope | EOL)
-
- Block = pp.Suppress('{') + pp.Optional(EOL) \
- + pp.ZeroOrMore(EOL | Statement + EOL | Scope) \
- + pp.Optional(Statement) + pp.Optional(EOL) \
- + pp.Suppress('}') + pp.Optional(EOL)
-
- Condition = pp.Optional(pp.White()) + pp.CharsNotIn(':{=}#\\\n')
- Condition.setParseAction(lambda x: ' '.join(x).strip())
-
- SingleLineScope = pp.Suppress(pp.Literal(':')) \
- + pp.Group(Scope | Block | StatementLine)('statements')
- MultiLineScope = Block('statements')
-
- SingleLineElse = pp.Suppress(pp.Literal(':')) \
- + pp.Group(Scope | StatementLine)('else_statements')
- MultiLineElse = pp.Group(Block)('else_statements')
- Else = pp.Suppress(pp.Keyword('else')) \
- + (SingleLineElse | MultiLineElse)
- Scope <<= pp.Group(Condition('condition')
- + (SingleLineScope | MultiLineScope)
- + pp.Optional(Else))
+ Statement = pp.Group(Load | Include | Option | ForLoop \
+ | DefineTestDefinition | FunctionCall | Operation)
+ StatementLine = Statement + (EOL | pp.FollowedBy('}'))
+ StatementGroup = pp.ZeroOrMore(StatementLine | Scope | pp.Suppress(EOL))
+
+ Block = pp.Suppress('{') + pp.Optional(LC | EOL) \
+ + StatementGroup + pp.Optional(LC | EOL) \
+ + pp.Suppress('}') + pp.Optional(LC | EOL)
+
+ ConditionEnd = pp.FollowedBy((pp.Optional(LC) + (pp.Literal(':') \
+ | pp.Literal('{') \
+ | pp.Literal('|'))))
+ ConditionPart = pp.CharsNotIn('#{}|:=\\\n') + pp.Optional(LC) + ConditionEnd
+ Condition = pp.Combine(ConditionPart \
+ + pp.ZeroOrMore((pp.Literal('|') ^ pp.Literal(':')) \
+ + ConditionPart))
+ Condition.setParseAction(lambda x: ' '.join(x).strip().replace(':', ' && ').strip(' && '))
+
+ SingleLineScope = pp.Suppress(pp.Literal(':')) + pp.Optional(LC) \
+ + pp.Group(Block | (Statement + EOL))('statements')
+ MultiLineScope = pp.Optional(LC) + Block('statements')
+
+ SingleLineElse = pp.Suppress(pp.Literal(':')) + pp.Optional(LC) \
+ + (Scope | Block | (Statement + pp.Optional(EOL)))
+ MultiLineElse = Block
+ ElseBranch = pp.Suppress(Else) + (SingleLineElse | MultiLineElse)
+ Scope <<= pp.Optional(LC) \
+ + pp.Group(Condition('condition') \
+ + (SingleLineScope | MultiLineScope) \
+ + pp.Optional(ElseBranch)('else_statements'))
if debug:
- for ename in 'EOL Identifier Substitution SubstitutionValue ' \
- 'LiteralValuePart Value Values SingleLineScope ' \
- 'MultiLineScope Scope SingleLineElse ' \
- 'MultiLineElse Else Condition Block ' \
- 'StatementGroup Statement Load Include Option ' \
- 'DefineTest ForLoop FunctionCall Operation'.split():
+ for ename in 'LC EOL ' \
+ 'Condition ConditionPart ConditionEnd ' \
+ 'Else ElseBranch SingleLineElse MultiLineElse ' \
+ 'SingleLineScope MultiLineScope ' \
+ 'Identifier ' \
+ 'Key Op Values Value ' \
+ 'Scope Block ' \
+ 'StatementGroup StatementLine Statement '\
+ 'Load Include Option DefineTest ForLoop ' \
+ 'FunctionCall CallArgs Operation'.split():
expr = locals()[ename]
expr.setName(ename)
expr.setDebug()
Grammar = StatementGroup('statements')
- Grammar.ignore(LC)
+ Grammar.ignore(pp.pythonStyleComment())
return Grammar
@@ -971,8 +982,8 @@ def simplify_condition(condition: str) -> str:
condition = condition.replace(' NOT ', ' ~ ')
condition = condition.replace(' AND ', ' & ')
condition = condition.replace(' OR ', ' | ')
- condition = condition.replace(' ON ', 'true')
- condition = condition.replace(' OFF ', 'false')
+ condition = condition.replace(' ON ', ' true ')
+ condition = condition.replace(' OFF ', ' false ')
try:
# Generate and simplify condition using sympy:
@@ -989,9 +1000,7 @@ def simplify_condition(condition: str) -> str:
# sympy did not like our input, so leave this condition alone:
condition = input_condition
- if condition == '':
- condition = 'ON'
- return condition
+ return condition or 'ON'
def recursive_evaluate_scope(scope: Scope, parent_condition: str = '',