[STAThread] // Required by ICSharpCode.TextEditor public static void Main(string[] args) { BMultiMap<string,string> options = new BMultiMap<string,string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions); if (!options.ContainsKey("nologo")) Console.WriteLine("LeMP macro compiler (pre-alpha)"); string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } if (options.ContainsKey("editor")) { Console.WriteLine("Starting editor..."); System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); Compiler c = ProcessArguments(options, filter, typeof(Macros), argList); Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP")); using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp)) c.Run(); } else if (args.Length == 0) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); Console.WriteLine(); Console.WriteLine("LeMP started without arguments. Starting editor (--editor)"); var thread = new ThreadEx(() => { System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); }); thread.Thread.SetApartmentState(ApartmentState.STA); thread.Start(); Console.WriteLine("Press Enter to run unit tests. Using the editor? Keep the terminal open."); Console.ReadLine(); RunTests.Run(new Loyc.Syntax.Lexing.TokenTests()); RunTests.Run(new Loyc.Syntax.Les.LesLexerTests()); RunTests.Run(new Loyc.Syntax.Les.LesParserTests()); RunTests.Run(new Loyc.Syntax.Les.LesPrinterTests()); RunLeMPTests(); Ecs.Program.RunEcsTests(); } }
private double?ParseNumericOption(BMultiMap <string, string> options, string key, IMessageSink sink, double?min = null, double?max = null) { string value; if (!options.TryGetValue(key, out value)) { return(null); } double num; if (double.TryParse(value ?? "", out num)) { if ((min == null || num >= min.Value) && (max == null || num <= max.Value)) { return(num); } } if (sink != null) { if (min != null && max != null) { sink.Error("--" + key, "Expected numeric value between {0} and {1}", min.Value, max.Value); } else { sink.Error("--" + key, "Expected numeric value"); } } return(null); }
private bool?ParseBoolOption(BMultiMap <string, string> options, string key, IMessageSink sink) { string value; if (!options.TryGetValue(key, out value)) { return(null); } if (value == null) { return(true); } if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase) || value == "1") { return(true); } if (value.Equals("false", StringComparison.InvariantCultureIgnoreCase) || value == "0") { return(false); } if (sink != null) { sink.Error("--" + key, "Expected boolean `true` or `false`"); } return(null); }
public IReadOnlyList <Pair <ILNode, IndexRange> > FindRelatedNodesCore(IndexRange targetRange, int maxSearchResults, bool trim) { var candidates = new Dictionary <Pair <ILNode, IndexRange>, float>(); // This is a heuristic search, not an algorithm; it is not guaranteed to find the // best answer, rather we scan enough entries to find what we're looking for with // high probability. In total, scan about 10x as many entries as maxSearchResults. Scan(_startLocations, targetRange.StartIndex, targetRange, 1, maxSearchResults * 5, candidates); Scan(_startLocations, targetRange.StartIndex, targetRange, -1, maxSearchResults * 2, candidates); Scan(_endLocations, targetRange.EndIndex, targetRange, 1, maxSearchResults * 1, candidates); Scan(_endLocations, targetRange.EndIndex, targetRange, -1, maxSearchResults * 2, candidates); var sorted = new BMultiMap <float, Pair <ILNode, IndexRange> >(null, (p, q) => 0); foreach (var candidate in candidates) { if (!trim || sorted[candidate.Value].StartIndex < maxSearchResults) { sorted[candidate.Value].Add(candidate.Key); } } if (trim && sorted.Count > maxSearchResults) { sorted.RemoveRange(maxSearchResults, sorted.Count - maxSearchResults); } return(sorted.Select(pair => pair.Value).ToList()); }
public void NodeAdded(AListNode <K, T> child, AListInnerBase <K, T> parent) { if (_nodes == null) { _nodes = new BMultiMap <AListNode <K, T>, AListInnerBase <K, T> >(CompareNodeHashCodes, CompareInnerHashCodes); } _nodes.Add(new KeyValuePair <AListNode <K, T>, AListInnerBase <K, T> >(child, parent)); }
public static void WarnAboutUnknownOptions(BMultiMap <string, string> options, IMessageSink sink, IDictionary <string, Pair <string, string> > knownOptions) { foreach (var opt in options.Keys) { if (!knownOptions.ContainsKey(opt)) { sink.Write(Severity.Warning, "Command line", "Unrecognized option '--{0}'", opt); } } }
public virtual int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputSize, IVsGeneratorProgress progressCallback) { string inputFolder = Path.GetDirectoryName(inputFilePath); string oldCurDir = Environment.CurrentDirectory; try { Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed var sourceFile = new StringCharSourceFile(inputFileContents, inputFilePath); var sink = ToMessageSink(progressCallback); var c = new Compiler(sink, sourceFile); var options = new BMultiMap <string, string>(); var argList = G.SplitCommandLineArguments(defaultNamespace); UG.ProcessCommandLineArguments(argList, options, "", LEL.Compiler.ShortOptions, LEL.Compiler.TwoArgOptions); string _; var KnownOptions = LEL.Compiler.KnownOptions; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { LEL.Compiler.ShowHelp(KnownOptions); } Symbol minSeverity = MessageSink.Note; var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); if (LEL.Compiler.ProcessArguments(c, options)) { LEL.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LEL.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("Loyc.LLParserGenerator")); c.AddMacros(typeof(Loyc.LLParserGenerator.Macros).Assembly); c.Run(); } var outputBytes = Encoding.UTF8.GetBytes(c.Output.ToString()); c.Output = null; // no longer needed outputSize = (uint)outputBytes.Length; outputFileContents[0] = Marshal.AllocCoTaskMem(outputBytes.Length); Marshal.Copy(outputBytes, 0, outputFileContents[0], outputBytes.Length); } else { outputFileContents[0] = IntPtr.Zero; outputSize = 0; } return(VSConstants.S_OK); } finally { Environment.CurrentDirectory = oldCurDir; } }
public static Compiler ProcessArguments(BMultiMap <string, string> options, SeverityMessageFilter sink, Type prelude, List <string> inputFiles) { if (inputFiles.Count == 0) { sink.Write(Severity.Error, null, "No input provided, stopping."); return(null); } Compiler c = new Compiler(sink, prelude); c.Files = new List <InputOutput>(OpenSourceFiles(sink, inputFiles)); return(ProcessArguments(c, options) ? c : null); }
private void RunLeMP(IList <string> args, string inputCode, string inputPath) { var options = new BMultiMap <string, string>(); UG.ProcessCommandLineArguments(args, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions); string _; var KnownOptions = LeMP.Compiler.KnownOptions; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { var ms = new MemoryStream(); LeMP.Compiler.ShowHelp(LeMP.Compiler.KnownOptions, new StreamWriter(ms)); string output = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length); _outFileName = null; ShowOutput(output); } else { var sink = MessageSink.FromDelegate(WriteMessage); var sourceFile = new InputOutput((UString)inputCode, Path.GetFileName(inputPath)); var c = new Compiler(sink, sourceFile); c.Files = new List <InputOutput> { sourceFile }; c.Parallel = false; // only one file, parallel doesn't help if (LeMP.Compiler.ProcessArguments(c, options)) { LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions); c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); if (inputPath.EndsWith(".les", StringComparison.OrdinalIgnoreCase)) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les")); } LempStarted = true; new Thread(() => { try { c.Run(); // Must get OutFileName after calling Run() _outFileName = sourceFile.OutFileName; ShowOutput(c.Output.ToString()); } finally { LempStarted = false; } }).Start(); } } }
public void RootChanged(AListNode <K, T> newRoot, bool clear) { if (newRoot == null) { if (!clear && _items.Count != 0) { BadState(); } _items.Clear(); _nodes = null; } _root = newRoot; }
[STAThread] // Required by ICSharpCode.TextEditor public static void Main(string[] args) { BMultiMap <string, string> options = new BMultiMap <string, string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions); if (!options.ContainsKey("nologo")) { Console.WriteLine("LeMP macro compiler (beta)"); } string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } if (options.ContainsKey("editor")) { Console.WriteLine("Starting editor..."); System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); Compiler c = ProcessArguments(options, filter, typeof(BuiltinMacros), argList); Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP")); using (LNode.PushPrinter(EcsNodePrinter.PrintPlainCSharp)) c.Run(); } else if (args.Length == 0) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); } }
/// <summary>Processes command-line arguments to build a BMultiMap and /// sends those options to the other overload of this method.</summary> /// <param name="args">Arg list from which to extract options. **NOTE**: /// discovered options are removed from the list. This parameter /// cannot be an array.</param> /// <param name="warnAboutUnknownOptions">Whether this method should /// call <see cref="WarnAboutUnknownOptions"/> for you.</param> /// <param name="autoOpenInputFiles">Whether to open input files /// for you by calling <see cref="OpenSourceFiles(IMessageSink, IEnumerable{string})"/>. /// </param> /// <param name="inputFiles">A list of input files to open if /// autoOpenInputFiles is true. If this is null, The input files are /// assumed to be those command-line arguments left over after the options /// are removed.</param> /// <returns>The map of options (key-value pairs and, for options that /// don't have a value, key-null pairs).</returns> /// <remarks> /// Note: If you get your command-line arguments as a single /// string, use <see cref="G.SplitCommandLineArguments(string)"/> first /// to split it into an array. /// <para/> /// This method doesn't check for --help. To implement --help, call /// <see cref="MaybeShowHelp"/> on the return value. /// </remarks> public BMultiMap <string, string> ProcessArguments(IList <string> args, bool warnAboutUnknownOptions, bool autoOpenInputFiles, IList <string> inputFiles = null) { BMultiMap <string, string> options = new BMultiMap <string, string>(); UG.ProcessCommandLineArguments(args, options, "", ShortOptions, TwoArgOptions); if (inputFiles == null && autoOpenInputFiles) { inputFiles = args; } if (!ProcessArguments(options, warnAboutUnknownOptions, inputFiles)) { return(null); } return(options); }
private static void Scan(BMultiMap <int, Pair <ILNode, int> > locations, int charIndex, IndexRange targetRange, int scanDirection, int iterations, Dictionary <Pair <ILNode, IndexRange>, float> results) { for (int i = locations.FindLowerBound(charIndex); iterations > 0; iterations--, i += scanDirection) { var pair = locations.TryGet(i, out bool fail); if (!fail) { var nodeWithRange = Pair.Create(pair.Value.Item1, RangeOf(pair)); float score = GetMismatchScore(pair, targetRange); if (score < results.TryGetValue(nodeWithRange, float.MaxValue)) { results[nodeWithRange] = score; } } } }
public static void Main(params string[] args) { IDictionary <string, Pair <string, string> > KnownOptions = LeMP.Compiler.KnownOptions; if (args.Length != 0) { BMultiMap <string, string> options = new BMultiMap <string, string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions); if (!options.ContainsKey("nologo")) { Console.WriteLine("LLLPG/LeMP macro compiler"); } string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _) || args.Length == 0) { LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); LeMP.Compiler c = LeMP.Compiler.ProcessArguments(options, filter, typeof(LeMP.Prelude.Les.Macros), argList); LeMP.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace); c.AddMacros(Assembly.GetExecutingAssembly()); c.AddMacros(typeof(LeMP.Prelude.Macros).Assembly); c.Run(); } } else { LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key)); Tests(); Ecs.Program.Main(args); // do EC# tests } }
public static void Main(string[] args) { BMultiMap <string, string> options = new BMultiMap <string, string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions); if (!options.ContainsKey("nologo")) { Console.WriteLine("LeMP macro compiler (pre-alpha)"); } string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); Compiler c = ProcessArguments(argList, options, filter, typeof(Macros)); Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp)) c.Run(); } else if (args.Length == 0) { Console.WriteLine("Running unit tests..."); RunTests.Run(new Loyc.Syntax.Les.LesLexerTests()); RunTests.Run(new Loyc.Syntax.Les.LesParserTests()); RunLeMPTests(); Ecs.Program.RunEcsTests(); } }
public static void Main(params string[] args) { IDictionary<string, Pair<string, string>> KnownOptions = LeMP.Compiler.KnownOptions; if (args.Length != 0) { BMultiMap<string,string> options = new BMultiMap<string,string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions); if (!options.ContainsKey("nologo")) Console.WriteLine("LLLPG/LeMP macro compiler"); string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _) || args.Length == 0) { LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); LeMP.Compiler c = LeMP.Compiler.ProcessArguments(options, filter, typeof(LeMP.Prelude.Les.Macros), argList); LeMP.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(Loyc.LLPG.Macros.MacroNamespace); c.AddMacros(Assembly.GetExecutingAssembly()); c.AddMacros(typeof(LeMP.Prelude.Macros).Assembly); c.Run(); } } else { LeMP.Compiler.ShowHelp(KnownOptions.OrderBy(p => p.Key)); Tests(); Ecs.Program.Main(args); // do EC# tests } }
public static Compiler ProcessArguments(List <string> inputFiles, BMultiMap <string, string> options, SeverityMessageFilter sink, Type prelude) { if (inputFiles.Count == 0) { sink.Write(Severity.Error, null, "No input provided, stopping."); return(null); } string value; if (options.TryGetValue("verbose", out value) && value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse sink.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong sink.MinSeverity = Severity.Verbose; } } var c = new Compiler(sink, prelude, inputFiles); return(ProcessArguments(c, options) ? c : null); }
public static void WarnAboutUnknownOptions(BMultiMap<string, string> options, IMessageSink sink, IDictionary<string, Pair<string, string>> knownOptions) { foreach (var opt in options.Keys) { if (!knownOptions.ContainsKey(opt)) sink.Write(Severity.Warning, "Command line", "Unrecognized option '--{0}'", opt); } }
public static bool ProcessArguments(Compiler c, BMultiMap<string, string> options) { string value; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.Note); if (options.TryGetValue("verbose", out value)) { if (value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong filter.MinSeverity = Severity.Verbose; } } } IMessageSink sink = c.Sink = filter; if (options.TryGetValue("max-expand", out value)) TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value)); foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { if (macroDll.Contains('\\') || macroDll.Contains('/')) { // Avoid "Absolute path information is required" exception string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll); assembly = Assembly.LoadFile(fullPath); } else assembly = Assembly.LoadFrom(macroDll); c.AddMacros(assembly); }); } foreach (var macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if (options.TryGetValue("noparallel", out value) && (value == null || value == "true")) c.Parallel = false; if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith(".")) c.OutExt = "." + c.OutExt; if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = lang.Printer ?? c.OutLang; } if (options.TryGetValue("forcelang", out value) && (value == null || value == "true")) c.ForceInLang = true; if (!options.ContainsKey("outlang") && c.OutExt != null && FileNameToLanguage(c.OutExt) == null) sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt); double num; if (options.TryGetValue("timeout", out value)) { if (!double.TryParse(value, out num) || !(num >= 0)) sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt); else c.AbortTimeout = TimeSpan.FromSeconds(num); } return true; }
public static Compiler ProcessArguments(BMultiMap<string, string> options, SeverityMessageFilter sink, Type prelude, List<string> inputFiles) { if (inputFiles.Count == 0) { sink.Write(Severity.Error, null, "No input provided, stopping."); return null; } Compiler c = new Compiler(sink, prelude); c.Files = new List<InputOutput>(OpenSourceFiles(sink, inputFiles)); return ProcessArguments(c, options) ? c : null; }
void WhereClausesOpt(ref LNode name) { TokenType la0; #line 1163 "EcsParserGrammar.les" var list = new BMultiMap<Symbol,LNode>(); #line default // Line 1164: (WhereClause)* for (;;) { la0 = LA0; if (la0 == TT.ContextualKeyword) list.Add(WhereClause()); else break; } #line 1165 "EcsParserGrammar.les" if ((list.Count != 0)) { if ((!name.CallsMin(S.Of, 2))) { Error("'{0}' is not generic and cannot use 'where' clauses.", name.ToString()); } else { var tparams = name.Args.ToRWList(); for (int i = 1; i < tparams.Count; i++) { var wheres = list[TParamSymbol(tparams[i])]; tparams[i] = tparams[i].PlusAttrs(wheres); wheres.Clear(); } name = name.WithArgs(tparams.ToRVList()); if ((list.Count > 0)) { Error(list[0].Value, "There is no type parameter named '{0}'", list[0].Key); } } } #line default }
private double? ParseNumericOption(BMultiMap<string, string> options, string key, IMessageSink sink, double? min = null, double? max = null) { string value; if (!options.TryGetValue(key, out value)) return null; double num; if (double.TryParse(value ?? "", out num)) { if ((min == null || num >= min.Value) && (max == null || num <= max.Value)) return num; } if (sink != null) { if (min != null && max != null) sink.Error("--" + key, "Expected numeric value between {0} and {1}", min.Value, max.Value); else sink.Error("--" + key, "Expected numeric value"); } return null; }
private void UpdateGraph(PlotModel model, MSet <EzDataPoint> points) { model.Series.Clear(); var allSeries = new BMultiMap <string, EzDataPoint>((a, b) => string.CompareOrdinal(a, b)); foreach (var dp in points) { allSeries.Add(dp.Series, dp); } // Add text labels to axis if the data uses text Parameters CategoryAxis cAxis = null; if (points.Any(dp => dp.Parameter is string)) { var headings = new SortedSet <string>(points.Select(dp => dp.Parameter as string).WhereNotNull()); cAxis = model.Axes.OfType <CategoryAxis>().SingleOrDefault(); if (cAxis == null) { model.Axes.Add(cAxis = new CategoryAxis { MajorGridlineStyle = LineStyle.Dot, Position = AxisPosition.Bottom }); } cAxis.Labels.Clear(); foreach (var text in headings) { cAxis.Labels.Add(text); } cAxis.Key = "CategoryAxis"; } int iSeries = 0; foreach (var series in allSeries.Values) { if (series.Any(p => p.Parameter is string)) { var plotSeries = new ColumnSeries { Title = series.First().Series }; plotSeries.XAxisKey = cAxis.Key; foreach (var dp in series) { plotSeries.Items.Add(new ColumnItem(dp.Value, cAxis.Labels.IndexOf(dp.Parameter.ToString()))); } model.Series.Add(plotSeries); } else { var plotSeries = new LineSeries { Title = series.First().Series }; if (cAxis != null) { plotSeries.XAxisKey = cAxis.Key; } // There are 7 marker types starting at 1, excluding None (0) plotSeries.MarkerType = (MarkerType)((iSeries % 7) + 1); plotSeries.MarkerSize = 4; plotSeries.MarkerFill = plotSeries.Color; foreach (var dp in series) { plotSeries.Points.Add(new OxyPlot.DataPoint(Convert.ToDouble(dp.Parameter), dp.Value)); } model.Series.Add(plotSeries); } iSeries++; } }
public static bool ProcessArguments(Compiler c, BMultiMap <string, string> options) { IMessageSink sink = c.Sink; if (c.Files.Count == 0) { return(false); } string value; if (options.TryGetValue("max-expand", out value)) { TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value)); } foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { if (macroDll.Contains('\\') || macroDll.Contains('/')) { // Avoid "Absolute path information is required" exception string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll); assembly = Assembly.LoadFile(fullPath); } else { assembly = Assembly.LoadFrom(macroDll); } c.AddMacros(assembly); }); } foreach (var macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if (options.TryGetValue("noparallel", out value) && (value == null || value == "true")) { c.Parallel = false; } if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith(".")) { c.OutExt = "." + c.OutExt; } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = lang.Printer ?? c.OutLang; } if (options.TryGetValue("forcelang", out value) && (value == null || value == "true")) { c.ForceInLang = true; } if (!options.ContainsKey("outlang") && c.OutExt != null && FileNameToLanguage(c.OutExt) == null) { sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt); } double num; if (options.TryGetValue("timeout", out value)) { if (!double.TryParse(value, out num) || !(num >= 0)) { sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt); } else { c.AbortTimeout = TimeSpan.FromSeconds(num); } } return(true); }
protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback) { string oldCurDir = Environment.CurrentDirectory; try { string inputFolder = Path.GetDirectoryName(inputFilePath); Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed var options = new BMultiMap<string, string>(); var argList = G.SplitCommandLineArguments(defaultNamespace); UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions); string _; var KnownOptions = LeMP.Compiler.KnownOptions; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) LeMP.Compiler.ShowHelp(KnownOptions); // Originally I wrote a conversion from IVsGeneratorProgress to // IMessageSink so that errors could be reported immediately and // directly to Visual Studio. This broke in a bizarre way when I // added processing on a separate thread (in order to be able to // abort the thread if it runs too long); I got the following // InvalidCastException: "Unable to cast COM object of type 'System.__ComObject' // to interface type 'Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress'. // This operation failed because the QueryInterface call on the COM component for // the interface with IID '{BED89B98-6EC9-43CB-B0A8-41D6E2D6669D}' failed due to // the following error: No such interface supported (Exception from HRESULT: // 0x80004002 (E_NOINTERFACE))." // // A simple solution is to store the messages rather than reporting // them immediately. I'll report the errors at the very end. MessageHolder sink = new MessageHolder(); var sourceFile = new InputOutput((UString)inputFileContents, Path.GetFileName(inputFilePath)); var c = new Compiler(sink, sourceFile) { AbortTimeout = TimeSpan.FromSeconds(10), Parallel = false // only one file, parallel doesn't help }; if (LeMP.Compiler.ProcessArguments(c, options)) { if (options.ContainsKey("no-out-header")) { options.Remove("no-out-header", 1); c.NoOutHeader = true; } LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions); if (c != null) { if (inputFilePath.EndsWith(".les", StringComparison.OrdinalIgnoreCase)) c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les")); Configure(c); c.Run(); // Report errors foreach (var msg in sink.List) ReportErrorToVS(progressCallback, msg.Severity, msg.Context, msg.Format, msg.Args); return Encoding.UTF8.GetBytes(c.Output.ToString()); } } return null; } finally { Environment.CurrentDirectory = oldCurDir; } }
/// <summary>Processes all standard command-line arguments from /// <see cref="KnownOptions"/>, except --help.</summary> /// <param name="options">A set of options, presumably derived from command- /// line options using <see cref="UG.ProcessCommandLineArguments"/></param> /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>) /// about options not listed in <see cref="KnownOptions"/>.</param> /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param> /// <returns>true, unless inputFiles != null and all input files failed to open.</returns> /// <remarks> /// This method calls AddStdMacros() unless options includes "nostdmacros". /// </remarks> public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null) { Compiler c = this; string value; bool? flag; double? num; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail); if (warnAboutUnknownOptions) { WarnAboutUnknownOptions(options, Sink, KnownOptions); } if (options.TryGetValue("verbose", out value)) { if (value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong filter.MinSeverity = Severity.Verbose; } } } IMessageSink sink = c.Sink = filter; if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null) { c.MaxExpansions = (int)num.Value; } foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { // When running standalone, Assembly.Load works properly, // but not when running in Visual Studio. I'm speculating it's // because Visual Studio loads the Custom Tool in the "LoadFrom" // context and Assembly.Load ignores assemblies loaded in the // LoadFrom context (maybe not VS's fault as it loads us via COM) // See https://blogs.msdn.microsoft.com/suzcook/2003/05/29/choosing-a-binding-context/ // Workaround for idiotic MS design: reprogram Load to find // assemblies that are already loaded. AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => { return(AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.FullName == e.Name)); }; string path = Path.Combine(Environment.CurrentDirectory, macroDll); byte[] bytes = File.ReadAllBytes(path); assembly = Assembly.Load(bytes); c.AddMacros(assembly); }); } foreach (string macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if ((flag = ParseBoolOption(options, "noparallel", sink)) != null) { c.Parallel = flag.Value; } if (options.TryGetValue("outext", out c.OutExt)) { if (c.OutExt != null && !c.OutExt.StartsWith(".")) { c.OutExt = "." + c.OutExt; } } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = (lang as ILNodePrinter) ?? c.OutLang; } if ((flag = ParseBoolOption(options, "forcelang", sink)) != null) { c.ForceInLang = flag.Value; } if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null) { sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt); } if ((num = ParseNumericOption(options, "timeout", sink)) != null) { c.AbortTimeout = TimeSpan.FromSeconds(num.Value); } foreach (string exprStr in options["set"]) { SetPropertyHelper(exprStr, quote: false); } foreach (string exprStr in options["snippet"]) { SetPropertyHelper(exprStr, quote: true); } if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value)) { AddStdMacros(); } if (options.TryGetValue("preserve-comments", out value)) { PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0"); } // Printing options if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null) { OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value); } if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null) { OutOptions.AllowChangeParentheses = flag.Value; } if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null) { OutOptions.OmitComments = flag.Value; } if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null) { OutOptions.OmitUnknownTrivia = flag.Value; } if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null) { OutOptions.PrintTriviaExplicitly = flag.Value; } if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null) { OutOptions.CompatibilityMode = flag.Value; } if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null) { OutOptions.CompactMode = flag.Value; } if (inputFiles != null) { this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles)); if (inputFiles.Count != 0 && Files.Count == 0) { return(false); } } return(true); }
/// <summary>Processes all standard command-line arguments from /// <see cref="KnownOptions"/>, except --help.</summary> /// <param name="options">A set of options, presumably derived from command- /// line options using <see cref="UG.ProcessCommandLineArguments"/></param> /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>) /// about options not listed in <see cref="KnownOptions"/>.</param> /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param> /// <returns>true, unless inputFiles != null and all input files failed to open.</returns> /// <remarks> /// This method calls AddStdMacros() unless options includes "nostdmacros". /// </remarks> public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null) { Compiler c = this; string value; bool? flag; double? num; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail); if (warnAboutUnknownOptions) { WarnAboutUnknownOptions(options, Sink, KnownOptions); } if (options.TryGetValue("verbose", out value)) { if (value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong filter.MinSeverity = Severity.Verbose; } } } IMessageSink sink = c.Sink = filter; if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null) { c.MaxExpansions = (int)num.Value; } foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { if (macroDll.Contains('\\') || macroDll.Contains('/')) { // Avoid "Absolute path information is required" exception string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll); assembly = Assembly.LoadFile(fullPath); } else { assembly = Assembly.LoadFrom(macroDll); } c.AddMacros(assembly); }); } foreach (string macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if ((flag = ParseBoolOption(options, "noparallel", sink)) != null) { c.Parallel = flag.Value; } if (options.TryGetValue("outext", out c.OutExt)) { if (c.OutExt != null && !c.OutExt.StartsWith(".")) { c.OutExt = "." + c.OutExt; } } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = (lang as ILNodePrinter) ?? c.OutLang; } if ((flag = ParseBoolOption(options, "forcelang", sink)) != null) { c.ForceInLang = flag.Value; } if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null) { sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt); } if ((num = ParseNumericOption(options, "timeout", sink)) != null) { c.AbortTimeout = TimeSpan.FromSeconds(num.Value); } foreach (string exprStr in options["set"]) { SetPropertyHelper(exprStr, quote: false); } foreach (string exprStr in options["snippet"]) { SetPropertyHelper(exprStr, quote: true); } if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value)) { AddStdMacros(); } if (options.TryGetValue("preserve-comments", out value)) { PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0"); } // Printing options if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null) { OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value); } if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null) { OutOptions.AllowChangeParentheses = flag.Value; } if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null) { OutOptions.OmitComments = flag.Value; } if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null) { OutOptions.OmitUnknownTrivia = flag.Value; } if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null) { OutOptions.PrintTriviaExplicitly = flag.Value; } if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null) { OutOptions.CompatibilityMode = flag.Value; } if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null) { OutOptions.CompactMode = flag.Value; } if (inputFiles != null) { this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles)); if (inputFiles.Count != 0 && Files.Count == 0) { return(false); } } return(true); }
private bool? ParseBoolOption(BMultiMap<string, string> options, string key, IMessageSink sink) { string value; if (!options.TryGetValue(key, out value)) return null; if (value == null) return true; if (value.Equals("true", StringComparison.InvariantCultureIgnoreCase) || value == "1") return true; if (value.Equals("false", StringComparison.InvariantCultureIgnoreCase) || value == "0") return false; if (sink != null) sink.Error("--" + key, "Expected boolean `true` or `false`"); return null; }
public AListIndexer() { _items = new BMultiMap <T, AListLeaf <K, T> >(CompareTHashCodes, CompareLeafHashCodes); }
public virtual int Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IntPtr[] outputFileContents, out uint outputSize, IVsGeneratorProgress progressCallback) { string inputFolder = Path.GetDirectoryName(inputFilePath); string oldCurDir = Environment.CurrentDirectory; try { Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed var sourceFile = new StringCharSourceFile(inputFileContents, inputFilePath); var sink = ToMessageSink(progressCallback); var c = new Compiler(sink, sourceFile); var options = new BMultiMap<string, string>(); var argList = G.SplitCommandLineArguments(defaultNamespace); UG.ProcessCommandLineArguments(argList, options, "", LEL.Compiler.ShortOptions, LEL.Compiler.TwoArgOptions); string _; var KnownOptions = LEL.Compiler.KnownOptions; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) LEL.Compiler.ShowHelp(KnownOptions); Symbol minSeverity = MessageSink.Note; var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); if (LEL.Compiler.ProcessArguments(c, options)) { LEL.Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LEL.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("Loyc.LLParserGenerator")); c.AddMacros(typeof(Loyc.LLParserGenerator.Macros).Assembly); c.Run(); } var outputBytes = Encoding.UTF8.GetBytes(c.Output.ToString()); c.Output = null; // no longer needed outputSize = (uint)outputBytes.Length; outputFileContents[0] = Marshal.AllocCoTaskMem(outputBytes.Length); Marshal.Copy(outputBytes, 0, outputFileContents[0], outputBytes.Length); } else { outputFileContents[0] = IntPtr.Zero; outputSize = 0; } return VSConstants.S_OK; } finally { Environment.CurrentDirectory = oldCurDir; } }
protected override byte[] Generate(string inputFilePath, string inputFileContents, string defaultNamespace, IVsGeneratorProgress progressCallback) { string oldCurDir = Environment.CurrentDirectory; try { string inputFolder = Path.GetDirectoryName(inputFilePath); Environment.CurrentDirectory = inputFolder; // --macros should be relative to file being processed var options = new BMultiMap <string, string>(); var argList = G.SplitCommandLineArguments(defaultNamespace); UG.ProcessCommandLineArguments(argList, options, "", LeMP.Compiler.ShortOptions, LeMP.Compiler.TwoArgOptions); string _; var KnownOptions = LeMP.Compiler.KnownOptions; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { LeMP.Compiler.ShowHelp(KnownOptions); } // Originally I wrote a conversion from IVsGeneratorProgress to // IMessageSink so that errors could be reported immediately and // directly to Visual Studio. This broke in a bizarre way when I // added processing on a separate thread (in order to be able to // abort the thread if it runs too long); I got the following // InvalidCastException: "Unable to cast COM object of type 'System.__ComObject' // to interface type 'Microsoft.VisualStudio.Shell.Interop.IVsGeneratorProgress'. // This operation failed because the QueryInterface call on the COM component for // the interface with IID '{BED89B98-6EC9-43CB-B0A8-41D6E2D6669D}' failed due to // the following error: No such interface supported (Exception from HRESULT: // 0x80004002 (E_NOINTERFACE))." // // A simple solution is to store the messages rather than reporting // them immediately. I'll report the errors at the very end. MessageHolder sink = new MessageHolder(); var sourceFile = new InputOutput((UString)inputFileContents, inputFilePath); var c = new Compiler(sink, sourceFile) { AbortTimeout = TimeSpan.FromSeconds(10), Parallel = false // only one file, parallel doesn't help }; if (c.ProcessArguments(options)) { if (options.ContainsKey("no-out-header")) { options.Remove("no-out-header", 1); c.NoOutHeader = true; } LeMP.Compiler.WarnAboutUnknownOptions(options, sink, KnownOptions); if (c != null) { if (inputFilePath.EndsWith(".les", StringComparison.OrdinalIgnoreCase)) { c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude.Les")); } Configure(c); c.Run(); // Report errors foreach (var msg in sink.List) { ReportErrorToVS(progressCallback, msg.Severity, msg.Context, msg.Format, msg.Args); } return(Encoding.UTF8.GetBytes(c.Output.ToString())); } } return(null); } finally { Environment.CurrentDirectory = oldCurDir; } }
[STAThread] // Required by ICSharpCode.TextEditor public static void Main(string[] args) { BMultiMap <string, string> options = new BMultiMap <string, string>(); var argList = args.ToList(); UG.ProcessCommandLineArguments(argList, options, "", ShortOptions, TwoArgOptions); if (!options.ContainsKey("nologo")) { Console.WriteLine("LeMP macro compiler (pre-alpha)"); } string _; if (options.TryGetValue("help", out _) || options.TryGetValue("?", out _)) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); return; } if (options.ContainsKey("editor")) { Console.WriteLine("Starting editor..."); System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); return; } Severity minSeverity = Severity.Note; #if DEBUG minSeverity = Severity.Debug; #endif var filter = new SeverityMessageFilter(MessageSink.Console, minSeverity); Compiler c = ProcessArguments(options, filter, typeof(Macros), argList); Compiler.WarnAboutUnknownOptions(options, MessageSink.Console, KnownOptions); if (c != null) { c.AddMacros(typeof(global::LeMP.StandardMacros).Assembly); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP.Prelude")); c.MacroProcessor.PreOpenedNamespaces.Add(GSymbol.Get("LeMP")); using (LNode.PushPrinter(Ecs.EcsNodePrinter.PrintPlainCSharp)) c.Run(); } else if (args.Length == 0) { ShowHelp(KnownOptions.OrderBy(p => p.Key)); Console.WriteLine(); Console.WriteLine("LeMP started without arguments. Starting editor (--editor)"); var thread = new ThreadEx(() => { System.Windows.Forms.Application.EnableVisualStyles(); System.Windows.Forms.Application.Run(new TextEditor.LempDemoForm()); }); thread.Thread.SetApartmentState(ApartmentState.STA); thread.Start(); Console.WriteLine("Press Enter to run unit tests. Using the editor? Keep the terminal open."); Console.ReadLine(); RunTests.Run(new Loyc.Syntax.Lexing.TokenTests()); RunTests.Run(new Loyc.Syntax.Les.LesLexerTests()); RunTests.Run(new Loyc.Syntax.Les.LesParserTests()); RunTests.Run(new Loyc.Syntax.Les.LesPrinterTests()); RunLeMPTests(); Ecs.Program.RunEcsTests(); } }
/// <summary>Processes command-line arguments to build a BMultiMap and /// sends those options to the other overload of this method.</summary> /// <param name="args">Arg list from which to extract options. **NOTE**: /// discovered options are removed from the list. This parameter /// cannot be an array.</param> /// <param name="warnAboutUnknownOptions">Whether this method should /// call <see cref="WarnAboutUnknownOptions"/> for you.</param> /// <param name="autoOpenInputFiles">Whether to open input files /// for you by calling <see cref="OpenSourceFiles(IMessageSink, IEnumerable{string})"/>. /// </param> /// <param name="inputFiles">A list of input files to open if /// autoOpenInputFiles is true. If this is null, The input files are /// assumed to be those command-line arguments left over after the options /// are removed.</param> /// <returns>The map of options (key-value pairs and, for options that /// don't have a value, key-null pairs).</returns> /// <remarks> /// Note: If you get your command-line arguments as a single /// string, use <see cref="G.SplitCommandLineArguments(string)"/> first /// to split it into an array. /// <para/> /// This method doesn't check for --help. To implement --help, call /// <see cref="MaybeShowHelp"/> on the return value. /// </remarks> public BMultiMap<string, string> ProcessArguments(IList<string> args, bool warnAboutUnknownOptions, bool autoOpenInputFiles, IList<string> inputFiles = null) { BMultiMap<string,string> options = new BMultiMap<string,string>(); UG.ProcessCommandLineArguments(args, options, "", ShortOptions, TwoArgOptions); if (inputFiles == null && autoOpenInputFiles) inputFiles = args; if (!ProcessArguments(options, warnAboutUnknownOptions, inputFiles)) return null; return options; }
/// <summary>Processes all standard command-line arguments from /// <see cref="KnownOptions"/>, except --help.</summary> /// <param name="options">A set of options, presumably derived from command- /// line options using <see cref="UG.ProcessCommandLineArguments"/></param> /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>) /// about options not listed in <see cref="KnownOptions"/>.</param> /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param> /// <returns>true, unless inputFiles != null and all input files failed to open.</returns> /// <remarks> /// This method calls AddStdMacros() unless options includes "nostdmacros". /// </remarks> public bool ProcessArguments(BMultiMap <string, string> options, bool warnAboutUnknownOptions, IList <string> inputFiles = null) { Compiler c = this; string value; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.Note); if (warnAboutUnknownOptions) { WarnAboutUnknownOptions(options, Sink, KnownOptions); } if (options.TryGetValue("verbose", out value)) { if (value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong filter.MinSeverity = Severity.Verbose; } } } IMessageSink sink = c.Sink = filter; if (options.TryGetValue("max-expand", out value)) { TryCatch("While parsing max-expand", sink, () => c.MaxExpansions = int.Parse(value)); } foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { if (macroDll.Contains('\\') || macroDll.Contains('/')) { // Avoid "Absolute path information is required" exception string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll); assembly = Assembly.LoadFile(fullPath); } else { assembly = Assembly.LoadFrom(macroDll); } c.AddMacros(assembly); }); } foreach (string macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if (options.TryGetValue("noparallel", out value) && (value == null || value == "true")) { c.Parallel = false; } if (options.TryGetValue("outext", out c.OutExt) && c.OutExt != null && !c.OutExt.StartsWith(".")) { c.OutExt = "." + c.OutExt; } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = lang.Printer ?? c.OutLang; } if (options.TryGetValue("forcelang", out value) && (value == null || value == "true")) { c.ForceInLang = true; } if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null) { sink.Write(Severity.Error, "--outext", "No language was found for extension «{0}»", c.OutExt); } double num; if (options.TryGetValue("timeout", out value)) { if (!double.TryParse(value, out num) || !(num >= 0)) { sink.Write(Severity.Error, "--timeout", "Invalid or missing timeout value", c.OutExt); } else { c.AbortTimeout = TimeSpan.FromSeconds(num); } } foreach (string exprStr in options["set"]) { SetPropertyHelper(exprStr, quote: false); } foreach (string exprStr in options["snippet"]) { SetPropertyHelper(exprStr, quote: true); } if (!options.TryGetValue("nostdmacros", out value)) { AddStdMacros(); } if (inputFiles != null) { this.Files = new List <InputOutput>(OpenSourceFiles(Sink, inputFiles)); if (inputFiles.Count != 0 && Files.Count == 0) { return(false); } } return(true); }
/// <summary>Processes all standard command-line arguments from /// <see cref="KnownOptions"/>, except --help.</summary> /// <param name="options">A set of options, presumably derived from command- /// line options using <see cref="UG.ProcessCommandLineArguments"/></param> /// <param name="warnAboutUnknownOptions">Whether to warn (to <see cref="Sink"/>) /// about options not listed in <see cref="KnownOptions"/>.</param> /// <param name="inputFiles">Files to open with <see cref="OpenSourceFiles"/></param> /// <returns>true, unless inputFiles != null and all input files failed to open.</returns> /// <remarks> /// This method calls AddStdMacros() unless options includes "nostdmacros". /// </remarks> public bool ProcessArguments(BMultiMap<string, string> options, bool warnAboutUnknownOptions, IList<string> inputFiles = null) { Compiler c = this; string value; bool? flag; double? num; var filter = c.Sink as SeverityMessageFilter ?? new SeverityMessageFilter(c.Sink, Severity.NoteDetail); if (warnAboutUnknownOptions) WarnAboutUnknownOptions(options, Sink, KnownOptions); if (options.TryGetValue("verbose", out value)) { if (value != "false") { try { // Enum.TryParse() does not exist before .NET 4 so use Enum.Parse filter.MinSeverity = (Severity)Enum.Parse(typeof(Severity), value); } catch (Exception) { // Docs say OverflowException, but that just sounds wrong filter.MinSeverity = Severity.Verbose; } } } IMessageSink sink = c.Sink = filter; if ((num = ParseNumericOption(options, "max-expand", sink, 0, 99999)) != null) c.MaxExpansions = (int)num.Value; foreach (var macroDll in options["macros"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { if (macroDll.Contains('\\') || macroDll.Contains('/')) { // Avoid "Absolute path information is required" exception string fullPath = Path.Combine(Environment.CurrentDirectory, macroDll); assembly = Assembly.LoadFile(fullPath); } else assembly = Assembly.LoadFrom(macroDll); c.AddMacros(assembly); }); } foreach (string macroDll in options["macros-longname"]) { Assembly assembly; TryCatch("While opening " + macroDll, sink, () => { assembly = Assembly.Load(macroDll); c.AddMacros(assembly); }); } if ((flag = ParseBoolOption(options, "noparallel", sink)) != null) c.Parallel = flag.Value; if (options.TryGetValue("outext", out c.OutExt)) { if (c.OutExt != null && !c.OutExt.StartsWith(".")) c.OutExt = "." + c.OutExt; } if (options.TryGetValue("inlang", out value)) { ApplyLanguageOption(sink, "--inlang", value, ref c.InLang); } if (options.TryGetValue("outlang", out value)) { IParsingService lang = null; ApplyLanguageOption(sink, "--outlang", value, ref lang); c.OutLang = (lang as ILNodePrinter) ?? c.OutLang; } if ((flag = ParseBoolOption(options, "forcelang", sink)) != null) c.ForceInLang = flag.Value; if (!options.ContainsKey("outlang") && c.OutExt != null && ParsingService.GetServiceForFileName(c.OutExt) == null) sink.Error("--outext", "No language was found for extension «{0}»", c.OutExt); if ((num = ParseNumericOption(options, "timeout", sink)) != null) c.AbortTimeout = TimeSpan.FromSeconds(num.Value); foreach (string exprStr in options["set"]) SetPropertyHelper(exprStr, quote: false); foreach (string exprStr in options["snippet"]) SetPropertyHelper(exprStr, quote: true); if (!options.TryGetValue("nostdmacros", out value) && !options.TryGetValue("no-std-macros", out value)) AddStdMacros(); if (options.TryGetValue("preserve-comments", out value)) PreserveComments = value == null || !value.ToString().ToLowerInvariant().IsOneOf("false", "0"); // Printing options if ((num = ParseNumericOption(options, "o-indent-spaces", sink, 0, 20)) != null) OutOptions.IndentString = num.Value <= 0 ? "\t" : new string(' ', (int)num.Value); if ((flag = ParseBoolOption(options, "o-allow-change-parens", sink)) != null) OutOptions.AllowChangeParentheses = flag.Value; if ((flag = ParseBoolOption(options, "o-omit-comments", sink)) != null) OutOptions.OmitComments = flag.Value; if ((flag = ParseBoolOption(options, "o-omit-unknown-trivia", sink)) != null) OutOptions.OmitUnknownTrivia = flag.Value; if ((flag = ParseBoolOption(options, "o-explicit-trivia", sink)) != null) OutOptions.PrintTriviaExplicitly = flag.Value; if ((flag = ParseBoolOption(options, "o-compatibility-mode", sink)) != null) OutOptions.CompatibilityMode = flag.Value; if ((flag = ParseBoolOption(options, "o-compact-mode", sink)) != null) OutOptions.CompactMode = flag.Value; if (inputFiles != null) { this.Files = new List<InputOutput>(OpenSourceFiles(Sink, inputFiles)); if (inputFiles.Count != 0 && Files.Count == 0) return false; } return true; }