private Regex(string pattern, RegexOptions options, TimeSpan matchTimeout, bool addToCache)
{
if (pattern == null)
{
throw new ArgumentNullException(nameof(pattern));
}
if (options < RegexOptions.None || (((int)options) >> MaxOptionShift) != 0)
{
throw new ArgumentOutOfRangeException(nameof(options));
}
if ((options & RegexOptions.ECMAScript) != 0 &&
(options & ~(RegexOptions.ECMAScript |
RegexOptions.IgnoreCase |
RegexOptions.Multiline |
RegexOptions.Compiled |
RegexOptions.CultureInvariant
#if DEBUG
| RegexOptions.Debug
#endif
)) != 0)
{
throw new ArgumentOutOfRangeException(nameof(options));
}
ValidateMatchTimeout(matchTimeout);
// After parameter validation assign
this.pattern = pattern;
roptions = options;
internalMatchTimeout = matchTimeout;
// Cache handling. Try to look up this regex in the cache.
CultureInfo culture = (options & RegexOptions.CultureInvariant) != 0 ?
CultureInfo.InvariantCulture :
CultureInfo.CurrentCulture;
var key = new CachedCodeEntryKey(options, culture.ToString(), pattern);
CachedCodeEntry cached = GetCachedCode(key, false);
if (cached == null)
{
// Parse the input
RegexTree tree = RegexParser.Parse(pattern, roptions, culture);
// Extract the relevant information
capnames = tree.CapNames;
capslist = tree.CapsList;
_code = RegexWriter.Write(tree);
caps = _code.Caps;
capsize = _code.CapSize;
InitializeReferences();
tree = null;
if (addToCache)
{
cached = GetCachedCode(key, true);
}
}
else
{
caps = cached.Caps;
capnames = cached.Capnames;
capslist = cached.Capslist;
capsize = cached.Capsize;
_code = cached.Code;
#if FEATURE_COMPILED
factory = cached.Factory;
#endif
// Cache runner and replacement
_runnerref = cached.Runnerref;
_replref = cached.ReplRef;
_refsInitialized = true;
}
#if FEATURE_COMPILED
// if the compile option is set, then compile the code if it's not already
if (UseOptionC() && factory == null)
{
factory = Compile(_code, roptions);
if (addToCache && cached != null)
{
cached.AddCompiled(factory);
}
_code = null;
}
#endif
}