summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-05-23 15:57:59 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-05-23 14:19:22 +0000
commitbfed22e3b7b6de27359d41f1a51ea345f7284ce2 (patch)
tree6265a864bd0fd29cd438815028522fe42ab08a5a /util
parenta2e0f19b61453dc472bca657935310dcfbf9fc86 (diff)
Remove all line continuations when processing qmake syntax
We constantly had to adjust the qmake grammar to handle line continuations (\\\n) in weird places. Instead of doing that, just do a preprocess step to remove all the LCs like we do with comments, and simplify the grammar not to take into account the LCs. From some manual testing it doesn't look like we get any regressions. Change-Id: I2017d59396004cf67b6cb54977583db65c65e7d3 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'util')
-rwxr-xr-xutil/cmake/pro2cmake.py59
-rwxr-xr-xutil/cmake/tests/test_lc_fixup.py8
2 files changed, 32 insertions, 35 deletions
diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py
index 0f3f796227..5a2db68e67 100755
--- a/util/cmake/pro2cmake.py
+++ b/util/cmake/pro2cmake.py
@@ -149,9 +149,12 @@ def process_qrc_file(target: str, filepath: str, base_dir: str = '') -> str:
def fixup_linecontinuation(contents: str) -> str:
- contents = re.sub(r'([^\t ])\\[ \t]*\n', '\\1 \\\n', contents)
- contents = re.sub(r'\\[ \t]*\n', '\\\n', contents)
-
+ # Remove all line continuations, aka a backslash followed by
+ # a newline character with an arbitrary amount of whitespace
+ # between the backslash and the newline.
+ # This greatly simplifies the qmake parsing grammar.
+ contents = re.sub(r'([^\t ])\\[ \t]*\n', '\\1 ', contents)
+ contents = re.sub(r'\\[ \t]*\n', '', contents)
return contents
@@ -721,8 +724,6 @@ class QmakeParser:
value.setDebug()
return value
- LC = add_element('LC', pp.Suppress(pp.Literal('\\\n')))
-
EOL = add_element('EOL', pp.Suppress(pp.LineEnd()))
Else = add_element('Else', pp.Keyword('else'))
Identifier = add_element('Identifier', pp.Word(pp.alphas + '_',
@@ -763,7 +764,7 @@ class QmakeParser:
| SubstitutionValue
| BracedValue))
- Values = add_element('Values', pp.ZeroOrMore(Value + pp.Optional(LC))('value'))
+ Values = add_element('Values', pp.ZeroOrMore(Value)('value'))
Op = add_element('OP',
pp.Literal('=') | pp.Literal('-=') | pp.Literal('+=') \
@@ -771,11 +772,8 @@ class QmakeParser:
Key = add_element('Key', Identifier)
- Operation = add_element('Operation',
- Key('key') + pp.Optional(LC) \
- + Op('operation') + pp.Optional(LC) \
- + Values('value'))
- CallArgs = add_element('CallArgs', pp.Optional(LC) + pp.nestedExpr())
+ Operation = add_element('Operation', Key('key') + Op('operation') + Values('value'))
+ CallArgs = add_element('CallArgs', pp.nestedExpr())
def parse_call_args(results):
out = ''
@@ -807,8 +805,7 @@ class QmakeParser:
# ignore the whole thing...
ForLoopSingleLine = add_element(
'ForLoopSingleLine',
- pp.Suppress(pp.Keyword('for') + CallArgs
- + pp.Literal(':') + pp.SkipTo(EOL, ignore=LC)))
+ pp.Suppress(pp.Keyword('for') + CallArgs + pp.Literal(':') + pp.SkipTo(EOL)))
# ignore the whole thing...
FunctionCall = add_element('FunctionCall', pp.Suppress(Identifier + pp.nestedExpr()))
@@ -823,29 +820,30 @@ class QmakeParser:
pp.ZeroOrMore(StatementLine | Scope | pp.Suppress(EOL)))
Block = add_element('Block',
- pp.Suppress('{') + pp.Optional(LC | EOL)
- + StatementGroup + pp.Optional(LC | EOL)
- + pp.Suppress('}') + pp.Optional(LC | EOL))
+ pp.Suppress('{') + pp.Optional(EOL)
+ + StatementGroup + pp.Optional(EOL)
+ + pp.Suppress('}') + pp.Optional(EOL))
ConditionEnd = add_element('ConditionEnd',
pp.FollowedBy((pp.Optional(pp.White())
- + pp.Optional(LC) + (pp.Literal(':')
- | pp.Literal('{')
- | pp.Literal('|')))))
+ + (pp.Literal(':')
+ | pp.Literal('{')
+ | pp.Literal('|')))))
ConditionPart1 = add_element('ConditionPart1',
(pp.Optional('!') + Identifier + pp.Optional(BracedValue)))
ConditionPart2 = add_element('ConditionPart2', pp.CharsNotIn('#{}|:=\\\n'))
ConditionPart = add_element(
'ConditionPart',
- (ConditionPart1 ^ ConditionPart2) + pp.Optional(LC) + ConditionEnd)
+ (ConditionPart1 ^ ConditionPart2) + ConditionEnd)
ConditionOp = add_element('ConditionOp', pp.Literal('|') ^ pp.Literal(':'))
- ConditionLC = add_element('ConditionLC',
- pp.Suppress(pp.Optional(pp.White(' ') + LC + pp.White(' '))))
+ ConditionWhiteSpace = add_element('ConditionWhiteSpace',
+ pp.Suppress(pp.Optional(pp.White(' '))))
ConditionRepeated = add_element('ConditionRepeated',
- pp.ZeroOrMore((ConditionOp) + ConditionLC + ConditionPart))
+ pp.ZeroOrMore(ConditionOp
+ + ConditionWhiteSpace + ConditionPart))
Condition = add_element('Condition', pp.Combine(ConditionPart + ConditionRepeated))
Condition.setParseAction(lambda x: ' '.join(x).strip().replace(':', ' && ').strip(' && '))
@@ -859,22 +857,21 @@ class QmakeParser:
.setResultsName('statements'))
SingleLineScope = add_element('SingleLineScope',
- pp.Suppress(pp.Literal(':')) + pp.Optional(LC)
+ pp.Suppress(pp.Literal(':'))
+ pp.Group(Block | (Statement + EOL))('statements'))
- MultiLineScope = add_element('MultiLineScope',
- pp.Optional(LC) + Block('statements'))
+ MultiLineScope = add_element('MultiLineScope', Block('statements'))
SingleLineElse = add_element('SingleLineElse',
- pp.Suppress(pp.Literal(':')) + pp.Optional(LC)
+ pp.Suppress(pp.Literal(':'))
+ (Scope | Block | (Statement + pp.Optional(EOL))))
MultiLineElse = add_element('MultiLineElse', Block)
ElseBranch = add_element('ElseBranch', pp.Suppress(Else) + (SingleLineElse | MultiLineElse))
# Scope is already add_element'ed in the forward declaration above.
- Scope <<= pp.Optional(LC) \
- + pp.Group(Condition('condition')
- + (SingleLineScope | MultiLineScope | ConditionEndingInFunctionCall)
- + pp.Optional(ElseBranch)('else_statements'))
+ Scope <<= \
+ pp.Group(Condition('condition')
+ + (SingleLineScope | MultiLineScope | ConditionEndingInFunctionCall)
+ + pp.Optional(ElseBranch)('else_statements'))
Grammar = StatementGroup('statements')
Grammar.ignore(pp.pythonStyleComment())
diff --git a/util/cmake/tests/test_lc_fixup.py b/util/cmake/tests/test_lc_fixup.py
index d3680e895d..841e11615e 100755
--- a/util/cmake/tests/test_lc_fixup.py
+++ b/util/cmake/tests/test_lc_fixup.py
@@ -29,18 +29,18 @@
from pro2cmake import fixup_linecontinuation
-from textwrap import dedent
-
def test_no_change():
input = "test \\\nline2\n line3"
+ output = "test line2\n line3"
result = fixup_linecontinuation(input)
- assert input == result
+ assert output == result
def test_fix():
input = "test \\\t\nline2\\\n line3\\ \nline4 \\ \t\nline5\\\n\n\n"
+ output = "test line2 line3 line4 line5 \n\n"
result = fixup_linecontinuation(input)
- assert 'test \\\nline2 \\\n line3 \\\nline4 \\\nline5 \\\n\n\n' == result
+ assert output == result