diff options
| author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-01-31 11:43:22 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@qt.io> | 2020-02-03 15:01:53 +0000 |
| commit | 4e7af2061e8c323b2a21f0549643a2cfab191664 (patch) | |
| tree | 54c6046915aee4a91eb6178183c022b8e547d244 /util/cmake/json_parser.py | |
| parent | 6251963ecd26bfc480b2871e26b6df4d7ab88cee (diff) | |
| parent | 3f386095adc6c280008c7e811e88f0215f1d862f (diff) | |
Merge remote-tracking branch 'origin/wip/cmake' into dev
This pulls the CMake port, which not only adds CMake files but also
modifies existing code. A brief summary of "seemingly unrelated" changes:
* configure.json was re-formatted to not use multi-line strings. That
is an extension of the Qt JSON parser but not JSON compliant, which
is needed for the configure.json-to-cmake conversion script (python).
* Some moc inclusions were added due to CMake's slightly different way
of handling moc. With the changes the files build with qmake and cmake.
* Since CMake just grep's for the Q_OBJECT macro to determine whether to
call moc (instead of doing pre-processing like qmake), the existing use
of "Q_OBJECT" in our documentation was changed to \Q_OBJECT, which cmake
doesn't see and which is now a qdoc macro.
* QTestLib's qFindTestData was extended to also search in the source
directory known at build time.
What this change also brings is a new way of building modules in Coin by using
YAML configuration files that describe the steps of building and testing in Coin
specific terms. The platform configuration files in qt5 are instructed to use the
old Coin built-in way of testing ("UseLegacyInstructions" feature) but for any
configurations that do not have this, these yaml files in the coin/ sub-directory
are used and shared across repositories.
Change-Id: I1d832c3400e8d6945ad787024ba60e7440225c08
Diffstat (limited to 'util/cmake/json_parser.py')
| -rw-r--r-- | util/cmake/json_parser.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/util/cmake/json_parser.py b/util/cmake/json_parser.py new file mode 100644 index 00000000000..a0aaecab9da --- /dev/null +++ b/util/cmake/json_parser.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the plugins of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:GPL-EXCEPT$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 as published by the Free Software +## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import pyparsing as pp # type: ignore +import json +import re +from helper import _set_up_py_parsing_nicer_debug_output + +_set_up_py_parsing_nicer_debug_output(pp) + + +class QMakeSpecificJSONParser: + def __init__(self, *, debug: bool = False) -> None: + self.debug = debug + self.grammar = self.create_py_parsing_grammar() + + def create_py_parsing_grammar(self): + # Keep around all whitespace. + pp.ParserElement.setDefaultWhitespaceChars("") + + def add_element(name: str, value: pp.ParserElement): + nonlocal self + if self.debug: + value.setName(name) + value.setDebug() + return value + + # Our grammar is pretty simple. We want to remove all newlines + # inside quoted strings, to make the quoted strings JSON + # compliant. So our grammar should skip to the first quote while + # keeping everything before it as-is, process the quoted string + # skip to the next quote, and repeat that until the end of the + # file. + + EOF = add_element("EOF", pp.StringEnd()) + SkipToQuote = add_element("SkipToQuote", pp.SkipTo('"')) + SkipToEOF = add_element("SkipToEOF", pp.SkipTo(EOF)) + + def remove_newlines_and_whitespace_in_quoted_string(tokens): + first_string = tokens[0] + replaced_string = re.sub(r"\n[ ]*", " ", first_string) + return replaced_string + + QuotedString = add_element( + "QuotedString", pp.QuotedString(quoteChar='"', multiline=True, unquoteResults=False) + ) + QuotedString.setParseAction(remove_newlines_and_whitespace_in_quoted_string) + + QuotedTerm = add_element("QuotedTerm", pp.Optional(SkipToQuote) + QuotedString) + Grammar = add_element("Grammar", pp.OneOrMore(QuotedTerm) + SkipToEOF) + + return Grammar + + def parse_file_using_py_parsing(self, file: str): + print(f'Pre processing "{file}" using py parsing to remove incorrect newlines.') + try: + with open(file, "r") as file_fd: + contents = file_fd.read() + + parser_result = self.grammar.parseString(contents, parseAll=True) + token_list = parser_result.asList() + joined_string = "".join(token_list) + + return joined_string + except pp.ParseException as pe: + print(pe.line) + print(" " * (pe.col - 1) + "^") + print(pe) + raise pe + + def parse(self, file: str): + pre_processed_string = self.parse_file_using_py_parsing(file) + print(f'Parsing "{file}" using json.loads().') + json_parsed = json.loads(pre_processed_string) + return json_parsed |
