public static Tres AsSingle <Tres> (Result[] r) where Tres : Result { if (r == null) { throw new ArgumentNullException(); } if (r.Length != 1) { throw new ArgumentException("Array should have exactly 1 member", "r"); } if (!(r[0] is Tres)) { throw ExHelp.Argument("r", "Array member should be a {0} but is instead {1}", typeof(Tres), r[0].GetType()); } return((Tres)r[0]); }
// This is MBuild-specific public static string CanonicalizeTarget(string target, string relbasis) { if (target == null) { throw new ArgumentNullException("target"); } if (target[0] != '/') { // Allow canonicalization of absolute target paths by // passing a null relbasis. Useful for something that // might look like /a/b/../c/./e if (relbasis == null) { throw new ArgumentNullException("relbasis"); } if (relbasis[0] != '/' || relbasis[relbasis.Length - 1] != '/') { throw ExHelp.Argument("relbasis", "Invalid basis `{0}'", relbasis); } target = relbasis + target; } int tlen = target.Length; char[] buf = new char[tlen]; int[] slashlocs = new int[tlen / 2]; int bufidx = 0, slashidx = 0, tidx; bool saw_slash = false; for (tidx = 0; tidx < tlen; /*nothing*/) { char c = target[tidx++]; if (!saw_slash) { buf[bufidx++] = c; if (c == '/') { slashlocs[slashidx++] = bufidx; saw_slash = true; } continue; } if (c == '/') { throw ExHelp.Argument("target", "Target name `{0}' cannot " + "contain `//'", target); } if (c != '.') { // Short-circuit. This cannot be a special construct. buf[bufidx++] = c; saw_slash = false; continue; } // We're a period after a slash. // If there are no characters left, that's illegal. int numleft = tlen - tidx; if (numleft < 1) { throw ExHelp.Argument("target", "Target name `{0}' cannot end " + "in bare `/.'", target); } // If there are two characters left, we may // be a '/./' construct. if (numleft > 0 && target[tidx] == '/') { // Preserve saw_slash! tidx++; continue; } // Or a trailing /.., which is also illegal. if (numleft == 1 && target[tidx] == '.') { throw ExHelp.Argument("target", "Target name `{0}' cannot end " + "in bare `/..'", target); } // If there are three, we may be a '/../' construct. if (numleft > 1 && target[tidx] == '.' && target[tidx + 1] == '/') { // Eat up to the previous point in buf, // and preserve saw_slash tidx += 2; slashidx -= 2; if (slashidx < 0) { throw ExHelp.Argument("target", "Target name `{0}' has too " + "many `..' sequences.", target); } bufidx = slashlocs[slashidx++]; continue; } // We're not a specal construct. Continue as usual. buf[bufidx++] = c; saw_slash = false; } return(new String(buf, 0, bufidx)); }