Swift: Add tests for parse modes.

This commit is contained in:
Geoffrey White
2023-07-10 17:00:30 +01:00
parent 7748a45c2f
commit a7a609d591
2 changed files with 132 additions and 68 deletions

View File

@@ -6319,167 +6319,204 @@ redos_variants.swift:
# 579| [RegExpConstant, RegExpNormalChar] c
regex.swift:
# 103| [RegExpDot] .
# 110| [RegExpDot] .
# 103| [RegExpStar] .*
# 110| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .
# 125| [RegExpDot] .
# 132| [RegExpDot] .
# 125| [RegExpStar] .*
# 132| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .
# 142| [RegExpDot] .
# 149| [RegExpDot] .
# 142| [RegExpStar] .*
# 149| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .
# 142| [RegExpDot] .
# 149| [RegExpDot] .
# 142| [RegExpPlus] .+
# 149| [RegExpPlus] .+
#-----| 0 -> [RegExpDot] .
# 149| [RegExpGroup] ([\w.]+)
# 156| [RegExpGroup] ([\w.]+)
#-----| 0 -> [RegExpPlus] [\w.]+
# 149| [RegExpStar] ([\w.]+)*
# 156| [RegExpStar] ([\w.]+)*
#-----| 0 -> [RegExpGroup] ([\w.]+)
# 149| [RegExpCharacterClass] [\w.]
# 156| [RegExpCharacterClass] [\w.]
#-----| 0 -> [RegExpCharacterClassEscape] \w
#-----| 1 -> [RegExpConstant, RegExpNormalChar] .
# 149| [RegExpPlus] [\w.]+
# 156| [RegExpPlus] [\w.]+
#-----| 0 -> [RegExpCharacterClass] [\w.]
# 149| [RegExpCharacterClassEscape] \w
# 156| [RegExpCharacterClassEscape] \w
# 149| [RegExpConstant, RegExpNormalChar] .
# 156| [RegExpConstant, RegExpNormalChar] .
# 156| [RegExpConstant, RegExpNormalChar]
# 156|
# 163| [RegExpConstant, RegExpNormalChar]
# 163|
# 157| [RegExpConstant, RegExpEscape] \n
# 164| [RegExpConstant, RegExpEscape] \n
# 158| [RegExpConstant, RegExpEscape] \n
# 165| [RegExpConstant, RegExpEscape] \n
# 168| [RegExpConstant, RegExpNormalChar] aa
# 175| [RegExpConstant, RegExpNormalChar] aa
# 168| [RegExpAlt] aa|bb
# 175| [RegExpAlt] aa|bb
#-----| 0 -> [RegExpConstant, RegExpNormalChar] aa
#-----| 1 -> [RegExpConstant, RegExpNormalChar] bb
# 168| [RegExpConstant, RegExpNormalChar] bb
# 175| [RegExpConstant, RegExpNormalChar] bb
# 172| [RegExpConstant, RegExpNormalChar] aa
# 179| [RegExpConstant, RegExpNormalChar] aa
# 172| [RegExpAlt] aa|
# 172| bb
# 179| [RegExpAlt] aa|
# 179| bb
#-----| 0 -> [RegExpConstant, RegExpNormalChar] aa
#-----| 1 -> [RegExpConstant, RegExpNormalChar]
#-----| bb
# 172| [RegExpConstant, RegExpNormalChar]
# 172| bb
# 179| [RegExpConstant, RegExpNormalChar]
# 179| bb
# 180| [RegExpCharacterClass] [a-z]
# 187| [RegExpCharacterClass] [a-z]
#-----| 0 -> [RegExpCharacterRange] a-z
# 180| [RegExpConstant, RegExpNormalChar] a
# 187| [RegExpConstant, RegExpNormalChar] a
# 180| [RegExpCharacterRange] a-z
# 187| [RegExpCharacterRange] a-z
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
#-----| 1 -> [RegExpConstant, RegExpNormalChar] z
# 180| [RegExpConstant, RegExpNormalChar] z
# 187| [RegExpConstant, RegExpNormalChar] z
# 181| [RegExpCharacterClass] [a-zA-Z]
# 188| [RegExpCharacterClass] [a-zA-Z]
#-----| 0 -> [RegExpCharacterRange] a-z
#-----| 1 -> [RegExpCharacterRange] A-Z
# 181| [RegExpConstant, RegExpNormalChar] a
# 188| [RegExpConstant, RegExpNormalChar] a
# 181| [RegExpCharacterRange] a-z
# 188| [RegExpCharacterRange] a-z
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
#-----| 1 -> [RegExpConstant, RegExpNormalChar] z
# 181| [RegExpConstant, RegExpNormalChar] z
# 188| [RegExpConstant, RegExpNormalChar] z
# 181| [RegExpConstant, RegExpNormalChar] A
# 188| [RegExpConstant, RegExpNormalChar] A
# 181| [RegExpCharacterRange] A-Z
# 188| [RegExpCharacterRange] A-Z
#-----| 0 -> [RegExpConstant, RegExpNormalChar] A
#-----| 1 -> [RegExpConstant, RegExpNormalChar] Z
# 181| [RegExpConstant, RegExpNormalChar] Z
# 188| [RegExpConstant, RegExpNormalChar] Z
# 184| [RegExpCharacterClass] [a-]
# 191| [RegExpCharacterClass] [a-]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
#-----| 1 -> [RegExpConstant, RegExpNormalChar] -
# 184| [RegExpConstant, RegExpNormalChar] a
# 191| [RegExpConstant, RegExpNormalChar] a
# 184| [RegExpConstant, RegExpNormalChar] -
# 191| [RegExpConstant, RegExpNormalChar] -
# 185| [RegExpCharacterClass] [-a]
# 192| [RegExpCharacterClass] [-a]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] -
#-----| 1 -> [RegExpConstant, RegExpNormalChar] a
# 185| [RegExpConstant, RegExpNormalChar] -
# 192| [RegExpConstant, RegExpNormalChar] -
# 185| [RegExpConstant, RegExpNormalChar] a
# 192| [RegExpConstant, RegExpNormalChar] a
# 186| [RegExpCharacterClass] [-]
# 193| [RegExpCharacterClass] [-]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] -
# 186| [RegExpConstant, RegExpNormalChar] -
# 193| [RegExpConstant, RegExpNormalChar] -
# 187| [RegExpCharacterClass] [*]
# 194| [RegExpCharacterClass] [*]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] *
# 187| [RegExpConstant, RegExpNormalChar] *
# 194| [RegExpConstant, RegExpNormalChar] *
# 188| [RegExpCharacterClass] [^a]
# 195| [RegExpCharacterClass] [^a]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
# 188| [RegExpConstant, RegExpNormalChar] a
# 195| [RegExpConstant, RegExpNormalChar] a
# 189| [RegExpCharacterClass] [a^]
# 196| [RegExpCharacterClass] [a^]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] a
#-----| 1 -> [RegExpConstant, RegExpNormalChar] ^
# 189| [RegExpConstant, RegExpNormalChar] a
# 196| [RegExpConstant, RegExpNormalChar] a
# 189| [RegExpConstant, RegExpNormalChar] ^
# 196| [RegExpConstant, RegExpNormalChar] ^
# 190| [RegExpCharacterClass] [\\]
# 197| [RegExpCharacterClass] [\\]
#-----| 0 -> [RegExpConstant, RegExpEscape] \\
# 190| [RegExpConstant, RegExpEscape] \\
# 197| [RegExpConstant, RegExpEscape] \\
# 191| [RegExpCharacterClass] [\\\]]
# 198| [RegExpCharacterClass] [\\\]]
#-----| 0 -> [RegExpConstant, RegExpEscape] \\
#-----| 1 -> [RegExpConstant, RegExpEscape] \]
# 191| [RegExpConstant, RegExpEscape] \\
# 198| [RegExpConstant, RegExpEscape] \\
# 191| [RegExpConstant, RegExpEscape] \]
# 198| [RegExpConstant, RegExpEscape] \]
# 192| [RegExpCharacterClass] [:]
# 199| [RegExpCharacterClass] [:]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] :
# 192| [RegExpConstant, RegExpNormalChar] :
# 199| [RegExpConstant, RegExpNormalChar] :
# 193| [RegExpNamedCharacterProperty] [:digit:]
# 200| [RegExpNamedCharacterProperty] [:digit:]
# 194| [RegExpNamedCharacterProperty] [:alnum:]
# 201| [RegExpNamedCharacterProperty] [:alnum:]
# 197| [RegExpCharacterClass] []a]
# 204| [RegExpCharacterClass] []a]
#-----| 0 -> [RegExpConstant, RegExpNormalChar] ]
#-----| 1 -> [RegExpConstant, RegExpNormalChar] a
# 197| [RegExpConstant, RegExpNormalChar] ]
# 204| [RegExpConstant, RegExpNormalChar] ]
# 197| [RegExpConstant, RegExpNormalChar] a
# 204| [RegExpConstant, RegExpNormalChar] a
# 198| [RegExpNamedCharacterProperty] [:aaaaa:]
# 205| [RegExpNamedCharacterProperty] [:aaaaa:]
# 209| [RegExpConstant, RegExpNormalChar] i
# 209| [RegExpConstant, RegExpNormalChar] abc
# 210| [RegExpConstant, RegExpNormalChar] s
# 210| [RegExpConstant, RegExpNormalChar] abc
# 211| [RegExpConstant, RegExpNormalChar] is
# 211| [RegExpConstant, RegExpNormalChar] abc
# 213| [RegExpConstant, RegExpNormalChar] abc
# 214| [RegExpConstant, RegExpNormalChar] abc
# 215| [RegExpConstant, RegExpNormalChar] abc
# 216| [RegExpConstant, RegExpNormalChar] abc
# 217| [RegExpConstant, RegExpNormalChar] abc
# 219| [RegExpDot] .
# 219| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .
# 220| [RegExpDot] .
# 220| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .
# 221| [RegExpDot] .
# 221| [RegExpStar] .*
#-----| 0 -> [RegExpDot] .

