int _FindSourceSite(bool download) { int R = -1; ARegex rx = null; for (int i = 0; i < s_sources.Length; i++) { if (download && s_sources[i].data == null) { try { using var client = new WebClient { CachePolicy = new System.Net.Cache.RequestCachePolicy() }; //get from cache if available and not too old s_sources[i].data = client.DownloadString(s_sources[i].site + "/assemblies.txt"); } catch (WebException) { } } if (R >= 0) { continue; } rx ??= new ARegex($@"(?m)^{_assembly};\d"); if (rx.IsMatch(s_sources[i].data)) { R = i; if (!download) { break; } } } return(R); }
private void _bAddComRegistry_Click(object button, EventArgs e) { //HKCU\TypeLib\typelibGuid\version\ var sFind = _tFindInList.Text; var rx = new ARegex(@"(?i) (?:Type |Object )?Library[ \d\.]*$"); var a = new List <_RegTypelib>(1000); using (var tlKey = Registry.ClassesRoot.OpenSubKey("TypeLib")) { //guids foreach (var sGuid in tlKey.GetSubKeyNames()) { if (sGuid.Length != 38) { continue; } //AOutput.Write(sGuid); using var guidKey = tlKey.OpenSubKey(sGuid); foreach (var sVer in guidKey.GetSubKeyNames()) { using var verKey = guidKey.OpenSubKey(sVer); if (verKey.GetValue("") is string description) { if (rx.MatchG(description, out var g)) { description = description.Remove(g.Start); } if (sFind.Length > 0 && description.Find(sFind, true) < 0) { continue; } a.Add(new _RegTypelib { guid = sGuid, text = description + ", " + sVer, version = sVer }); } //else AOutput.Write(sGuid); //some Microsoft typelibs. VS does not show these too. } } } if (a.Count == 0) { _NotFound(button, sFind); return; } a.Sort((x, y) => string.Compare(x.text, y.text, true)); var dd = new PopupList { Items = a.ToArray(), SelectedAction = o => _ConvertTypeLibrary(o.ResultItem as _RegTypelib, button) }; dd.Show(_bAddComRegistry); }
/// <summary> /// If s has *? characters, prepends "**t ". /// But if s has single * character, converts to "**r regexp" that ignores it. Because single * often is used to indicate unsaved state. /// If canMakeVerbatim and makes regex or s contains '\' and no newlines/controlchars, prepends @" and appends " and replaces all " with "". /// s can be null. /// </summary> public static string EscapeWindowName(string s, bool canMakeVerbatim) { if (s == null) { return(s); } if (AWildex.HasWildcardChars(s)) { int i = s.IndexOf('*'); if (i >= 0 && s.IndexOf('*', i + 1) < 0) { s = "**r " + ARegex.EscapeQE(s.Remove(i)) + @"\*?" + ARegex.EscapeQE(s.Substring(i + 1)); } else { s = "**t " + s; } } if (canMakeVerbatim && s.IndexOf('\\') >= 0 && !s.RegexIsMatch(@"[\x00-\x1F\x85\x{2028}\x{2029}]")) { s = "@\"" + s.Replace("\"", "\"\"") + "\""; } return(s); }
private static void ExplicitRegexSamples() { // Let's start with stateless regular expressions #region Regex 1: AC var reg1 = ARegex.Concat( ARegex.SingleElement <Payload>(e => e.Field1 == "A"), ARegex.SingleElement <Payload>(e => e.Field1 == "C")); RunPatternQuery("Regex 1: AC", reg1, source); #endregion #region Regex 2: A(B*)C var reg2 = ARegex.Concat( ARegex.SingleElement <Payload>(e => e.Field1 == "A"), ARegex.KleeneStar(ARegex.SingleElement <Payload>(e => e.Field1 == "B")), ARegex.SingleElement <Payload>(e => e.Field1 == "C")); RunPatternQuery("Regex 2: A(B*)C", reg2, source); #endregion #region Regex 3: A(B+|C*)A var reg3 = ARegex.Concat ( ARegex.SingleElement <Payload>(e => e.Field1 == "A"), ARegex.Or ( ARegex.KleenePlus(ARegex.SingleElement <Payload>(e => e.Field1 == "B")), ARegex.KleeneStar(ARegex.SingleElement <Payload>(e => e.Field1 == "C"))), ARegex.SingleElement <Payload>(e => e.Field1 == "A")); RunPatternQuery("Regex 3: A(B+|C*)A", reg3, source); #endregion #region Regex 4: A(C|epsilon)A var reg4 = ARegex.Concat ( ARegex.SingleElement <Payload>(e => e.Field1 == "A"), ARegex.Or ( ARegex.SingleElement <Payload>(e => e.Field1 == "C"), ARegex.Epsilon <Payload>()), ARegex.SingleElement <Payload>(e => e.Field1 == "A")); RunPatternQuery("Regex 4: A(C|epsilon)A", reg4, source); #endregion // Next step: regular expressions with state (register) accumulation #region Regex 5: A(B*)C and accumulate a sum of Field2 for B* var reg5 = ARegex.Concat( ARegex.SingleElement <Payload, int>(e => e.Field1 == "A", (ev, d) => 0), // start with A ARegex.KleeneStar( ARegex.SingleElement <Payload, int>( e => e.Field1 == "B", (ev, d) => d + ev.Field2)), // accumulate a sum for B* ARegex.SingleElement <Payload, int>(e => e.Field1 == "C")); // end with C RunPatternQuery("Regex 5: A(B*)C and accumulate a sum of Field2 for B*", reg5, source); #endregion #region Regex 6: A(B*)C and report list of all contributing events for every match var reg6 = ARegex.Concat ( ARegex.SingleElement <Payload, FList <Payload> >( e => e.Field1 == "A", (ev, list) => new FList <Payload>().FAdd(ev)), // A ARegex.KleeneStar(ARegex.SingleElement <Payload, FList <Payload> >( e => e.Field1 == "B", (ev, list) => list.FAdd(ev))), // B* ARegex.SingleElement <Payload, FList <Payload> >( e => e.Field1 == "C", (ev, list) => list.FAdd(ev))); // C RunPatternQuery("Regex 6: A(B*)C and report list of all contributing events for every match", reg6, source); #endregion // Regular expression with time constraints expressed using registers #region Regex 7: A is followed by B within 100 time units (AB) var reg7 = ARegex.Concat ( ARegex.SingleElement <Payload, long>( ev => ev.Field1 == "A", (ts, ev, reg) => ts), // start with A, store timestamp in register ARegex.SingleElement <Payload, long>( (ts, ev, reg) => ev.Field1 == "B" && ts < reg + 100)); // end with B within 100 units of A RunPatternQuery("Regex 7: A is followed by B within 100 time units (AB)", reg7, source); #endregion #region Regex 8: A(.*)C where C is after >= 20 ticks of A var reg8 = ARegex.Concat ( ARegex.SingleElement <Payload, long>( e => e.Field1 == "A", (ts, ev, reg) => ts), // A, store timestamp in register ARegex.KleeneStar(ARegex.SingleElement <Payload, long>()), // (.*) ARegex.SingleElement <Payload, long>( (ts, ev, reg) => ev.Field1 == "C" && ts - reg >= 20)); // C, compare event timestamp with register value RunPatternQuery("Regex 8: A(.*)C where C is after >= 20 ticks of A", reg8, source); #endregion // Regular expressions with state accumulation and local time constraints #region Regex 9: Sequence of A's followed by a B within 100 time units [(A*)B] and report the sum of Field2 for A* var reg9 = ARegex.Concat ( ARegex.KleeneStar( ARegex.SingleElement <Payload, ValueTuple <int, long> >( ev => ev.Field1 == "A", (ts, ev, reg) => ValueTuple.Create(reg.Item1 + ev.Field2, ts))), // accumulate a sum for A* ARegex.SingleElement <Payload, ValueTuple <int, long> >( (ts, ev, reg) => ev.Field1 == "B" && ts < reg.Item2 + 100)); // end with B within 100 units RunPatternQuery("Regex 9: Sequence of A's followed by a B within 100 time units [(A*)B] and report the sum of Field2 for A*", reg9, source); #endregion #region Regex 10: A(.*)C , C is within 100 time units of A, report (A.Field2 + C.Field2) (skip the .* matches) var reg10 = ARegex.Concat( ARegex.SingleElement <Payload, ValueTuple <int, long> >( ev => ev.Field1 == "A", (ts, ev, reg) => ValueTuple.Create(ev.Field2, ts)), ARegex.KleeneStar(ARegex.SingleElement <Payload, ValueTuple <int, long> >()), ARegex.SingleElement <Payload, ValueTuple <int, long> >( (ts, ev, reg) => ev.Field1 == "C" && ts < reg.Item2 + 100, (ts, ev, reg) => ValueTuple.Create(reg.Item1 + ev.Field2, reg.Item2))); RunPatternQuery("Regex 10: A(.*)C , C is within 100 time units of A, report (A.Field2 + C.Field2) (skip the .* matches)", reg10, source); #endregion }
internal RXMatch(ARegex regex, string subject, int rc, in Cpp.RegexMatch k)
void _GetServerMessages() { _c.ZTags.OutputServerProcessMessages(Program.OutputServer, m => { if (m.Type != OutServMessageType.Write) { return; } //create links in compilation errors/warnings or run-time stack trace var s = m.Text; int i; if (s.Length >= 22) { if (s.Starts("<><Z #") && s.Eq(12, ">Compilation: ")) //compilation { if (s_rx1 == null) { s_rx1 = new ARegex(@"(?m)^\[(.+?)(\((\d+),(\d+)\))?\]: "); } m.Text = s_rx1.Replace(s, x => { var f = Program.Model.FindByFilePath(x[1].Value); if (f == null) { return(x[0].Value); } return($"<open \"{f.IdStringWithWorkspace}|{x[3].Value}|{x[4].Value}\">{f.Name}{x[2].Value}<>: "); }); } else if ((i = s.Find("\n at ") + 1) > 0 && s.Find(":line ", i) > 0) //stack trace with source file info { if (_sb == null) { _sb = new StringBuilder(s.Length + 2000); } else { _sb.Clear(); } var b = _sb; //AOutput.QM2.Write("'" + s + "'"); int iLiteral = 0; if (!s.Starts("<>")) { b.Append("<>"); } else { iLiteral = i - 1; if (s[iLiteral - 1] == '\r') { iLiteral--; } if (0 == s.Eq(iLiteral -= 3, false, "<_>", "<\a>")) { iLiteral = 0; } } if (iLiteral > 0) { b.Append(s, 0, iLiteral).AppendLine(); } else { b.Append(s, 0, i); } var rx = s_rx2; if (rx == null) { s_rx2 = rx = new ARegex(@" in (.+?):line (?=\d+$)"); } bool replaced = false, isMain = false; int stackEnd = s.Length /*, stackEnd2 = 0*/; foreach (var k in s.Segments(SegSep.Line, range: i..)) { //AOutput.QM2.Write("'"+k+"'"); if (s.Eq(k.start, " at ")) { if (isMain) { //if(stackEnd2 == 0 && s.Eq(k.start, " at Script.Main(String[] args) in ")) stackEnd2 = k.start; //rejected. In some cases may cut something important. continue; } if (!rx.MatchG(s, out var g, 1, (k.start + 6)..k.end)) { continue; //note: no " at " if this is an inner exception marker. Also in aggregate exception stack trace. } var f = Program.Model.FindByFilePath(g.Value); if (f == null) { continue; } int i1 = g.End + 6, len1 = k.end - i1; b.Append(" at ") .Append("<open \"").Append(f.IdStringWithWorkspace).Append('|').Append(s, i1, len1).Append("\">") .Append("line ").Append(s, i1, len1).Append("<> in <z 0xFAFAD2>").Append(f.Name).Append("<>"); isMain = s.Eq(k.start, " at Script..ctor(String[] args) in "); if (!isMain || !f.IsScript) { b.Append(", <\a>").Append(s, k.start + 6, g.Start - k.start - 10).Append("</\a>"); } b.AppendLine(); replaced = true; } else if (!(s.Eq(k.start, " ---") || s.Eq(k.start, "---"))) { stackEnd = k.start; break; } } if (replaced) { int j = stackEnd; //int j = stackEnd2 > 0 ? stackEnd2 : stackEnd; if (s[j - 1] == '\n') { if (s[--j - 1] == '\r') { j--; } } b.Append(" <fold><\a> --- Raw stack trace ---\r\n").Append(s, i, j - i).Append("</\a></fold>"); if (iLiteral > 0 && 0 != s.Eq(stackEnd, false, "</_>", "</\a")) { stackEnd += 4; } int more = s.Length - stackEnd; if (more > 0) { if (!s.Eq(stackEnd, "</fold>")) { b.AppendLine(); } b.Append(s, stackEnd, more); } m.Text = b.ToString(); //AOutput.QM2.Write("'" + m.Text + "'"); } if (_sb.Capacity > 10_000) { _sb = null; //let GC free it. Usually < 4000. } }