public void Char_pointer_check_for_valid_char() { CharPointer pointer = ""; Assert.Equal(pointer.HasValidChar, true); Assert.Equal(pointer.Value, '\0'); pointer = pointer.Increment(); Assert.Equal(pointer.HasValidChar, false); Assert.Throws <Exception>(() => pointer.Value); pointer = ""; pointer = pointer.Increment(-1); Assert.Equal(pointer.HasValidChar, false); }
public void Char_can_point_to_null_terminator() { CharPointer test = "t"; Assert.Equal(test.Value, 't'); test = test.Increment(); Assert.Equal(test.Value, '\0'); }
public void Char_pointer_tests() { CharPointer pointer = CharPointer.Null; Assert.Equal(pointer, CharPointer.Null); Assert.Null(pointer.Source); Assert.Null(pointer.Value); Assert.Throws <Exception>(() => { pointer.Increment(); }); pointer = null; Assert.Equal(pointer, CharPointer.Null); Assert.Null(pointer.Value); pointer = ""; Assert.NotEqual(pointer, CharPointer.Null); }
private static MatchResult DoWild(CharPointer p, CharPointer text, MatchFlags flags) { char p_ch; var pattern = p; for ( ; (p_ch = p.Value) != '\0'; text = text.Increment(), p = p.Increment()) { int matched; char t_ch; if ((t_ch = text.Value) == '\0' && p_ch != '*') { return(MatchResult.AbortAll); } if (flags.HasFlag(MatchFlags.CaseFold)) { if (char.IsUpper(t_ch)) { t_ch = char.ToLower(t_ch); } if (char.IsUpper(p_ch)) { p_ch = char.ToLower(p_ch); } } switch (p_ch) { case '\\': p = p.Increment(); p_ch = p.Value; // fallthrough goto default; default: if (t_ch != p_ch) { return(MatchResult.NoMatch); } continue; case '?': if (flags.HasFlag(MatchFlags.PathName) && t_ch == '/') { return(MatchResult.NoMatch); } continue; case '*': p = p.Increment(); bool match_slash; if (p.Value == '*') { var prev_p = p.Increment(-2); p = p.Increment(); while (p.Value == '*') { p.Increment(); } if (!flags.HasFlag(MatchFlags.PathName)) { match_slash = true; } else if ((prev_p.Index < pattern.Index || prev_p.Value == '/') && (p.Value == '\0' || p.Value == '/' || (p.Value == '\\' && p.Increment().Value == '/'))) { if (p.Value == '/' && DoWild(p.Increment(), text, flags) == MatchResult.Match) { return(MatchResult.Match); } match_slash = true; } else { return(MatchResult.AbortMalformed); } } else { match_slash = !flags.HasFlag(MatchFlags.PathName); } if (p.Value == '\0') { /* Trailing "**" matches everything. Trailing "*" matches * only if there are no more slash characters. */ if (!match_slash) { if (text.Source.Substring(text.Index).Contains("/")) { return(MatchResult.NoMatch); } } return((int)MatchResult.Match); } else if (!match_slash && p.Value == '/') { var nextIndex = text.Source.Substring(text.Index).IndexOf('/'); if (nextIndex == -1) { return(MatchResult.NoMatch); } text = text.Increment(nextIndex); break; } while (true) { if (t_ch == '\0') { break; } if (!Sane.IsGlobSpecial(p.Value)) { p_ch = p.Value; if ((flags.HasFlag(MatchFlags.CaseFold)) && char.IsUpper(p_ch)) { p_ch = char.ToLower(p_ch); } while ((t_ch = text.Value) != '\0' && (match_slash || t_ch != '/')) { if (flags.HasFlag(MatchFlags.CaseFold) && char.IsUpper(t_ch)) { t_ch = char.ToLower(t_ch); } if (t_ch == p_ch) { break; } text = text.Increment(); } if (t_ch != p_ch) { return(MatchResult.NoMatch); } } if ((matched = (int)DoWild(p, text, flags)) != (int)MatchResult.NoMatch) { if (!match_slash || matched != (int)MatchResult.AbortToStartStart) { return((MatchResult)matched); } } else if (!match_slash && t_ch == '/') { return(MatchResult.AbortToStartStart); } text = text.Increment(); t_ch = text.Value; } return(MatchResult.AbortAll); case '[': p = p.Increment(); p_ch = p.Value; if (p_ch == '^') { p_ch = '!'; } var negated = p_ch == '!' ? 1 : 0; if (negated == 1) { p = p.Increment(); p_ch = p.Value; } var prev_ch = '\0'; matched = 0; bool Next() { prev_ch = p_ch; p = p.Increment(); p_ch = p.Value; return(p_ch != ']'); } do { if (p_ch == '\0') { return(MatchResult.AbortAll); } if (p_ch == '\\') { p = p.Increment(); p_ch = p.Value; if (p_ch == '\0') { return(MatchResult.AbortAll); } if (t_ch == p_ch) { matched = 1; } } else if (p_ch == '-' && prev_ch != '\0' && p.Increment().Value != '\0' && p.Increment().Value != ']') { p = p.Increment(); p_ch = p.Value; if (p_ch == '\\') { p = p.Increment(); p_ch = p.Value; if (p_ch == '\0') { return(MatchResult.AbortAll); } } if (t_ch <= p_ch && t_ch >= prev_ch) { matched = 1; } else if (flags.HasFlag(MatchFlags.CaseFold) && char.IsLower(t_ch)) { var t_ch_upper = char.ToUpper(t_ch); if (t_ch_upper <= p_ch && t_ch_upper >= prev_ch) { matched = 1; } } p_ch = '\0'; } else if (p_ch == '[' && p.Increment().Value == ':') { CharPointer s; for (s = p.Increment(2); (p_ch = p.Value) != '\0' && p_ch != ']'; p = p.Increment()) { } if (p_ch == '\0') { return(MatchResult.AbortAll); } var i = p.Index - s.Index - 1; if (i < 0 || p.Increment(-1).Value != ':') { p = s.Increment(-2); p_ch = '['; if (t_ch == p_ch) { matched = 1; } continue; } var temp = s.Source.Substring(s.Index); if (temp.StartsWith("alnum")) { if (Sane.IsAlNum(t_ch)) { matched = 1; } } else if (temp.StartsWith("alpha")) { if (Sane.IsAlpha(t_ch)) { matched = 1; } } else if (temp.StartsWith("blank")) { if (Sane.IsBlank(t_ch)) { matched = 1; } } else if (temp.StartsWith("cntrl")) { if (Sane.IsCtrl(t_ch)) { matched = 1; } } else if (temp.StartsWith("digit")) { if (Sane.IsDigit(t_ch)) { matched = 1; } } else if (temp.StartsWith("graph")) { if (Sane.IsGraph(t_ch)) { matched = 1; } } else if (temp.StartsWith("lower")) { if (char.IsLower(t_ch)) { matched = 1; } } else if (temp.StartsWith("print")) { if (Sane.IsPrint(t_ch)) { matched = 1; } } else if (temp.StartsWith("punct")) { if (Sane.IsPunc(t_ch)) { matched = 1; } } else if (temp.StartsWith("space")) { if (Sane.IsSpace(t_ch)) { matched = 1; } } else if (temp.StartsWith("upper")) { if (char.IsUpper(t_ch)) { matched = 1; } else if (flags.HasFlag(MatchFlags.CaseFold) && char.IsLower(t_ch)) { matched = 1; } } else if (temp.StartsWith("xdigit")) { if (Sane.IsXDigit(t_ch)) { matched = 1; } } else { return(MatchResult.AbortAll); } } else if (t_ch == p_ch) { matched = 1; } } while (Next()); if (matched == negated || (flags.HasFlag(MatchFlags.PathName) && t_ch == '/')) { return(MatchResult.NoMatch); } continue; } } return(text.Index < text.Source.Length ? MatchResult.NoMatch : MatchResult.Match); }