View File

@@ -17,9 +17,12 @@ struct Regex<Output> : RegexComponent {
init(_ pattern: String) throws where Output == AnyRegexOutput { }
func firstMatch(in string: String) throws -> Regex<Output>.Match? { return nil}
func prefixMatch(in string: String) throws -> Regex<Output>.Match? { return nil}
func wholeMatch(in string: String) throws -> Regex<Output>.Match? { return nil}
func ignoresCase(_ ignoresCase: Bool = true) -> Regex<Regex<Output>.RegexOutput> { return self }
func dotMatchesNewlines(_ dotMatchesNewlines: Bool = true) -> Regex<Regex<Output>.RegexOutput> { return self }
func firstMatch(in string: String) throws -> Regex<Output>.Match? { return nil }
func prefixMatch(in string: String) throws -> Regex<Output>.Match? { return nil }
func wholeMatch(in string: String) throws -> Regex<Output>.Match? { return nil }
typealias RegexOutput = Output
}
@@ -49,6 +52,7 @@ class NSString : NSObject {
var rawValue: UInt
static var regularExpression: NSString.CompareOptions { get { return CompareOptions(rawValue: 1) } }
static var caseInsensitive: NSString.CompareOptions { get { return CompareOptions(rawValue: 2) } }
}
convenience init(string aString: String) { self.init() }
@@ -76,6 +80,9 @@ class NSTextCheckingResult : NSObject {
class NSRegularExpression : NSObject {
struct Options : OptionSet {
var rawValue: UInt
static var caseInsensitive: NSRegularExpression.Options { get { return Options(rawValue: 1) } }
static var dotMatchesLineSeparators: NSRegularExpression.Options { get { return Options(rawValue: 2) } }
}
struct MatchingOptions : OptionSet {
@@ -196,4 +203,24 @@ func myRegexpMethodsTests(b: Bool, str_unknown: String) throws {
// invalid (Swift doesn't like these regexs)
_ = try Regex("[]a]").firstMatch(in: input) // this is valid in other regex implementations, and is likely harmless to accept
_ = try Regex("[:aaaaa:]").firstMatch(in: input) // $ hasParseFailure
// --- parse modes ---
_ = try Regex("(?i)abc").firstMatch(in: input) // $ input=input modes=IGNORECASE regex=(?i)abc SPURIOUS: hasParseFailure
_ = try Regex("(?s)abc").firstMatch(in: input) // $ input=input modes=DOTALL regex=(?s)abc SPURIOUS: $hasParseFailure
_ = try Regex("(?is)abc").firstMatch(in: input) // $ input=input regex=(?is)abc MISSING: modes="DOTALL | IGNORECASE" SPURIOUS: modes=IGNORECASE $hasParseFailure
_ = try Regex("abc").dotMatchesNewlines(true).firstMatch(in: input) // $ input=input regex=abc MISSING: modes=DOTALL
_ = try Regex("abc").dotMatchesNewlines(false).firstMatch(in: input) // $ input=input regex=abc
_ = try Regex("abc").dotMatchesNewlines(true).dotMatchesNewlines(false).firstMatch(in: input) // $ input=input regex=abc
_ = try Regex("abc").dotMatchesNewlines(false).dotMatchesNewlines(true).firstMatch(in: input) // $ input=input regex=abc MISSING: modes=DOTALL
_ = try Regex("abc").dotMatchesNewlines().ignoresCase().firstMatch(in: input) // $ input=input regex=abc MISSING: modes="DOTALL | IGNORECASE"
_ = try NSRegularExpression(pattern: ".*", options: .caseInsensitive).firstMatch(in: input, range: NSMakeRange(0, input.utf16.count)) // $ regex=.* input=input MISSING: modes=IGNORECASE
_ = try NSRegularExpression(pattern: ".*", options: .dotMatchesLineSeparators).firstMatch(in: input, range: NSMakeRange(0, input.utf16.count)) // $ regex=.* input=input MISSING: modes=DOTALL
_ = try NSRegularExpression(pattern: ".*", options: [.caseInsensitive, .dotMatchesLineSeparators]).firstMatch(in: input, range: NSMakeRange(0, input.utf16.count)) // $ regex=.* input=input MISSING: modes="DOTALL | IGNORECASE"
_ = input.replacingOccurrences(of: ".*", with: "", options: [.regularExpression, .caseInsensitive]) // $ MISSING: regex=.* input=input modes=IGNORECASE
_ = NSString(string: "abc").replacingOccurrences(of: ".*", with: "", options: [.regularExpression, .caseInsensitive], range: NSMakeRange(0, inputNS.length)) // $ MISSING: regex=.* input=inputNS modes=IGNORECASE
}