private static FlowControlStruct FunctionFor(string[] line, int LineNo) { FlowControlStruct NullLoop = new FlowControlStruct(2); if (line.Length < 3) { Warn("Missing arguments to function 'For'"); return NullLoop; } if (line[1] == "Each") line[1] = line[2]; switch (line[1]) { case "Count": { if (line.Length < 5) { Warn("Missing arguments to function 'For Count'"); return NullLoop; } if (line.Length > 6) Warn("Unexpected extra arguments to 'For Count'"); int start, end, step = 1; if (!int.TryParse(line[3], out start) || !int.TryParse(line[4], out end) || (line.Length >= 6 && !int.TryParse(line[5], out step))) { Warn("Invalid argument to 'For Count'"); return NullLoop; } List<string> steps = new List<string>(); for (int i = start; i <= end; i += step) { steps.Add(i.ToString()); } return new FlowControlStruct(steps.ToArray(), line[2], LineNo); } case "DataFile": { if (line.Length < 4) { Warn("Missing arguments to function 'For Each DataFile'"); return NullLoop; } if (line.Length > 4) Warn("Unexpected extra arguments to 'For Each DataFile'"); string[] strFiles = (string[])ExecuteMethod(() => m_midInstaller.Fomod.GetFileList().ToArray()); for (Int32 i = strFiles.Length - 1; i >= 0; i--) strFiles[i] = strFiles[i].Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); return new FlowControlStruct(strFiles, line[3], LineNo); } } return NullLoop; }
private static FlowControlStruct FunctionFor(IReadOnlyCollection <string> line, int lineNo) { var nullLoop = new FlowControlStruct(3); if (line.Count < 3) { Warn("Missing arguments for 'For'"); return(nullLoop); } var elementAt = line.ElementAt(1); if (elementAt == "Each") { elementAt = line.ElementAt(2); } switch (elementAt) { case "Count": { if (line.Count < 5) { Warn("Missing arguments to function 'For Count'"); return(nullLoop); } if (line.Count > 6) { Warn("Unexpected extra arguments for 'For Count'"); } int step = 1; if (!int.TryParse(line.ElementAt(3), out var start) || !int.TryParse(line.ElementAt(4), out var end) || line.Count >= 6 && !int.TryParse(line.ElementAt(5), out step)) { Warn("Invalid argument to 'For Count'"); return(nullLoop); } var steps = new List <string>(); for (int i = start; i < +end; i += step) { steps.Add(i.ToString()); } return(new FlowControlStruct(steps.ToArray(), line.ElementAt(2), lineNo)); } case "DataFolder": case "PluginFolder": case "DataFile": case "Plugin": { string root; if (elementAt == "DataFolder" || elementAt == "DataFile") { root = DataFiles; } else { root = Plugins; } if (line.Count < 5) { Warn($"Missing arguments for 'For Each {elementAt}'"); return(nullLoop); } if (line.Count > 7) { Warn($"Unexpected extra arguments to 'For Each {elementAt}'"); } if (!Utils.IsSafeFolderName(line.ElementAt(4))) { Warn($"Invalid argument for 'For Each {elementAt}'\nDirectory '{line.ElementAt(4)}' is not valid"); return(nullLoop); } if (!Directory.Exists(Path.Combine(root, line.ElementAt(4)))) { Warn($"Invalid argument for 'For Each {elementAt}'\nDirectory '{line.ElementAt(4)}' does not exist"); } var option = SearchOption.TopDirectoryOnly; if (line.Count > 5) { switch (line.ElementAt(5)) { case "True": option = SearchOption.AllDirectories; break; case "False": break; default: Warn($"Invalid argument '{line.ElementAt(5)}' for 'For Each {elementAt}'.\nExpected 'True' or 'False'"); break; } } try { var paths = Directory.GetDirectories(Path.Combine(root, line.ElementAt(4)), line.Count > 6 ? line.ElementAt(6) : "*", option); for (var i = 0; i < paths.Length; i++) { if (Path.IsPathRooted(paths[i])) { paths[i] = paths[i].Substring(root.Length); } } return(new FlowControlStruct(paths, line.ElementAt(3), lineNo)); } catch { Warn($"Invalid argument for 'For Each {elementAt}'"); return(nullLoop); } } default: Warn("Unexpected function for 'For'"); return(nullLoop); } }