| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the test suite of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 21 | ** included in the packaging of this file. Please review the following | 
| 22 | ** information to ensure the GNU General Public License requirements will | 
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 24 | ** | 
| 25 | ** $QT_END_LICENSE$ | 
| 26 | ** | 
| 27 | ****************************************************************************/ | 
| 28 |  | 
| 29 | #include "tst_qmakelib.h" | 
| 30 |  | 
| 31 | #include <proitems.h> | 
| 32 | #include <qmakevfs.h> | 
| 33 | #include <qmakeparser.h> | 
| 34 |  | 
| 35 | class TokenStream | 
| 36 | { | 
| 37 | public: | 
| 38 |     TokenStream() {} | 
| 39 |     QString toString() const { return ts; } | 
| 40 |  | 
| 41 |     TokenStream &operator<<(ushort n) { ts += QChar(n); return *this; } | 
| 42 |     TokenStream &operator<<(uint n) { ts += QChar(n & 0xffff); ts += QChar(n >> 16); return *this; } | 
| 43 |     TokenStream &operator<<(const QStringRef &s) { ts += s; return *this; } | 
| 44 |     TokenStream &operator<<(const ProString &s) { return *this << ushort(s.length()) << s.toQStringRef(); } | 
| 45 |     TokenStream &operator<<(const ProKey &s) { return *this << s.hash() << s.toString(); } | 
| 46 |  | 
| 47 | private: | 
| 48 |     QString ts; | 
| 49 | }; | 
| 50 |  | 
| 51 | #define TS(s) (TokenStream() s).toString() | 
| 52 | #define H(n) ushort(n) | 
| 53 | #define I(n) uint(n) | 
| 54 | #define S(s) ProString(QString::fromWCharArray(s)) | 
| 55 | #define HS(s) ProKey(QString::fromWCharArray(s)) | 
| 56 |  | 
| 57 | QT_WARNING_PUSH | 
| 58 | QT_WARNING_DISABLE_MSVC(4003)  // "not enough actual parameters for macro TS()" | 
| 59 |  | 
| 60 | void tst_qmakelib::addParseOperators() | 
| 61 | { | 
| 62 |     QTest::newRow(dataTag: "assign none" ) | 
| 63 |             << "VAR ="  | 
| 64 |             << TS( | 
| 65 |     /*     0 */ << H(TokLine) << H(1) | 
| 66 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 67 |     /*     9 */ << H(TokAssign) << H(0) | 
| 68 |     /*    11 */ << H(TokValueTerminator)) | 
| 69 |             << ""  | 
| 70 |             << true; | 
| 71 |  | 
| 72 |     QTest::newRow(dataTag: "append none" ) | 
| 73 |             << "VAR +="  | 
| 74 |             << TS( | 
| 75 |     /*     0 */ << H(TokLine) << H(1) | 
| 76 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 77 |     /*     9 */ << H(TokAppend) << H(0) | 
| 78 |     /*    11 */ << H(TokValueTerminator)) | 
| 79 |             << ""  | 
| 80 |             << true; | 
| 81 |  | 
| 82 |     QTest::newRow(dataTag: "unique append none" ) | 
| 83 |             << "VAR *="  | 
| 84 |             << TS( | 
| 85 |     /*     0 */ << H(TokLine) << H(1) | 
| 86 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 87 |     /*     9 */ << H(TokAppendUnique) << H(0) | 
| 88 |     /*    11 */ << H(TokValueTerminator)) | 
| 89 |             << ""  | 
| 90 |             << true; | 
| 91 |  | 
| 92 |     QTest::newRow(dataTag: "remove none" ) | 
| 93 |             << "VAR -="  | 
| 94 |             << TS( | 
| 95 |     /*     0 */ << H(TokLine) << H(1) | 
| 96 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 97 |     /*     9 */ << H(TokRemove) << H(0) | 
| 98 |     /*    11 */ << H(TokValueTerminator)) | 
| 99 |             << ""  | 
| 100 |             << true; | 
| 101 |  | 
| 102 |     QTest::newRow(dataTag: "replace empty" ) | 
| 103 |             << "VAR ~="  | 
| 104 |             << TS( | 
| 105 |     /*     0 */ << H(TokLine) << H(1) | 
| 106 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 107 |     /*     9 */ << H(TokReplace) << H(0) | 
| 108 |     /*    11 */ << H(TokValueTerminator)) | 
| 109 |             << ""  | 
| 110 |             << true; | 
| 111 |  | 
| 112 |     QTest::newRow(dataTag: "assignment without variable" ) | 
| 113 |             << "="  | 
| 114 |             << TS( | 
| 115 |     /*     0 */ << H(TokLine) << H(1) | 
| 116 |     /*     2 */ << H(TokAssign) << H(0) | 
| 117 |     /*     4 */ << H(TokValueTerminator)) | 
| 118 |             << "in:1: Assignment needs exactly one word on the left hand side."  | 
| 119 |             << false; | 
| 120 |  | 
| 121 |     QTest::newRow(dataTag: "assignment with multiple variables" ) | 
| 122 |             << "VAR VAR ="  | 
| 123 |             << TS( | 
| 124 |     /*     0 */ << H(TokLine) << H(1) | 
| 125 |     /*     2 */ << H(TokAssign) << H(0) | 
| 126 |     /*     4 */ << H(TokValueTerminator)) | 
| 127 |             << "in:1: Assignment needs exactly one word on the left hand side."  | 
| 128 |             << false; | 
| 129 | } | 
| 130 |  | 
| 131 | void tst_qmakelib::addParseValues() | 
| 132 | { | 
| 133 | #define ASSIGN_VAR(h) \ | 
| 134 |         H(TokLine) << H(1) \ | 
| 135 |         << H(TokHashLiteral) << HS(L"VAR") \ | 
| 136 |         << H(TokAssign) << H(h) | 
| 137 |  | 
| 138 |     QTest::newRow(dataTag: "one literal" ) | 
| 139 |             << "VAR = val"  | 
| 140 |             << TS( | 
| 141 |     /*     0 */ << ASSIGN_VAR(0) | 
| 142 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"val" ) | 
| 143 |     /*    16 */ << H(TokValueTerminator)) | 
| 144 |             << ""  | 
| 145 |             << true; | 
| 146 |  | 
| 147 |     QTest::newRow(dataTag: "one literal (squeezed)" ) | 
| 148 |             << "VAR=val"  | 
| 149 |             << TS( | 
| 150 |     /*     0 */ << ASSIGN_VAR(0) | 
| 151 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"val" ) | 
| 152 |     /*    16 */ << H(TokValueTerminator)) | 
| 153 |             << ""  | 
| 154 |             << true; | 
| 155 |  | 
| 156 |     QTest::newRow(dataTag: "many literals" ) | 
| 157 |             << "VAR = foo barbaz bak hello"  | 
| 158 |             << TS( | 
| 159 |     /*     0 */ << ASSIGN_VAR(4) | 
| 160 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 161 |     /*    16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz" ) | 
| 162 |     /*    24 */ << H(TokLiteral | TokNewStr) << S(L"bak" ) | 
| 163 |     /*    29 */ << H(TokLiteral | TokNewStr) << S(L"hello" ) | 
| 164 |     /*    36 */ << H(TokValueTerminator)) | 
| 165 |             << ""  | 
| 166 |             << true; | 
| 167 |  | 
| 168 |     QTest::newRow(dataTag: "many literals (tab-separated" ) | 
| 169 |             << "VAR\t=\tfoo\tbarbaz\tbak\thello"  | 
| 170 |             << TS( | 
| 171 |     /*     0 */ << ASSIGN_VAR(4) | 
| 172 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 173 |     /*    16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz" ) | 
| 174 |     /*    24 */ << H(TokLiteral | TokNewStr) << S(L"bak" ) | 
| 175 |     /*    29 */ << H(TokLiteral | TokNewStr) << S(L"hello" ) | 
| 176 |     /*    36 */ << H(TokValueTerminator)) | 
| 177 |             << ""  | 
| 178 |             << true; | 
| 179 |  | 
| 180 |     QTest::newRow(dataTag: "one quoted literal" ) | 
| 181 |             << "VAR = \"val ue\""  | 
| 182 |             << TS( | 
| 183 |     /*     0 */ << ASSIGN_VAR(0) | 
| 184 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"val ue" ) | 
| 185 |     /*    19 */ << H(TokValueTerminator)) | 
| 186 |             << ""  | 
| 187 |             << true; | 
| 188 |  | 
| 189 |     QTest::newRow(dataTag: "quoted literal with missing quote" ) | 
| 190 |             << "VAR = val \"ue"  | 
| 191 |             << TS( | 
| 192 |     /*     0 */ << H(TokLine) << H(1) | 
| 193 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 194 |     /*     9 */ << H(TokAssign) << H(0) | 
| 195 |     /*    11 */ << H(TokValueTerminator)) | 
| 196 |             << "in:1: Missing closing \" quote"  | 
| 197 |             << false; | 
| 198 |  | 
| 199 |     QTest::newRow(dataTag: "many quoted literals" ) | 
| 200 |             << "VAR = \"foo\" barbaz    'bak hello' \"\""  | 
| 201 |             << TS( | 
| 202 |     /*     0 */ << ASSIGN_VAR(3) | 
| 203 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 204 |     /*    16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz" ) | 
| 205 |     /*    24 */ << H(TokLiteral | TokNewStr) << S(L"bak hello" ) | 
| 206 |     /*    35 */ << H(TokValueTerminator)) | 
| 207 |             << ""  | 
| 208 |             << true; | 
| 209 |  | 
| 210 |     QTest::newRow(dataTag: "many quoted literals (with tabs)" ) | 
| 211 |             << "VAR\t=\t\"foo\"\tbarbaz\t'bak\thello'"  | 
| 212 |             << TS( | 
| 213 |     /*     0 */ << ASSIGN_VAR(3) | 
| 214 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 215 |     /*    16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz" ) | 
| 216 |     /*    24 */ << H(TokLiteral | TokNewStr) << S(L"bak\thello" ) | 
| 217 |     /*    35 */ << H(TokValueTerminator)) | 
| 218 |             << ""  | 
| 219 |             << true; | 
| 220 |  | 
| 221 |     QTest::newRow(dataTag: "quoted and unquoted spaces" ) | 
| 222 |             << "  VAR = \"val ue   \"   "  | 
| 223 |             << TS( | 
| 224 |     /*     0 */ << ASSIGN_VAR(0) | 
| 225 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"val ue   " ) | 
| 226 |     /*    22 */ << H(TokValueTerminator)) | 
| 227 |             << ""  | 
| 228 |             << true; | 
| 229 |  | 
| 230 |     QTest::newRow(dataTag: "funny literals" ) | 
| 231 |             << "VAR = foo:bar|!baz(blam!, ${foo})"  | 
| 232 |             << TS( | 
| 233 |     /*     0 */ << ASSIGN_VAR(2) | 
| 234 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo:bar|!baz(blam!," ) | 
| 235 |     /*    32 */ << H(TokLiteral | TokNewStr) << S(L"${foo})" ) | 
| 236 |     /*    41 */ << H(TokValueTerminator)) | 
| 237 |             << ""  | 
| 238 |             << true; | 
| 239 |  | 
| 240 |     QTest::newRow(dataTag: "literals with escapes" ) | 
| 241 |             << "VAR = \\{hi\\} \\[ho\\] \\)uh\\( \"\\\\oh\\$\"\\' \\$\\${FOO}"  | 
| 242 |             << TS( | 
| 243 |     /*     0 */ << ASSIGN_VAR(5) | 
| 244 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"{hi}" ) | 
| 245 |     /*    17 */ << H(TokLiteral | TokNewStr) << S(L"[ho]" ) | 
| 246 |     /*    23 */ << H(TokLiteral | TokNewStr) << S(L")uh(" ) | 
| 247 |     /*    29 */ << H(TokLiteral | TokNewStr) << S(L"\\oh$'" ) | 
| 248 |     /*    36 */ << H(TokLiteral | TokNewStr) << S(L"$${FOO}" ) | 
| 249 |     /*    45 */ << H(TokValueTerminator)) | 
| 250 |             << ""  | 
| 251 |             << true; | 
| 252 |  | 
| 253 |     QTest::newRow(dataTag: "magic variables" ) | 
| 254 |             << "VAR = $$LITERAL_HASH $$LITERAL_DOLLAR $$LITERAL_WHITESPACE $$_FILE_ $$_LINE_"  | 
| 255 |             << TS( | 
| 256 |     /*     0 */ << ASSIGN_VAR(5) | 
| 257 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"#" ) | 
| 258 |     /*    14 */ << H(TokLiteral | TokNewStr) << S(L"$" ) | 
| 259 |     /*    17 */ << H(TokLiteral | TokNewStr) << S(L"\t" ) | 
| 260 |     /*    20 */ << H(TokLiteral | TokNewStr) << S(L"in" ) | 
| 261 |     /*    24 */ << H(TokLiteral | TokNewStr) << S(L"1" ) | 
| 262 |     /*    27 */ << H(TokValueTerminator)) | 
| 263 |             << ""  | 
| 264 |             << true; | 
| 265 |  | 
| 266 |     QTest::newRow(dataTag: "continuations and comments" ) | 
| 267 |             << "VAR = foo \\\n  bar\n  \n"  | 
| 268 |                "GAR = foo \\ # comment\n  bar \\\n   # comment\n baz \\\n"  | 
| 269 |                     "\"quoted \\ #comment\n    escape\" \\\n    right\\\n      after \\\n    gorilla!\n \n\n"  | 
| 270 |                "MOO = \\\n  kuh # comment\nLOO =\n\n"  | 
| 271 |                "FOO = bar \\\n# comment\n   baz \\\n    \n# comment\n"  | 
| 272 |                "GAZ="  | 
| 273 |             << TS( | 
| 274 |     /*     0 */ << H(TokLine) << H(1) | 
| 275 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 276 |     /*     9 */ << H(TokAssign) << H(2) | 
| 277 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 278 |     /*    16 */ << H(TokLiteral | TokNewStr) << S(L"bar" ) | 
| 279 |     /*    21 */ << H(TokValueTerminator) | 
| 280 |     /*    22 */ << H(TokLine) << H(4) | 
| 281 |     /*    24 */ << H(TokHashLiteral) << HS(L"GAR" ) | 
| 282 |     /*    31 */ << H(TokAssign) << H(7) | 
| 283 |     /*    33 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 284 |     /*    38 */ << H(TokLiteral | TokNewStr) << S(L"bar" ) | 
| 285 |     /*    43 */ << H(TokLiteral | TokNewStr) << S(L"baz" ) | 
| 286 |     /*    48 */ << H(TokLiteral | TokNewStr) << S(L"quoted  escape" ) | 
| 287 |     /*    64 */ << H(TokLiteral | TokNewStr) << S(L"right" ) | 
| 288 |     /*    71 */ << H(TokLiteral | TokNewStr) << S(L"after" ) | 
| 289 |     /*    78 */ << H(TokLiteral | TokNewStr) << S(L"gorilla!" ) | 
| 290 |     /*    88 */ << H(TokValueTerminator) | 
| 291 |     /*    89 */ << H(TokLine) << H(15) | 
| 292 |     /*    91 */ << H(TokHashLiteral) << HS(L"MOO" ) | 
| 293 |     /*    98 */ << H(TokAssign) << H(0) | 
| 294 |     /*   100 */ << H(TokLiteral | TokNewStr) << S(L"kuh" ) | 
| 295 |     /*   105 */ << H(TokValueTerminator) | 
| 296 |     /*   106 */ << H(TokLine) << H(17) | 
| 297 |     /*   108 */ << H(TokHashLiteral) << HS(L"LOO" ) | 
| 298 |     /*   115 */ << H(TokAssign) << H(0) | 
| 299 |     /*   117 */ << H(TokValueTerminator) | 
| 300 |     /*   118 */ << H(TokLine) << H(19) | 
| 301 |     /*   120 */ << H(TokHashLiteral) << HS(L"FOO" ) | 
| 302 |     /*   127 */ << H(TokAssign) << H(2) | 
| 303 |     /*   129 */ << H(TokLiteral | TokNewStr) << S(L"bar" ) | 
| 304 |     /*   134 */ << H(TokLiteral | TokNewStr) << S(L"baz" ) | 
| 305 |     /*   139 */ << H(TokValueTerminator) | 
| 306 |     /*   140 */ << H(TokLine) << H(24) | 
| 307 |     /*   142 */ << H(TokHashLiteral) << HS(L"GAZ" ) | 
| 308 |     /*   149 */ << H(TokAssign) << H(0) | 
| 309 |     /*   151 */ << H(TokValueTerminator)) | 
| 310 |             << ""  | 
| 311 |             << true; | 
| 312 |  | 
| 313 |     QTest::newRow(dataTag: "accidental continuation" ) | 
| 314 |             << "VAR0 = \\\n    this \\\n    is \\\n    ok\n"  | 
| 315 |                "VAR1 = \\\n    this \\\n    is=still \\\n    ok\n"  | 
| 316 |                "VAR2 = \\\n    this \\\n    is \\\n"  | 
| 317 |                "VAR3 = \\\n    not ok\n"  | 
| 318 |             << TS( | 
| 319 |     /*     0 */ << H(TokLine) << H(1) | 
| 320 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR0" ) | 
| 321 |     /*    10 */ << H(TokAssign) << H(3) | 
| 322 |     /*    12 */ << H(TokLiteral | TokNewStr) << S(L"this" ) | 
| 323 |     /*    18 */ << H(TokLiteral | TokNewStr) << S(L"is" ) | 
| 324 |     /*    22 */ << H(TokLiteral | TokNewStr) << S(L"ok" ) | 
| 325 |     /*    26 */ << H(TokValueTerminator) | 
| 326 |     /*    27 */ << H(TokLine) << H(5) | 
| 327 |     /*    29 */ << H(TokHashLiteral) << HS(L"VAR1" ) | 
| 328 |     /*    37 */ << H(TokAssign) << H(3) | 
| 329 |     /*    39 */ << H(TokLiteral | TokNewStr) << S(L"this" ) | 
| 330 |     /*    45 */ << H(TokLiteral | TokNewStr) << S(L"is=still" ) | 
| 331 |     /*    55 */ << H(TokLiteral | TokNewStr) << S(L"ok" ) | 
| 332 |     /*    59 */ << H(TokValueTerminator) | 
| 333 |     /*    60 */ << H(TokLine) << H(9) | 
| 334 |     /*    62 */ << H(TokHashLiteral) << HS(L"VAR2" ) | 
| 335 |     /*    70 */ << H(TokAssign) << H(6) | 
| 336 |     /*    72 */ << H(TokLiteral | TokNewStr) << S(L"this" ) | 
| 337 |     /*    78 */ << H(TokLiteral | TokNewStr) << S(L"is" ) | 
| 338 |     /*    82 */ << H(TokLiteral | TokNewStr) << S(L"VAR3" ) | 
| 339 |     /*    88 */ << H(TokLiteral | TokNewStr) << S(L"=" ) | 
| 340 |     /*    91 */ << H(TokLiteral | TokNewStr) << S(L"not" ) | 
| 341 |     /*    96 */ << H(TokLiteral | TokNewStr) << S(L"ok" ) | 
| 342 |     /*   100 */ << H(TokValueTerminator)) | 
| 343 |             << "WARNING: in:12: Possible accidental line continuation"  | 
| 344 |             << true; | 
| 345 |  | 
| 346 |     QTest::newRow(dataTag: "plain variable expansion" ) | 
| 347 |             << "VAR = $$bar"  | 
| 348 |             << TS( | 
| 349 |     /*     0 */ << ASSIGN_VAR(0) | 
| 350 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"bar" ) | 
| 351 |     /*    18 */ << H(TokValueTerminator)) | 
| 352 |             << ""  | 
| 353 |             << true; | 
| 354 |  | 
| 355 |     QTest::newRow(dataTag: "braced variable expansion" ) | 
| 356 |             << "VAR = $${foo/bar}"  | 
| 357 |             << TS( | 
| 358 |     /*     0 */ << ASSIGN_VAR(0) | 
| 359 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"foo/bar" ) | 
| 360 |     /*    22 */ << H(TokValueTerminator)) | 
| 361 |             << ""  | 
| 362 |             << true; | 
| 363 |  | 
| 364 |     QTest::newRow(dataTag: "bogus variable expansion" ) | 
| 365 |             << "VAR = $$  "  | 
| 366 |             << TS( | 
| 367 |     /*     0 */ << ASSIGN_VAR(0) | 
| 368 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"" ) | 
| 369 |     /*    15 */ << H(TokValueTerminator)) | 
| 370 |             << "WARNING: in:1: Missing name in expansion"  | 
| 371 |             << true; | 
| 372 |  | 
| 373 |     QTest::newRow(dataTag: "bogus braced variable expansion" ) | 
| 374 |             << "VAR = $${}"  | 
| 375 |             << TS( | 
| 376 |     /*     0 */ << ASSIGN_VAR(0) | 
| 377 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"" ) | 
| 378 |     /*    15 */ << H(TokValueTerminator)) | 
| 379 |             << "WARNING: in:1: Missing name in expansion"  | 
| 380 |             << true; | 
| 381 |  | 
| 382 |     QTest::newRow(dataTag: "unterminated braced variable expansion" ) | 
| 383 |             << "VAR = $${FOO"  | 
| 384 |             << TS( | 
| 385 |     /*     0 */ << H(TokLine) << H(1) | 
| 386 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 387 |     /*     9 */ << H(TokAssign) << H(0) | 
| 388 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"FOO" ) | 
| 389 |     /*    18 */ << H(TokValueTerminator)) | 
| 390 |             << "in:1: Missing } terminator [found end-of-line]"  | 
| 391 |             << false; | 
| 392 |  | 
| 393 |     QTest::newRow(dataTag: "invalid identifier in braced variable expansion" ) | 
| 394 |             << "VAR = $${FOO/BAR+BAZ}"  | 
| 395 |             << TS( | 
| 396 |     /*     0 */ << H(TokLine) << H(1) | 
| 397 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 398 |     /*     9 */ << H(TokAssign) << H(0) | 
| 399 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"FOO/BAR" ) | 
| 400 |     /*    22 */ << H(TokLiteral) << S(L"+BAZ" ) | 
| 401 |     /*    28 */ << H(TokValueTerminator)) | 
| 402 |             << "in:1: Missing } terminator [found +]"  | 
| 403 |             << false; | 
| 404 |  | 
| 405 |     QTest::newRow(dataTag: "property expansion" ) | 
| 406 |             << "VAR = $$[bar]"  | 
| 407 |             << TS( | 
| 408 |     /*     0 */ << ASSIGN_VAR(0) | 
| 409 |     /*    11 */ << H(TokProperty | TokNewStr) << HS(L"bar" ) | 
| 410 |     /*    18 */ << H(TokValueTerminator)) | 
| 411 |             << ""  | 
| 412 |             << true; | 
| 413 |  | 
| 414 |     QTest::newRow(dataTag: "environment expansion" ) | 
| 415 |             << "VAR = $$(bar)"  | 
| 416 |             << TS( | 
| 417 |     /*     0 */ << ASSIGN_VAR(0) | 
| 418 |     /*    11 */ << H(TokEnvVar | TokNewStr) << S(L"bar" ) | 
| 419 |     /*    16 */ << H(TokValueTerminator)) | 
| 420 |             << ""  | 
| 421 |             << true; | 
| 422 |  | 
| 423 |     QTest::newRow(dataTag: "plain function call" ) | 
| 424 |             << "VAR = $$bar()"  | 
| 425 |             << TS( | 
| 426 |     /*     0 */ << ASSIGN_VAR(0) | 
| 427 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 428 |     /*    18 */     << H(TokFuncTerminator) | 
| 429 |     /*    19 */ << H(TokValueTerminator)) | 
| 430 |             << ""  | 
| 431 |             << true; | 
| 432 |  | 
| 433 |     QTest::newRow(dataTag: "braced function call" ) | 
| 434 |             << "VAR = $${bar()}"  | 
| 435 |             << TS( | 
| 436 |     /*     0 */ << ASSIGN_VAR(0) | 
| 437 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 438 |     /*    18 */     << H(TokFuncTerminator) | 
| 439 |     /*    19 */ << H(TokValueTerminator)) | 
| 440 |             << ""  | 
| 441 |             << true; | 
| 442 |  | 
| 443 |     QTest::newRow(dataTag: "function call with one argument" ) | 
| 444 |             << "VAR = $$bar(blubb)"  | 
| 445 |             << TS( | 
| 446 |     /*     0 */ << ASSIGN_VAR(0) | 
| 447 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 448 |     /*    18 */     << H(TokLiteral | TokNewStr) << S(L"blubb" ) | 
| 449 |     /*    25 */     << H(TokFuncTerminator) | 
| 450 |     /*    26 */ << H(TokValueTerminator)) | 
| 451 |             << ""  | 
| 452 |             << true; | 
| 453 |  | 
| 454 |     QTest::newRow(dataTag: "function call with multiple arguments" ) | 
| 455 |             << "VAR = $$bar(  blubb blubb, hey  ,$$you)"  | 
| 456 |             << TS( | 
| 457 |     /*     0 */ << ASSIGN_VAR(0) | 
| 458 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 459 |     /*    18 */     << H(TokLiteral | TokNewStr) << S(L"blubb" ) | 
| 460 |     /*    25 */     << H(TokLiteral | TokNewStr) << S(L"blubb" ) | 
| 461 |     /*    32 */     << H(TokArgSeparator) | 
| 462 |     /*    33 */     << H(TokLiteral | TokNewStr) << S(L"hey" ) | 
| 463 |     /*    38 */     << H(TokArgSeparator) | 
| 464 |     /*    39 */     << H(TokVariable | TokNewStr) << HS(L"you" ) | 
| 465 |     /*    46 */     << H(TokFuncTerminator) | 
| 466 |     /*    47 */ << H(TokValueTerminator)) | 
| 467 |             << ""  | 
| 468 |             << true; | 
| 469 |  | 
| 470 |     QTest::newRow(dataTag: "nested function call" ) | 
| 471 |             << "VAR = $$foo(yo, $$bar(blubb))"  | 
| 472 |             << TS( | 
| 473 |     /*     0 */ << ASSIGN_VAR(0) | 
| 474 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"foo" ) | 
| 475 |     /*    18 */     << H(TokLiteral | TokNewStr) << S(L"yo" ) | 
| 476 |     /*    22 */     << H(TokArgSeparator) | 
| 477 |     /*    23 */     << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 478 |     /*    30 */         << H(TokLiteral | TokNewStr) << S(L"blubb" ) | 
| 479 |     /*    37 */         << H(TokFuncTerminator) | 
| 480 |     /*    38 */     << H(TokFuncTerminator) | 
| 481 |     /*    39 */ << H(TokValueTerminator)) | 
| 482 |             << ""  | 
| 483 |             << true; | 
| 484 |  | 
| 485 |     // This is a rather questionable "feature" | 
| 486 |     QTest::newRow(dataTag: "function call with parenthesized argument" ) | 
| 487 |             << "VAR = $$bar(blubb (yo, man) blabb, nope)"  | 
| 488 |             << TS( | 
| 489 |     /*     0 */ << ASSIGN_VAR(0) | 
| 490 |     /*    11 */ << H(TokFuncName | TokNewStr) << HS(L"bar" ) | 
| 491 |     /*    18 */     << H(TokLiteral | TokNewStr) << S(L"blubb" ) | 
| 492 |     /*    25 */     << H(TokLiteral | TokNewStr) << S(L"(yo," ) | 
| 493 |     /*    31 */     << H(TokLiteral | TokNewStr) << S(L"man)" ) | 
| 494 |     /*    37 */     << H(TokLiteral | TokNewStr) << S(L"blabb" ) | 
| 495 |     /*    44 */     << H(TokArgSeparator) | 
| 496 |     /*    45 */     << H(TokLiteral | TokNewStr) << S(L"nope" ) | 
| 497 |     /*    51 */     << H(TokFuncTerminator) | 
| 498 |     /*    52 */ << H(TokValueTerminator)) | 
| 499 |             << ""  | 
| 500 |             << true; | 
| 501 |  | 
| 502 |     QTest::newRow(dataTag: "separate literal and expansion" ) | 
| 503 |             << "VAR = foo $$bar"  | 
| 504 |             << TS( | 
| 505 |     /*     0 */ << ASSIGN_VAR(2) | 
| 506 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 507 |     /*    16 */ << H(TokVariable | TokNewStr) << HS(L"bar" ) | 
| 508 |     /*    23 */ << H(TokValueTerminator)) | 
| 509 |             << ""  | 
| 510 |             << true; | 
| 511 |  | 
| 512 |     QTest::newRow(dataTag: "separate expansion and literal" ) | 
| 513 |             << "VAR = $$bar foo"  | 
| 514 |             << TS( | 
| 515 |     /*     0 */ << ASSIGN_VAR(0) | 
| 516 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"bar" ) | 
| 517 |     /*    18 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 518 |     /*    23 */ << H(TokValueTerminator)) | 
| 519 |             << ""  | 
| 520 |             << true; | 
| 521 |  | 
| 522 |     QTest::newRow(dataTag: "joined literal and expansion" ) | 
| 523 |             << "VAR = foo$$bar"  | 
| 524 |             << TS( | 
| 525 |     /*     0 */ << ASSIGN_VAR(0) | 
| 526 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 527 |     /*    16 */ << H(TokVariable) << HS(L"bar" ) | 
| 528 |     /*    23 */ << H(TokValueTerminator)) | 
| 529 |             << ""  | 
| 530 |             << true; | 
| 531 |  | 
| 532 |     QTest::newRow(dataTag: "joined expansion and literal" ) | 
| 533 |             << "VAR = $${bar}foo"  | 
| 534 |             << TS( | 
| 535 |     /*     0 */ << ASSIGN_VAR(0) | 
| 536 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"bar" ) | 
| 537 |     /*    18 */ << H(TokLiteral) << S(L"foo" ) | 
| 538 |     /*    23 */ << H(TokValueTerminator)) | 
| 539 |             << ""  | 
| 540 |             << true; | 
| 541 |  | 
| 542 |     QTest::newRow(dataTag: "plain variable expansion with funny name and literal" ) | 
| 543 |             << "VAR = $$az_AZ_09.dot/nix"  | 
| 544 |             << TS( | 
| 545 |     /*     0 */ << ASSIGN_VAR(0) | 
| 546 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot" ) | 
| 547 |     /*    27 */ << H(TokLiteral) << S(L"/nix" ) | 
| 548 |     /*    33 */ << H(TokValueTerminator)) | 
| 549 |             << ""  | 
| 550 |             << true; | 
| 551 |  | 
| 552 |     QTest::newRow(dataTag: "braced variable expansion with funny name" ) | 
| 553 |             << "VAR = $${az_AZ_09.dot/nix}"  | 
| 554 |             << TS( | 
| 555 |     /*     0 */ << ASSIGN_VAR(0) | 
| 556 |     /*    11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot/nix" ) | 
| 557 |     /*    31 */ << H(TokValueTerminator)) | 
| 558 |             << ""  | 
| 559 |             << true; | 
| 560 |  | 
| 561 |     QTest::newRow(dataTag: "quoted joined literal and expansion" ) | 
| 562 |             << "VAR = 'foo$$bar'"  | 
| 563 |             << TS( | 
| 564 |     /*     0 */ << ASSIGN_VAR(0) | 
| 565 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 566 |     /*    16 */ << H(TokVariable | TokQuoted) << HS(L"bar" ) | 
| 567 |     /*    23 */ << H(TokValueTerminator)) | 
| 568 |             << ""  | 
| 569 |             << true; | 
| 570 |  | 
| 571 |     QTest::newRow(dataTag: "assignment with expansion in variable name" ) | 
| 572 |             << "VAR$$EXTRA ="  | 
| 573 |             << TS( | 
| 574 |     /*     0 */ << H(TokLine) << H(1) | 
| 575 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 576 |     /*     9 */ << H(TokVariable) << HS(L"EXTRA" ) | 
| 577 |     /*    18 */ << H(TokAssign) << H(0) | 
| 578 |     /*    20 */ << H(TokValueTerminator)) | 
| 579 |             << ""  | 
| 580 |             << true; | 
| 581 | } | 
| 582 |  | 
| 583 | void tst_qmakelib::addParseConditions() | 
| 584 | { | 
| 585 |     QTest::newRow(dataTag: "one test" ) | 
| 586 |             << "foo"  | 
| 587 |             << TS( | 
| 588 |     /*     0 */ << H(TokLine) << H(1) | 
| 589 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 590 |     /*     9 */ << H(TokCondition)) | 
| 591 |             << ""  | 
| 592 |             << true; | 
| 593 |  | 
| 594 |     QTest::newRow(dataTag: "wildcard-test" ) | 
| 595 |             << "foo-*"  | 
| 596 |             << TS( | 
| 597 |     /*     0 */ << H(TokLine) << H(1) | 
| 598 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo-*" ) | 
| 599 |     /*    11 */ << H(TokCondition)) | 
| 600 |             << ""  | 
| 601 |             << true; | 
| 602 |  | 
| 603 |     // This is a rather questionable "feature" | 
| 604 |     QTest::newRow(dataTag: "one quoted test" ) | 
| 605 |             << "\"foo\""  | 
| 606 |             << TS( | 
| 607 |     /*     0 */ << H(TokLine) << H(1) | 
| 608 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 609 |     /*     9 */ << H(TokCondition)) | 
| 610 |             << ""  | 
| 611 |             << true; | 
| 612 |  | 
| 613 |     QTest::newRow(dataTag: "two tests" ) | 
| 614 |             << "foo\nbar"  | 
| 615 |             << TS( | 
| 616 |     /*     0 */ << H(TokLine) << H(1) | 
| 617 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 618 |     /*     9 */ << H(TokCondition) | 
| 619 |     /*    10 */ << H(TokLine) << H(2) | 
| 620 |     /*    12 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 621 |     /*    19 */ << H(TokCondition)) | 
| 622 |             << ""  | 
| 623 |             << true; | 
| 624 |  | 
| 625 |     QTest::newRow(dataTag: "bogus two tests" ) | 
| 626 |             << "foo bar\nbaz"  | 
| 627 |             << TS() | 
| 628 |             << "in:1: Extra characters after test expression."  | 
| 629 |             << false; | 
| 630 |  | 
| 631 |     QTest::newRow(dataTag: "test-AND-test" ) | 
| 632 |             << "foo:bar"  | 
| 633 |             << TS( | 
| 634 |     /*     0 */ << H(TokLine) << H(1) | 
| 635 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 636 |     /*     9 */ << H(TokCondition) | 
| 637 |     /*    10 */ << H(TokAnd) | 
| 638 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 639 |     /*    18 */ << H(TokCondition)) | 
| 640 |             << ""  | 
| 641 |             << true; | 
| 642 |  | 
| 643 |     QTest::newRow(dataTag: "test-OR-test" ) | 
| 644 |             << "  foo  | bar "  | 
| 645 |             << TS( | 
| 646 |     /*     0 */ << H(TokLine) << H(1) | 
| 647 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 648 |     /*     9 */ << H(TokCondition) | 
| 649 |     /*    10 */ << H(TokOr) | 
| 650 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 651 |     /*    18 */ << H(TokCondition)) | 
| 652 |             << ""  | 
| 653 |             << true; | 
| 654 |  | 
| 655 |     QTest::newRow(dataTag: "NOT-test" ) | 
| 656 |             << "!foo"  | 
| 657 |             << TS( | 
| 658 |     /*     0 */ << H(TokLine) << H(1) | 
| 659 |     /*     2 */ << H(TokNot) | 
| 660 |     /*     3 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 661 |     /*    10 */ << H(TokCondition)) | 
| 662 |             << ""  | 
| 663 |             << true; | 
| 664 |  | 
| 665 |     QTest::newRow(dataTag: "NOT-NOT-test" ) | 
| 666 |             << "!!foo"  | 
| 667 |             << TS( | 
| 668 |     /*     0 */ << H(TokLine) << H(1) | 
| 669 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 670 |     /*     9 */ << H(TokCondition)) | 
| 671 |             << ""  | 
| 672 |             << true; | 
| 673 |  | 
| 674 |     // This is a rather questionable "feature" | 
| 675 |     QTest::newRow(dataTag: "quoted-NOT-test" ) | 
| 676 |             << "\"!foo\""  | 
| 677 |             << TS( | 
| 678 |     /*     0 */ << H(TokLine) << H(1) | 
| 679 |     /*     2 */ << H(TokNot) | 
| 680 |     /*     3 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 681 |     /*    10 */ << H(TokCondition)) | 
| 682 |             << ""  | 
| 683 |             << true; | 
| 684 |  | 
| 685 |     // This is a rather questionable "feature" | 
| 686 |     QTest::newRow(dataTag: "NOT-quoted-test" ) | 
| 687 |             << "!\"foo\""  | 
| 688 |             << TS( | 
| 689 |     /*     0 */ << H(TokLine) << H(1) | 
| 690 |     /*     2 */ << H(TokNot) | 
| 691 |     /*     3 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 692 |     /*    10 */ << H(TokCondition)) | 
| 693 |             << ""  | 
| 694 |             << true; | 
| 695 |  | 
| 696 |     QTest::newRow(dataTag: "test-AND-NOT-test" ) | 
| 697 |             << "foo:!bar"  | 
| 698 |             << TS( | 
| 699 |     /*     0 */ << H(TokLine) << H(1) | 
| 700 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 701 |     /*     9 */ << H(TokCondition) | 
| 702 |     /*    10 */ << H(TokAnd) | 
| 703 |     /*    11 */ << H(TokNot) | 
| 704 |     /*    12 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 705 |     /*    19 */ << H(TokCondition)) | 
| 706 |             << ""  | 
| 707 |             << true; | 
| 708 |  | 
| 709 |     QTest::newRow(dataTag: "test-assignment" ) | 
| 710 |             << "foo\nVAR="  | 
| 711 |             << TS( | 
| 712 |     /*     0 */ << H(TokLine) << H(1) | 
| 713 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 714 |     /*     9 */ << H(TokCondition) | 
| 715 |     /*    10 */ << H(TokLine) << H(2) | 
| 716 |     /*    12 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 717 |     /*    19 */ << H(TokAssign) << H(0) | 
| 718 |     /*    21 */ << H(TokValueTerminator)) | 
| 719 |             << ""  | 
| 720 |             << true; | 
| 721 |  | 
| 722 |     QTest::newRow(dataTag: "test-AND-assignment" ) | 
| 723 |             << "foo: VAR ="  | 
| 724 |             << TS( | 
| 725 |     /*     0 */ << H(TokLine) << H(1) | 
| 726 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 727 |     /*     9 */ << H(TokCondition) | 
| 728 |     /*    10 */ << H(TokBranch) | 
| 729 |     /*    11 */ /* then branch */ << I(11) | 
| 730 |     /*    13 */     << H(TokHashLiteral) << HS(L"VAR" ) | 
| 731 |     /*    20 */     << H(TokAssign) << H(0) | 
| 732 |     /*    22 */     << H(TokValueTerminator) | 
| 733 |     /*    23 */     << H(TokTerminator) | 
| 734 |     /*    24 */ /* else branch */ << I(0)) | 
| 735 |             << ""  | 
| 736 |             << true; | 
| 737 |  | 
| 738 |     QTest::newRow(dataTag: "test-else-test" ) | 
| 739 |             << "foo\nelse: bar"  | 
| 740 |             << TS( | 
| 741 |     /*     0 */ << H(TokLine) << H(1) | 
| 742 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 743 |     /*     9 */ << H(TokCondition) | 
| 744 |     /*    10 */ << H(TokBranch) | 
| 745 |     /*    11 */ /* then branch */ << I(0) | 
| 746 |     /*    13 */ /* else branch */ << I(11) | 
| 747 |     /*    15 */     << H(TokLine) << H(2) | 
| 748 |     /*    17 */     << H(TokHashLiteral) << HS(L"bar" ) | 
| 749 |     /*    24 */     << H(TokCondition) | 
| 750 |     /*    25 */     << H(TokTerminator)) | 
| 751 |             << ""  | 
| 752 |             << true; | 
| 753 |  | 
| 754 |     QTest::newRow(dataTag: "function-else-test" ) | 
| 755 |             << "foo()\nelse: bar"  | 
| 756 |             << TS( | 
| 757 |     /*     0 */ << H(TokLine) << H(1) | 
| 758 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 759 |     /*     9 */ << H(TokTestCall) | 
| 760 |     /*    10 */     << H(TokFuncTerminator) | 
| 761 |     /*    11 */ << H(TokBranch) | 
| 762 |     /*    12 */ /* then branch */ << I(0) | 
| 763 |     /*    14 */ /* else branch */ << I(11) | 
| 764 |     /*    16 */     << H(TokLine) << H(2) | 
| 765 |     /*    18 */     << H(TokHashLiteral) << HS(L"bar" ) | 
| 766 |     /*    25 */     << H(TokCondition) | 
| 767 |     /*    26 */     << H(TokTerminator)) | 
| 768 |             << ""  | 
| 769 |             << true; | 
| 770 |  | 
| 771 |     QTest::newRow(dataTag: "test-AND-test-else-test" ) | 
| 772 |             << "foo:bar\nelse: baz"  | 
| 773 |             << TS( | 
| 774 |     /*     0 */ << H(TokLine) << H(1) | 
| 775 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 776 |     /*     9 */ << H(TokCondition) | 
| 777 |     /*    10 */ << H(TokAnd) | 
| 778 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 779 |     /*    18 */ << H(TokCondition) | 
| 780 |     /*    19 */ << H(TokBranch) | 
| 781 |     /*    20 */ /* then branch */ << I(0) | 
| 782 |     /*    22 */ /* else branch */ << I(11) | 
| 783 |     /*    24 */     << H(TokLine) << H(2) | 
| 784 |     /*    26 */     << H(TokHashLiteral) << HS(L"baz" ) | 
| 785 |     /*    33 */     << H(TokCondition) | 
| 786 |     /*    34 */     << H(TokTerminator)) | 
| 787 |             << ""  | 
| 788 |             << true; | 
| 789 |  | 
| 790 |     QTest::newRow(dataTag: "test-AND-test-else-test-else-test-function" ) | 
| 791 |             << "foo:bar\nelse: baz\nelse: bak\nbuzz()"  | 
| 792 |             << TS( | 
| 793 |     /*     0 */ << H(TokLine) << H(1) | 
| 794 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 795 |     /*     9 */ << H(TokCondition) | 
| 796 |     /*    10 */ << H(TokAnd) | 
| 797 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 798 |     /*    18 */ << H(TokCondition) | 
| 799 |     /*    19 */ << H(TokBranch) | 
| 800 |     /*    20 */ /* then branch */ << I(0) | 
| 801 |     /*    22 */ /* else branch */ << I(27) | 
| 802 |     /*    24 */     << H(TokLine) << H(2) | 
| 803 |     /*    26 */     << H(TokHashLiteral) << HS(L"baz" ) | 
| 804 |     /*    33 */     << H(TokCondition) | 
| 805 |     /*    34 */     << H(TokBranch) | 
| 806 |     /*    35 */     /* then branch */ << I(0) | 
| 807 |     /*    37 */     /* else branch */ << I(11) | 
| 808 |     /*    39 */         << H(TokLine) << H(3) | 
| 809 |     /*    41 */         << H(TokHashLiteral) << HS(L"bak" ) | 
| 810 |     /*    48 */         << H(TokCondition) | 
| 811 |     /*    49 */         << H(TokTerminator) | 
| 812 |     /*    50 */     << H(TokTerminator) | 
| 813 |     /*    51 */ << H(TokLine) << H(4) | 
| 814 |     /*    53 */ << H(TokHashLiteral) << HS(L"buzz" ) | 
| 815 |     /*    61 */ << H(TokTestCall) | 
| 816 |     /*    62 */     << H(TokFuncTerminator)) | 
| 817 |             << ""  | 
| 818 |             << true; | 
| 819 |  | 
| 820 |     QTest::newRow(dataTag: "test-assignment-else-assignment" ) | 
| 821 |             << "foo: VAR =\nelse: VAR="  | 
| 822 |             << TS( | 
| 823 |     /*     0 */ << H(TokLine) << H(1) | 
| 824 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 825 |     /*     9 */ << H(TokCondition) | 
| 826 |     /*    10 */ << H(TokBranch) | 
| 827 |     /*    11 */ /* then branch */ << I(11) | 
| 828 |     /*    13 */     << H(TokHashLiteral) << HS(L"VAR" ) | 
| 829 |     /*    20 */     << H(TokAssign) << H(0) | 
| 830 |     /*    22 */     << H(TokValueTerminator) | 
| 831 |     /*    23 */     << H(TokTerminator) | 
| 832 |     /*    24 */ /* else branch */ << I(13) | 
| 833 |     /*    26 */     << H(TokLine) << H(2) | 
| 834 |     /*    28 */     << H(TokHashLiteral) << HS(L"VAR" ) | 
| 835 |     /*    35 */     << H(TokAssign) << H(0) | 
| 836 |     /*    37 */     << H(TokValueTerminator) | 
| 837 |     /*    38 */     << H(TokTerminator)) | 
| 838 |             << ""  | 
| 839 |             << true; | 
| 840 |  | 
| 841 |     QTest::newRow(dataTag: "test-else-test-assignment" ) | 
| 842 |             << "foo\nelse: bar: VAR ="  | 
| 843 |             << TS( | 
| 844 |     /*     0 */ << H(TokLine) << H(1) | 
| 845 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 846 |     /*     9 */ << H(TokCondition) | 
| 847 |     /*    10 */ << H(TokBranch) | 
| 848 |     /*    11 */ /* then branch */ << I(0) | 
| 849 |     /*    13 */ /* else branch */ << I(27) | 
| 850 |     /*    15 */     << H(TokLine) << H(2) | 
| 851 |     /*    17 */     << H(TokHashLiteral) << HS(L"bar" ) | 
| 852 |     /*    24 */     << H(TokCondition) | 
| 853 |     /*    25 */     << H(TokBranch) | 
| 854 |     /*    26 */     /* then branch */ << I(11) | 
| 855 |     /*    28 */         << H(TokHashLiteral) << HS(L"VAR" ) | 
| 856 |     /*    35 */         << H(TokAssign) << H(0) | 
| 857 |     /*    37 */         << H(TokValueTerminator) | 
| 858 |     /*    38 */         << H(TokTerminator) | 
| 859 |     /*    39 */     /* else branch */ << I(0) | 
| 860 |     /*    41 */     << H(TokTerminator)) | 
| 861 |             << ""  | 
| 862 |             << true; | 
| 863 |  | 
| 864 |     QTest::newRow(dataTag: "one function" ) | 
| 865 |             << "foo()"  | 
| 866 |             << TS( | 
| 867 |     /*     0 */ << H(TokLine) << H(1) | 
| 868 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 869 |     /*     9 */ << H(TokTestCall) | 
| 870 |     /*    10 */     << H(TokFuncTerminator)) | 
| 871 |             << ""  | 
| 872 |             << true; | 
| 873 |  | 
| 874 |     QTest::newRow(dataTag: "one function (with spaces)" ) | 
| 875 |             << " foo(  ) "  | 
| 876 |             << TS( | 
| 877 |     /*     0 */ << H(TokLine) << H(1) | 
| 878 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 879 |     /*     9 */ << H(TokTestCall) | 
| 880 |     /*    10 */     << H(TokFuncTerminator)) | 
| 881 |             << ""  | 
| 882 |             << true; | 
| 883 |  | 
| 884 |     QTest::newRow(dataTag: "unterminated function call" ) | 
| 885 |             << "foo(\nfoo"  | 
| 886 |             << TS() | 
| 887 |             << "in:1: Missing closing parenthesis in function call"  | 
| 888 |             << false; | 
| 889 |  | 
| 890 |     QTest::newRow(dataTag: "function with arguments" ) | 
| 891 |             << "foo(blah, hi ho)"  | 
| 892 |             << TS( | 
| 893 |     /*     0 */ << H(TokLine) << H(1) | 
| 894 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 895 |     /*     9 */ << H(TokTestCall) | 
| 896 |     /*    10 */     << H(TokLiteral | TokNewStr) << S(L"blah" ) | 
| 897 |     /*    16 */     << H(TokArgSeparator) | 
| 898 |     /*    17 */     << H(TokLiteral | TokNewStr) << S(L"hi" ) | 
| 899 |     /*    21 */     << H(TokLiteral | TokNewStr) << S(L"ho" ) | 
| 900 |     /*    25 */     << H(TokFuncTerminator)) | 
| 901 |             << ""  | 
| 902 |             << true; | 
| 903 |  | 
| 904 |     QTest::newRow(dataTag: "function with empty arguments" ) | 
| 905 |             << "foo(,)"  | 
| 906 |             << TS( | 
| 907 |     /*     0 */ << H(TokLine) << H(1) | 
| 908 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 909 |     /*     9 */ << H(TokTestCall) | 
| 910 |     /*    10 */     << H(TokArgSeparator) | 
| 911 |     /*    11 */     << H(TokFuncTerminator)) | 
| 912 |             << ""  | 
| 913 |             << true; | 
| 914 |  | 
| 915 |     QTest::newRow(dataTag: "function with funny arguments" ) | 
| 916 |             << "foo(blah\\, \"hi ,  \\ho\" ,uh\\  ,\\oh  ,,   )"  | 
| 917 |             << TS( | 
| 918 |     /*     0 */ << H(TokLine) << H(1) | 
| 919 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 920 |     /*     9 */ << H(TokTestCall) | 
| 921 |     /*    10 */     << H(TokLiteral | TokNewStr) << S(L"blah\\" ) | 
| 922 |     /*    17 */     << H(TokArgSeparator) | 
| 923 |     /*    18 */     << H(TokLiteral | TokNewStr) << S(L"hi ,  \\ho" ) | 
| 924 |     /*    29 */     << H(TokArgSeparator) | 
| 925 |     /*    30 */     << H(TokLiteral | TokNewStr) << S(L"uh\\" ) | 
| 926 |     /*    35 */     << H(TokArgSeparator) | 
| 927 |     /*    36 */     << H(TokLiteral | TokNewStr) << S(L"\\oh" ) | 
| 928 |     /*    41 */     << H(TokArgSeparator) | 
| 929 |     /*    42 */     << H(TokArgSeparator) | 
| 930 |     /*    43 */     << H(TokFuncTerminator)) | 
| 931 |             << "WARNING: in:1: Unescaped backslashes are deprecated\n"  | 
| 932 |                "WARNING: in:1: Unescaped backslashes are deprecated\n"  | 
| 933 |                "WARNING: in:1: Unescaped backslashes are deprecated\n"  | 
| 934 |                "WARNING: in:1: Unescaped backslashes are deprecated"  | 
| 935 |             << true; | 
| 936 |  | 
| 937 |     QTest::newRow(dataTag: "function with nested call" ) | 
| 938 |             << "foo($$blah(hi ho))"  | 
| 939 |             << TS( | 
| 940 |     /*     0 */ << H(TokLine) << H(1) | 
| 941 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 942 |     /*     9 */ << H(TokTestCall) | 
| 943 |     /*    10 */     << H(TokFuncName | TokNewStr) << HS(L"blah" ) | 
| 944 |     /*    18 */         << H(TokLiteral | TokNewStr) << S(L"hi" ) | 
| 945 |     /*    22 */         << H(TokLiteral | TokNewStr) << S(L"ho" ) | 
| 946 |     /*    26 */         << H(TokFuncTerminator) | 
| 947 |     /*    27 */     << H(TokFuncTerminator)) | 
| 948 |             << ""  | 
| 949 |             << true; | 
| 950 |  | 
| 951 |     QTest::newRow(dataTag: "stand-alone parentheses" ) | 
| 952 |             << "()"  | 
| 953 |             << TS( | 
| 954 |     /*     0 */ << H(TokLine) << H(1) | 
| 955 |     /*     2 */ << H(TokTestCall) | 
| 956 |     /*     3 */     << H(TokFuncTerminator)) | 
| 957 |             << "in:1: Opening parenthesis without prior test name."  | 
| 958 |             << false; | 
| 959 |  | 
| 960 |     QTest::newRow(dataTag: "bogus test and function" ) | 
| 961 |             << "foo bar()"  | 
| 962 |             << TS( | 
| 963 |     /*     0 */ << H(TokLine) << H(1) | 
| 964 |     /*     2 */ << H(TokTestCall) | 
| 965 |     /*     3 */     << H(TokFuncTerminator)) | 
| 966 |             << "in:1: Extra characters after test expression."  | 
| 967 |             << false; | 
| 968 |  | 
| 969 |     // This is a rather questionable "feature" | 
| 970 |     QTest::newRow(dataTag: "two functions" ) | 
| 971 |             << "foo() bar()"  | 
| 972 |             << TS( | 
| 973 |     /*     0 */ << H(TokLine) << H(1) | 
| 974 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 975 |     /*     9 */ << H(TokTestCall) | 
| 976 |     /*    10 */     << H(TokFuncTerminator) | 
| 977 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 978 |     /*    18 */ << H(TokTestCall) | 
| 979 |     /*    19 */     << H(TokFuncTerminator)) | 
| 980 |             << ""  | 
| 981 |             << true; | 
| 982 |  | 
| 983 |     QTest::newRow(dataTag: "function-AND-test" ) | 
| 984 |             << "foo():bar"  | 
| 985 |             << TS( | 
| 986 |     /*     0 */ << H(TokLine) << H(1) | 
| 987 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 988 |     /*     9 */ << H(TokTestCall) | 
| 989 |     /*    10 */     << H(TokFuncTerminator) | 
| 990 |     /*    11 */ << H(TokAnd) | 
| 991 |     /*    12 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 992 |     /*    19 */ << H(TokCondition)) | 
| 993 |             << ""  | 
| 994 |             << true; | 
| 995 |  | 
| 996 |     QTest::newRow(dataTag: "test-AND-function" ) | 
| 997 |             << "foo:bar()"  | 
| 998 |             << TS( | 
| 999 |     /*     0 */ << H(TokLine) << H(1) | 
| 1000 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 1001 |     /*     9 */ << H(TokCondition) | 
| 1002 |     /*    10 */ << H(TokAnd) | 
| 1003 |     /*    11 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 1004 |     /*    18 */ << H(TokTestCall) | 
| 1005 |     /*    19 */     << H(TokFuncTerminator)) | 
| 1006 |             << ""  | 
| 1007 |             << true; | 
| 1008 |  | 
| 1009 |     QTest::newRow(dataTag: "NOT-function-AND-test" ) | 
| 1010 |             << "!foo():bar"  | 
| 1011 |             << TS( | 
| 1012 |     /*     0 */ << H(TokLine) << H(1) | 
| 1013 |     /*     2 */ << H(TokNot) | 
| 1014 |     /*     3 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 1015 |     /*    10 */ << H(TokTestCall) | 
| 1016 |     /*    11 */     << H(TokFuncTerminator) | 
| 1017 |     /*    12 */ << H(TokAnd) | 
| 1018 |     /*    13 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 1019 |     /*    20 */ << H(TokCondition)) | 
| 1020 |             << ""  | 
| 1021 |             << true; | 
| 1022 |  | 
| 1023 |     QTest::newRow(dataTag: "test-AND-NOT-function" ) | 
| 1024 |             << "foo:!bar()"  | 
| 1025 |             << TS( | 
| 1026 |     /*     0 */ << H(TokLine) << H(1) | 
| 1027 |     /*     2 */ << H(TokHashLiteral) << HS(L"foo" ) | 
| 1028 |     /*     9 */ << H(TokCondition) | 
| 1029 |     /*    10 */ << H(TokAnd) | 
| 1030 |     /*    11 */ << H(TokNot) | 
| 1031 |     /*    12 */ << H(TokHashLiteral) << HS(L"bar" ) | 
| 1032 |     /*    19 */ << H(TokTestCall) | 
| 1033 |     /*    20 */     << H(TokFuncTerminator)) | 
| 1034 |             << ""  | 
| 1035 |             << true; | 
| 1036 | } | 
| 1037 |  | 
| 1038 | void tst_qmakelib::addParseControlStatements() | 
| 1039 | { | 
| 1040 |     QTest::newRow(dataTag: "for(VAR, LIST) loop" ) | 
| 1041 |             << "for(VAR, LIST)"  | 
| 1042 |             << TS( | 
| 1043 |     /*     0 */ << H(TokLine) << H(1) | 
| 1044 |     /*     2 */ << H(TokForLoop) << HS(L"VAR" ) | 
| 1045 |     /*     9 */ /* iterator */ << I(7) | 
| 1046 |     /*    11 */     << H(TokLiteral | TokNewStr) << S(L"LIST" ) | 
| 1047 |     /*    17 */     << H(TokValueTerminator) | 
| 1048 |     /*    18 */ /* body */ << I(1) | 
| 1049 |     /*    20 */     << H(TokTerminator)) | 
| 1050 |             << ""  | 
| 1051 |             << true; | 
| 1052 |  | 
| 1053 |     QTest::newRow(dataTag: "for(ever) loop" ) | 
| 1054 |             << "for(ever)"  | 
| 1055 |             << TS( | 
| 1056 |     /*     0 */ << H(TokLine) << H(1) | 
| 1057 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1058 |     /*     6 */ /* iterator */ << I(9) | 
| 1059 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1060 |     /*    16 */     << H(TokValueTerminator) | 
| 1061 |     /*    17 */ /* body */ << I(1) | 
| 1062 |     /*    19 */     << H(TokTerminator)) | 
| 1063 |             << ""  | 
| 1064 |             << true; | 
| 1065 |  | 
| 1066 |     // This is a rather questionable "feature" | 
| 1067 |     QTest::newRow(dataTag: "for($$blub) loop" ) | 
| 1068 |             << "for($$blub)"  | 
| 1069 |             << TS( | 
| 1070 |     /*     0 */ << H(TokLine) << H(1) | 
| 1071 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1072 |     /*     6 */ /* iterator */ << I(9) | 
| 1073 |     /*     8 */     << H(TokVariable | TokNewStr) << HS(L"blub" ) | 
| 1074 |     /*    16 */     << H(TokValueTerminator) | 
| 1075 |     /*    17 */ /* body */ << I(1) | 
| 1076 |     /*    19 */     << H(TokTerminator)) | 
| 1077 |             << ""  | 
| 1078 |             << true; | 
| 1079 |  | 
| 1080 |     QTest::newRow(dataTag: "test-for-test-else-test" ) | 
| 1081 |             << "true:for(VAR, LIST): true\nelse: true"  | 
| 1082 |             << TS( | 
| 1083 |     /*     0 */ << H(TokLine) << H(1) | 
| 1084 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1085 |     /*    10 */ << H(TokCondition) | 
| 1086 |     /*    11 */ << H(TokBranch) | 
| 1087 |     /*    12 */ /* then branch */ << I(31) | 
| 1088 |     /*    14 */     << H(TokForLoop) << HS(L"VAR" ) | 
| 1089 |     /*    21 */     /* iterator */ << I(7) | 
| 1090 |     /*    23 */         << H(TokLiteral | TokNewStr) << S(L"LIST" ) | 
| 1091 |     /*    29 */         << H(TokValueTerminator) | 
| 1092 |     /*    30 */     /* body */ << I(12) | 
| 1093 |     /*    32 */         << H(TokLine) << H(1) | 
| 1094 |     /*    34 */         << H(TokHashLiteral) << HS(L"true" ) | 
| 1095 |     /*    42 */         << H(TokCondition) | 
| 1096 |     /*    43 */         << H(TokTerminator) | 
| 1097 |     /*    44 */     << H(TokTerminator) | 
| 1098 |     /*    45 */ /* else branch */ << I(12) | 
| 1099 |     /*    47 */     << H(TokLine) << H(2) | 
| 1100 |     /*    49 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1101 |     /*    57 */     << H(TokCondition) | 
| 1102 |     /*    58 */     << H(TokTerminator)) | 
| 1103 |             << ""  | 
| 1104 |             << true; | 
| 1105 |  | 
| 1106 |     QTest::newRow(dataTag: "next()" ) | 
| 1107 |             << "for(ever): next()"  | 
| 1108 |             << TS( | 
| 1109 |     /*     0 */ << H(TokLine) << H(1) | 
| 1110 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1111 |     /*     6 */ /* iterator */ << I(9) | 
| 1112 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1113 |     /*    16 */     << H(TokValueTerminator) | 
| 1114 |     /*    17 */ /* body */ << I(4) | 
| 1115 |     /*    19 */     << H(TokLine) << H(1) | 
| 1116 |     /*    21 */     << H(TokNext) | 
| 1117 |     /*    22 */     << H(TokTerminator)) | 
| 1118 |             << ""  | 
| 1119 |             << true; | 
| 1120 |  | 
| 1121 |     QTest::newRow(dataTag: "break()" ) | 
| 1122 |             << "for(ever): break()"  | 
| 1123 |             << TS( | 
| 1124 |     /*     0 */ << H(TokLine) << H(1) | 
| 1125 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1126 |     /*     6 */ /* iterator */ << I(9) | 
| 1127 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1128 |     /*    16 */     << H(TokValueTerminator) | 
| 1129 |     /*    17 */ /* body */ << I(4) | 
| 1130 |     /*    19 */     << H(TokLine) << H(1) | 
| 1131 |     /*    21 */     << H(TokBreak) | 
| 1132 |     /*    22 */     << H(TokTerminator)) | 
| 1133 |             << ""  | 
| 1134 |             << true; | 
| 1135 |  | 
| 1136 |     QTest::newRow(dataTag: "top-level return()" ) | 
| 1137 |             << "return()"  | 
| 1138 |             << TS( | 
| 1139 |     /*     0 */ << H(TokLine) << H(1) | 
| 1140 |     /*     2 */ << H(TokReturn)) | 
| 1141 |             << ""  | 
| 1142 |             << true; | 
| 1143 |  | 
| 1144 |     QTest::newRow(dataTag: "else" ) | 
| 1145 |             << "else"  | 
| 1146 |             << TS() | 
| 1147 |             << "in:1: Unexpected 'else'."  | 
| 1148 |             << false; | 
| 1149 |  | 
| 1150 |     QTest::newRow(dataTag: "test-{else}" ) | 
| 1151 |             << "test { else }"  | 
| 1152 |             << TS( | 
| 1153 |     /*     0 */ << H(TokLine) << H(1) | 
| 1154 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1155 |     /*    10 */ << H(TokCondition) | 
| 1156 |     /*    11 */ << H(TokBranch) | 
| 1157 |     /*    12 */ /* then branch */ << I(1) | 
| 1158 |     /*    14 */     << H(TokTerminator) | 
| 1159 |     /*    15 */ /* else branch */ << I(0)) | 
| 1160 |             << "in:1: Unexpected 'else'."  | 
| 1161 |             << false; | 
| 1162 |  | 
| 1163 |     QTest::newRow(dataTag: "defineTest-{else}" ) | 
| 1164 |             << "defineTest(fn) { else }"  | 
| 1165 |             << TS( | 
| 1166 |     /*     0 */ << H(TokLine) << H(1) | 
| 1167 |     /*     2 */ << H(TokTestDef) << HS(L"fn" ) | 
| 1168 |     /*     8 */ /* body */ << I(1) | 
| 1169 |     /*    10 */     << H(TokTerminator)) | 
| 1170 |             << "in:1: Unexpected 'else'."  | 
| 1171 |             << false; | 
| 1172 |  | 
| 1173 |     QTest::newRow(dataTag: "for-else" ) | 
| 1174 |             << "for(ever) { else }"  | 
| 1175 |             << TS( | 
| 1176 |     /*     0 */ << H(TokLine) << H(1) | 
| 1177 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1178 |     /*     6 */ /* iterator */ << I(9) | 
| 1179 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1180 |     /*    16 */     << H(TokValueTerminator) | 
| 1181 |     /*    17 */ /* body */ << I(1) | 
| 1182 |     /*    19 */     << H(TokTerminator)) | 
| 1183 |             << "in:1: Unexpected 'else'."  | 
| 1184 |             << false; | 
| 1185 |  | 
| 1186 |     QTest::newRow(dataTag: "double-test-else" ) | 
| 1187 |             << "foo bar\nelse"  | 
| 1188 |             << TS( | 
| 1189 |     /*     0 */ << H(TokBranch) | 
| 1190 |     /*     1 */ /* then branch */ << I(0) | 
| 1191 |     /*     3 */ /* else branch */ << I(1)  // This seems weird | 
| 1192 |     /*     5 */     << H(TokTerminator)) | 
| 1193 |             << "in:1: Extra characters after test expression."  | 
| 1194 |             << false; | 
| 1195 |  | 
| 1196 |     QTest::newRow(dataTag: "test-function-else" ) | 
| 1197 |             << "foo bar()\nelse"  | 
| 1198 |             << TS( | 
| 1199 |     /*     0 */ << H(TokLine) << H(1) | 
| 1200 |     /*     2 */ << H(TokTestCall)  // This seems pointless | 
| 1201 |     /*     3 */     << H(TokFuncTerminator) | 
| 1202 |     /*     4 */ << H(TokBranch) | 
| 1203 |     /*     5 */ /* then branch */ << I(0) | 
| 1204 |     /*     7 */ /* else branch */ << I(1)  // This seems weird | 
| 1205 |     /*     9 */     << H(TokTerminator)) | 
| 1206 |             << "in:1: Extra characters after test expression."  | 
| 1207 |             << false; | 
| 1208 | } | 
| 1209 |  | 
| 1210 | void tst_qmakelib::addParseBraces() | 
| 1211 | { | 
| 1212 |     QTest::newRow(dataTag: "{}" ) | 
| 1213 |             << "{ }"  | 
| 1214 |             << TS() | 
| 1215 |             << ""  | 
| 1216 |             << true; | 
| 1217 |  | 
| 1218 |     QTest::newRow(dataTag: "{}-newlines" ) | 
| 1219 |             << "\n\n{ }\n\n"  | 
| 1220 |             << TS() | 
| 1221 |             << ""  | 
| 1222 |             << true; | 
| 1223 |  | 
| 1224 |     QTest::newRow(dataTag: "{" ) | 
| 1225 |             << "{"  | 
| 1226 |             << TS() | 
| 1227 |             << "in:2: Missing closing brace(s)."  | 
| 1228 |             << false; | 
| 1229 |  | 
| 1230 |     QTest::newRow(dataTag: "test {" ) | 
| 1231 |             << "test {"  | 
| 1232 |             << TS( | 
| 1233 |     /*     0 */ << H(TokLine) << H(1) | 
| 1234 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1235 |     /*    10 */ << H(TokCondition) | 
| 1236 |     /*    11 */ << H(TokBranch) | 
| 1237 |     /*    12 */ /* then branch */ << I(1) | 
| 1238 |     /*    14 */     << H(TokTerminator) | 
| 1239 |     /*    15 */ /* else branch */ << I(0)) | 
| 1240 |             << "in:2: Missing closing brace(s)."  | 
| 1241 |             << false; | 
| 1242 |  | 
| 1243 |     QTest::newRow(dataTag: "}" ) | 
| 1244 |             << "}"  | 
| 1245 |             << TS() | 
| 1246 |             << "in:1: Excess closing brace."  | 
| 1247 |             << false; | 
| 1248 |  | 
| 1249 |     QTest::newRow(dataTag: "{test}" ) | 
| 1250 |             << "{ true }"  | 
| 1251 |             << TS( | 
| 1252 |     /*     0 */ << H(TokLine) << H(1) | 
| 1253 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1254 |     /*    10 */ << H(TokCondition)) | 
| 1255 |             << ""  | 
| 1256 |             << true; | 
| 1257 |  | 
| 1258 |     QTest::newRow(dataTag: "{test-newlines}" ) | 
| 1259 |             << "{\ntrue\n}"  | 
| 1260 |             << TS( | 
| 1261 |     /*     0 */ << H(TokLine) << H(2) | 
| 1262 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1263 |     /*    10 */ << H(TokCondition)) | 
| 1264 |             << ""  | 
| 1265 |             << true; | 
| 1266 |  | 
| 1267 |     QTest::newRow(dataTag: "{assignment-test}-test" ) | 
| 1268 |             << "{ VAR = { foo } bar } true"  | 
| 1269 |             << TS( | 
| 1270 |     /*     0 */ << H(TokLine) << H(1) | 
| 1271 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 1272 |     /*     9 */ << H(TokAssign) << H(4) | 
| 1273 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"{" ) | 
| 1274 |     /*    14 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 1275 |     /*    19 */ << H(TokLiteral | TokNewStr) << S(L"}" ) | 
| 1276 |     /*    22 */ << H(TokLiteral | TokNewStr) << S(L"bar" ) | 
| 1277 |     /*    27 */ << H(TokValueTerminator) | 
| 1278 |     /*    28 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1279 |     /*    36 */ << H(TokCondition)) | 
| 1280 |             << ""  | 
| 1281 |             << true; | 
| 1282 |  | 
| 1283 |     QTest::newRow(dataTag: "assignment with excess opening brace" ) | 
| 1284 |             << "VAR = { { foo }"  | 
| 1285 |             << TS( | 
| 1286 |     /*     0 */ << H(TokLine) << H(1) | 
| 1287 |     /*     2 */ << H(TokHashLiteral) << HS(L"VAR" ) | 
| 1288 |     /*     9 */ << H(TokAssign) << H(4) | 
| 1289 |     /*    11 */ << H(TokLiteral | TokNewStr) << S(L"{" ) | 
| 1290 |     /*    14 */ << H(TokLiteral | TokNewStr) << S(L"{" ) | 
| 1291 |     /*    17 */ << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 1292 |     /*    22 */ << H(TokLiteral | TokNewStr) << S(L"}" ) | 
| 1293 |     /*    25 */ << H(TokValueTerminator)) | 
| 1294 |             << "WARNING: in:1: Possible braces mismatch"  | 
| 1295 |             << true; | 
| 1296 |  | 
| 1297 |     QTest::newRow(dataTag: "test-{}" ) | 
| 1298 |             << "true {}"  | 
| 1299 |             << TS( | 
| 1300 |     /*     0 */ << H(TokLine) << H(1) | 
| 1301 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1302 |     /*    10 */ << H(TokCondition) | 
| 1303 |     /*    11 */ << H(TokBranch) | 
| 1304 |     /*    12 */ /* then branch */ << I(1) | 
| 1305 |     /*    14 */     << H(TokTerminator) | 
| 1306 |     /*    15 */ /* else branch */ << I(0)) | 
| 1307 |             << ""  | 
| 1308 |             << true; | 
| 1309 |  | 
| 1310 |     QTest::newRow(dataTag: "test-{newlines}" ) | 
| 1311 |             << "true {\n}"  | 
| 1312 |             << TS( | 
| 1313 |     /*     0 */ << H(TokLine) << H(1) | 
| 1314 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1315 |     /*    10 */ << H(TokCondition) | 
| 1316 |     /*    11 */ << H(TokBranch) | 
| 1317 |     /*    12 */ /* then branch */ << I(1) | 
| 1318 |     /*    14 */     << H(TokTerminator) | 
| 1319 |     /*    15 */ /* else branch */ << I(0)) | 
| 1320 |             << ""  | 
| 1321 |             << true; | 
| 1322 |  | 
| 1323 |     QTest::newRow(dataTag: "test-{test}" ) | 
| 1324 |             << "true { true }"  | 
| 1325 |             << TS( | 
| 1326 |     /*     0 */ << H(TokLine) << H(1) | 
| 1327 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1328 |     /*    10 */ << H(TokCondition) | 
| 1329 |     /*    11 */ << H(TokBranch) | 
| 1330 |     /*    12 */ /* then branch */ << I(10) | 
| 1331 |     /*    14 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1332 |     /*    22 */     << H(TokCondition) | 
| 1333 |     /*    23 */     << H(TokTerminator) | 
| 1334 |     /*    24 */ /* else branch */ << I(0)) | 
| 1335 |             << ""  | 
| 1336 |             << true; | 
| 1337 |  | 
| 1338 |     QTest::newRow(dataTag: "test:-{test}" ) | 
| 1339 |             << "true: { true }"  | 
| 1340 |             << TS( | 
| 1341 |     /*     0 */ << H(TokLine) << H(1) | 
| 1342 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1343 |     /*    10 */ << H(TokCondition) | 
| 1344 |     /*    11 */ << H(TokBranch) | 
| 1345 |     /*    12 */ /* then branch */ << I(10) | 
| 1346 |     /*    14 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1347 |     /*    22 */     << H(TokCondition) | 
| 1348 |     /*    23 */     << H(TokTerminator) | 
| 1349 |     /*    24 */ /* else branch */ << I(0)) | 
| 1350 |             << "WARNING: in:1: Excess colon in front of opening brace."  | 
| 1351 |             << true; | 
| 1352 |  | 
| 1353 |     QTest::newRow(dataTag: "test-{test-newlines}" ) | 
| 1354 |             << "true {\ntrue\n}"  | 
| 1355 |             << TS( | 
| 1356 |     /*     0 */ << H(TokLine) << H(1) | 
| 1357 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1358 |     /*    10 */ << H(TokCondition) | 
| 1359 |     /*    11 */ << H(TokBranch) | 
| 1360 |     /*    12 */ /* then branch */ << I(12) | 
| 1361 |     /*    14 */     << H(TokLine) << H(2) | 
| 1362 |     /*    16 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1363 |     /*    24 */     << H(TokCondition) | 
| 1364 |     /*    25 */     << H(TokTerminator) | 
| 1365 |     /*    26 */ /* else branch */ << I(0)) | 
| 1366 |             << ""  | 
| 1367 |             << true; | 
| 1368 |  | 
| 1369 |     QTest::newRow(dataTag: "test:-{test-newlines}" ) | 
| 1370 |             << "true: {\ntrue\n}"  | 
| 1371 |             << TS( | 
| 1372 |     /*     0 */ << H(TokLine) << H(1) | 
| 1373 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1374 |     /*    10 */ << H(TokCondition) | 
| 1375 |     /*    11 */ << H(TokBranch) | 
| 1376 |     /*    12 */ /* then branch */ << I(12) | 
| 1377 |     /*    14 */     << H(TokLine) << H(2) | 
| 1378 |     /*    16 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1379 |     /*    24 */     << H(TokCondition) | 
| 1380 |     /*    25 */     << H(TokTerminator) | 
| 1381 |     /*    26 */ /* else branch */ << I(0)) | 
| 1382 |             << "WARNING: in:1: Excess colon in front of opening brace."  | 
| 1383 |             << true; | 
| 1384 |  | 
| 1385 |     QTest::newRow(dataTag: "test-{assignment}" ) | 
| 1386 |             << "true { VAR = {foo} }"  | 
| 1387 |             << TS( | 
| 1388 |     /*     0 */ << H(TokLine) << H(1) | 
| 1389 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1390 |     /*    10 */ << H(TokCondition) | 
| 1391 |     /*    11 */ << H(TokBranch) | 
| 1392 |     /*    12 */ /* then branch */ << I(18) | 
| 1393 |     /*    14 */     << H(TokHashLiteral) << HS(L"VAR" ) | 
| 1394 |     /*    21 */     << H(TokAssign) << H(0) | 
| 1395 |     /*    23 */     << H(TokLiteral | TokNewStr) << S(L"{foo}" ) | 
| 1396 |     /*    30 */     << H(TokValueTerminator) | 
| 1397 |     /*    31 */     << H(TokTerminator) | 
| 1398 |     /*    32 */ /* else branch */ << I(0)) | 
| 1399 |             << ""  | 
| 1400 |             << true; | 
| 1401 |  | 
| 1402 |     QTest::newRow(dataTag: "test-{test-assignment}" ) | 
| 1403 |             << "true { true: VAR = {foo} }"  | 
| 1404 |             << TS( | 
| 1405 |     /*     0 */ << H(TokLine) << H(1) | 
| 1406 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1407 |     /*    10 */ << H(TokCondition) | 
| 1408 |     /*    11 */ << H(TokBranch) | 
| 1409 |     /*    12 */ /* then branch */ << I(33) | 
| 1410 |     /*    14 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1411 |     /*    22 */     << H(TokCondition) | 
| 1412 |     /*    23 */     << H(TokBranch) | 
| 1413 |     /*    24 */     /* then branch */ << I(18) | 
| 1414 |     /*    26 */         << H(TokHashLiteral) << HS(L"VAR" ) | 
| 1415 |     /*    33 */         << H(TokAssign) << H(0) | 
| 1416 |     /*    35 */         << H(TokLiteral | TokNewStr) << S(L"{foo}" ) | 
| 1417 |     /*    42 */         << H(TokValueTerminator) | 
| 1418 |     /*    43 */         << H(TokTerminator) | 
| 1419 |     /*    44 */     /* else branch */ << I(0) | 
| 1420 |     /*    46 */     << H(TokTerminator) | 
| 1421 |     /*    47 */ /* else branch */ << I(0)) | 
| 1422 |             << ""  | 
| 1423 |             << true; | 
| 1424 |  | 
| 1425 |     QTest::newRow(dataTag: "test-{assignment-newlines}" ) | 
| 1426 |             << "true {\nVAR = {foo}\n}"  | 
| 1427 |             << TS( | 
| 1428 |     /*     0 */ << H(TokLine) << H(1) | 
| 1429 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1430 |     /*    10 */ << H(TokCondition) | 
| 1431 |     /*    11 */ << H(TokBranch) | 
| 1432 |     /*    12 */ /* then branch */ << I(20) | 
| 1433 |     /*    14 */     << H(TokLine) << H(2) | 
| 1434 |     /*    16 */     << H(TokHashLiteral) << HS(L"VAR" ) | 
| 1435 |     /*    23 */     << H(TokAssign) << H(0) | 
| 1436 |     /*    25 */     << H(TokLiteral | TokNewStr) << S(L"{foo}" ) | 
| 1437 |     /*    32 */     << H(TokValueTerminator) | 
| 1438 |     /*    33 */     << H(TokTerminator) | 
| 1439 |     /*    34 */ /* else branch */ << I(0)) | 
| 1440 |             << ""  | 
| 1441 |             << true; | 
| 1442 |  | 
| 1443 |     QTest::newRow(dataTag: "test-{}-else-test-{}" ) | 
| 1444 |             << "true {} else: true {}"  | 
| 1445 |             << TS( | 
| 1446 |     /*     0 */ << H(TokLine) << H(1) | 
| 1447 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1448 |     /*    10 */ << H(TokCondition) | 
| 1449 |     /*    11 */ << H(TokBranch) | 
| 1450 |     /*    12 */ /* then branch */ << I(1) | 
| 1451 |     /*    14 */     << H(TokTerminator) | 
| 1452 |     /*    15 */ /* else branch */ << I(18) | 
| 1453 |     /*    17 */     << H(TokLine) << H(1) | 
| 1454 |     /*    19 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1455 |     /*    27 */     << H(TokCondition) | 
| 1456 |     /*    28 */     << H(TokBranch) | 
| 1457 |     /*    29 */     /* then branch */ << I(1) | 
| 1458 |     /*    31 */         << H(TokTerminator) | 
| 1459 |     /*    32 */     /* else branch */ << I(0) | 
| 1460 |     /*    34 */     << H(TokTerminator)) | 
| 1461 |             << ""  | 
| 1462 |             << true; | 
| 1463 |  | 
| 1464 |     QTest::newRow(dataTag: "test-{}-else-test-{}-newlines" ) | 
| 1465 |             << "true {\n}\nelse: true {\n}"  | 
| 1466 |             << TS( | 
| 1467 |     /*     0 */ << H(TokLine) << H(1) | 
| 1468 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1469 |     /*    10 */ << H(TokCondition) | 
| 1470 |     /*    11 */ << H(TokBranch) | 
| 1471 |     /*    12 */ /* then branch */ << I(1) | 
| 1472 |     /*    14 */     << H(TokTerminator) | 
| 1473 |     /*    15 */ /* else branch */ << I(18) | 
| 1474 |     /*    17 */     << H(TokLine) << H(3) | 
| 1475 |     /*    19 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1476 |     /*    27 */     << H(TokCondition) | 
| 1477 |     /*    28 */     << H(TokBranch) | 
| 1478 |     /*    29 */     /* then branch */ << I(1) | 
| 1479 |     /*    31 */         << H(TokTerminator) | 
| 1480 |     /*    32 */     /* else branch */ << I(0) | 
| 1481 |     /*    34 */     << H(TokTerminator)) | 
| 1482 |             << ""  | 
| 1483 |             << true; | 
| 1484 |  | 
| 1485 |     QTest::newRow(dataTag: "test-{test}-else-test-{}-newlines" ) | 
| 1486 |             << "true {\ntrue\n}\nelse: true {\n}"  | 
| 1487 |             << TS( | 
| 1488 |     /*     0 */ << H(TokLine) << H(1) | 
| 1489 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1490 |     /*    10 */ << H(TokCondition) | 
| 1491 |     /*    11 */ << H(TokBranch) | 
| 1492 |     /*    12 */ /* then branch */ << I(12) | 
| 1493 |     /*    14 */     << H(TokLine) << H(2) | 
| 1494 |     /*    16 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1495 |     /*    24 */     << H(TokCondition) | 
| 1496 |     /*    25 */     << H(TokTerminator) | 
| 1497 |     /*    26 */ /* else branch */ << I(18) | 
| 1498 |     /*    28 */     << H(TokLine) << H(4) | 
| 1499 |     /*    30 */     << H(TokHashLiteral) << HS(L"true" ) | 
| 1500 |     /*    38 */     << H(TokCondition) | 
| 1501 |     /*    39 */     << H(TokBranch) | 
| 1502 |     /*    40 */     /* then branch */ << I(1) | 
| 1503 |     /*    42 */         << H(TokTerminator) | 
| 1504 |     /*    43 */     /* else branch */ << I(0) | 
| 1505 |     /*    45 */     << H(TokTerminator)) | 
| 1506 |             << ""  | 
| 1507 |             << true; | 
| 1508 |  | 
| 1509 |     QTest::newRow(dataTag: "for-{next}" ) | 
| 1510 |             << "for(ever) { next() }"  | 
| 1511 |             << TS( | 
| 1512 |     /*     0 */ << H(TokLine) << H(1) | 
| 1513 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1514 |     /*     6 */ /* iterator */ << I(9) | 
| 1515 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1516 |     /*    16 */     << H(TokValueTerminator) | 
| 1517 |     /*    17 */ /* body */ << I(4) | 
| 1518 |     /*    19 */     << H(TokLine) << H(1) | 
| 1519 |     /*    21 */     << H(TokNext) | 
| 1520 |     /*    22 */     << H(TokTerminator)) | 
| 1521 |             << ""  | 
| 1522 |             << true; | 
| 1523 |  | 
| 1524 |     QTest::newRow(dataTag: "for:-{next}" ) | 
| 1525 |             << "for(ever): { next() }"  | 
| 1526 |             << TS( | 
| 1527 |     /*     0 */ << H(TokLine) << H(1) | 
| 1528 |     /*     2 */ << H(TokForLoop) << HS(L"" ) | 
| 1529 |     /*     6 */ /* iterator */ << I(9) | 
| 1530 |     /*     8 */     << H(TokHashLiteral) << HS(L"ever" ) | 
| 1531 |     /*    16 */     << H(TokValueTerminator) | 
| 1532 |     /*    17 */ /* body */ << I(4) | 
| 1533 |     /*    19 */     << H(TokLine) << H(1) | 
| 1534 |     /*    21 */     << H(TokNext) | 
| 1535 |     /*    22 */     << H(TokTerminator)) | 
| 1536 |             << "WARNING: in:1: Excess colon in front of opening brace."  | 
| 1537 |             << true; | 
| 1538 |  | 
| 1539 |     QTest::newRow(dataTag: "test-for-{test-else-test-newlines}" ) | 
| 1540 |             << "true:for(VAR, LIST) {\ntrue\nelse: true\n}"  | 
| 1541 |             << TS( | 
| 1542 |     /*     0 */ << H(TokLine) << H(1) | 
| 1543 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1544 |     /*    10 */ << H(TokCondition) | 
| 1545 |     /*    11 */ << H(TokBranch) | 
| 1546 |     /*    12 */ /* then branch */ << I(48) | 
| 1547 |     /*    14 */     << H(TokForLoop) << HS(L"VAR" ) | 
| 1548 |     /*    21 */     /* iterator */ << I(7) | 
| 1549 |     /*    23 */         << H(TokLiteral | TokNewStr) << S(L"LIST" ) | 
| 1550 |     /*    29 */         << H(TokValueTerminator) | 
| 1551 |     /*    30 */     /* body */ << I(29) | 
| 1552 |     /*    32 */         << H(TokLine) << H(2) | 
| 1553 |     /*    34 */         << H(TokHashLiteral) << HS(L"true" ) | 
| 1554 |     /*    42 */         << H(TokCondition) | 
| 1555 |     /*    43 */         << H(TokBranch) | 
| 1556 |     /*    44 */         /* then branch */ << I(0) | 
| 1557 |     /*    46 */         /* else branch */ << I(12) | 
| 1558 |     /*    48 */             << H(TokLine) << H(3) | 
| 1559 |     /*    50 */             << H(TokHashLiteral) << HS(L"true" ) | 
| 1560 |     /*    58 */             << H(TokCondition) | 
| 1561 |     /*    59 */             << H(TokTerminator) | 
| 1562 |     /*    60 */         << H(TokTerminator) | 
| 1563 |     /*    61 */     << H(TokTerminator) | 
| 1564 |     /*    62 */ /* else branch */ << I(0)) | 
| 1565 |             << ""  | 
| 1566 |             << true; | 
| 1567 |  | 
| 1568 |     QTest::newRow(dataTag: "test-for-{test-else-test}" ) | 
| 1569 |             << "true:for(VAR, LIST) { true\nelse: true }"  | 
| 1570 |             << TS( | 
| 1571 |     /*     0 */ << H(TokLine) << H(1) | 
| 1572 |     /*     2 */ << H(TokHashLiteral) << HS(L"true" ) | 
| 1573 |     /*    10 */ << H(TokCondition) | 
| 1574 |     /*    11 */ << H(TokBranch) | 
| 1575 |     /*    12 */ /* then branch */ << I(48) | 
| 1576 |     /*    14 */     << H(TokForLoop) << HS(L"VAR" ) | 
| 1577 |     /*    21 */     /* iterator */ << I(7) | 
| 1578 |     /*    23 */         << H(TokLiteral | TokNewStr) << S(L"LIST" ) | 
| 1579 |     /*    29 */         << H(TokValueTerminator) | 
| 1580 |     /*    30 */     /* body */ << I(29) | 
| 1581 |     /*    32 */         << H(TokLine) << H(1) | 
| 1582 |     /*    34 */         << H(TokHashLiteral) << HS(L"true" ) | 
| 1583 |     /*    42 */         << H(TokCondition) | 
| 1584 |     /*    43 */         << H(TokBranch) | 
| 1585 |     /*    44 */         /* then branch */ << I(0) | 
| 1586 |     /*    46 */         /* else branch */ << I(12) | 
| 1587 |     /*    48 */             << H(TokLine) << H(2) | 
| 1588 |     /*    50 */             << H(TokHashLiteral) << HS(L"true" ) | 
| 1589 |     /*    58 */             << H(TokCondition) | 
| 1590 |     /*    59 */             << H(TokTerminator) | 
| 1591 |     /*    60 */         << H(TokTerminator) | 
| 1592 |     /*    61 */     << H(TokTerminator) | 
| 1593 |     /*    62 */ /* else branch */ << I(0)) | 
| 1594 |             << ""  | 
| 1595 |             << true; | 
| 1596 | } | 
| 1597 |  | 
| 1598 | void tst_qmakelib::addParseCustomFunctions() | 
| 1599 | { | 
| 1600 |     QTest::newRow(dataTag: "defineTest-{newlines}" ) | 
| 1601 |             << "defineTest(test) {\n}"  | 
| 1602 |             << TS( | 
| 1603 |     /*     0 */ << H(TokLine) << H(1) | 
| 1604 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1605 |     /*    10 */ /* body */ << I(1) | 
| 1606 |     /*    12 */     << H(TokTerminator)) | 
| 1607 |             << ""  | 
| 1608 |             << true; | 
| 1609 |  | 
| 1610 |     QTest::newRow(dataTag: "defineTest:-test" ) | 
| 1611 |             << "defineTest(test): test"  | 
| 1612 |             << TS( | 
| 1613 |     /*     0 */ << H(TokLine) << H(1) | 
| 1614 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1615 |     /*    10 */ /* body */ << I(12) | 
| 1616 |     /*    12 */     << H(TokLine) << H(1) | 
| 1617 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1618 |     /*    22 */     << H(TokCondition) | 
| 1619 |     /*    23 */     << H(TokTerminator)) | 
| 1620 |             << ""  | 
| 1621 |             << true; | 
| 1622 |  | 
| 1623 |     QTest::newRow(dataTag: "defineTest-{test}" ) | 
| 1624 |             << "defineTest(test) { test }"  | 
| 1625 |             << TS( | 
| 1626 |     /*     0 */ << H(TokLine) << H(1) | 
| 1627 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1628 |     /*    10 */ /* body */ << I(12) | 
| 1629 |     /*    12 */     << H(TokLine) << H(1) | 
| 1630 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1631 |     /*    22 */     << H(TokCondition) | 
| 1632 |     /*    23 */     << H(TokTerminator)) | 
| 1633 |             << ""  | 
| 1634 |             << true; | 
| 1635 |  | 
| 1636 |     QTest::newRow(dataTag: "defineTest-{return}" ) | 
| 1637 |             << "defineTest(test) { return() }"  | 
| 1638 |             << TS( | 
| 1639 |     /*     0 */ << H(TokLine) << H(1) | 
| 1640 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1641 |     /*    10 */ /* body */ << I(4) | 
| 1642 |     /*    12 */     << H(TokLine) << H(1) | 
| 1643 |     /*    14 */     << H(TokReturn) | 
| 1644 |     /*    15 */     << H(TokTerminator)) | 
| 1645 |             << ""  | 
| 1646 |             << true; | 
| 1647 |  | 
| 1648 |     QTest::newRow(dataTag: "defineReplace-{return-stuff}" ) | 
| 1649 |             << "defineReplace(stuff) { return(foo bar) }"  | 
| 1650 |             << TS( | 
| 1651 |     /*     0 */ << H(TokLine) << H(1) | 
| 1652 |     /*     2 */ << H(TokReplaceDef) << HS(L"stuff" ) | 
| 1653 |     /*    11 */ /* body */ << I(14) | 
| 1654 |     /*    13 */     << H(TokLine) << H(1) | 
| 1655 |     /*    15 */     << H(TokLiteral | TokNewStr) << S(L"foo" ) | 
| 1656 |     /*    20 */     << H(TokLiteral | TokNewStr) << S(L"bar" ) | 
| 1657 |     /*    25 */     << H(TokReturn) | 
| 1658 |     /*    26 */     << H(TokTerminator)) | 
| 1659 |             << ""  | 
| 1660 |             << true; | 
| 1661 |  | 
| 1662 |     QTest::newRow(dataTag: "test-AND-defineTest-{}" ) | 
| 1663 |             << "test: defineTest(test) {}"  | 
| 1664 |             << TS( | 
| 1665 |     /*     0 */ << H(TokLine) << H(1) | 
| 1666 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1667 |     /*    10 */ << H(TokCondition) | 
| 1668 |     /*    11 */ << H(TokAnd) | 
| 1669 |     /*    12 */ << H(TokTestDef) << HS(L"test" ) | 
| 1670 |     /*    20 */ /* body */ << I(1) | 
| 1671 |     /*    22 */     << H(TokTerminator)) | 
| 1672 |             << ""  | 
| 1673 |             << true; | 
| 1674 |  | 
| 1675 |     QTest::newRow(dataTag: "test-OR-defineTest-{}" ) | 
| 1676 |             << "test| defineTest(test) {}"  | 
| 1677 |             << TS( | 
| 1678 |     /*     0 */ << H(TokLine) << H(1) | 
| 1679 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1680 |     /*    10 */ << H(TokCondition) | 
| 1681 |     /*    11 */ << H(TokOr) | 
| 1682 |     /*    12 */ << H(TokTestDef) << HS(L"test" ) | 
| 1683 |     /*    20 */ /* body */ << I(1) | 
| 1684 |     /*    22 */     << H(TokTerminator)) | 
| 1685 |             << ""  | 
| 1686 |             << true; | 
| 1687 |  | 
| 1688 |     QTest::newRow(dataTag: "bypassNesting()-{return}" ) | 
| 1689 |             << "defineTest(test) { bypassNesting() { return(true) } }"  | 
| 1690 |             << TS( | 
| 1691 |     /*     0 */ << H(TokLine) << H(1) | 
| 1692 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1693 |     /*    10 */ /* body */ << I(16) | 
| 1694 |     /*    12 */     << H(TokLine) << H(1) | 
| 1695 |     /*    14 */     << H(TokBypassNesting) | 
| 1696 |     /*    15 */     /* block */ << I(10) | 
| 1697 |     /*    17 */         << H(TokLine) << H(1) | 
| 1698 |     /*    19 */         << H(TokLiteral | TokNewStr) << S(L"true" ) | 
| 1699 |     /*    25 */         << H(TokReturn) | 
| 1700 |     /*    26 */         << H(TokTerminator) | 
| 1701 |     /*    27 */     << H(TokTerminator)) | 
| 1702 |             << ""  | 
| 1703 |             << true; | 
| 1704 |  | 
| 1705 |     QTest::newRow(dataTag: "test-AND-bypassNesting()-{}" ) | 
| 1706 |             << "defineTest(test) { test: bypassNesting() {} }"  | 
| 1707 |             << TS( | 
| 1708 |     /*     0 */ << H(TokLine) << H(1) | 
| 1709 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1710 |     /*    10 */ /* body */ << I(17) | 
| 1711 |     /*    12 */     << H(TokLine) << H(1) | 
| 1712 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1713 |     /*    22 */     << H(TokCondition) | 
| 1714 |     /*    23 */     << H(TokAnd) | 
| 1715 |     /*    24 */     << H(TokBypassNesting) | 
| 1716 |     /*    25 */     /* block */ << I(1) | 
| 1717 |     /*    27 */         << H(TokTerminator) | 
| 1718 |     /*    28 */     << H(TokTerminator)) | 
| 1719 |             << ""  | 
| 1720 |             << true; | 
| 1721 |  | 
| 1722 |     QTest::newRow(dataTag: "test-OR-bypassNesting()-{}" ) | 
| 1723 |             << "defineTest(test) { test| bypassNesting() {} }"  | 
| 1724 |             << TS( | 
| 1725 |     /*     0 */ << H(TokLine) << H(1) | 
| 1726 |     /*     2 */ << H(TokTestDef) << HS(L"test" ) | 
| 1727 |     /*    10 */ /* body */ << I(17) | 
| 1728 |     /*    12 */     << H(TokLine) << H(1) | 
| 1729 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1730 |     /*    22 */     << H(TokCondition) | 
| 1731 |     /*    23 */     << H(TokOr) | 
| 1732 |     /*    24 */     << H(TokBypassNesting) | 
| 1733 |     /*    25 */     /* block */ << I(1) | 
| 1734 |     /*    27 */         << H(TokTerminator) | 
| 1735 |     /*    28 */     << H(TokTerminator)) | 
| 1736 |             << ""  | 
| 1737 |             << true; | 
| 1738 | } | 
| 1739 |  | 
| 1740 | void tst_qmakelib::addParseAbuse() | 
| 1741 | { | 
| 1742 |     QTest::newRow(dataTag: "!" ) | 
| 1743 |             << ""  | 
| 1744 |             << TS() | 
| 1745 |             << ""  | 
| 1746 |             << true; | 
| 1747 |  | 
| 1748 |     QTest::newRow(dataTag: "|" ) | 
| 1749 |             << ""  | 
| 1750 |             << TS() | 
| 1751 |             << ""  | 
| 1752 |             << true; | 
| 1753 |  | 
| 1754 |     QTest::newRow(dataTag: ":" ) | 
| 1755 |             << ""  | 
| 1756 |             << TS() | 
| 1757 |             << ""  | 
| 1758 |             << true; | 
| 1759 |  | 
| 1760 |     QTest::newRow(dataTag: "NOT-assignment" ) | 
| 1761 |             << "!VAR ="  | 
| 1762 |             << TS() | 
| 1763 |             << "in:1: Unexpected NOT operator in front of assignment."  | 
| 1764 |             << false; | 
| 1765 |  | 
| 1766 |     QTest::newRow(dataTag: "NOT-{}" ) | 
| 1767 |             << "!{}"  | 
| 1768 |             << TS() | 
| 1769 |             << "in:1: Unexpected NOT operator in front of opening brace."  | 
| 1770 |             << false; | 
| 1771 |  | 
| 1772 |     QTest::newRow(dataTag: "NOT-else" ) | 
| 1773 |             << "test\n!else {}"  | 
| 1774 |             << TS() | 
| 1775 |             << "in:2: Unexpected NOT operator in front of else."  | 
| 1776 |             << false; | 
| 1777 |  | 
| 1778 |     QTest::newRow(dataTag: "NOT-for-{}" ) | 
| 1779 |             << "!for(ever) {}"  | 
| 1780 |             << TS() | 
| 1781 |             << "in:1: Unexpected NOT operator in front of for()."  | 
| 1782 |             << false; | 
| 1783 |  | 
| 1784 |     QTest::newRow(dataTag: "NOT-defineTest-{}" ) | 
| 1785 |             << "!defineTest(test) {}"  | 
| 1786 |             << TS() | 
| 1787 |             << "in:1: Unexpected NOT operator in front of function definition."  | 
| 1788 |             << false; | 
| 1789 |  | 
| 1790 |     QTest::newRow(dataTag: "outer-bypassNesting()-{}" ) | 
| 1791 |             << "bypassNesting() {}"  | 
| 1792 |             << TS() | 
| 1793 |             << "in:1: Unexpected bypassNesting()."  | 
| 1794 |             << false; | 
| 1795 |  | 
| 1796 |     QTest::newRow(dataTag: "bypassNesting(arg)-{}" ) | 
| 1797 |             << "defineTest(test) { bypassNesting(arg) {} }"  | 
| 1798 |             << TS() | 
| 1799 |             << "in:1: bypassNesting() requires zero arguments."  | 
| 1800 |             << false; | 
| 1801 |  | 
| 1802 |     QTest::newRow(dataTag: "NOT-bypassNesting()-{}" ) | 
| 1803 |             << "defineTest(test) { !bypassNesting() {} }"  | 
| 1804 |             << TS() | 
| 1805 |             << "in:1: Unexpected NOT operator in front of bypassNesting()."  | 
| 1806 |             << false; | 
| 1807 |  | 
| 1808 |     QTest::newRow(dataTag: "AND-test" ) | 
| 1809 |             << ":test"  | 
| 1810 |             << TS( | 
| 1811 |     /*     0 */ << H(TokLine) << H(1) | 
| 1812 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1813 |     /*    10 */ << H(TokCondition)) | 
| 1814 |             << "in:1: AND operator without prior condition."  | 
| 1815 |             << false; | 
| 1816 |  | 
| 1817 |     QTest::newRow(dataTag: "test-AND-else" ) | 
| 1818 |             << "test:else"  | 
| 1819 |             << TS( | 
| 1820 |     /*     0 */ << H(TokLine) << H(1) | 
| 1821 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1822 |     /*    10 */ << H(TokCondition)) | 
| 1823 |             << "in:1: Unexpected AND operator in front of else."  | 
| 1824 |             << false; | 
| 1825 |  | 
| 1826 |     QTest::newRow(dataTag: "test-AND-AND-test" ) | 
| 1827 |             << "test::test"  | 
| 1828 |             << TS( | 
| 1829 |     /*     0 */ << H(TokLine) << H(1) | 
| 1830 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1831 |     /*    10 */ << H(TokCondition) | 
| 1832 |     /*    11 */ << H(TokAnd) | 
| 1833 |     /*    12 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1834 |     /*    20 */ << H(TokCondition)) | 
| 1835 |             << "WARNING: in:1: Stray AND operator in front of AND operator."  | 
| 1836 |             << true; | 
| 1837 |  | 
| 1838 |     QTest::newRow(dataTag: "test-AND-OR-test" ) | 
| 1839 |             << "test:|test"  | 
| 1840 |             << TS( | 
| 1841 |     /*     0 */ << H(TokLine) << H(1) | 
| 1842 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1843 |     /*    10 */ << H(TokCondition) | 
| 1844 |     /*    11 */ << H(TokOr) | 
| 1845 |     /*    12 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1846 |     /*    20 */ << H(TokCondition)) | 
| 1847 |             << "WARNING: in:1: Stray AND operator in front of OR operator."  | 
| 1848 |             << true; | 
| 1849 |  | 
| 1850 |     QTest::newRow(dataTag: "test-{AND-test}" ) | 
| 1851 |             << "test { :test }"  | 
| 1852 |             << TS( | 
| 1853 |     /*     0 */ << H(TokLine) << H(1) | 
| 1854 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1855 |     /*    10 */ << H(TokCondition) | 
| 1856 |     /*    11 */ << H(TokBranch) | 
| 1857 |     /*    12 */ /* then branch */ << I(10) | 
| 1858 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1859 |     /*    22 */     << H(TokCondition) | 
| 1860 |     /*    23 */     << H(TokTerminator) | 
| 1861 |     /*    24 */ /* else branch */ << I(0)) | 
| 1862 |             << "in:1: AND operator without prior condition."  | 
| 1863 |             << false; | 
| 1864 |  | 
| 1865 |     QTest::newRow(dataTag: "test-OR-assignment" ) | 
| 1866 |             << "foo| VAR ="  | 
| 1867 |             << TS() | 
| 1868 |             << "in:1: Unexpected OR operator in front of assignment."  | 
| 1869 |             << false; | 
| 1870 |  | 
| 1871 |     QTest::newRow(dataTag: "test-OR-{}" ) | 
| 1872 |             << "foo|{}"  | 
| 1873 |             << TS() | 
| 1874 |             << "in:1: Unexpected OR operator in front of opening brace."  | 
| 1875 |             << false; | 
| 1876 |  | 
| 1877 |     QTest::newRow(dataTag: "test-OR-for" ) | 
| 1878 |             << "foo|for(ever) {}"  | 
| 1879 |             << TS() | 
| 1880 |             << "in:1: Unexpected OR operator in front of for()."  | 
| 1881 |             << false; | 
| 1882 |  | 
| 1883 |     QTest::newRow(dataTag: "OR-test" ) | 
| 1884 |             << "|test"  | 
| 1885 |             << TS( | 
| 1886 |     /*     0 */ << H(TokLine) << H(1) | 
| 1887 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1888 |     /*    10 */ << H(TokCondition)) | 
| 1889 |             << "in:1: OR operator without prior condition."  | 
| 1890 |             << false; | 
| 1891 |  | 
| 1892 |     QTest::newRow(dataTag: "test-OR-else" ) | 
| 1893 |             << "test|else"  | 
| 1894 |             << TS( | 
| 1895 |     /*     0 */ << H(TokLine) << H(1) | 
| 1896 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1897 |     /*    10 */ << H(TokCondition)) | 
| 1898 |             << "in:1: Unexpected OR operator in front of else."  | 
| 1899 |             << false; | 
| 1900 |  | 
| 1901 |     QTest::newRow(dataTag: "test-OR-OR-test" ) | 
| 1902 |             << "test||test"  | 
| 1903 |             << TS( | 
| 1904 |     /*     0 */ << H(TokLine) << H(1) | 
| 1905 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1906 |     /*    10 */ << H(TokCondition) | 
| 1907 |     /*    11 */ << H(TokOr) | 
| 1908 |     /*    12 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1909 |     /*    20 */ << H(TokCondition)) | 
| 1910 |             << "WARNING: in:1: Stray OR operator in front of OR operator."  | 
| 1911 |             << true; | 
| 1912 |  | 
| 1913 |     QTest::newRow(dataTag: "test-OR-AND-test" ) | 
| 1914 |             << "test|:test"  | 
| 1915 |             << TS( | 
| 1916 |     /*     0 */ << H(TokLine) << H(1) | 
| 1917 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1918 |     /*    10 */ << H(TokCondition) | 
| 1919 |     /*    11 */ << H(TokAnd) | 
| 1920 |     /*    12 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1921 |     /*    20 */ << H(TokCondition)) | 
| 1922 |             << "WARNING: in:1: Stray OR operator in front of AND operator."  | 
| 1923 |             << true; | 
| 1924 |  | 
| 1925 |     QTest::newRow(dataTag: "test-{OR-test}" ) | 
| 1926 |             << "test { |test }"  | 
| 1927 |             << TS( | 
| 1928 |     /*     0 */ << H(TokLine) << H(1) | 
| 1929 |     /*     2 */ << H(TokHashLiteral) << HS(L"test" ) | 
| 1930 |     /*    10 */ << H(TokCondition) | 
| 1931 |     /*    11 */ << H(TokBranch) | 
| 1932 |     /*    12 */ /* then branch */ << I(10) | 
| 1933 |     /*    14 */     << H(TokHashLiteral) << HS(L"test" ) | 
| 1934 |     /*    22 */     << H(TokCondition) | 
| 1935 |     /*    23 */     << H(TokTerminator) | 
| 1936 |     /*    24 */ /* else branch */ << I(0)) | 
| 1937 |             << "in:1: OR operator without prior condition."  | 
| 1938 |             << false; | 
| 1939 |  | 
| 1940 |     // Token buffer overflow. Verify with Valgrind or asan. | 
| 1941 |     QTest::newRow(dataTag: "QTCREATORBUG-16508" ) | 
| 1942 |             << "a{b{c{d{"  | 
| 1943 |             << TS() | 
| 1944 |             << "in:2: Missing closing brace(s)."  | 
| 1945 |             << false; | 
| 1946 | } | 
| 1947 |  | 
| 1948 | void tst_qmakelib::proParser_data() | 
| 1949 | { | 
| 1950 |     QTest::addColumn<QString>(name: "in" ); | 
| 1951 |     QTest::addColumn<QString>(name: "out" ); | 
| 1952 |     QTest::addColumn<QString>(name: "msgs" ); | 
| 1953 |     QTest::addColumn<bool>(name: "ok" ); | 
| 1954 |  | 
| 1955 |     QTest::newRow(dataTag: "empty" ) | 
| 1956 |             << ""  | 
| 1957 |             << TS() | 
| 1958 |             << ""  | 
| 1959 |             << true; | 
| 1960 |  | 
| 1961 |     QTest::newRow(dataTag: "empty (whitespace)" ) | 
| 1962 |             << "  \t   \t"  | 
| 1963 |             << TS() | 
| 1964 |             << ""  | 
| 1965 |             << true; | 
| 1966 |  | 
| 1967 |     addParseOperators();  // Variable operators | 
| 1968 |  | 
| 1969 |     addParseValues(); | 
| 1970 |  | 
| 1971 |     addParseConditions();  // "Tests" | 
| 1972 |  | 
| 1973 |     addParseControlStatements(); | 
| 1974 |  | 
| 1975 |     addParseBraces(); | 
| 1976 |  | 
| 1977 |     addParseCustomFunctions(); | 
| 1978 |  | 
| 1979 |     addParseAbuse();  // Mostly operator abuse | 
| 1980 |  | 
| 1981 |     // option() (these produce no tokens) | 
| 1982 |  | 
| 1983 |     QTest::newRow(dataTag: "option(host_build)" ) | 
| 1984 |             << "option(host_build)"  | 
| 1985 |             << TS() | 
| 1986 |             << ""  | 
| 1987 |             << true; | 
| 1988 |  | 
| 1989 |     QTest::newRow(dataTag: "option()" ) | 
| 1990 |             << "option()"  | 
| 1991 |             << TS() | 
| 1992 |             << "in:1: option() requires one literal argument."  | 
| 1993 |             << false; | 
| 1994 |  | 
| 1995 |     QTest::newRow(dataTag: "option(host_build magic)" ) | 
| 1996 |             << "option(host_build magic)"  | 
| 1997 |             << TS() | 
| 1998 |             << "in:1: option() requires one literal argument."  | 
| 1999 |             << false; | 
| 2000 |  | 
| 2001 |     QTest::newRow(dataTag: "option(host_build, magic)" ) | 
| 2002 |             << "option(host_build, magic)"  | 
| 2003 |             << TS() | 
| 2004 |             << "in:1: option() requires one literal argument."  | 
| 2005 |             << false; | 
| 2006 |  | 
| 2007 |     QTest::newRow(dataTag: "option($$OPTION)" ) | 
| 2008 |             << "option($$OPTION)"  | 
| 2009 |             << TS() | 
| 2010 |             << "in:1: option() requires one literal argument."  | 
| 2011 |             << false; | 
| 2012 |  | 
| 2013 |     QTest::newRow(dataTag: "{option(host_build)}" ) | 
| 2014 |             << "{option(host_build)}"  | 
| 2015 |             << TS() | 
| 2016 |             << "in:1: option() must appear outside any control structures."  | 
| 2017 |             << false; | 
| 2018 | } | 
| 2019 |  | 
| 2020 | QT_WARNING_POP | 
| 2021 |  | 
| 2022 | void tst_qmakelib::proParser() | 
| 2023 | { | 
| 2024 |     QFETCH(QString, in); | 
| 2025 |     QFETCH(QString, out); | 
| 2026 |     QFETCH(QString, msgs); | 
| 2027 |     QFETCH(bool, ok); | 
| 2028 |  | 
| 2029 |     bool verified = true; | 
| 2030 |     QMakeTestHandler handler; | 
| 2031 |     handler.setExpectedMessages(msgs.split(sep: '\n', behavior: Qt::SkipEmptyParts)); | 
| 2032 |     QMakeVfs vfs; | 
| 2033 |     QMakeParser parser(0, &vfs, &handler); | 
| 2034 |     ProFile *pro = parser.parsedProBlock(contents: QStringRef(&in), id: 0, name: "in" , line: 1, grammar: QMakeParser::FullGrammar); | 
| 2035 |     if (handler.printedMessages()) { | 
| 2036 |         qWarning(msg: "Got unexpected message(s)" ); | 
| 2037 |         verified = false; | 
| 2038 |     } | 
| 2039 |     QStringList missingMsgs = handler.expectedMessages(); | 
| 2040 |     if (!missingMsgs.isEmpty()) { | 
| 2041 |         foreach (const QString &msg, missingMsgs) | 
| 2042 |             qWarning(msg: "Missing message: %s" , qPrintable(msg)); | 
| 2043 |         verified = false; | 
| 2044 |     } | 
| 2045 |     if (pro->isOk() != ok) { | 
| 2046 |         static const char * const lbl[] = { "failure" , "success"  }; | 
| 2047 |         qWarning(msg: "Expected %s, got %s" , lbl[int(ok)], lbl[1 - int(ok)]); | 
| 2048 |         verified = false; | 
| 2049 |     } | 
| 2050 |     if (pro->items() != out && (ok || !out.isEmpty())) { | 
| 2051 |         qWarning(msg: "Bytecode mismatch.\nActual:%s\nExpected:%s" , | 
| 2052 |                  qPrintable(QMakeParser::formatProBlock(pro->items())), | 
| 2053 |                  qPrintable(QMakeParser::formatProBlock(out))); | 
| 2054 |         verified = false; | 
| 2055 |     } | 
| 2056 |     pro->deref(); | 
| 2057 |     QVERIFY(verified); | 
| 2058 | } | 
| 2059 |  |