/tests/auto/qregexp/tst_qregexp.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 1459 lines · 1142 code · 179 blank · 138 comment · 76 complexity · f8b34d4b89e0865242aef7c3e1b3a223 MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
  4. ** All rights reserved.
  5. ** Contact: Nokia Corporation (qt-info@nokia.com)
  6. **
  7. ** This file is part of the test suite of the Qt Toolkit.
  8. **
  9. ** $QT_BEGIN_LICENSE:LGPL$
  10. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include <QtTest/QtTest>
  42. #include <qregexp.h>
  43. const int N = 1;
  44. //TESTED_CLASS=
  45. //TESTED_FILES=
  46. class tst_QRegExp : public QObject
  47. {
  48. Q_OBJECT
  49. public:
  50. tst_QRegExp();
  51. virtual ~tst_QRegExp();
  52. public slots:
  53. void init();
  54. void cleanup();
  55. private slots:
  56. void getSetCheck();
  57. void indexIn_data();
  58. void indexIn_addMoreRows(const QByteArray &stri);
  59. void indexIn();
  60. void lastIndexIn_data();
  61. void lastIndexIn();
  62. void matchedLength();
  63. void wildcard_data();
  64. void wildcard();
  65. void testEscapingWildcard_data();
  66. void testEscapingWildcard();
  67. void testInvalidWildcard_data();
  68. void testInvalidWildcard();
  69. void caretAnchoredOptimization();
  70. void isEmpty();
  71. void prepareEngineOptimization();
  72. void swap();
  73. void operator_eq();
  74. /*
  75. void isValid();
  76. void pattern();
  77. void setPattern();
  78. void caseSensitive();
  79. void setCaseSensitive();
  80. void minimal();
  81. void setMinimal();
  82. */
  83. void exactMatch();
  84. void capturedTexts();
  85. /*
  86. void cap();
  87. void pos();
  88. void errorString();
  89. void escape();
  90. */
  91. void staticRegExp();
  92. void rainersSlowRegExpCopyBug();
  93. void nonExistingBackReferenceBug();
  94. void reentrancy();
  95. void threadsafeEngineCache();
  96. void QTBUG_7049_data();
  97. void QTBUG_7049();
  98. void interval();
  99. };
  100. // Testing get/set functions
  101. void tst_QRegExp::getSetCheck()
  102. {
  103. QRegExp obj1;
  104. // PatternSyntax QRegExp::patternSyntax()
  105. // void QRegExp::setPatternSyntax(PatternSyntax)
  106. obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::RegExp));
  107. QCOMPARE(QRegExp::PatternSyntax(QRegExp::RegExp), obj1.patternSyntax());
  108. obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::Wildcard));
  109. QCOMPARE(QRegExp::PatternSyntax(QRegExp::Wildcard), obj1.patternSyntax());
  110. obj1.setPatternSyntax(QRegExp::PatternSyntax(QRegExp::FixedString));
  111. QCOMPARE(QRegExp::PatternSyntax(QRegExp::FixedString), obj1.patternSyntax());
  112. }
  113. extern const char email[];
  114. tst_QRegExp::tst_QRegExp()
  115. {
  116. }
  117. tst_QRegExp::~tst_QRegExp()
  118. {
  119. }
  120. void tst_QRegExp::lastIndexIn_data()
  121. {
  122. indexIn_data();
  123. }
  124. void tst_QRegExp::indexIn_data()
  125. {
  126. QTest::addColumn<QString>("regexpStr");
  127. QTest::addColumn<QString>("target");
  128. QTest::addColumn<int>("pos");
  129. QTest::addColumn<int>("len");
  130. QTest::addColumn<QStringList>("caps");
  131. for (int i = 0; i < N; ++i) {
  132. QByteArray stri;
  133. if (i > 0)
  134. stri.setNum(i);
  135. // anchors
  136. QTest::newRow( stri + "anc00" ) << QString("a(?=)z") << QString("az") << 0 << 2 << QStringList();
  137. QTest::newRow( stri + "anc01" ) << QString("a(?!)z") << QString("az") << -1 << -1 << QStringList();
  138. QTest::newRow( stri + "anc02" ) << QString("a(?:(?=)|(?=))z") << QString("az") << 0 << 2
  139. << QStringList();
  140. QTest::newRow( stri + "anc03" ) << QString("a(?:(?=)|(?!))z") << QString("az") << 0 << 2
  141. << QStringList();
  142. QTest::newRow( stri + "anc04" ) << QString("a(?:(?!)|(?=))z") << QString("az") << 0 << 2
  143. << QStringList();
  144. QTest::newRow( stri + "anc05" ) << QString("a(?:(?!)|(?!))z") << QString("az") << -1 << -1
  145. << QStringList();
  146. QTest::newRow( stri + "anc06" ) << QString("a(?:(?=)|b)z") << QString("az") << 0 << 2
  147. << QStringList();
  148. QTest::newRow( stri + "anc07" ) << QString("a(?:(?=)|b)z") << QString("abz") << 0 << 3
  149. << QStringList();
  150. QTest::newRow( stri + "anc08" ) << QString("a(?:(?!)|b)z") << QString("az") << -1 << -1
  151. << QStringList();
  152. QTest::newRow( stri + "anc09" ) << QString("a(?:(?!)|b)z") << QString("abz") << 0 << 3
  153. << QStringList();
  154. #if 0
  155. QTest::newRow( stri + "anc10" ) << QString("a?(?=^b$)") << QString("ab") << 0 << 1
  156. << QStringList();
  157. QTest::newRow( stri + "anc11" ) << QString("a?(?=^b$)") << QString("b") << 0 << 0
  158. << QStringList();
  159. #endif
  160. // back-references
  161. QTest::newRow( stri + "bref00" ) << QString("(a*)(\\1)") << QString("aaaaa") << 0 << 4
  162. << QStringList( QStringList() << "aa" << "aa" );
  163. QTest::newRow( stri + "bref01" ) << QString("<(\\w*)>.+</\\1>") << QString("<b>blabla</b>bla</>")
  164. << 0 << 13 << QStringList( QStringList() << "b" );
  165. QTest::newRow( stri + "bref02" ) << QString("<(\\w*)>.+</\\1>") << QString("<>blabla</b>bla</>")
  166. << 0 << 18 << QStringList( QStringList() << "" );
  167. QTest::newRow( stri + "bref03" ) << QString("((a*\\2)\\2)") << QString("aaaa") << 0 << 4
  168. << QStringList( QStringList() << QString("aaaa") << "aa" );
  169. QTest::newRow( stri + "bref04" ) << QString("^(aa+)\\1+$") << QString("aaaaaa") << 0 << 6
  170. << QStringList( QStringList() << QString("aa") );
  171. QTest::newRow( stri + "bref05" ) << QString("^(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)"
  172. "\\14\\13\\12\\11\\10\\9\\8\\7\\6\\5\\4\\3\\2\\1")
  173. << QString("12345678910111213141413121110987654321") << 0 << 38
  174. << QStringList( QStringList() << "1" << "2" << "3" << "4" << "5" << "6"
  175. << "7" << "8" << "9" << "10" << "11"
  176. << "12" << "13" << "14");
  177. // captures
  178. QTest::newRow( stri + "cap00" ) << QString("(a*)") << QString("") << 0 << 0
  179. << QStringList( QStringList() << QString("") );
  180. QTest::newRow( stri + "cap01" ) << QString("(a*)") << QString("aaa") << 0 << 3
  181. << QStringList( QStringList() << "aaa" );
  182. QTest::newRow( stri + "cap02" ) << QString("(a*)") << QString("baaa") << 0 << 0
  183. << QStringList( QStringList() << QString("") );
  184. QTest::newRow( stri + "cap03" ) << QString("(a*)(a*)") << QString("aaa") << 0 << 3
  185. << QStringList( QStringList() << QString("aaa") << QString("") );
  186. QTest::newRow( stri + "cap04" ) << QString("(a*)(b*)") << QString("aaabbb") << 0 << 6
  187. << QStringList( QStringList() << QString("aaa") << QString("bbb") );
  188. QTest::newRow( stri + "cap06" ) << QString("(a*)a*") << QString("aaa") << 0 << 3
  189. << QStringList( QStringList() << QString("aaa") );
  190. QTest::newRow( stri + "cap07" ) << QString("((a*a*)*)") << QString("aaa") << 0 << 3
  191. << QStringList( QStringList() << "aaa" << QString("aaa") );
  192. QTest::newRow( stri + "cap08" ) << QString("(((a)*(b)*)*)") << QString("ababa") << 0 << 5
  193. << QStringList( QStringList() << QString("ababa") << QString("a") << QString("a")
  194. << "" );
  195. QTest::newRow( stri + "cap09" ) << QString("(((a)*(b)*)c)*") << QString("") << 0 << 0
  196. << QStringList( QStringList() << QString("") << QString("") << QString("") << QString("") );
  197. QTest::newRow( stri + "cap10" ) << QString("(((a)*(b)*)c)*") << QString("abc") << 0 << 3
  198. << QStringList( QStringList() << "abc" << "ab" << "a"
  199. << "b" );
  200. QTest::newRow( stri + "cap11" ) << QString("(((a)*(b)*)c)*") << QString("abcc") << 0 << 4
  201. << QStringList( QStringList() << "c" << "" << "" << "" );
  202. QTest::newRow( stri + "cap12" ) << QString("(((a)*(b)*)c)*") << QString("abcac") << 0 << 5
  203. << QStringList( QStringList() << "ac" << "a" << "a" << "" );
  204. QTest::newRow( stri + "cap13" ) << QString("(to|top)?(o|polo)?(gical|o?logical)")
  205. << QString("topological") << 0 << 11
  206. << QStringList( QStringList() << "top" << "o"
  207. << "logical" );
  208. QTest::newRow( stri + "cap14" ) << QString("(a)+") << QString("aaaa") << 0 << 4
  209. << QStringList( QStringList() << "a" );
  210. // concatenation
  211. QTest::newRow( stri + "cat00" ) << QString("") << QString("") << 0 << 0 << QStringList();
  212. QTest::newRow( stri + "cat01" ) << QString("") << QString("a") << 0 << 0 << QStringList();
  213. QTest::newRow( stri + "cat02" ) << QString("a") << QString("") << -1 << -1 << QStringList();
  214. QTest::newRow( stri + "cat03" ) << QString("a") << QString("a") << 0 << 1 << QStringList();
  215. QTest::newRow( stri + "cat04" ) << QString("a") << QString("b") << -1 << -1 << QStringList();
  216. QTest::newRow( stri + "cat05" ) << QString("b") << QString("a") << -1 << -1 << QStringList();
  217. QTest::newRow( stri + "cat06" ) << QString("ab") << QString("ab") << 0 << 2 << QStringList();
  218. QTest::newRow( stri + "cat07" ) << QString("ab") << QString("ba") << -1 << -1 << QStringList();
  219. QTest::newRow( stri + "cat08" ) << QString("abab") << QString("abbaababab") << 4 << 4
  220. << QStringList();
  221. indexIn_addMoreRows(stri);
  222. }
  223. }
  224. void tst_QRegExp::indexIn_addMoreRows(const QByteArray &stri)
  225. {
  226. // from Perl Cookbook
  227. QTest::newRow( stri + "cook00" ) << QString("^(m*)(d?c{0,3}|c[dm])(1?x{0,3}|x[lc])(v?i{0"
  228. ",3}|i[vx])$")
  229. << QString("mmxl") << 0 << 4
  230. << QStringList( QStringList() << "mm" << "" << "xl"
  231. << "" );
  232. QTest::newRow( stri + "cook01" ) << QString("(\\S+)(\\s+)(\\S+)") << QString(" a b") << 1 << 5
  233. << QStringList( QStringList() << "a" << " " << "b" );
  234. QTest::newRow( stri + "cook02" ) << QString("(\\w+)\\s*=\\s*(.*)\\s*$") << QString(" PATH=. ") << 1
  235. << 7 << QStringList( QStringList() << "PATH" << ". " );
  236. QTest::newRow( stri + "cook03" ) << QString(".{80,}")
  237. << QString("0000000011111111222222223333333344444444555"
  238. "5555566666666777777778888888899999999000000"
  239. "00aaaaaaaa")
  240. << 0 << 96 << QStringList();
  241. QTest::newRow( stri + "cook04" ) << QString("(\\d+)/(\\d+)/(\\d+) (\\d+):(\\d+):(\\d+)")
  242. << QString("1978/05/24 07:30:00") << 0 << 19
  243. << QStringList( QStringList() << "1978" << "05" << "24"
  244. << "07" << "30" << "00" );
  245. QTest::newRow( stri + "cook05" ) << QString("/usr/bin") << QString("/usr/local/bin:/usr/bin")
  246. << 15 << 8 << QStringList();
  247. QTest::newRow( stri + "cook06" ) << QString("%([0-9A-Fa-f]{2})") << QString("http://%7f") << 7 << 3
  248. << QStringList( QStringList() << "7f" );
  249. QTest::newRow( stri + "cook07" ) << QString("/\\*.*\\*/") << QString("i++; /* increment i */") << 5
  250. << 17 << QStringList();
  251. QTest::newRow( stri + "cook08" ) << QString("^\\s+") << QString(" aaa ") << 0 << 3
  252. << QStringList();
  253. QTest::newRow( stri + "cook09" ) << QString("\\s+$") << QString(" aaa ") << 6 << 3
  254. << QStringList();
  255. QTest::newRow( stri + "cook10" ) << QString("^.*::") << QString("Box::cat") << 0 << 5
  256. << QStringList();
  257. QTest::newRow( stri + "cook11" ) << QString("^([01]?\\d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\"
  258. "d\\d|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-"
  259. "4]\\d|25[0-5])\\.([01]?\\d\\d|2[0-4]\\d|25["
  260. "0-5])$")
  261. << QString("255.00.40.30") << 0 << 12
  262. << QStringList( QStringList() << "255" << "00" << "40"
  263. << "30" );
  264. QTest::newRow( stri + "cook12" ) << QString("^.*/") << QString(" /usr/local/bin/moc") << 0 << 16
  265. << QStringList();
  266. QTest::newRow( stri + "cook13" ) << QString(":co#(\\d+):") << QString("bla:co#55:") << 3 << 7
  267. << QStringList( QStringList() << "55" );
  268. QTest::newRow( stri + "cook14" ) << QString("linux") << QString("alphalinuxinunix") << 5 << 5
  269. << QStringList();
  270. QTest::newRow( stri + "cook15" ) << QString("(\\d+\\.?\\d*|\\.\\d+)") << QString("0.0.5") << 0 << 3
  271. << QStringList( QStringList() << "0.0" );
  272. // mathematical trivia
  273. QTest::newRow( stri + "math00" ) << QString("^(a\\1*)$") << QString("a") << 0 << 1
  274. << QStringList( QStringList() << "a" );
  275. QTest::newRow( stri + "math01" ) << QString("^(a\\1*)$") << QString("aa") << 0 << 2
  276. << QStringList( QStringList() << "aa" );
  277. QTest::newRow( stri + "math02" ) << QString("^(a\\1*)$") << QString("aaa") << -1 << -1
  278. << QStringList( QStringList() << QString() );
  279. QTest::newRow( stri + "math03" ) << QString("^(a\\1*)$") << QString("aaaa") << 0 << 4
  280. << QStringList( QStringList() << "aaaa" );
  281. QTest::newRow( stri + "math04" ) << QString("^(a\\1*)$") << QString("aaaaa") << -1 << -1
  282. << QStringList( QStringList() << QString() );
  283. QTest::newRow( stri + "math05" ) << QString("^(a\\1*)$") << QString("aaaaaa") << -1 << -1
  284. << QStringList( QStringList() << QString() );
  285. QTest::newRow( stri + "math06" ) << QString("^(a\\1*)$") << QString("aaaaaaa") << -1 << -1
  286. << QStringList( QStringList() << QString() );
  287. QTest::newRow( stri + "math07" ) << QString("^(a\\1*)$") << QString("aaaaaaaa") << 0 << 8
  288. << QStringList( QStringList() << "aaaaaaaa" );
  289. QTest::newRow( stri + "math08" ) << QString("^(a\\1*)$") << QString("aaaaaaaaa") << -1 << -1
  290. << QStringList( QStringList() << QString() );
  291. QTest::newRow( stri + "math09" ) << QString("^a(?:a(\\1a))*$") << QString("a") << 0 << 1
  292. << QStringList( QStringList() << "" );
  293. QTest::newRow( stri + "math10" ) << QString("^a(?:a(\\1a))*$") << QString("aaa") << 0 << 3
  294. << QStringList( QStringList() << "a" );
  295. QTest::newRow( stri + "math13" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
  296. "?=a$)))*a$")
  297. << QString("aaa") << 0 << 3
  298. << QStringList( QStringList() << "a" << "a" << "" );
  299. QTest::newRow( stri + "math14" ) << QString("^(?:((?:^a)?\\2\\3)(\\3\\1|(?=a$))(\\1\\2|("
  300. "?=a$)))*a$")
  301. << QString("aaaaa") << 0 << 5
  302. << QStringList( QStringList() << "a" << "a" << "aa" );
  303. QTest::newRow( stri + "math17" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
  304. ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
  305. << QString("aaa") << 0 << 3
  306. << QStringList( QStringList() << "" << "" << "" << "aaa"
  307. << "a" << "aa" );
  308. QTest::newRow( stri + "math18" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
  309. ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
  310. << QString("aaaaa") << 0 << 5
  311. << QStringList( QStringList() << "aaaaa" << "a" << "aaa"
  312. << "" << "" << "" );
  313. QTest::newRow( stri + "math19" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
  314. ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
  315. << QString("aaaaaaaa") << 0 << 8
  316. << QStringList( QStringList() << "" << "" << ""
  317. << "aaaaaaaa" << "a"
  318. << "aa" );
  319. QTest::newRow( stri + "math20" ) << QString("^(?:(a(?:(\\1\\3)(\\1\\2))*(?:\\1\\3)?)|((?"
  320. ":(\\4(?:^a)?\\6)(\\4\\5))*(?:\\4\\6)?))$")
  321. << QString("aaaaaaaaa") << -1 << -1
  322. << QStringList( QStringList() << QString()
  323. << QString()
  324. << QString()
  325. << QString()
  326. << QString()
  327. << QString() );
  328. QTest::newRow( stri + "math21" ) << QString("^(aa+)\\1+$") << QString("aaaaaaaaaaaa") << 0 << 12
  329. << QStringList( QStringList() << "aa" );
  330. static const char * const squareRegExp[] = {
  331. "^a(?:(\\1aa)a)*$",
  332. "^(\\2(\\1a))+$",
  333. #if 0
  334. "^(?:(\\B\\1aa|^a))+$",
  335. #endif
  336. "^((\\2a)*)\\1\\2a$",
  337. 0
  338. };
  339. int ii = 0;
  340. while ( squareRegExp[ii] != 0 ) {
  341. for ( int j = 0; j < 100; j++ ) {
  342. QString name;
  343. name.sprintf( "square%.1d%.2d", ii, j );
  344. QString target = "";
  345. target.fill( 'a', j );
  346. int pos = -1;
  347. int len = -1;
  348. for ( int k = 1; k * k <= j; k++ ) {
  349. if ( k * k == j ) {
  350. pos = 0;
  351. len = j;
  352. break;
  353. }
  354. }
  355. QTest::newRow( name.toLatin1() ) << QString( squareRegExp[ii] ) << target
  356. << pos << len << QStringList( "IGNORE ME" );
  357. }
  358. ii++;
  359. }
  360. // miscellaneous
  361. QTest::newRow( stri + "misc00" ) << QString(email)
  362. << QString("troll1@trolltech.com") << 0 << 20
  363. << QStringList();
  364. QTest::newRow( stri + "misc01" ) << QString("[0-9]*\\.[0-9]+") << QString("pi = 3.14") << 5 << 4
  365. << QStringList();
  366. // or operator
  367. QTest::newRow( stri + "or00" ) << QString("(?:|b)") << QString("xxx") << 0 << 0 << QStringList();
  368. QTest::newRow( stri + "or01" ) << QString("(?:|b)") << QString("b") << 0 << 1 << QStringList();
  369. QTest::newRow( stri + "or02" ) << QString("(?:b|)") << QString("") << 0 << 0 << QStringList();
  370. QTest::newRow( stri + "or03" ) << QString("(?:b|)") << QString("b") << 0 << 1 << QStringList();
  371. QTest::newRow( stri + "or04" ) << QString("(?:||b||)") << QString("") << 0 << 0 << QStringList();
  372. QTest::newRow( stri + "or05" ) << QString("(?:||b||)") << QString("b") << 0 << 1 << QStringList();
  373. QTest::newRow( stri + "or06" ) << QString("(?:a|b)") << QString("") << -1 << -1 << QStringList();
  374. QTest::newRow( stri + "or07" ) << QString("(?:a|b)") << QString("cc") << -1 << -1 << QStringList();
  375. QTest::newRow( stri + "or08" ) << QString("(?:a|b)") << QString("abc") << 0 << 1 << QStringList();
  376. QTest::newRow( stri + "or09" ) << QString("(?:a|b)") << QString("cba") << 1 << 1 << QStringList();
  377. QTest::newRow( stri + "or10" ) << QString("(?:ab|ba)") << QString("aba") << 0 << 2
  378. << QStringList();
  379. QTest::newRow( stri + "or11" ) << QString("(?:ab|ba)") << QString("bab") << 0 << 2
  380. << QStringList();
  381. QTest::newRow( stri + "or12" ) << QString("(?:ab|ba)") << QString("caba") << 1 << 2
  382. << QStringList();
  383. QTest::newRow( stri + "or13" ) << QString("(?:ab|ba)") << QString("cbab") << 1 << 2
  384. << QStringList();
  385. // quantifiers
  386. QTest::newRow( stri + "qua00" ) << QString("((([a-j])){0,0})") << QString("") << 0 << 0
  387. << QStringList( QStringList() << "" << "" << "" );
  388. QTest::newRow( stri + "qua01" ) << QString("((([a-j])){0,0})") << QString("a") << 0 << 0
  389. << QStringList( QStringList() << "" << "" << "" );
  390. QTest::newRow( stri + "qua02" ) << QString("((([a-j])){0,0})") << QString("xyz") << 0 << 0
  391. << QStringList( QStringList() << "" << "" << "" );
  392. QTest::newRow( stri + "qua03" ) << QString("((([a-j]))?)") << QString("") << 0 << 0
  393. << QStringList( QStringList() << "" << "" << "" );
  394. QTest::newRow( stri + "qua04" ) << QString("((([a-j]))?)") << QString("a") << 0 << 1
  395. << QStringList( QStringList() << "a" << "a" << "a" );
  396. QTest::newRow( stri + "qua05" ) << QString("((([a-j]))?)") << QString("x") << 0 << 0
  397. << QStringList( QStringList() << "" << "" << "" );
  398. QTest::newRow( stri + "qua06" ) << QString("((([a-j]))?)") << QString("ab") << 0 << 1
  399. << QStringList( QStringList() << "a" << "a" << "a" );
  400. QTest::newRow( stri + "qua07" ) << QString("((([a-j]))?)") << QString("xa") << 0 << 0
  401. << QStringList( QStringList() << "" << "" << "" );
  402. QTest::newRow( stri + "qua08" ) << QString("((([a-j])){0,3})") << QString("") << 0 << 0
  403. << QStringList( QStringList() << "" << "" << "" );
  404. QTest::newRow( stri + "qua09" ) << QString("((([a-j])){0,3})") << QString("a") << 0 << 1
  405. << QStringList( QStringList() << "a" << "a" << "a" );
  406. QTest::newRow( stri + "qua10" ) << QString("((([a-j])){0,3})") << QString("abcd") << 0 << 3
  407. << QStringList( QStringList() << "abc" << "c" << "c" );
  408. QTest::newRow( stri + "qua11" ) << QString("((([a-j])){0,3})") << QString("abcde") << 0 << 3
  409. << QStringList( QStringList() << "abc" << "c" << "c" );
  410. QTest::newRow( stri + "qua12" ) << QString("((([a-j])){2,4})") << QString("a") << -1 << -1
  411. << QStringList( QStringList() << QString()
  412. << QString()
  413. << QString() );
  414. QTest::newRow( stri + "qua13" ) << QString("((([a-j])){2,4})") << QString("ab") << 0 << 2
  415. << QStringList( QStringList() << "ab" << "b" << "b" );
  416. QTest::newRow( stri + "qua14" ) << QString("((([a-j])){2,4})") << QString("abcd") << 0 << 4
  417. << QStringList( QStringList() << "abcd" << "d" << "d" );
  418. QTest::newRow( stri + "qua15" ) << QString("((([a-j])){2,4})") << QString("abcdef") << 0 << 4
  419. << QStringList( QStringList() << "abcd" << "d" << "d" );
  420. QTest::newRow( stri + "qua16" ) << QString("((([a-j])){2,4})") << QString("xaybcd") << 3 << 3
  421. << QStringList( QStringList() << "bcd" << "d" << "d" );
  422. QTest::newRow( stri + "qua17" ) << QString("((([a-j])){0,})") << QString("abcdefgh") << 0 << 8
  423. << QStringList( QStringList() << "abcdefgh" << "h" << "h" );
  424. QTest::newRow( stri + "qua18" ) << QString("((([a-j])){,0})") << QString("abcdefgh") << 0 << 0
  425. << QStringList( QStringList() << "" << "" << "" );
  426. QTest::newRow( stri + "qua19" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("123332333") << 0
  427. << 9
  428. << QStringList( QStringList() << "123332333" << "2333"
  429. << "3" );
  430. QTest::newRow( stri + "qua20" ) << QString("(1(2(3){3,4}){2,3}){1,2}")
  431. << QString("12333323333233331233332333323333") << 0 << 32
  432. << QStringList( QStringList() << "1233332333323333"
  433. << "23333" << "3" );
  434. QTest::newRow( stri + "qua21" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("") << -1 << -1
  435. << QStringList( QStringList() << QString()
  436. << QString()
  437. << QString() );
  438. QTest::newRow( stri + "qua22" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333") << -1
  439. << -1
  440. << QStringList( QStringList() << QString()
  441. << QString()
  442. << QString() );
  443. QTest::newRow( stri + "qua23" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("12333233") << -1
  444. << -1
  445. << QStringList( QStringList() << QString()
  446. << QString()
  447. << QString() );
  448. QTest::newRow( stri + "qua24" ) << QString("(1(2(3){3,4}){2,3}){1,2}") << QString("122333") << -1
  449. << -1
  450. << QStringList( QStringList() << QString()
  451. << QString()
  452. << QString() );
  453. // star operator
  454. QTest::newRow( stri + "star00" ) << QString("(?:)*") << QString("") << 0 << 0 << QStringList();
  455. QTest::newRow( stri + "star01" ) << QString("(?:)*") << QString("abc") << 0 << 0 << QStringList();
  456. QTest::newRow( stri + "star02" ) << QString("(?:a)*") << QString("") << 0 << 0 << QStringList();
  457. QTest::newRow( stri + "star03" ) << QString("(?:a)*") << QString("a") << 0 << 1 << QStringList();
  458. QTest::newRow( stri + "star04" ) << QString("(?:a)*") << QString("aaa") << 0 << 3 << QStringList();
  459. QTest::newRow( stri + "star05" ) << QString("(?:a)*") << QString("bbbbaaa") << 0 << 0
  460. << QStringList();
  461. QTest::newRow( stri + "star06" ) << QString("(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 0
  462. << QStringList();
  463. QTest::newRow( stri + "star07" ) << QString("(?:b)*(?:a)*") << QString("") << 0 << 0
  464. << QStringList();
  465. QTest::newRow( stri + "star08" ) << QString("(?:b)*(?:a)*") << QString("a") << 0 << 1
  466. << QStringList();
  467. QTest::newRow( stri + "star09" ) << QString("(?:b)*(?:a)*") << QString("aaa") << 0 << 3
  468. << QStringList();
  469. QTest::newRow( stri + "star10" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaa") << 0 << 7
  470. << QStringList();
  471. QTest::newRow( stri + "star11" ) << QString("(?:b)*(?:a)*") << QString("bbbbaaabbaaaaa") << 0 << 7
  472. << QStringList();
  473. QTest::newRow( stri + "star12" ) << QString("(?:a|b)*") << QString("c") << 0 << 0 << QStringList();
  474. QTest::newRow( stri + "star13" ) << QString("(?:a|b)*") << QString("abac") << 0 << 3
  475. << QStringList();
  476. QTest::newRow( stri + "star14" ) << QString("(?:a|b|)*") << QString("c") << 0 << 0
  477. << QStringList();
  478. QTest::newRow( stri + "star15" ) << QString("(?:a|b|)*") << QString("abac") << 0 << 3
  479. << QStringList();
  480. QTest::newRow( stri + "star16" ) << QString("(?:ab|ba|b)*") << QString("abbbababbbaaab") << 0 << 11
  481. << QStringList();
  482. }
  483. void tst_QRegExp::init()
  484. {
  485. }
  486. void tst_QRegExp::cleanup()
  487. {
  488. }
  489. /*
  490. void tst_QRegExp::isEmpty()
  491. {
  492. }
  493. void tst_QRegExp::isValid()
  494. {
  495. }
  496. void tst_QRegExp::pattern()
  497. {
  498. }
  499. void tst_QRegExp::setPattern()
  500. {
  501. }
  502. void tst_QRegExp::caseSensitive()
  503. {
  504. }
  505. void tst_QRegExp::setCaseSensitive()
  506. {
  507. }
  508. void tst_QRegExp::minimal()
  509. {
  510. }
  511. void tst_QRegExp::setMinimal()
  512. {
  513. }
  514. */
  515. void tst_QRegExp::exactMatch()
  516. {
  517. QRegExp rx_d( "\\d" );
  518. QRegExp rx_s( "\\s" );
  519. QRegExp rx_w( "\\w" );
  520. QRegExp rx_D( "\\D" );
  521. QRegExp rx_S( "\\S" );
  522. QRegExp rx_W( "\\W" );
  523. for ( int i = 0; i < 65536; i++ ) {
  524. QChar ch( i );
  525. bool is_d = ( ch.category() == QChar::Number_DecimalDigit );
  526. bool is_s = ch.isSpace();
  527. bool is_w = ( ch.isLetterOrNumber()
  528. || ch.isMark()
  529. || ch == '_' );
  530. QVERIFY( rx_d.exactMatch(QString(ch)) == is_d );
  531. QVERIFY( rx_s.exactMatch(QString(ch)) == is_s );
  532. QVERIFY( rx_w.exactMatch(QString(ch)) == is_w );
  533. QVERIFY( rx_D.exactMatch(QString(ch)) != is_d );
  534. QVERIFY( rx_S.exactMatch(QString(ch)) != is_s );
  535. QVERIFY( rx_W.exactMatch(QString(ch)) != is_w );
  536. }
  537. }
  538. void tst_QRegExp::capturedTexts()
  539. {
  540. QRegExp rx1("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
  541. rx1.exactMatch("aaa");
  542. QCOMPARE(rx1.matchedLength(), 3);
  543. QCOMPARE(rx1.cap(0), QString("aaa"));
  544. QCOMPARE(rx1.cap(1), QString("aaa"));
  545. QRegExp rx2("a*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
  546. rx2.exactMatch("aaa");
  547. QCOMPARE(rx2.matchedLength(), 3);
  548. QCOMPARE(rx2.cap(0), QString("aaa"));
  549. QCOMPARE(rx2.cap(1), QString(""));
  550. QRegExp rx3("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp);
  551. rx3.exactMatch("aaa");
  552. QCOMPARE(rx3.matchedLength(), 3);
  553. QCOMPARE(rx3.cap(0), QString("aaa"));
  554. QCOMPARE(rx3.cap(1), QString("aa"));
  555. QRegExp rx4("(?:a|aa)(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
  556. rx4.exactMatch("aaa");
  557. QCOMPARE(rx4.matchedLength(), 3);
  558. QCOMPARE(rx4.cap(0), QString("aaa"));
  559. QCOMPARE(rx4.cap(1), QString("a"));
  560. QRegExp rx5("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp);
  561. rx5.exactMatch("aaa");
  562. QCOMPARE(rx5.matchedLength(), 3);
  563. QCOMPARE(rx5.cap(0), QString("aaa"));
  564. QCOMPARE(rx5.cap(1), QString("a"));
  565. QCOMPARE(rx5.cap(2), QString("aa"));
  566. QRegExp rx6("(a)*(a*)", Qt::CaseSensitive, QRegExp::RegExp2);
  567. rx6.exactMatch("aaa");
  568. QCOMPARE(rx6.matchedLength(), 3);
  569. QCOMPARE(rx6.cap(0), QString("aaa"));
  570. QCOMPARE(rx6.cap(1), QString("a"));
  571. QCOMPARE(rx6.cap(2), QString(""));
  572. QRegExp rx7("([A-Za-z_])([A-Za-z_0-9]*)");
  573. rx7.setCaseSensitivity(Qt::CaseSensitive);
  574. rx7.setPatternSyntax(QRegExp::RegExp);
  575. QCOMPARE(rx7.captureCount(), 2);
  576. int pos = rx7.indexIn("(10 + delta4) * 32");
  577. QCOMPARE(pos, 6);
  578. QCOMPARE(rx7.matchedLength(), 6);
  579. QCOMPARE(rx7.cap(0), QString("delta4"));
  580. QCOMPARE(rx7.cap(1), QString("d"));
  581. QCOMPARE(rx7.cap(2), QString("elta4"));
  582. }
  583. /*
  584. void tst_QRegExp::cap()
  585. {
  586. }
  587. void tst_QRegExp::pos()
  588. {
  589. }
  590. void tst_QRegExp::errorString()
  591. {
  592. }
  593. void tst_QRegExp::escape()
  594. {
  595. }
  596. */
  597. void tst_QRegExp::indexIn()
  598. {
  599. QFETCH( QString, regexpStr );
  600. QFETCH( QString, target );
  601. QFETCH( int, pos );
  602. QFETCH( int, len );
  603. QFETCH( QStringList, caps );
  604. caps.prepend( "dummy cap(0)" );
  605. {
  606. QRegExp rx( regexpStr );
  607. QVERIFY( rx.isValid() );
  608. int mypos = rx.indexIn( target );
  609. int mylen = rx.matchedLength();
  610. QStringList mycaps = rx.capturedTexts();
  611. QCOMPARE( mypos, pos );
  612. QCOMPARE( mylen, len );
  613. if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
  614. QCOMPARE( mycaps.count(), caps.count() );
  615. for ( int i = 1; i < (int) mycaps.count(); i++ )
  616. QCOMPARE( mycaps[i], caps[i] );
  617. }
  618. }
  619. // same as above, but with RegExp2
  620. {
  621. QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
  622. QVERIFY( rx.isValid() );
  623. int mypos = rx.indexIn( target );
  624. int mylen = rx.matchedLength();
  625. QStringList mycaps = rx.capturedTexts();
  626. QCOMPARE( mypos, pos );
  627. QCOMPARE( mylen, len );
  628. if ( caps.size() > 1 && caps[1] != "IGNORE ME" ) {
  629. QCOMPARE( mycaps.count(), caps.count() );
  630. for ( int i = 1; i < (int) mycaps.count(); i++ )
  631. QCOMPARE( mycaps[i], caps[i] );
  632. }
  633. }
  634. }
  635. void tst_QRegExp::lastIndexIn()
  636. {
  637. QFETCH( QString, regexpStr );
  638. QFETCH( QString, target );
  639. QFETCH( int, pos );
  640. QFETCH( int, len );
  641. QFETCH( QStringList, caps );
  642. caps.prepend( "dummy" );
  643. /*
  644. The test data was really designed for indexIn(), not
  645. lastIndexIn(), but it turns out that we can reuse much of that
  646. for lastIndexIn().
  647. */
  648. {
  649. QRegExp rx( regexpStr );
  650. QVERIFY( rx.isValid() );
  651. int mypos = rx.lastIndexIn( target, target.length() );
  652. int mylen = rx.matchedLength();
  653. QStringList mycaps = rx.capturedTexts();
  654. if ( mypos <= pos || pos == -1 ) {
  655. QCOMPARE( mypos, pos );
  656. QCOMPARE( mylen, len );
  657. if (caps.size() > 1 && caps[1] != "IGNORE ME") {
  658. QCOMPARE( mycaps.count(), caps.count() );
  659. for ( int i = 1; i < (int) mycaps.count(); i++ )
  660. QCOMPARE( mycaps[i], caps[i] );
  661. }
  662. }
  663. }
  664. {
  665. QRegExp rx( regexpStr, Qt::CaseSensitive, QRegExp::RegExp2 );
  666. QVERIFY( rx.isValid() );
  667. int mypos = rx.lastIndexIn( target, target.length() );
  668. int mylen = rx.matchedLength();
  669. QStringList mycaps = rx.capturedTexts();
  670. if ( mypos <= pos || pos == -1 ) {
  671. QCOMPARE( mypos, pos );
  672. QCOMPARE( mylen, len );
  673. if (caps.size() > 1 && caps[1] != "IGNORE ME") {
  674. QCOMPARE( mycaps.count(), caps.count() );
  675. for ( int i = 1; i < (int) mycaps.count(); i++ )
  676. QCOMPARE( mycaps[i], caps[i] );
  677. }
  678. }
  679. }
  680. }
  681. void tst_QRegExp::matchedLength()
  682. {
  683. QRegExp r1( "a+" );
  684. r1.exactMatch( "aaaba" );
  685. QCOMPARE( r1.matchedLength(), 3 );
  686. }
  687. const char email[] =
  688. "^[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff"
  689. "]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\x"
  690. "ff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:"
  691. "(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@"
  692. ",;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\""
  693. "]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?"
  694. ":\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x"
  695. "80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*"
  696. ")*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*"
  697. "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
  698. "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
  699. ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>"
  700. "@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\["
  701. "\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\"
  702. "x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x"
  703. "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
  704. "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
  705. "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x"
  706. "80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\"
  707. "015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\"
  708. "\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\["
  709. "\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037"
  710. "\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff"
  711. "])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80"
  712. "-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x"
  713. "80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]"
  714. "*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x"
  715. "80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\"
  716. "\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040"
  717. "\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\"
  718. "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xf"
  719. "f\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-"
  720. "\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015"
  721. "()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x8"
  722. "0-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*|(?:[^(\\040)<>@,;:\".\\\\\\[\\"
  723. "]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x"
  724. "80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\"
  725. "\\x80-\\xff\\n\\015\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\"
  726. "010\\012-\\037]*(?:(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x8"
  727. "0-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\"
  728. "x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)|\"[^\\\\"
  729. "\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015"
  730. "\"]*)*\")[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037]*)*<"
  731. "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
  732. "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
  733. "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:@"
  734. "[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]"
  735. "|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xf"
  736. "f\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:["
  737. "^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:"
  738. "\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015"
  739. "\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
  740. "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
  741. "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
  742. "\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff"
  743. "\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*("
  744. "?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\x"
  745. "ff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-"
  746. "\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xf"
  747. "f])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\"
  748. "040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\"
  749. "([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\"
  750. "n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*(?:,["
  751. "\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|"
  752. "\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff"
  753. "\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*@[\\0"
  754. "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
  755. "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
  756. "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
  757. "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
  758. "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
  759. "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
  760. "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
  761. "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
  762. "()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015"
  763. "()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^"
  764. "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\0"
  765. "15()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x8"
  766. "0-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?"
  767. ":[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*("
  768. "?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\"
  769. "x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]"
  770. "*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)*)*:[\\040\\t]*"
  771. "(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\"
  772. "\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015("
  773. ")]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*)?(?:[^(\\040)"
  774. "<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\"
  775. "[\\]\\000-\\037\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^"
  776. "\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\"
  777. "\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\"
  778. "n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\"
  779. "\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\040\\t]*(?:\\([^\\"
  780. "\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff"
  781. "\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^"
  782. "\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\"
  783. "\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
  784. "37\\x80-\\xff])|\"[^\\\\\\x80-\\xff\\n\\015\"]*(?:\\\\[^\\x80-\\xff][^"
  785. "\\\\\\x80-\\xff\\n\\015\"]*)*\")[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
  786. "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
  787. "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
  788. "\\n\\015()]*)*\\)[\\040\\t]*)*)*@[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n"
  789. "\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:"
  790. "\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff"
  791. "\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\0"
  792. "37\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff])"
  793. "|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]]|\\\\[^\\x80-\\xff])*\\])[\\040"
  794. "\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\([^"
  795. "\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n\\"
  796. "015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:\\.[\\0"
  797. "40\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()]*(?:(?:\\\\[^\\x80-\\xff]|\\("
  798. "[^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\x80-\\xff][^\\\\\\x80-\\xff\\n"
  799. "\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015()]*)*\\)[\\040\\t]*)*(?:[^(\\"
  800. "040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+(?![^(\\040)<>@,;:\".\\"
  801. "\\\\[\\]\\000-\\037\\x80-\\xff])|\\[(?:[^\\\\\\x80-\\xff\\n\\015\\[\\]"
  802. "]|\\\\[^\\x80-\\xff])*\\])[\\040\\t]*(?:\\([^\\\\\\x80-\\xff\\n\\015()"
  803. "]*(?:(?:\\\\[^\\x80-\\xff]|\\([^\\\\\\x80-\\xff\\n\\015()]*(?:\\\\[^\\"
  804. "x80-\\xff][^\\\\\\x80-\\xff\\n\\015()]*)*\\))[^\\\\\\x80-\\xff\\n\\015"
  805. "()]*)*\\)[\\040\\t]*)*)*>)$";
  806. void tst_QRegExp::wildcard_data()
  807. {
  808. QTest::addColumn<QString>("rxp");
  809. QTest::addColumn<QString>("string");
  810. QTest::addColumn<int>("foundIndex");
  811. QTest::newRow( "data0" ) << QString("*.html") << QString("test.html") << 0;
  812. QTest::newRow( "data1" ) << QString("*.html") << QString("test.htm") << -1;
  813. QTest::newRow( "data2" ) << QString("bar*") << QString("foobarbaz") << 3;
  814. QTest::newRow( "data3" ) << QString("*") << QString("Trolltech") << 0;
  815. QTest::newRow( "data4" ) << QString(".html") << QString("test.html") << 4;
  816. QTest::newRow( "data5" ) << QString(".h") << QString("test.cpp") << -1;
  817. QTest::newRow( "data6" ) << QString(".???l") << QString("test.html") << 4;
  818. QTest::newRow( "data7" ) << QString("?") << QString("test.html") << 0;
  819. QTest::newRow( "data8" ) << QString("?m") << QString("test.html") << 6;
  820. QTest::newRow( "data9" ) << QString(".h[a-z]ml") << QString("test.html") << 4;
  821. QTest::newRow( "data10" ) << QString(".h[A-Z]ml") << QString("test.html") << -1;
  822. QTest::newRow( "data11" ) << QString(".h[A-Z]ml") << QString("test.hTml") << 4;
  823. }
  824. void tst_QRegExp::wildcard()
  825. {
  826. QFETCH( QString, rxp );
  827. QFETCH( QString, string );
  828. QFETCH( int, foundIndex );
  829. QRegExp r( rxp );
  830. r.setPatternSyntax(QRegExp::WildcardUnix);
  831. QCOMPARE( r.indexIn( string ), foundIndex );
  832. }
  833. void tst_QRegExp::testEscapingWildcard_data(){
  834. QTest::addColumn<QString>("pattern");
  835. QTest::addColumn<QString>("teststring");
  836. QTest::addColumn<bool>("isMatching");
  837. QTest::newRow("[ Not escaped") << "[Qt;" << "[Qt;" << false;
  838. QTest::newRow("[ Escaped") << "\\[Qt;" << "[Qt;" << true;
  839. QTest::newRow("] Not escaped") << "]Ik;" << "]Ik;" << false;
  840. QTest::newRow("] Escaped") << "\\]Ip;" << "]Ip;" << true;
  841. QTest::newRow("? Not escaped valid") << "?Ou:" << ".Ou:" << true;
  842. QTest::newRow("? Not escaped invalid") << "?Tr;" << "Tr;" << false;
  843. QTest::newRow("? Escaped") << "\\?O;" << "?O;" << true;
  844. QTest::newRow("[] not escaped") << "[lL]" << "l" << true;
  845. QTest::newRow("[] escaped") << "\\[\\]" << "[]" << true;
  846. QTest::newRow("case [[]") << "[[abc]" << "[" << true;
  847. QTest::newRow("case []abc] match ]") << "[]abc]" << "]" << true;
  848. QTest::newRow("case []abc] match a") << "[]abc]" << "a" << true;
  849. QTest::newRow("case [abc] match a") << "[abc]" << "a" << true;
  850. QTest::newRow("case []] don't match [") << "[]abc]" << "[" << false;
  851. QTest::newRow("case [^]abc] match d") << "[^]abc]" << "d" << true;
  852. QTest::newRow("case [^]abc] don't match ]") << "[^]abc]" << "]" << false;
  853. QTest::newRow("* Not escaped with char") << "*Te;" << "12345Te;" << true;
  854. QTest::newRow("* Not escaped without char") << "*Ch;" << "Ch;" << true;
  855. QTest::newRow("* Not escaped invalid") << "*Ro;" << "o;" << false;
  856. QTest::newRow("* Escaped") << "\\[Cks;" << "[Cks;" << true;
  857. QTest::newRow("a true '\\' in input") << "\\Qt;" << "\\Qt;" << true;
  858. QTest::newRow("two true '\\' in input") << "\\\\Qt;" << "\\\\Qt;" << true;
  859. QTest::newRow("a '\\' at the end") << "\\\\Qt;\\" << "\\\\Qt;\\" << true;
  860. }
  861. void tst_QRegExp::testEscapingWildcard(){
  862. QFETCH(QString, pattern);
  863. QRegExp re(pattern);
  864. re.setPatternSyntax(QRegExp::WildcardUnix);
  865. QFETCH(QString, teststring);
  866. QFETCH(bool, isMatching);
  867. QCOMPARE(re.exactMatch(teststring), isMatching);
  868. }
  869. void tst_QRegExp::testInvalidWildcard_data(){
  870. QTest::addColumn<QString>("pattern");
  871. QTest::addColumn<bool>("isValid");
  872. QTest::newRow("valid []") << "[abc]" << true;
  873. QTest::newRow("invalid [") << "[abc" << false;
  874. QTest::newRow("ending [") << "abc[" << false;
  875. QTest::newRow("ending ]") << "abc]" << false;
  876. QTest::newRow("ending [^") << "abc[^" << false;
  877. QTest::newRow("ending [\\") << "abc[\\" << false;
  878. QTest::newRow("ending []") << "abc[]" << false;
  879. QTest::newRow("ending [[") << "abc[[" << false;
  880. }
  881. void tst_QRegExp::testInvalidWildcard(){
  882. QFETCH(QString, pattern);
  883. QRegExp re(pattern);
  884. re.setPatternSyntax(QRegExp::Wildcard);
  885. QFETCH(bool, isValid);
  886. QCOMPARE(re.isValid(), isValid);
  887. }
  888. void tst_QRegExp::caretAnchoredOptimization()
  889. {
  890. QString s = "---babnana----";
  891. s.replace( QRegExp("^-*|(-*)$"), "" );
  892. QVERIFY(s == "babnana");
  893. s = "---babnana----";
  894. s.replace( QRegExp("^-*|(-{0,})$"), "" );
  895. QVERIFY(s == "babnana");
  896. s = "---babnana----";
  897. s.replace( QRegExp("^-*|(-{1,})$"), "" );
  898. QVERIFY(s == "babnana");
  899. s = "---babnana----";
  900. s.replace( QRegExp("^-*|(-+)$"), "" );
  901. QVERIFY(s == "babnana");
  902. }
  903. void tst_QRegExp::isEmpty()
  904. {
  905. QRegExp rx1;
  906. QVERIFY(rx1.isEmpty());
  907. QRegExp rx2 = rx1;
  908. QVERIFY(rx2.isEmpty());
  909. rx2.setPattern("");
  910. QVERIFY(rx2.isEmpty());
  911. rx2.setPattern("foo");
  912. QVERIFY(!rx2.isEmpty());
  913. rx2.setPattern(")(");
  914. QVERIFY(!rx2.isEmpty());
  915. rx2.setPattern("");
  916. QVERIFY(rx2.isEmpty());
  917. rx2.setPatternSyntax(QRegExp::Wildcard);
  918. rx2.setPattern("");
  919. QVERIFY(rx2.isEmpty());
  920. }
  921. static QRegExp re("foo.*bar");
  922. void tst_QRegExp::staticRegExp()
  923. {
  924. QVERIFY(re.exactMatch("fooHARRYbar"));
  925. // the actual test is that a static regexp should not crash
  926. }
  927. void tst_QRegExp::rainersSlowRegExpCopyBug()
  928. {
  929. // this test should take an extreme amount of time if QRegExp is broken
  930. QRegExp original(email);
  931. #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  932. for (int i = 0; i < 100; ++i) {
  933. #else
  934. for (int i = 0; i < 100000; ++i) {
  935. #endif
  936. QRegExp copy = original;
  937. (void)copy.exactMatch("~");
  938. QRegExp copy2 = original;
  939. }
  940. }
  941. void tst_QRegExp::nonExistingBackReferenceBug()
  942. {
  943. {
  944. QRegExp rx("<\\5>");
  945. QVERIFY(rx.isValid());
  946. QCOMPARE(rx.indexIn("<>"), 0);
  947. QCOMPARE(rx.capturedTexts(), QStringList("<>"));
  948. }
  949. {
  950. QRegExp rx("<\\1>");
  951. QVERIFY(rx.isValid());
  952. QCOMPARE(rx.indexIn("<>"), 0);
  953. QCOMPARE(rx.capturedTexts(), QStringList("<>"));
  954. }
  955. {
  956. QRegExp rx("(?:<\\1>)\\1\\5\\4");
  957. QVERIFY(rx.isValid());
  958. QCOMPARE(rx.indexIn("<>"), 0);
  959. QCOMPARE(rx.capturedTexts(), QStringList("<>"));
  960. }
  961. }
  962. class Thread : public QThread
  963. {
  964. public:
  965. Thread(const QRegExp &rx) : rx(rx) {}
  966. void run();
  967. QRegExp rx;
  968. };
  969. void Thread::run()
  970. {
  971. QString str = "abc";
  972. for (int i = 0; i < 10; ++i)
  973. str += str;
  974. str += "abbbdekcz";
  975. int x;
  976. #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
  977. for (int j = 0; j < 100; ++j) {
  978. #else
  979. for (int j = 0; j < 10000; ++j) {
  980. #endif
  981. x = rx.indexIn(str);
  982. }
  983. QCOMPARE(x, 3072);
  984. }
  985. void tst_QRegExp::reentrancy()
  986. {
  987. QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
  988. Thread *threads[10];
  989. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
  990. threads[i] = new Thread(rx);
  991. threads[i]->start();
  992. }
  993. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
  994. threads[i]->wait();
  995. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
  996. delete threads[i];
  997. }
  998. class Thread2 : public QThread
  999. {
  1000. public:
  1001. void run();
  1002. };
  1003. void Thread2::run()
  1004. {
  1005. QRegExp rx("(ab{2,}d?e?f?[g-z]?)c");
  1006. QString str = "abc";
  1007. for (int i = 0; i < 10; ++i)
  1008. str += str;
  1009. str += "abbbdekcz";
  1010. int x;
  1011. #if defined(Q_OS_WINCE)
  1012. for (int j = 0; j < 100; ++j) {
  1013. #else
  1014. for (int j = 0; j < 10000; ++j) {
  1015. #endif
  1016. x = rx.indexIn(str);
  1017. }
  1018. QCOMPARE(x, 3072);
  1019. }
  1020. // Test that multiple threads can construct equal QRegExps.
  1021. // (In the current QRegExp design each engine instatance will share
  1022. // the same cache key, so the threads will race for the cache entry
  1023. // in the global cache.)
  1024. void tst_QRegExp::threadsafeEngineCache()
  1025. {
  1026. Thread2 *threads[10];
  1027. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i) {
  1028. threads[i] = new Thread2();
  1029. threads[i]->start();
  1030. }
  1031. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
  1032. threads[i]->wait();
  1033. for (int i = 0; i < int(sizeof(threads) / sizeof(threads[0])); ++i)
  1034. delete threads[i];
  1035. }
  1036. void tst_QRegExp::prepareEngineOptimization()
  1037. {
  1038. QRegExp rx0("(f?)(?:(o?)(o?))?");
  1039. QRegExp rx1(rx0);
  1040. QCOMPARE(rx1.capturedTexts(), QStringList() << "" << "" << "" << "");
  1041. QCOMPARE(rx1.matchedLength(), -1);
  1042. QCOMPARE(rx1.matchedLength(), -1);
  1043. QCOMPARE(rx1.captureCount(), 3);
  1044. QCOMPARE(rx1.exactMatch("foo"), true);
  1045. QCOMPARE(rx1.matchedLength(), 3);
  1046. QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
  1047. QCOMPARE(rx1.captureCount(), 3);
  1048. QCOMPARE(rx1.matchedLength(), 3);
  1049. QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
  1050. QCOMPARE(rx1.pos(3), 2);
  1051. QCOMPARE(rx1.exactMatch("foo"), true);
  1052. QCOMPARE(rx1.captureCount(), 3);
  1053. QCOMPARE(rx1.matchedLength(), 3);
  1054. QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
  1055. QCOMPARE(rx1.pos(3), 2);
  1056. QRegExp rx2 = rx1;
  1057. QCOMPARE(rx1.captureCount(), 3);
  1058. QCOMPARE(rx1.matchedLength(), 3);
  1059. QCOMPARE(rx1.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
  1060. QCOMPARE(rx1.pos(3), 2);
  1061. QCOMPARE(rx2.captureCount(), 3);
  1062. QCOMPARE(rx2.matchedLength(), 3);
  1063. QCOMPARE(rx2.capturedTexts(), QStringList() << "foo" << "f" << "o" << "o");
  1064. QCOMPARE(rx2.pos(3), 2);
  1065. QCOMPARE(rx1.exactMatch("fo"), true);
  1066. QCOMPARE(rx1.captureCount(), 3);
  1067. QCOMPARE(rx1.matchedLength(), 2);
  1068. QCOMPARE(rx1.capturedTexts(), QStringList() << "fo" << "f" << "o" << "");
  1069. QCOMPARE(rx1.pos(2), 1);
  1070. #if 0
  1071. QCOMPARE(rx1.pos(3), -1); // ###
  1072. #endif
  1073. QRegExp rx3;
  1074. QVERIFY(rx3.isValid());
  1075. QRegExp rx4("foo", Qt::CaseInsensitive, QRegExp::RegExp);
  1076. QVERIFY(rx4.isValid());
  1077. QRegExp rx5("foo", Qt::CaseInsensitive, QRegExp::RegExp2);
  1078. QVERIFY(rx5.isValid());
  1079. QRegExp rx6("foo", Qt::CaseInsensitive, QRegExp::FixedString);
  1080. QVERIFY(rx6.isValid());
  1081. QRegExp rx7("foo", Qt::CaseInsensitive, QRegExp::Wildcard);
  1082. QVERIFY(rx7.isValid());
  1083. QRegExp rx8("][", Qt::CaseInsensitive, QRegExp::RegExp);
  1084. QVERIFY(!rx8.isValid());
  1085. QRegExp rx9("][", Qt::CaseInsensitive, QRegExp::RegExp2);
  1086. QVERIFY(!rx9.isValid());
  1087. QRegExp rx10("][", Qt::CaseInsensitive, QRegExp::Wildcard);
  1088. QVERIFY(!rx10.isValid());
  1089. QRegExp rx11("][", Qt::CaseInsensitive, QRegExp::FixedString);
  1090. QVERIFY(rx11.isValid());
  1091. QVERIFY(rx11.exactMatch("]["));
  1092. QCOMPARE(rx11.matchedLength(), 2);
  1093. rx11.setPatternSyntax(QRegExp::Wildcard);
  1094. QVERIFY(!rx11.isValid());
  1095. QCOMPARE(rx11.captureCount(), 0);
  1096. QCOMPARE(rx11.matchedLength(), -1);
  1097. rx11.setPatternSyntax(QRegExp::RegExp);
  1098. QVERIFY(!rx11.isValid());
  1099. QCOMPARE(rx11.captureCount(), 0);
  1100. QCOMPARE(rx11.matchedLength(), -1);
  1101. rx11.setPattern("(foo)");
  1102. QVERIFY(rx11.isValid());
  1103. QCOMPARE(rx11.captureCount(), 1);
  1104. QCOMPARE(rx11.matchedLength(), -1);
  1105. QCOMPARE(rx11.indexIn("ofoo"), 1);
  1106. QCOMPARE(rx11.captureCount(), 1);
  1107. QCOMPARE(rx11.matchedLength(), 3);
  1108. rx11.setPatternSyntax(QRegExp::RegExp);
  1109. QCOMPARE(rx11.captureCount(), 1);
  1110. QCOMPARE(rx11.matchedLength(), 3);
  1111. /*
  1112. This behavior isn't entirely consistent with setPatter(),
  1113. setPatternSyntax(), and setCaseSensitivity(), but I'm testing
  1114. it here to ensure that it doesn't change subtly in future
  1115. releases.
  1116. */
  1117. rx11.setMinimal(true);
  1118. QCOMPARE(rx11.matchedLength(), 3);
  1119. rx11.setMinimal(false);
  1120. QCOMPARE(rx11.matchedLength(), 3);
  1121. rx11.setPatternSyntax(QRegExp::Wildcard);
  1122. QCOMPARE(rx11.captureCount(), 0);
  1123. QCOMPARE(rx11.matchedLength(), -1);
  1124. rx11.setPatternSyntax(QRegExp::RegExp);
  1125. QCOMPARE(rx11.captureCount(), 1);
  1126. QCOMPARE(rx11.matchedLength(), -1);
  1127. }
  1128. void tst_QRegExp::swap()
  1129. {
  1130. QRegExp r1(QLatin1String(".*")), r2(QLatin1String("a*"));
  1131. r1.swap(r2);
  1132. QCOMPARE(r1.pattern(),QLatin1String("a*"));
  1133. QCOMPARE(r2.pattern(),QLatin1String(".*"));
  1134. }
  1135. void tst_QRegExp::operator_eq()
  1136. {
  1137. const int I = 2;
  1138. const int J = 4;
  1139. const int K = 2;
  1140. const int ELL = 2;
  1141. QRegExp rxtable[I * J * K * ELL];
  1142. int n;
  1143. n = 0;
  1144. for (int i = 0; i < I; ++i) {
  1145. for (int j = 0; j < J; ++j) {
  1146. for (int k = 0; k < K; ++k) {
  1147. for (int ell = 0; ell < ELL; ++ell) {
  1148. Qt::CaseSensitivity cs = i == 0 ? Qt::CaseSensitive : Qt::CaseInsensitive;
  1149. QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(j);
  1150. bool minimal = k == 0;
  1151. if (ell == 0) {
  1152. QRegExp rx("foo", cs, syntax);
  1153. rx.setMinimal(minimal);
  1154. rxtable[n++] = rx;
  1155. } else {
  1156. QRegExp rx;
  1157. rx.setPattern("bar");
  1158. rx.setMinimal(true);
  1159. rx.exactMatch("bar");
  1160. rx.setCaseSensitivity(cs);
  1161. rx.setMinimal(minimal);
  1162. rx.setPattern("foo");
  1163. rx.setPatternSyntax(syntax);
  1164. rx.exactMatch("foo");
  1165. rxtable[n++] = rx;
  1166. }
  1167. }
  1168. }
  1169. }
  1170. }
  1171. for (int i = 0; i < I * J * K * ELL; ++i) {
  1172. for (int j = 0; j < I * J * K * ELL; ++j) {
  1173. QCOMPARE(rxtable[i] == rxtable[j], i / ELL == j / ELL);
  1174. QCOMPARE(rxtable[i] != rxtable[j], i / ELL != j / ELL);
  1175. }
  1176. }
  1177. }
  1178. void tst_QRegExp::QTBUG_7049_data()
  1179. {
  1180. QTest::addColumn<QString>("reStr");
  1181. QTest::addColumn<QString>("text");
  1182. QTest::addColumn<int>("matchIndex");
  1183. QTest::addColumn<int>("pos0");
  1184. QTest::addColumn<int>("pos1");
  1185. QTest::addColumn<int>("pos2");
  1186. QTest::addColumn<QString>("cap0");
  1187. QTest::addColumn<QString>("cap1");
  1188. QTest::addColumn<QString>("cap2");
  1189. QTest::newRow("no match")
  1190. << QString("(a) (b)") << QString("b a") << -1
  1191. << -1 << -1 << -1 << QString() << QString() << QString();
  1192. QTest::newRow("both captures match")
  1193. << QString("(a) (b)") << QString("a b") << 0
  1194. << 0 << 0 << 2 << QString("a b") << QString("a") << QString("b");
  1195. QTest::newRow("first capture matches @0")
  1196. << QString("(a*)|(b*)") << QString("axx") << 0
  1197. << 0 << 0 << -1 << QString("a") << QString("a") << QString();
  1198. QTest::newRow("second capture matches @0")
  1199. << QString("(a*)|(b*)") << QString("bxx") << 0
  1200. << 0 << -1 << 0 << QString("b") << QString() << QString("b");
  1201. QTest::newRow("first capture empty match @0")
  1202. << QString("(a*)|(b*)") << QString("xx") << 0
  1203. << 0 << -1 << -1 << QString("") << QString() << QString();
  1204. QTest::newRow("second capture empty match @0")
  1205. << QString("(a)|(b*)") << QString("xx") << 0
  1206. << 0 << -1 << -1 << QString("") << QString() << QString();
  1207. QTest::newRow("first capture matches @1")
  1208. << QString("x(?:(a*)|(b*))") << QString("-xa") << 1
  1209. << 1 << 2 << -1 << QString("xa") << QString("a") << QString();
  1210. QTest::newRow("second capture matches @1")
  1211. << QString("x(?:(a*)|(b*))") << QString("-xb") << 1
  1212. << 1 << -1 << 2 << QString("xb") << QString() << QString("b");
  1213. QTest::newRow("first capture empty match @1")
  1214. << QString("x(?:(a*)|(b*))") << QString("-xx") << 1
  1215. << 1 << -1 << -1 << QString("x") << QString() << QString();
  1216. QTest::newRow("second capture empty match @1")
  1217. << QString("x(?:(a)|(b*))") << QString("-xx") << 1
  1218. << 1 << -1 << -1 << QString("x") << QString() << QString();
  1219. QTest::newRow("first capture matches @2")
  1220. << QString("(a)|(b)") << QString("xxa") << 2
  1221. << 2 << 2 << -1 << QString("a") << QString("a") << QString();
  1222. QTest::newRow("second capture matches @2")
  1223. << QString("(a)|(b)") << QString("xxb") << 2
  1224. << 2 << -1 << 2 << QString("b") << QString() << QString("b");
  1225. QTest::newRow("no match - with options")
  1226. << QString("(a)|(b)") << QString("xx") << -1
  1227. << -1 << -1 << -1 << QString() << QString() << QString();
  1228. }
  1229. void tst_QRegExp::QTBUG_7049()
  1230. {
  1231. QFETCH( QString, reStr );
  1232. QFETCH( QString, text );
  1233. QFETCH( int, matchIndex );
  1234. QFETCH( int, pos0 );
  1235. QFETCH( int, pos1 );
  1236. QFETCH( int, pos2 );
  1237. QFETCH( QString, cap0 );
  1238. QFETCH( QString, cap1 );
  1239. QFETCH( QString, cap2 );
  1240. QRegExp re(reStr);
  1241. QCOMPARE(re.numCaptures(), 2);
  1242. QCOMPARE(re.capturedTexts().size(), 3);
  1243. QCOMPARE(re.indexIn(text), matchIndex);
  1244. QCOMPARE( re.pos(0), pos0 );
  1245. QCOMPARE( re.pos(1), pos1 );
  1246. QCOMPARE( re.pos(2), pos2 );
  1247. QCOMPARE( re.cap(0).isNull(), cap0.isNull() );
  1248. QCOMPARE( re.cap(0), cap0 );
  1249. QCOMPARE( re.cap(1).isNull(), cap1.isNull() );
  1250. QCOMPARE( re.cap(1), cap1 );
  1251. QCOMPARE( re.cap(2).isNull(), cap2.isNull() );
  1252. QCOMPARE( re.cap(2), cap2 );
  1253. }
  1254. void tst_QRegExp::interval()
  1255. {
  1256. {
  1257. QRegExp exp("a{0,1}");
  1258. QVERIFY(exp.isValid());
  1259. }
  1260. {
  1261. QRegExp exp("a{1,1}");
  1262. QVERIFY(exp.isValid());
  1263. }
  1264. {
  1265. QRegExp exp("a{1,0}");
  1266. QVERIFY(!exp.isValid());
  1267. }
  1268. }
  1269. QTEST_APPLESS_MAIN(tst_QRegExp)
  1270. #include "tst_qregexp.moc"