private static bool ParseProjectFile(string projectFile, out CompilationJob job) { job = null; if (!IsLegalPProjFile(projectFile, out FileInfo projectFilePath)) { CommandlineOutput.WriteMessage( $"Illegal P project file name {projectFile} or file {projectFilePath?.FullName} not found", SeverityKind.Error); return(false); } CommandlineOutput.WriteMessage($".... Parsing the project file: {projectFile}", SeverityKind.Info); CompilerOutput outputLanguage = CompilerOutput.C; List <FileInfo> inputFiles = new List <FileInfo>(); bool generateSourceMaps = false; List <string> projectDependencies = new List <string>(); // get all project dependencies and the input files var dependencies = GetAllProjectDependencies(projectFilePath); inputFiles.AddRange(dependencies.inputFiles); projectDependencies.AddRange(dependencies.projectDependencies); if (inputFiles.Count == 0) { CommandlineOutput.WriteMessage("At least one .p file must be provided as input files", SeverityKind.Error); return(false); } // get project name string projectName = GetProjectName(projectFilePath); // get output directory DirectoryInfo outputDirectory = GetOutputDirectory(projectFilePath); // get target language GetTargetLanguage(projectFilePath, ref outputLanguage, ref generateSourceMaps); job = new CompilationJob(output: new DefaultCompilerOutput(outputDirectory), outputLanguage: outputLanguage, inputFiles: inputFiles, projectName: projectName, generateSourceMaps: generateSourceMaps, projectDependencies); return(true); }
public static CommandLineParseResult ParseArguments(IEnumerable <string> args, out CompilationJob job) { job = null; CompilerOutput outputLanguage = CompilerOutput.C; DirectoryInfo outputDirectory = null; List <string> commandLineFileNames = new List <string>(); List <FileInfo> inputFiles = new List <FileInfo>(); string targetName = null; bool generateSourceMaps = false; // enforce the argument prority // proj takes priority over everything else and no other arguments should be passed if (args.Where(a => a.ToLowerInvariant().Contains("-proj:")).Any() && args.Count() > 1) { CommandlineOutput.WriteMessage("-proj cannot be combined with other commandline options", SeverityKind.Error); return(Failure); } foreach (string x in args) { string arg = x; string colonArg = null; if (arg[0] == '-') { int colonIndex = arg.IndexOf(':'); if (colonIndex >= 0) { arg = x.Substring(0, colonIndex); colonArg = x.Substring(colonIndex + 1); } switch (arg.Substring(1).ToLowerInvariant()) { case "t": case "target": if (colonArg == null) { CommandlineOutput.WriteMessage("Missing target name", SeverityKind.Error); } else if (targetName == null) { targetName = colonArg; } else { CommandlineOutput.WriteMessage("Only one target must be specified", SeverityKind.Error); } break; case "g": case "generate": switch (colonArg?.ToLowerInvariant()) { case null: CommandlineOutput.WriteMessage( "Missing generation argument, expecting generate:[C,Coyote]", SeverityKind.Error); return(Failure); case "c": outputLanguage = CompilerOutput.C; break; case "coyote": outputLanguage = CompilerOutput.Coyote; break; default: CommandlineOutput.WriteMessage( $"Unrecognized generate option '{colonArg}', expecting C or Coyote", SeverityKind.Error); return(Failure); } break; case "o": case "outputdir": if (colonArg == null) { CommandlineOutput.WriteMessage("Must supply path for output directory", SeverityKind.Error); return(Failure); } outputDirectory = Directory.CreateDirectory(colonArg); break; case "proj": if (colonArg == null) { CommandlineOutput.WriteMessage("Must supply project file for compilation", SeverityKind.Error); return(Failure); } else { // Parse the project file and generate the compilation job, ignore all other arguments passed if (ParseProjectFile(colonArg, out job)) { return(Success); } else { return(Failure); } } case "s": case "sourcemaps": switch (colonArg?.ToLowerInvariant()) { case null: case "true": generateSourceMaps = true; break; case "false": generateSourceMaps = false; break; default: CommandlineOutput.WriteMessage( "sourcemaps argument must be either 'true' or 'false'", SeverityKind.Error); return(Failure); } break; case "h": case "help": case "-help": return(HelpRequested); default: commandLineFileNames.Add(arg); CommandlineOutput.WriteMessage($"Unknown Command {arg.Substring(1)}", SeverityKind.Error); return(Failure); } } else { commandLineFileNames.Add(arg); } } // We are here so no project file supplied lets create a compilation job with other arguments // Each command line file name must be a legal P file name foreach (string inputFileName in commandLineFileNames) { if (IsLegalPFile(inputFileName, out FileInfo fullPathName)) { inputFiles.Add(fullPathName); } else { CommandlineOutput.WriteMessage( $"Illegal P file name {inputFileName} or file {fullPathName.FullName} not found", SeverityKind.Error); } } if (inputFiles.Count == 0) { CommandlineOutput.WriteMessage("At least one .p file must be provided", SeverityKind.Error); return(Failure); } string projectName = targetName ?? Path.GetFileNameWithoutExtension(inputFiles[0].FullName); if (!IsLegalUnitName(projectName)) { CommandlineOutput.WriteMessage($"{projectName} is not a legal project name", SeverityKind.Error); return(Failure); } if (outputDirectory == null) { outputDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); } job = new CompilationJob(output: new DefaultCompilerOutput(outputDirectory), outputLanguage: outputLanguage, inputFiles: inputFiles, projectName: projectName, generateSourceMaps: generateSourceMaps); return(Success); }
/// <summary> /// Parse commandline arguments /// </summary> /// <param name="args">list of commandline inputs</param> /// <param name="job">P's compilation job</param> /// <returns></returns> public static CommandLineParseResult ParseArguments(IEnumerable <string> args, out CompilationJob job) { job = null; var commandlineParser = new ParseCommandlineOptions(CommandlineOutput); // enforce the argument priority var commandlineArgs = args.ToList(); if (commandlineArgs.Any(a => a.ToLowerInvariant().Contains("-h"))) { return(HelpRequested); } // proj takes priority over everything else and no other arguments should be allowed if (commandlineArgs.Any(a => a.ToLowerInvariant().Contains("-proj:"))) { if (commandlineArgs.Count() > 1) { CommandlineOutput.WriteMessage("-proj option cannot be combined with other commandline options", SeverityKind.Error); return(Failure); } else { var option = commandlineArgs.First(); var projectPath = option.Substring(option.IndexOf(":", StringComparison.Ordinal) + 1); // Parse the project file and generate the compilation job return(commandlineParser.ParseProjectFile(projectPath, out job) ? Success : Failure); } } else { // parse command line options and generate the compilation job return(commandlineParser.ParseCommandLineOptions(commandlineArgs, out job) ? Success : Failure); } }
private static bool ParseProjectFile(string projectFile, out CompilationJob job) { job = null; if (!IsLegalPProjFile(projectFile, out FileInfo fullPathName)) { CommandlineOutput.WriteMessage( $"Illegal P project file name {projectFile} or file {fullPathName?.FullName} not found", SeverityKind.Error); return(false); } CommandlineOutput.WriteMessage($".... Parsing the project file: {projectFile}", SeverityKind.Info); CompilerOutput outputLanguage = CompilerOutput.C; DirectoryInfo outputDirectory = null; List <FileInfo> inputFiles = new List <FileInfo>(); string targetName = null; bool generateSourceMaps = false; XElement projectXML = XElement.Load(fullPathName.FullName); // get all files to be compiled foreach (XElement inputs in projectXML.Elements("InputFiles")) { foreach (XElement inputFileName in inputs.Elements("PFile")) { var pFiles = new List <string>(); if (Directory.Exists(inputFileName.Value)) { foreach (var files in Directory.GetFiles(inputFileName.Value, "*.p")) { pFiles.Add(files); } } else { pFiles.Add(inputFileName.Value); } foreach (var pFile in pFiles) { if (IsLegalPFile(pFile, out FileInfo pFilePathName)) { CommandlineOutput.WriteMessage($"....... project includes: {pFilePathName.FullName}", SeverityKind.Info); inputFiles.Add(pFilePathName); } else { CommandlineOutput.WriteMessage( $"Illegal P file name {pFile} or file {pFilePathName?.FullName} not found", SeverityKind.Error); } } } } if (inputFiles.Count == 0) { CommandlineOutput.WriteMessage("At least one .p file must be provided as input files", SeverityKind.Error); return(false); } // get target file name if (projectXML.Elements("TargetFileName").Any()) { targetName = projectXML.Element("TargetFileName").Value; if (!IsLegalUnitName(targetName)) { CommandlineOutput.WriteMessage($"{targetName} is not a legal target file name", SeverityKind.Error); return(false); } } string projectName = targetName ?? Path.GetFileNameWithoutExtension(inputFiles[0].FullName); // get output directory outputDirectory = projectXML.Elements("OutputDir").Any() ? Directory.CreateDirectory(projectXML.Element("OutputDir").Value) : new DirectoryInfo(Directory.GetCurrentDirectory()); // get target language if (projectXML.Elements("Target").Any()) { switch (projectXML.Element("Target").Value.ToLowerInvariant()) { case "c": outputLanguage = CompilerOutput.C; // check for generate source maps attribute try { if (projectXML.Element("Target").Attributes("sourcemaps").Any()) { generateSourceMaps = bool.Parse(projectXML.Element("Target").Attribute("sourcemaps").Value); } } catch (Exception) { CommandlineOutput.WriteMessage($"Expected true or false, received {projectXML.Element("Target").Attribute("sourcemaps").Value}", SeverityKind.Error); } break; case "p#": outputLanguage = CompilerOutput.PSharp; break; default: outputLanguage = CompilerOutput.C; break; } } job = new CompilationJob(output: new DefaultCompilerOutput(outputDirectory), outputLanguage: outputLanguage, inputFiles: inputFiles, projectName: projectName, generateSourceMaps: generateSourceMaps); return(true); }
/// <summary> /// Parse the commandline arguments to construct the compilation job /// </summary> /// <param name="args">Commandline arguments</param> /// <param name="job">Generated Compilation job</param> /// <returns></returns> internal bool ParseCommandLineOptions(IEnumerable <string> args, out CompilationJob job) { string targetName = null; CompilerOutput outputLanguage = CompilerOutput.CSharp; DirectoryInfo outputDirectory = null; List <FileInfo> inputFiles = new List <FileInfo>(); job = null; try { foreach (string x in args) { string arg = x; string colonArg = null; if (arg[0] == '-') { int colonIndex = arg.IndexOf(':'); if (colonIndex >= 0) { arg = x.Substring(0, colonIndex); colonArg = x.Substring(colonIndex + 1); } switch (arg.Substring(1).ToLowerInvariant()) { case "t": case "target": if (colonArg == null) { throw new CommandlineParsingError("Missing target project name (-t:<project name>)"); } else if (targetName == null) { targetName = colonArg; } else { throw new CommandlineParsingError("Only one target must be specified with (-t)"); } break; case "g": case "generate": switch (colonArg?.ToLowerInvariant()) { case null: throw new CommandlineParsingError("Missing generation argument, expecting generate:[C,CSharp,RVM]"); case "c": outputLanguage = CompilerOutput.C; break; case "csharp": outputLanguage = CompilerOutput.CSharp; break; case "rvm": outputLanguage = CompilerOutput.Rvm; break; default: throw new CommandlineParsingError($"Unrecognized generate option '{colonArg}', expecting C or CSharp"); } break; case "o": case "outputdir": if (colonArg == null) { throw new CommandlineParsingError("Must supply path for output directory (-o:<output directory>)"); } outputDirectory = Directory.CreateDirectory(colonArg); break; default: CommandLineOptions.PrintUsage(); throw new CommandlineParsingError($"Illegal Command {arg.Substring(1)}"); } } else { if (IsLegalPFile(arg, out FileInfo fullPathName)) { inputFiles.Add(fullPathName); } else { throw new CommandlineParsingError($"Illegal P file name {arg} or file {fullPathName.FullName} not found"); } } } if (inputFiles.Count == 0) { commandlineOutput.WriteError("At least one .p file must be provided"); return(false); } string projectName = targetName ?? Path.GetFileNameWithoutExtension(inputFiles[0].FullName); if (!IsLegalProjectName(projectName)) { commandlineOutput.WriteError($"{projectName} is not a legal project name"); return(false); } if (outputDirectory == null) { outputDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); } job = new CompilationJob(output: new DefaultCompilerOutput(outputDirectory), outputDirectory, outputLanguage: outputLanguage, inputFiles: inputFiles, projectName: projectName, outputDirectory); commandlineOutput.WriteInfo($"----------------------------------------"); return(true); } catch (CommandlineParsingError ex) { commandlineOutput.WriteError($"<Error parsing commandline>:\n {ex.Message}"); return(false); } catch (Exception other) { commandlineOutput.WriteError($"<Internal Error>:\n {other.Message}\n <Please report to the P team ([email protected]) or create an issue on GitHub, Thanks!>"); return(false); } }
public static CommandLineParseResult ParseArguments(IEnumerable <string> args, out CompilationJob job) { job = null; var outputLanguage = CompilerOutput.C; DirectoryInfo outputDirectory = null; var commandLineFileNames = new List <string>(); var inputFiles = new List <FileInfo>(); string targetName = null; var generateSourceMaps = false; foreach (var x in args) { var arg = x; string colonArg = null; if (arg[0] == '-') { var colonIndex = arg.IndexOf(':'); if (colonIndex >= 0) { arg = x.Substring(0, colonIndex); colonArg = x.Substring(colonIndex + 1); } switch (arg.Substring(1).ToLowerInvariant()) { case "t": case "target": if (colonArg == null) { CommandlineOutput.WriteMessage("Missing target name", SeverityKind.Error); } else if (targetName == null) { targetName = colonArg; } else { CommandlineOutput.WriteMessage("Only one target must be specified", SeverityKind.Error); } break; case "g": case "generate": switch (colonArg?.ToLowerInvariant()) { case null: CommandlineOutput.WriteMessage( "Missing generation argument, expecting generate:[C,P#]", SeverityKind.Error); return(Failure); case "c": outputLanguage = CompilerOutput.C; break; case "p#": outputLanguage = CompilerOutput.PSharp; break; default: CommandlineOutput.WriteMessage( $"Unrecognized generate option '{colonArg}', expecting C or P#", SeverityKind.Error); return(Failure); } break; case "o": case "outputdir": if (colonArg == null) { CommandlineOutput.WriteMessage("Must supply path for output directory", SeverityKind.Error); return(Failure); } outputDirectory = Directory.CreateDirectory(colonArg); break; case "s": case "sourcemaps": switch (colonArg?.ToLowerInvariant()) { case null: case "true": generateSourceMaps = true; break; case "false": generateSourceMaps = false; break; default: CommandlineOutput.WriteMessage( "sourcemaps argument must be either 'true' or 'false'", SeverityKind.Error); return(Failure); } break; case "h": case "help": case "-help": return(HelpRequested); default: commandLineFileNames.Add(arg); CommandlineOutput.WriteMessage($"Unknown Command {arg.Substring(1)}", SeverityKind.Error); return(Failure); } } else { commandLineFileNames.Add(arg); } } // Each command line file name must be a legal P file name foreach (var inputFileName in commandLineFileNames) { if (IsLegalPFile(inputFileName, out var fullPathName)) { inputFiles.Add(fullPathName); } else { CommandlineOutput.WriteMessage( $"Illegal P file name {fullPathName} or file {fullPathName} not found", SeverityKind.Error); } } if (inputFiles.Count == 0) { CommandlineOutput.WriteMessage("At least one .p file must be provided", SeverityKind.Error); return(Failure); } var projectName = targetName ?? Path.GetFileNameWithoutExtension(inputFiles[0].FullName); if (!IsLegalUnitName(projectName)) { CommandlineOutput.WriteMessage($"{projectName} is not a legal project name", SeverityKind.Error); return(Failure); } if (outputDirectory == null) { outputDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); } job = new CompilationJob(new DefaultCompilerOutput(outputDirectory), outputLanguage, inputFiles, projectName, generateSourceMaps); return(Success); }