Skip to content

Commit db58698

Browse files
authored
Fix C++ regex term source locations for raw and encoding-prefixed literals
1 parent 9fdf8b7 commit db58698

3 files changed

Lines changed: 188 additions & 115 deletions

File tree

cpp/ql/lib/semmle/code/cpp/regex/RegexTreeView.qll

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,64 @@ private RegExpTerm seqChild(RegExp re, int start, int end, int i) {
106106
// ---------------------------------------------------------------------------
107107
// Module Impl (implements RegexTreeViewSig)
108108
// ---------------------------------------------------------------------------
109+
/**
110+
* Gets the length of the C++ encoding prefix (`L`, `u`, `U`, `u8`) at the
111+
* start of a string-literal spelling, or 0 if none is present.
112+
*
113+
* `u8` is checked before `u` so that a `u8"..."` literal is not mistakenly
114+
* seen as a `u"..."` literal.
115+
*/
116+
bindingset[spelling]
117+
private int getEncodingPrefixLength(string spelling) {
118+
if spelling.substring(0, 2) = "u8"
119+
then result = 2
120+
else
121+
if spelling.substring(0, 1) = ["L", "u", "U"]
122+
then result = 1
123+
else result = 0
124+
}
125+
126+
/**
127+
* Gets the number of characters at the start of the raw spelling of the
128+
* string literal `re` that precede its first content character. This is
129+
* the width of the encoding prefix (if any) plus the opening delimiter:
130+
* `"` for a non-raw literal, or `R"delim(` (with a possibly-empty
131+
* user-chosen `delim`) for a raw literal.
132+
*
133+
* For a plain narrow `"..."` literal this returns 1, matching the earlier
134+
* hard-coded gap.
135+
*
136+
* If the spelling cannot be recognized (for example after macro
137+
* expansion), falls back to 1 so that no location becomes empty.
138+
*/
139+
private int getContentOffset(RegExp re) {
140+
result = tryGetContentOffset(re)
141+
or
142+
not exists(tryGetContentOffset(re)) and result = 1
143+
}
144+
145+
/**
146+
* Gets the content offset of `re` when its raw spelling matches a
147+
* recognized C++ string-literal form.
148+
*/
149+
private int tryGetContentOffset(RegExp re) {
150+
exists(string spelling, int encLen |
151+
spelling = re.getValueText() and
152+
encLen = getEncodingPrefixLength(spelling)
153+
|
154+
// Raw string: `R"delim(...)delim"`. The content starts one past the
155+
// `(` that terminates the raw prefix; the delimiter is the (possibly
156+
// empty) text between the opening `"` and that `(`.
157+
spelling.charAt(encLen) = "R" and
158+
spelling.charAt(encLen + 1) = "\"" and
159+
result = spelling.indexOf("(", 0, encLen + 2) + 1
160+
or
161+
// Non-raw string: `"..."`. Content starts one past the opening `"`.
162+
spelling.charAt(encLen) = "\"" and
163+
result = encLen + 1
164+
)
165+
}
166+
109167
/** An implementation that satisfies the `RegexTreeViewSig` signature. */
110168
module Impl implements RegexTreeViewSig {
111169
// -------------------------------------------------------------------------
@@ -290,18 +348,33 @@ module Impl implements RegexTreeViewSig {
290348
/**
291349
* Holds if this term is found at the given source location.
292350
*
293-
* The location maps back to character offsets within the C++ string literal.
294-
* Because the literal's start column already accounts for the opening `"`,
295-
* we add 1 to skip the quote itself.
351+
* The location maps back to character offsets within the C++ string
352+
* literal. The gap between the literal's start column and its first
353+
* content character depends on the literal's raw spelling: it accounts
354+
* for any encoding prefix (`L`, `u`, `U`, `u8`) and for the opening
355+
* delimiter, which is a single `"` for a plain literal and `R"delim(`
356+
* (with a possibly-empty user-chosen `delim`) for a raw literal.
357+
* `getContentOffset` computes this gap from the raw spelling so that
358+
* every literal form maps to the correct source columns.
359+
*
360+
* This is an approximation that handles single-line literals: for a
361+
* literal whose content spans multiple source lines (for example a raw
362+
* string containing newlines) the reported column is a column within
363+
* the literal's start line, mirroring the documented approximations in
364+
* the Java and Python regex tree views.
296365
*/
297366
predicate hasLocationInfo(
298367
string filepath, int startline, int startcolumn, int endline, int endcolumn
299368
) {
300-
exists(Location loc | loc = re.getLocation() |
369+
exists(Location loc, int contentOffset |
370+
loc = re.getLocation() and
371+
contentOffset = getContentOffset(re)
372+
|
301373
loc.hasLocationInfo(filepath, startline, _, _, _) and
302-
startcolumn = loc.getStartColumn() + start + 1 and
374+
startcolumn = loc.getStartColumn() + contentOffset + start and
303375
endline = startline and
304-
endcolumn = loc.getStartColumn() + end // end is exclusive, so -1+1 = 0 offset
376+
// `end` is exclusive, so subtract 1 to point at the last character.
377+
endcolumn = loc.getStartColumn() + contentOffset + end - 1
305378
)
306379
}
307380

cpp/ql/test/library-tests/regex/locations.expected

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -673,56 +673,56 @@
673673
| b | RegExpNormalChar | test.cpp | 430 | 22 | 430 | 22 | 19 | 2 | 3 |
674674
| \\s | RegExpCharacterClassEscape | test.cpp | 431 | 20 | 431 | 21 | 19 | 0 | 2 |
675675
| \\s+ | RegExpPlus | test.cpp | 431 | 20 | 431 | 22 | 19 | 0 | 3 |
676-
| a | RegExpConstant | test.cpp | 436 | 20 | 436 | 20 | 19 | 0 | 1 |
677-
| a | RegExpNormalChar | test.cpp | 436 | 20 | 436 | 20 | 19 | 0 | 1 |
678-
| a+ | RegExpPlus | test.cpp | 436 | 20 | 436 | 21 | 19 | 0 | 2 |
679-
| a+b | RegExpSequence | test.cpp | 436 | 20 | 436 | 22 | 19 | 0 | 3 |
680-
| b | RegExpConstant | test.cpp | 436 | 22 | 436 | 22 | 19 | 2 | 3 |
681-
| b | RegExpNormalChar | test.cpp | 436 | 22 | 436 | 22 | 19 | 2 | 3 |
682-
| \\s | RegExpCharacterClassEscape | test.cpp | 437 | 20 | 437 | 21 | 19 | 0 | 2 |
683-
| \\s+ | RegExpPlus | test.cpp | 437 | 20 | 437 | 22 | 19 | 0 | 3 |
684-
| \\s+$ | RegExpSequence | test.cpp | 437 | 20 | 437 | 23 | 19 | 0 | 4 |
685-
| $ | RegExpDollar | test.cpp | 437 | 23 | 437 | 23 | 19 | 3 | 4 |
686-
| \\( | RegExpConstant | test.cpp | 438 | 20 | 438 | 21 | 19 | 0 | 2 |
687-
| \\( | RegExpEscape | test.cpp | 438 | 20 | 438 | 21 | 19 | 0 | 2 |
688-
| \\(([,\\w]+)+\\)$ | RegExpSequence | test.cpp | 438 | 20 | 438 | 33 | 19 | 0 | 14 |
689-
| ([,\\w]+) | RegExpGroup | test.cpp | 438 | 22 | 438 | 29 | 19 | 2 | 10 |
690-
| ([,\\w]+)+ | RegExpPlus | test.cpp | 438 | 22 | 438 | 30 | 19 | 2 | 11 |
691-
| [,\\w] | RegExpCharacterClass | test.cpp | 438 | 23 | 438 | 27 | 19 | 3 | 8 |
692-
| [,\\w]+ | RegExpPlus | test.cpp | 438 | 23 | 438 | 28 | 19 | 3 | 9 |
693-
| , | RegExpConstant | test.cpp | 438 | 24 | 438 | 24 | 19 | 4 | 5 |
694-
| , | RegExpNormalChar | test.cpp | 438 | 24 | 438 | 24 | 19 | 4 | 5 |
695-
| \\w | RegExpCharacterClassEscape | test.cpp | 438 | 25 | 438 | 26 | 19 | 5 | 7 |
696-
| \\) | RegExpConstant | test.cpp | 438 | 31 | 438 | 32 | 19 | 11 | 13 |
697-
| \\) | RegExpEscape | test.cpp | 438 | 31 | 438 | 32 | 19 | 11 | 13 |
698-
| $ | RegExpDollar | test.cpp | 438 | 33 | 438 | 33 | 19 | 13 | 14 |
699-
| a | RegExpConstant | test.cpp | 442 | 20 | 442 | 20 | 19 | 0 | 1 |
700-
| a | RegExpNormalChar | test.cpp | 442 | 20 | 442 | 20 | 19 | 0 | 1 |
701-
| a+ | RegExpPlus | test.cpp | 442 | 20 | 442 | 21 | 19 | 0 | 2 |
702-
| a+b | RegExpSequence | test.cpp | 442 | 20 | 442 | 22 | 19 | 0 | 3 |
703-
| b | RegExpConstant | test.cpp | 442 | 22 | 442 | 22 | 19 | 2 | 3 |
704-
| b | RegExpNormalChar | test.cpp | 442 | 22 | 442 | 22 | 19 | 2 | 3 |
705-
| a | RegExpConstant | test.cpp | 446 | 21 | 446 | 21 | 20 | 0 | 1 |
706-
| a | RegExpNormalChar | test.cpp | 446 | 21 | 446 | 21 | 20 | 0 | 1 |
707-
| a+ | RegExpPlus | test.cpp | 446 | 21 | 446 | 22 | 20 | 0 | 2 |
708-
| a+b | RegExpSequence | test.cpp | 446 | 21 | 446 | 23 | 20 | 0 | 3 |
709-
| b | RegExpConstant | test.cpp | 446 | 23 | 446 | 23 | 20 | 2 | 3 |
710-
| b | RegExpNormalChar | test.cpp | 446 | 23 | 446 | 23 | 20 | 2 | 3 |
711-
| a | RegExpConstant | test.cpp | 447 | 21 | 447 | 21 | 20 | 0 | 1 |
712-
| a | RegExpNormalChar | test.cpp | 447 | 21 | 447 | 21 | 20 | 0 | 1 |
713-
| a+ | RegExpPlus | test.cpp | 447 | 21 | 447 | 22 | 20 | 0 | 2 |
714-
| a+b | RegExpSequence | test.cpp | 447 | 21 | 447 | 23 | 20 | 0 | 3 |
715-
| b | RegExpConstant | test.cpp | 447 | 23 | 447 | 23 | 20 | 2 | 3 |
716-
| b | RegExpNormalChar | test.cpp | 447 | 23 | 447 | 23 | 20 | 2 | 3 |
717-
| a | RegExpConstant | test.cpp | 459 | 20 | 459 | 20 | 19 | 0 | 1 |
718-
| a | RegExpNormalChar | test.cpp | 459 | 20 | 459 | 20 | 19 | 0 | 1 |
719-
| a+ | RegExpPlus | test.cpp | 459 | 20 | 459 | 21 | 19 | 0 | 2 |
720-
| a+b | RegExpSequence | test.cpp | 459 | 20 | 459 | 22 | 19 | 0 | 3 |
721-
| b | RegExpConstant | test.cpp | 459 | 22 | 459 | 22 | 19 | 2 | 3 |
722-
| b | RegExpNormalChar | test.cpp | 459 | 22 | 459 | 22 | 19 | 2 | 3 |
723-
| a | RegExpConstant | test.cpp | 460 | 20 | 460 | 20 | 19 | 0 | 1 |
724-
| a | RegExpNormalChar | test.cpp | 460 | 20 | 460 | 20 | 19 | 0 | 1 |
725-
| a+ | RegExpPlus | test.cpp | 460 | 20 | 460 | 21 | 19 | 0 | 2 |
726-
| a+b | RegExpSequence | test.cpp | 460 | 20 | 460 | 22 | 19 | 0 | 3 |
727-
| b | RegExpConstant | test.cpp | 460 | 22 | 460 | 22 | 19 | 2 | 3 |
728-
| b | RegExpNormalChar | test.cpp | 460 | 22 | 460 | 22 | 19 | 2 | 3 |
676+
| a | RegExpConstant | test.cpp | 436 | 22 | 436 | 22 | 19 | 0 | 1 |
677+
| a | RegExpNormalChar | test.cpp | 436 | 22 | 436 | 22 | 19 | 0 | 1 |
678+
| a+ | RegExpPlus | test.cpp | 436 | 22 | 436 | 23 | 19 | 0 | 2 |
679+
| a+b | RegExpSequence | test.cpp | 436 | 22 | 436 | 24 | 19 | 0 | 3 |
680+
| b | RegExpConstant | test.cpp | 436 | 24 | 436 | 24 | 19 | 2 | 3 |
681+
| b | RegExpNormalChar | test.cpp | 436 | 24 | 436 | 24 | 19 | 2 | 3 |
682+
| \\s | RegExpCharacterClassEscape | test.cpp | 437 | 22 | 437 | 23 | 19 | 0 | 2 |
683+
| \\s+ | RegExpPlus | test.cpp | 437 | 22 | 437 | 24 | 19 | 0 | 3 |
684+
| \\s+$ | RegExpSequence | test.cpp | 437 | 22 | 437 | 25 | 19 | 0 | 4 |
685+
| $ | RegExpDollar | test.cpp | 437 | 25 | 437 | 25 | 19 | 3 | 4 |
686+
| \\( | RegExpConstant | test.cpp | 438 | 22 | 438 | 23 | 19 | 0 | 2 |
687+
| \\( | RegExpEscape | test.cpp | 438 | 22 | 438 | 23 | 19 | 0 | 2 |
688+
| \\(([,\\w]+)+\\)$ | RegExpSequence | test.cpp | 438 | 22 | 438 | 35 | 19 | 0 | 14 |
689+
| ([,\\w]+) | RegExpGroup | test.cpp | 438 | 24 | 438 | 31 | 19 | 2 | 10 |
690+
| ([,\\w]+)+ | RegExpPlus | test.cpp | 438 | 24 | 438 | 32 | 19 | 2 | 11 |
691+
| [,\\w] | RegExpCharacterClass | test.cpp | 438 | 25 | 438 | 29 | 19 | 3 | 8 |
692+
| [,\\w]+ | RegExpPlus | test.cpp | 438 | 25 | 438 | 30 | 19 | 3 | 9 |
693+
| , | RegExpConstant | test.cpp | 438 | 26 | 438 | 26 | 19 | 4 | 5 |
694+
| , | RegExpNormalChar | test.cpp | 438 | 26 | 438 | 26 | 19 | 4 | 5 |
695+
| \\w | RegExpCharacterClassEscape | test.cpp | 438 | 27 | 438 | 28 | 19 | 5 | 7 |
696+
| \\) | RegExpConstant | test.cpp | 438 | 33 | 438 | 34 | 19 | 11 | 13 |
697+
| \\) | RegExpEscape | test.cpp | 438 | 33 | 438 | 34 | 19 | 11 | 13 |
698+
| $ | RegExpDollar | test.cpp | 438 | 35 | 438 | 35 | 19 | 13 | 14 |
699+
| a | RegExpConstant | test.cpp | 442 | 23 | 442 | 23 | 19 | 0 | 1 |
700+
| a | RegExpNormalChar | test.cpp | 442 | 23 | 442 | 23 | 19 | 0 | 1 |
701+
| a+ | RegExpPlus | test.cpp | 442 | 23 | 442 | 24 | 19 | 0 | 2 |
702+
| a+b | RegExpSequence | test.cpp | 442 | 23 | 442 | 25 | 19 | 0 | 3 |
703+
| b | RegExpConstant | test.cpp | 442 | 25 | 442 | 25 | 19 | 2 | 3 |
704+
| b | RegExpNormalChar | test.cpp | 442 | 25 | 442 | 25 | 19 | 2 | 3 |
705+
| a | RegExpConstant | test.cpp | 446 | 22 | 446 | 22 | 20 | 0 | 1 |
706+
| a | RegExpNormalChar | test.cpp | 446 | 22 | 446 | 22 | 20 | 0 | 1 |
707+
| a+ | RegExpPlus | test.cpp | 446 | 22 | 446 | 23 | 20 | 0 | 2 |
708+
| a+b | RegExpSequence | test.cpp | 446 | 22 | 446 | 24 | 20 | 0 | 3 |
709+
| b | RegExpConstant | test.cpp | 446 | 24 | 446 | 24 | 20 | 2 | 3 |
710+
| b | RegExpNormalChar | test.cpp | 446 | 24 | 446 | 24 | 20 | 2 | 3 |
711+
| a | RegExpConstant | test.cpp | 447 | 24 | 447 | 24 | 20 | 0 | 1 |
712+
| a | RegExpNormalChar | test.cpp | 447 | 24 | 447 | 24 | 20 | 0 | 1 |
713+
| a+ | RegExpPlus | test.cpp | 447 | 24 | 447 | 25 | 20 | 0 | 2 |
714+
| a+b | RegExpSequence | test.cpp | 447 | 24 | 447 | 26 | 20 | 0 | 3 |
715+
| b | RegExpConstant | test.cpp | 447 | 26 | 447 | 26 | 20 | 2 | 3 |
716+
| b | RegExpNormalChar | test.cpp | 447 | 26 | 447 | 26 | 20 | 2 | 3 |
717+
| a | RegExpConstant | test.cpp | 459 | 22 | 459 | 22 | 19 | 0 | 1 |
718+
| a | RegExpNormalChar | test.cpp | 459 | 22 | 459 | 22 | 19 | 0 | 1 |
719+
| a+ | RegExpPlus | test.cpp | 459 | 22 | 459 | 23 | 19 | 0 | 2 |
720+
| a+b | RegExpSequence | test.cpp | 459 | 22 | 459 | 24 | 19 | 0 | 3 |
721+
| b | RegExpConstant | test.cpp | 459 | 24 | 459 | 24 | 19 | 2 | 3 |
722+
| b | RegExpNormalChar | test.cpp | 459 | 24 | 459 | 24 | 19 | 2 | 3 |
723+
| a | RegExpConstant | test.cpp | 460 | 24 | 460 | 24 | 19 | 0 | 1 |
724+
| a | RegExpNormalChar | test.cpp | 460 | 24 | 460 | 24 | 19 | 0 | 1 |
725+
| a+ | RegExpPlus | test.cpp | 460 | 24 | 460 | 25 | 19 | 0 | 2 |
726+
| a+b | RegExpSequence | test.cpp | 460 | 24 | 460 | 26 | 19 | 0 | 3 |
727+
| b | RegExpConstant | test.cpp | 460 | 26 | 460 | 26 | 19 | 2 | 3 |
728+
| b | RegExpNormalChar | test.cpp | 460 | 26 | 460 | 26 | 19 | 2 | 3 |

cpp/ql/test/library-tests/regex/regexp.expected

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ groupNumber
2727
| test.cpp:361:19:361:32 | ([[:alpha:]]+) | 1 |
2828
| test.cpp:415:21:415:58 | ([[:alpha:]]+[[:digit:]]*[[:space:]]?) | 1 |
2929
| test.cpp:415:60:415:85 | ([[:punct:]]\|[[:xdigit:]]) | 2 |
30-
| test.cpp:438:22:438:29 | ([,\\w]+) | 1 |
30+
| test.cpp:438:24:438:31 | ([,\\w]+) | 1 |
3131
term
3232
| test.cpp:133:20:133:20 | a | RegExpConstant,RegExpNormalChar |
3333
| test.cpp:133:20:133:21 | a* | RegExpStar |
@@ -530,44 +530,44 @@ term
530530
| test.cpp:430:22:430:22 | b | RegExpConstant,RegExpNormalChar |
531531
| test.cpp:431:20:431:21 | \\s | RegExpCharacterClassEscape |
532532
| test.cpp:431:20:431:22 | \\s+ | RegExpPlus |
533-
| test.cpp:436:20:436:20 | a | RegExpConstant,RegExpNormalChar |
534-
| test.cpp:436:20:436:21 | a+ | RegExpPlus |
535-
| test.cpp:436:20:436:22 | a+b | RegExpSequence |
536-
| test.cpp:436:22:436:22 | b | RegExpConstant,RegExpNormalChar |
537-
| test.cpp:437:20:437:21 | \\s | RegExpCharacterClassEscape |
538-
| test.cpp:437:20:437:22 | \\s+ | RegExpPlus |
539-
| test.cpp:437:20:437:23 | \\s+$ | RegExpSequence |
540-
| test.cpp:437:23:437:23 | $ | RegExpDollar |
541-
| test.cpp:438:20:438:21 | \\( | RegExpConstant,RegExpEscape |
542-
| test.cpp:438:20:438:33 | \\(([,\\w]+)+\\)$ | RegExpSequence |
543-
| test.cpp:438:22:438:29 | ([,\\w]+) | RegExpGroup |
544-
| test.cpp:438:22:438:30 | ([,\\w]+)+ | RegExpPlus |
545-
| test.cpp:438:23:438:27 | [,\\w] | RegExpCharacterClass |
546-
| test.cpp:438:23:438:28 | [,\\w]+ | RegExpPlus |
547-
| test.cpp:438:24:438:24 | , | RegExpConstant,RegExpNormalChar |
548-
| test.cpp:438:25:438:26 | \\w | RegExpCharacterClassEscape |
549-
| test.cpp:438:31:438:32 | \\) | RegExpConstant,RegExpEscape |
550-
| test.cpp:438:33:438:33 | $ | RegExpDollar |
551-
| test.cpp:442:20:442:20 | a | RegExpConstant,RegExpNormalChar |
552-
| test.cpp:442:20:442:21 | a+ | RegExpPlus |
553-
| test.cpp:442:20:442:22 | a+b | RegExpSequence |
554-
| test.cpp:442:22:442:22 | b | RegExpConstant,RegExpNormalChar |
555-
| test.cpp:446:21:446:21 | a | RegExpConstant,RegExpNormalChar |
556-
| test.cpp:446:21:446:22 | a+ | RegExpPlus |
557-
| test.cpp:446:21:446:23 | a+b | RegExpSequence |
558-
| test.cpp:446:23:446:23 | b | RegExpConstant,RegExpNormalChar |
559-
| test.cpp:447:21:447:21 | a | RegExpConstant,RegExpNormalChar |
560-
| test.cpp:447:21:447:22 | a+ | RegExpPlus |
561-
| test.cpp:447:21:447:23 | a+b | RegExpSequence |
562-
| test.cpp:447:23:447:23 | b | RegExpConstant,RegExpNormalChar |
563-
| test.cpp:459:20:459:20 | a | RegExpConstant,RegExpNormalChar |
564-
| test.cpp:459:20:459:21 | a+ | RegExpPlus |
565-
| test.cpp:459:20:459:22 | a+b | RegExpSequence |
566-
| test.cpp:459:22:459:22 | b | RegExpConstant,RegExpNormalChar |
567-
| test.cpp:460:20:460:20 | a | RegExpConstant,RegExpNormalChar |
568-
| test.cpp:460:20:460:21 | a+ | RegExpPlus |
569-
| test.cpp:460:20:460:22 | a+b | RegExpSequence |
570-
| test.cpp:460:22:460:22 | b | RegExpConstant,RegExpNormalChar |
533+
| test.cpp:436:22:436:22 | a | RegExpConstant,RegExpNormalChar |
534+
| test.cpp:436:22:436:23 | a+ | RegExpPlus |
535+
| test.cpp:436:22:436:24 | a+b | RegExpSequence |
536+
| test.cpp:436:24:436:24 | b | RegExpConstant,RegExpNormalChar |
537+
| test.cpp:437:22:437:23 | \\s | RegExpCharacterClassEscape |
538+
| test.cpp:437:22:437:24 | \\s+ | RegExpPlus |
539+
| test.cpp:437:22:437:25 | \\s+$ | RegExpSequence |
540+
| test.cpp:437:25:437:25 | $ | RegExpDollar |
541+
| test.cpp:438:22:438:23 | \\( | RegExpConstant,RegExpEscape |
542+
| test.cpp:438:22:438:35 | \\(([,\\w]+)+\\)$ | RegExpSequence |
543+
| test.cpp:438:24:438:31 | ([,\\w]+) | RegExpGroup |
544+
| test.cpp:438:24:438:32 | ([,\\w]+)+ | RegExpPlus |
545+
| test.cpp:438:25:438:29 | [,\\w] | RegExpCharacterClass |
546+
| test.cpp:438:25:438:30 | [,\\w]+ | RegExpPlus |
547+
| test.cpp:438:26:438:26 | , | RegExpConstant,RegExpNormalChar |
548+
| test.cpp:438:27:438:28 | \\w | RegExpCharacterClassEscape |
549+
| test.cpp:438:33:438:34 | \\) | RegExpConstant,RegExpEscape |
550+
| test.cpp:438:35:438:35 | $ | RegExpDollar |
551+
| test.cpp:442:23:442:23 | a | RegExpConstant,RegExpNormalChar |
552+
| test.cpp:442:23:442:24 | a+ | RegExpPlus |
553+
| test.cpp:442:23:442:25 | a+b | RegExpSequence |
554+
| test.cpp:442:25:442:25 | b | RegExpConstant,RegExpNormalChar |
555+
| test.cpp:446:22:446:22 | a | RegExpConstant,RegExpNormalChar |
556+
| test.cpp:446:22:446:23 | a+ | RegExpPlus |
557+
| test.cpp:446:22:446:24 | a+b | RegExpSequence |
558+
| test.cpp:446:24:446:24 | b | RegExpConstant,RegExpNormalChar |
559+
| test.cpp:447:24:447:24 | a | RegExpConstant,RegExpNormalChar |
560+
| test.cpp:447:24:447:25 | a+ | RegExpPlus |
561+
| test.cpp:447:24:447:26 | a+b | RegExpSequence |
562+
| test.cpp:447:26:447:26 | b | RegExpConstant,RegExpNormalChar |
563+
| test.cpp:459:22:459:22 | a | RegExpConstant,RegExpNormalChar |
564+
| test.cpp:459:22:459:23 | a+ | RegExpPlus |
565+
| test.cpp:459:22:459:24 | a+b | RegExpSequence |
566+
| test.cpp:459:24:459:24 | b | RegExpConstant,RegExpNormalChar |
567+
| test.cpp:460:24:460:24 | a | RegExpConstant,RegExpNormalChar |
568+
| test.cpp:460:24:460:25 | a+ | RegExpPlus |
569+
| test.cpp:460:24:460:26 | a+b | RegExpSequence |
570+
| test.cpp:460:26:460:26 | b | RegExpConstant,RegExpNormalChar |
571571
regExpNormalCharValue
572572
| test.cpp:133:20:133:20 | a | a |
573573
| test.cpp:133:22:133:22 | b | b |
@@ -765,20 +765,20 @@ regExpNormalCharValue
765765
| test.cpp:430:20:430:20 | a | a |
766766
| test.cpp:430:22:430:22 | b | b |
767767
| test.cpp:431:20:431:21 | \\s | s |
768-
| test.cpp:436:20:436:20 | a | a |
769-
| test.cpp:436:22:436:22 | b | b |
770-
| test.cpp:437:20:437:21 | \\s | s |
771-
| test.cpp:438:20:438:21 | \\( | ( |
772-
| test.cpp:438:24:438:24 | , | , |
773-
| test.cpp:438:25:438:26 | \\w | w |
774-
| test.cpp:438:31:438:32 | \\) | ) |
775-
| test.cpp:442:20:442:20 | a | a |
776-
| test.cpp:442:22:442:22 | b | b |
777-
| test.cpp:446:21:446:21 | a | a |
778-
| test.cpp:446:23:446:23 | b | b |
779-
| test.cpp:447:21:447:21 | a | a |
780-
| test.cpp:447:23:447:23 | b | b |
781-
| test.cpp:459:20:459:20 | a | a |
782-
| test.cpp:459:22:459:22 | b | b |
783-
| test.cpp:460:20:460:20 | a | a |
784-
| test.cpp:460:22:460:22 | b | b |
768+
| test.cpp:436:22:436:22 | a | a |
769+
| test.cpp:436:24:436:24 | b | b |
770+
| test.cpp:437:22:437:23 | \\s | s |
771+
| test.cpp:438:22:438:23 | \\( | ( |
772+
| test.cpp:438:26:438:26 | , | , |
773+
| test.cpp:438:27:438:28 | \\w | w |
774+
| test.cpp:438:33:438:34 | \\) | ) |
775+
| test.cpp:442:23:442:23 | a | a |
776+
| test.cpp:442:25:442:25 | b | b |
777+
| test.cpp:446:22:446:22 | a | a |
778+
| test.cpp:446:24:446:24 | b | b |
779+
| test.cpp:447:24:447:24 | a | a |
780+
| test.cpp:447:26:447:26 | b | b |
781+
| test.cpp:459:22:459:22 | a | a |
782+
| test.cpp:459:24:459:24 | b | b |
783+
| test.cpp:460:24:460:24 | a | a |
784+
| test.cpp:460:26:460:26 | b | b |

0 commit comments

Comments
 (0)