diff options
author | Joerg Bornemann <joerg.bornemann@digia.com> | 2014-01-16 16:50:00 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@digia.com> | 2014-01-20 16:58:49 +0100 |
commit | fe3941568f11ea02996af489453bc5606b6988fd (patch) | |
tree | 8b410caad9ddfce47e13347b9b4509d3cf1ea2b0 /tests/auto/blackbox | |
parent | f64c7492a3ba5cd73994be810be7ff529a19f37e (diff) |
add autotest for dynamic rule outputs
Task-number: QBS-370
Change-Id: Ib70597d8eeed711842cfb86f8d1ecb434f6b40bd
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Diffstat (limited to 'tests/auto/blackbox')
6 files changed, 415 insertions, 0 deletions
diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l b/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l new file mode 100644 index 000000000..b29f8798f --- /dev/null +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/after/numbers.l @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Build Suite. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +/* scanner for integer and float numbers */ + +%option noyywrap + +%{ +/* need this for the call to atof() below */ +#include <math.h> +%} + +DIGIT [0-9] + +%% + +{DIGIT}+ { + printf("integer: %s (%d)\n", yytext, atoi(yytext)); + } + +{DIGIT}+"."{DIGIT}* { + printf("float: %s (%g)\n", yytext, atof(yytext)); + } + +"{"[\^{}}\n]*"}" /* eat up one-line comments */ + +[ \t\n]+ /* eat up whitespace */ + +. printf("Unexpected character: %s\n", yytext); + +%% + +int main(int argc, char **argv) +{ + if (argc > 1) + yyin = fopen(argv[1], "r"); + else + yyin = stdin; + + yylex(); + return 0; +} + diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js new file mode 100644 index 000000000..232e8338f --- /dev/null +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/flexoptionsreader.js @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Build Suite. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +// needs import qbs.TextFile + +function readFlexOptions(filePath) +{ + function splitOptions(str) + { + var options = []; + var opt = ""; + var inquote = false; + for (var i = 0; i < str.length; ++i) { + if (str[i] === '"') { + opt += '"'; + inquote = !inquote; + } else if (str[i] === ' ' && !inquote) { + options.push(opt); + opt = ""; + } else { + opt += str[i]; + } + } + if (opt.length) + options.push(opt); + return options; + } + + function unquote(str) + { + var l = str.length; + if (l > 2 && str[0] === '"' && str[l - 1] === '"') + return str.substr(1, l - 2); + return str; + } + + function parseOptionLine(result, str) + { + var options = splitOptions(str); + var re = /^(outfile|header-file)=(.*)$/; + var reres; + for (var k in options) { + re.lastIndex = 0; + reres = re.exec(options[k]); + if (reres === null) + continue; + result[reres[1]] = unquote(reres[2]); + } + } + + var tf = new TextFile(input.fileName); + var line; + var optrex = /^%option\s+(.*$)/; + var res; + var options = {}; + while (!tf.atEof()) { + line = tf.readLine(); + if (line === "%%") + break; + optrex.lastIndex = 0; + res = optrex.exec(line); + if (res === null) + continue; + parseOptionLine(options, res[1]); + } + tf.close(); + return options; +} + diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs new file mode 100644 index 000000000..b822e852e --- /dev/null +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/genlexer.qbs @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Build Suite. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +import qbs 1.0 +import qbs.File +import qbs.FileInfo +import qbs.TextFile +import "flexoptionsreader.js" as FlexOptionsReader + +Project { + Product { + name: "genlexer" + type: "application" + Depends { name: "cpp" } + Group { + files: ["numbers.l"] + fileTags: ["flex"] + } + property bool isFlexAvailable: File.exists("/usr/bin/flex") // ### replace with PathProbe + Rule { + inputs: ["flex"] + outputFileTags: ["c", "hpp"] + outputArtifacts: { + var options = FlexOptionsReader.readFlexOptions(input.fileName); + var sourceFileName = options["outfile"] || "lex.yy.c"; + var headerFileName = options["header-file"]; + var result = [{ + filePath: "GeneratedFiles/" + product.name + "/" + sourceFileName, + fileTags: ["c"] + }]; + if (headerFileName) { + result.push({ + filePath: "GeneratedFiles/" + product.name + "/" + headerFileName, + fileTags: ["hpp"] + }); + } + return result; + } + prepare: { + var cmd; + if (product.isFlexAvailable) { + // flex is available. Let's call it. + cmd = new Command("flex", [input.fileName]); + cmd.workingDirectory = product.buildDirectory + "/GeneratedFiles/" + product.name; + } else { + // No flex available here, generate some C source and header. + cmd = new JavaScriptCommand(); + cmd.sourceFileName = outputs["c"][0].fileName; + cmd.headerFileName = outputs["hpp"] ? outputs["hpp"][0].fileName : ""; + cmd.sourceCode = function() { + var fsrc = new TextFile(sourceFileName, TextFile.WriteOnly); + if (headerFileName) { + fsrc.write("#include \"" + FileInfo.fileName(headerFileName) + + "\"\n\n"); + var fhdr = new TextFile(headerFileName, TextFile.WriteOnly); + fhdr.write("// a rather empty header file\n"); + fhdr.close(); + } + fsrc.write("int main() { return 0; }\n"); + fsrc.close(); + }; + } + cmd.description = "flexing " + FileInfo.fileName(input.fileName); + return cmd; + } + } + } +} + diff --git a/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l new file mode 100644 index 000000000..19f503562 --- /dev/null +++ b/tests/auto/blackbox/testdata/dynamicRuleOutputs/before/numbers.l @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Build Suite. +** +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ + +/* scanner for integer and float numbers */ + +%option noyywrap +%option outfile="numberscanner.c" header-file="numberscanner.h" + +%{ +/* need this for the call to atof() below */ +#include <math.h> +%} + +DIGIT [0-9] + +%% + +{DIGIT}+ { + printf("integer: %s (%d)\n", yytext, atoi(yytext)); + } + +{DIGIT}+"."{DIGIT}* { + printf("float: %s (%g)\n", yytext, atof(yytext)); + } + +"{"[\^{}}\n]*"}" /* eat up one-line comments */ + +[ \t\n]+ /* eat up whitespace */ + +. printf("Unexpected character: %s\n", yytext); + +%% + +int main(int argc, char **argv) +{ + if (argc > 1) + yyin = fopen(argv[1], "r"); + else + yyin = stdin; + + yylex(); + return 0; +} + diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index 8e894d2ae..47778a030 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -1368,6 +1368,59 @@ void TestBlackbox::dynamicLibs() QCOMPARE(runQbs(), 0); } +void TestBlackbox::dynamicRuleOutputs() +{ + QSKIP("QBS-370"); + const QString testDir = testDataDir + "/dynamicRuleOutputs"; + QDir::setCurrent(testDir); + if (QFile::exists("work")) + rmDirR("work"); + QDir().mkdir("work"); + ccp("before", "work"); + QDir::setCurrent(testDir + "/work"); + QCOMPARE(runQbs(), 0); + + const QString appFile = buildDir + "/genlexer" + QTC_HOST_EXE_SUFFIX; + const QString headerFile1 = buildDir + "/GeneratedFiles/genlexer/numberscanner.h"; + const QString sourceFile1 = buildDir + "/GeneratedFiles/genlexer/numberscanner.c"; + const QString sourceFile2 = buildDir + "/GeneratedFiles/genlexer/lex.yy.c"; + + // Check build #1: source and header file name are specified in numbers.l + QVERIFY(QFile::exists(appFile)); + QVERIFY(QFile::exists(headerFile1)); + QVERIFY(QFile::exists(sourceFile1)); + QVERIFY(!QFile::exists(sourceFile2)); + + QDateTime appFileTimeStamp1 = QFileInfo(appFile).lastModified(); + waitForNewTimestamp(); + QFile::remove("numbers.l"); + QFile::copy("../after/numbers.l", "numbers.l"); + touch("numbers.l"); + QCOMPARE(runQbs(), 0); + + // Check build #2: no file names are specified in numbers.l + // flex will default to lex.yy.c without header file. + QDateTime appFileTimeStamp2 = QFileInfo(appFile).lastModified(); + QVERIFY(appFileTimeStamp1 < appFileTimeStamp2); + QVERIFY(!QFile::exists(headerFile1)); + QVERIFY(!QFile::exists(sourceFile1)); + QVERIFY(QFile::exists(sourceFile2)); + + waitForNewTimestamp(); + QFile::remove("numbers.l"); + QFile::copy("../before/numbers.l", "numbers.l"); + touch("numbers.l"); + QCOMPARE(runQbs(), 0); + + // Check build #3: source and header file name are specified in numbers.l + QDateTime appFileTimeStamp3 = QFileInfo(appFile).lastModified(); + QVERIFY(appFileTimeStamp2 < appFileTimeStamp3); + QVERIFY(QFile::exists(appFile)); + QVERIFY(QFile::exists(headerFile1)); + QVERIFY(QFile::exists(sourceFile1)); + QVERIFY(!QFile::exists(sourceFile2)); +} + void TestBlackbox::explicitlyDependsOn() { QDir::setCurrent(testDataDir + "/explicitlyDependsOn"); diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h index 2d0d6ff33..7d9c2a6d2 100644 --- a/tests/auto/blackbox/tst_blackbox.h +++ b/tests/auto/blackbox/tst_blackbox.h @@ -107,6 +107,7 @@ private slots: void duplicateProductNames(); void duplicateProductNames_data(); void dynamicLibs(); + void dynamicRuleOutputs(); void explicitlyDependsOn(); void fileDependencies(); void jsExtensionsFile(); |