/// <summary> /// Execute method. /// </summary> /// <param name="pipe">NamedPipeServerStream</param> public override void execute(NamedPipeServerStream pipe) { ReturnCode returnCode = ReturnCode.Success; ConfigSerializer configSerializer = new ConfigSerializer(); byte[] messagebuffer = new byte[100]; byte[] originalbuffer = new byte[100]; int i = 0; do { pipe.Read(messagebuffer, 0, messagebuffer.Length); System.Buffer.BlockCopy(messagebuffer, 0, originalbuffer, i, messagebuffer.Length); Array.Resize(ref originalbuffer, originalbuffer.Length + 100); messagebuffer = new byte[100]; i = i + 100; }while (!pipe.IsMessageComplete); try { TypeCobolConfiguration config = new TypeCobolConfiguration(); config = configSerializer.Deserialize(originalbuffer); config.Format = TypeCobolOptionSet.CreateFormat(config.EncFormat, ref config); returnCode = CLI.runOnce(config); //Try to run TypeCobol ad get status in returnCode } catch { returnCode = ReturnCode.FatalError; } finally { //Write a "reponse" to the client which is waiting pipe.WriteByte((byte)returnCode); } }
public TypeCobolOptions(TypeCobolConfiguration config) { HaltOnMissingCopy = config.HaltOnMissingCopyFilePath != null; ExecToStep = config.ExecToStep; UseAntlrProgramParsing = config.UseAntlrProgramParsing; UseEuroInformationLegacyReplacingSyntax = config.UseEuroInformationLegacyReplacingSyntax; }
public Workspace(string rootDirectoryFullName, string workspaceName) { TypeCobolConfiguration = new TypeCobolConfiguration(); OpenedFileCompiler = new Dictionary <Uri, FileCompiler>(); this.RootDirectoryFullName = rootDirectoryFullName; this.WorkspaceName = workspaceName; this.CompilationProject = new CompilationProject( WorkspaceName, RootDirectoryFullName, Extensions, Encoding.GetEncoding("iso-8859-1"), EndOfLineDelimiter.CrLfCharacters, 80, ColumnsLayout.CobolReferenceFormat, new TypeCobolOptions()); //Initialize a default CompilationProject - has to be recreated after ConfigurationChange Notification }
public Workspace(string rootDirectoryFullName, string workspaceName, Queue <MessageActionWrapper> messagesActionsQueue, Func <string, Uri, bool> logger) { MessagesActionsQueue = messagesActionsQueue; TypeCobolConfiguration = new TypeCobolConfiguration(); OpenedFileCompiler = new Dictionary <Uri, FileCompiler>(); _fileCompilerWaittingForNodePhase = new List <FileCompiler>(); _Logger = logger; this._rootDirectoryFullName = rootDirectoryFullName; this._workspaceName = workspaceName; this.CompilationProject = new CompilationProject( _workspaceName, _rootDirectoryFullName, _extensions, Encoding.GetEncoding("iso-8859-1"), EndOfLineDelimiter.CrLfCharacters, 80, ColumnsLayout.CobolReferenceFormat, new TypeCobolOptions()); //Initialize a default CompilationProject - has to be recreated after ConfigurationChange Notification _DepWatcher = new DependenciesFileWatcher(this); }
static int Main(string[] argv) { bool help = false; bool version = false; bool once = false; StartClient startClient = StartClient.No; var config = new TypeCobolConfiguration(); config.CommandLine = string.Join(" ", argv); var pipename = "TypeCobol.Server"; var p = TypeCobolOptionSet.GetCommonTypeCobolOptions(config); //Add custom options for CLI p.Add(string.Format("USAGE\n {0} [OPTIONS]... [PIPENAME]\n VERSION:\n {1} \n DESCRIPTION: \n Run the TypeCObol parser server", PROGNAME, PROGVERSION)); p.Add("k|startServer:", "Start the server if not already started, and executes commandline.\n" + "By default the server is started in window mode\n" + "'{hidden}' hide the window.", v => { if ("hidden".Equals(v, StringComparison.InvariantCultureIgnoreCase)) { startClient = StartClient.HiddenWindow; } else { startClient = StartClient.NormalWindow; } }); p.Add("1|once", "Parse one set of files and exit. If present, this option does NOT launch the server.", v => once = (v != null)); p.Add("h|help", "Output a usage message and exit.", v => help = (v != null)); p.Add("V|version", "Output the version number of " + PROGNAME + " and exit.", v => version = (v != null)); //Add DefaultCopies to running session var folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); config.CopyFolders.Add(folder + @"\DefaultCopies\"); try { List <string> args; try { args = p.Parse(argv); } catch (OptionException ex) { return(exit(ReturnCode.FatalError, ex.Message)); } if (help) { p.WriteOptionDescriptions(Console.Out); return(0); } if (version) { Console.WriteLine(PROGVERSION); return(0); } if (config.Telemetry) { AnalyticsWrapper.Telemetry.DisableTelemetry = false; //If telemetry arg is passed enable telemetry } if (config.OutputFiles.Count == 0 && config.ExecToStep >= ExecutionStep.Generate) { config.ExecToStep = ExecutionStep.SemanticCheck; //If there is no given output file, we can't run generation, fallback to SemanticCheck } if (config.OutputFiles.Count > 0 && config.InputFiles.Count != config.OutputFiles.Count) { return(exit(ReturnCode.OutputFileError, "The number of output files must be equal to the number of input files.")); } if (args.Count > 0) { pipename = args[0]; } //"startClient" will be true when "-K" is passed as an argument in command line. if (startClient != StartClient.No && once) { pipename = "TypeCobol.Server"; using (NamedPipeClientStream namedPipeClient = new NamedPipeClientStream(pipename)) { try { namedPipeClient.Connect(100); } catch (TimeoutException tEx) { System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); if (startClient == StartClient.NormalWindow) { startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal; } else { startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; } startInfo.FileName = "cmd.exe"; startInfo.Arguments = @"/c " + folder + Path.DirectorySeparatorChar + "TypeCobol.CLI.exe"; process.StartInfo = startInfo; process.Start(); namedPipeClient.Connect(1000); } namedPipeClient.WriteByte(68); ConfigSerializer configSerializer = new ConfigSerializer(); var configBytes = configSerializer.Serialize(config); namedPipeClient.Write(configBytes, 0, configBytes.Length); //Wait for the response "job is done" var returnCode = namedPipeClient.ReadByte(); //Get running server ReturnCode return(exit((ReturnCode)returnCode, "")); } } //option -1 else if (once) { var returnCode = CLI.runOnce(config); if (returnCode != ReturnCode.Success) { return(exit(returnCode, "Operation failled")); } } else { runServer(pipename); } } catch (Exception e) { AnalyticsWrapper.Telemetry.TrackException(e); return(exit(ReturnCode.FatalError, e.Message)); } return(exit((int)ReturnCode.Success, "Success")); }
/// <summary> /// Handle the Configuration change notification. /// </summary> /// <param name="arguments">The arguments</param> public void DidChangeConfigurationParams(IEnumerable <string> arguments) { TypeCobolConfiguration = new TypeCobolConfiguration(); var options = TypeCobolOptionSet.GetCommonTypeCobolOptions(TypeCobolConfiguration); var errors = TypeCobolOptionSet.InitializeCobolOptions(TypeCobolConfiguration, arguments, options); //Adding default copies folder var folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); TypeCobolConfiguration.CopyFolders.Add(folder + @"\DefaultCopies\"); if (TypeCobolConfiguration.Telemetry) { AnalyticsWrapper.Telemetry.TelemetryVerboseLevel = TelemetryVerboseLevel.Completion; //If telemetry arg is passed enable telemetry } if (TypeCobolConfiguration.ExecToStep >= ExecutionStep.Generate) { TypeCobolConfiguration.ExecToStep = ExecutionStep.CrossCheck; //Language Server does not support Cobol Generation for now } var typeCobolOptions = new TypeCobolOptions { HaltOnMissingCopy = TypeCobolConfiguration.HaltOnMissingCopyFilePath != null, ExecToStep = TypeCobolConfiguration.ExecToStep, #if EUROINFO_RULES AutoRemarksEnable = TypeCobolConfiguration.AutoRemarks #endif }; CompilationProject = new CompilationProject(_workspaceName, _rootDirectoryFullName, _extensions, TypeCobolConfiguration.Format.Encoding, TypeCobolConfiguration.Format.EndOfLineDelimiter, TypeCobolConfiguration.Format.FixedLineLength, TypeCobolConfiguration.Format.ColumnsLayout, typeCobolOptions); if (TypeCobolConfiguration.CopyFolders != null && TypeCobolConfiguration.CopyFolders.Count > 0) { foreach (var copyFolder in TypeCobolConfiguration.CopyFolders) { CompilationProject.SourceFileProvider.AddLocalDirectoryLibrary(copyFolder, false, new[] { ".cpy" }, TypeCobolConfiguration.Format.Encoding, TypeCobolConfiguration.Format.EndOfLineDelimiter, TypeCobolConfiguration.Format.FixedLineLength); } } if (OpenedFileCompiler.Count > 0) { RefreshOpenedFiles(); } else { RefreshCustomSymbols(); } //Dispose previous watcher before setting new ones _DepWatcher.Dispose(); foreach (var depFolder in TypeCobolConfiguration.Dependencies) { _DepWatcher.SetDirectoryWatcher(depFolder); } foreach (var intrinsicFolder in TypeCobolConfiguration.Copies) { _DepWatcher.SetDirectoryWatcher(intrinsicFolder); } }
/// <summary> /// runOnce method to parse the input file(s). /// </summary> /// <param name="config">Config</param> internal static ReturnCode runOnce(TypeCobolConfiguration config) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string debugLine = DateTime.Now + " start parsing of "; if (config.InputFiles.Count > 0) { debugLine += Path.GetFileName(config.InputFiles[0]); } debugLine += "\n"; File.AppendAllText("TypeCobol.CLI.log", debugLine); Console.WriteLine(debugLine); TextWriter textWriter; if (config.ErrorFile == null) { textWriter = Console.Error; } else { textWriter = File.CreateText(config.ErrorFile); } AbstractErrorWriter errorWriter; if (config.IsErrorXML) { errorWriter = new XMLWriter(textWriter); } else { errorWriter = new ConsoleWriter(textWriter); } errorWriter.Outputs = config.OutputFiles; //Call the runOnce2() Methode and manage all the different kinds of exception. ReturnCode returnCode; try { returnCode = runOnce2(config, errorWriter); } catch (TypeCobolException typeCobolException)//Catch managed exceptions { AnalyticsWrapper.Telemetry.TrackException(typeCobolException); if (typeCobolException.NeedMail) { AnalyticsWrapper.Telemetry.SendMail(typeCobolException, config.InputFiles, config.CopyFolders, config.CommandLine); } if (typeCobolException.Logged) { Server.AddError(errorWriter, typeCobolException.MessageCode, typeCobolException.ColumnStartIndex, typeCobolException.ColumnEndIndex, typeCobolException.LineNumber, typeCobolException.Message + "\n" + typeCobolException.StackTrace, typeCobolException.Path); } if (typeCobolException is PresenceOfDiagnostics) { returnCode = ReturnCode.ParsingDiagnostics; } else if (typeCobolException is ParsingException) { returnCode = ReturnCode.FatalError; } else if (typeCobolException is GenerationException) { returnCode = ReturnCode.GenerationError; } else if (typeCobolException is MissingCopyException) { returnCode = ReturnCode.MissingCopy; } else { returnCode = ReturnCode.FatalError; //Just in case.. } } catch (Exception e)//Catch any other exception { AnalyticsWrapper.Telemetry.TrackException(e); AnalyticsWrapper.Telemetry.SendMail(e, config.InputFiles, config.CopyFolders, config.CommandLine); Server.AddError(errorWriter, MessageCode.SyntaxErrorInParser, e.Message + e.StackTrace, string.Empty); returnCode = ReturnCode.FatalError; } errorWriter.Write(returnCode); errorWriter.FlushAndClose(); errorWriter = null; //as textWriter can be a Text file created, we need to close it textWriter.Close(); stopWatch.Stop(); debugLine = " parsed in " + stopWatch.Elapsed + " ms\n"; File.AppendAllText("TypeCobol.CLI.log", debugLine); Console.WriteLine(debugLine); AnalyticsWrapper.Telemetry.TrackEvent("[Duration] Execution Time", EventType.Genration, new Dictionary <string, string> { { "Duration", "Duration" } }, //Custom properties for metrics new Dictionary <string, double> { { "ExecutionTime", stopWatch.Elapsed.Milliseconds } }); //Metrics fo duration return(returnCode); }
private static ReturnCode runOnce2(TypeCobolConfiguration config, AbstractErrorWriter errorWriter) { var parser = new Parser(); bool diagDetected = false; if (config.ExecToStep > ExecutionStep.Preprocessor) { #region Event Diags Handler EventHandler <Tools.APIHelpers.DiagnosticsErrorEvent> DiagnosticsErrorEvent = delegate(object sender, Tools.APIHelpers.DiagnosticsErrorEvent diagEvent) { //Delegate Event to handle diagnostics generated while loading dependencies/intrinsics diagDetected = true; var diagnostic = diagEvent.Diagnostic; Server.AddError(errorWriter, MessageCode.IntrinsicLoading, diagnostic.ColumnStart, diagnostic.ColumnEnd, diagnostic.Line, "Error while parsing " + diagEvent.Path + ": " + diagnostic, diagEvent.Path); }; EventHandler <Tools.APIHelpers.DiagnosticsErrorEvent> DependencyErrorEvent = delegate(object sender, Tools.APIHelpers.DiagnosticsErrorEvent diagEvent) { //Delegate Event to handle diagnostics generated while loading dependencies/intrinsics Server.AddError(errorWriter, diagEvent.Path, diagEvent.Diagnostic); }; #endregion parser.CustomSymbols = Tools.APIHelpers.Helpers.LoadIntrinsic(config.Copies, config.Format, DiagnosticsErrorEvent); //Load intrinsic parser.CustomSymbols = Tools.APIHelpers.Helpers.LoadDependencies(config.Dependencies, config.Format, parser.CustomSymbols, config.InputFiles, DependencyErrorEvent); //Load dependencies if (diagDetected) { throw new CopyLoadingException("Diagnostics detected while parsing Intrinsic file", null, null, logged: false, needMail: false); } } ReturnCode returnCode = ReturnCode.Success; for (int c = 0; c < config.InputFiles.Count; c++) { string path = config.InputFiles[c]; try { var typeCobolOptions = new TypeCobolOptions { HaltOnMissingCopy = config.HaltOnMissingCopyFilePath != null, ExecToStep = config.ExecToStep, }; #if EUROINFO_RULES typeCobolOptions.AutoRemarksEnable = config.AutoRemarks; #endif parser.Init(path, typeCobolOptions, config.Format, config.CopyFolders); //Init parser create CompilationProject & Compiler before parsing the given file } catch (Exception ex) { throw new ParsingException(MessageCode.ParserInit, ex.Message, path, ex); //Make ParsingException trace back to RunOnce() } parser.Parse(path); bool copyAreMissing = false; if (!string.IsNullOrEmpty(config.HaltOnMissingCopyFilePath)) { if (parser.MissingCopys.Count > 0) { //Write in the specified file all the absent copys detected File.WriteAllLines(config.HaltOnMissingCopyFilePath, parser.MissingCopys); copyAreMissing = true; } else { //Delete the file File.Delete(config.HaltOnMissingCopyFilePath); } } if (config.ExecToStep >= ExecutionStep.Preprocessor && !string.IsNullOrEmpty(config.ExtractedCopiesFilePath)) { if (parser.Results.CopyTextNamesVariations.Count > 0) { #if EUROINFO_RULES var copiesName = parser.Results.CopyTextNamesVariations.Select(cp => cp.TextName).Distinct(); //Get copies without suffix #else var copiesName = parser.Results.CopyTextNamesVariations.Select(cp => cp.TextNameWithSuffix).Distinct(); //Get copies with suffix #endif //Create an output document of all the copy encountered by the parser File.WriteAllLines(config.ExtractedCopiesFilePath, copiesName); } else { File.Delete(config.ExtractedCopiesFilePath); } } var allDiags = parser.Results.AllDiagnostics(); errorWriter.AddErrors(path, allDiags.Take(config.MaximumDiagnostics == 0 ? allDiags.Count : config.MaximumDiagnostics)); //Write diags into error file if (allDiags.Count > 0) { foreach (var diag in allDiags) { if (diag.CatchedException != null) { AnalyticsWrapper.Telemetry.TrackException(diag.CatchedException); AnalyticsWrapper.Telemetry.SendMail(diag.CatchedException, config.InputFiles, config.CopyFolders, config.CommandLine); } } AnalyticsWrapper.Telemetry.TrackEvent("[Diagnostics] Detected", EventType.Diagnostics); //Exception is thrown just below } //Copy missing is more important than diagnostics if (copyAreMissing) { throw new MissingCopyException("Some copy are missing", path, null, logged: false, needMail: false); } else if (parser.Results.AllDiagnostics().Any(d => d.Info.Severity == Compiler.Diagnostics.Severity.Error)) { throw new PresenceOfDiagnostics("Diagnostics Detected"); //Make ParsingException trace back to RunOnce() } if (parser.Results.CodeElementsDocumentSnapshot == null && config.ExecToStep > ExecutionStep.Preprocessor) { throw new ParsingException(MessageCode.SyntaxErrorInParser, "File \"" + path + "\" has syntactic error(s) preventing codegen (CodeElements).", path); //Make ParsingException trace back to RunOnce() } else if (parser.Results.ProgramClassDocumentSnapshot == null && config.ExecToStep > ExecutionStep.SyntaxCheck) { throw new ParsingException(MessageCode.SyntaxErrorInParser, "File \"" + path + "\" has semantic error(s) preventing codegen (ProgramClass).", path); //Make ParsingException trace back to RunOnce() } if (config.ExecToStep >= ExecutionStep.Preprocessor && !string.IsNullOrEmpty(config.ExpandingCopyFilePath)) { try { var generator = GeneratorFactoryManager.Instance.Create(TypeCobol.Tools.Options_Config.OutputFormat.ExpandingCopy.ToString(), parser.Results, new StreamWriter(config.ExpandingCopyFilePath), null, null); generator.Generate(parser.Results, ColumnsLayout.CobolReferenceFormat); } catch (Exception e) { throw new GenerationException(e.Message, path, e); } } if (config.ExecToStep >= ExecutionStep.Generate) { try { //Load skeletons if necessary List <Skeleton> skeletons = null; if (!(string.IsNullOrEmpty(config.skeletonPath))) { skeletons = TypeCobol.Codegen.Config.Config.Parse(config.skeletonPath); } //Get Generator from specified config.OutputFormat var generator = GeneratorFactoryManager.Instance.Create(config.OutputFormat.ToString(), parser.Results, new StreamWriter(config.OutputFiles[c]), skeletons, AnalyticsWrapper.Telemetry.TypeCobolVersion); if (generator == null) { throw new GenerationException("Unknown OutputFormat=" + config.OutputFormat + "_", path); } //Generate and check diagnostics generator.Generate(parser.Results, ColumnsLayout.CobolReferenceFormat); if (generator.Diagnostics != null) { errorWriter.AddErrors(path, generator.Diagnostics); //Write diags into error file throw new PresenceOfDiagnostics("Diagnostics Detected"); //Make ParsingException trace back to RunOnce() } } catch (PresenceOfDiagnostics) { throw; //Throw the same exception to let runOnce() knows there is a problem } catch (GenerationException) { throw; //Throw the same exception to let runOnce() knows there is a problem } catch (Exception e) { //Otherwise create a new GenerationException throw new GenerationException(e.Message, path, e); } } if (parser.Results.AllDiagnostics().Any(d => d.Info.Severity == Compiler.Diagnostics.Severity.Warning)) { returnCode = ReturnCode.Warning; } } return(returnCode); }
private static ReturnCode runOnce2(TypeCobolConfiguration config, AbstractErrorWriter errorWriter) { SymbolTable baseTable = null; #region Dependencies parsing var depParser = new Parser(); bool diagDetected = false; if (config.ExecToStep > ExecutionStep.Preprocessor) { #region Event Diags Handler EventHandler <Tools.APIHelpers.DiagnosticsErrorEvent> DiagnosticsErrorEvent = delegate(object sender, Tools.APIHelpers.DiagnosticsErrorEvent diagEvent) { //Delegate Event to handle diagnostics generated while loading dependencies/intrinsics diagDetected = true; var diagnostic = diagEvent.Diagnostic; Server.AddError(errorWriter, MessageCode.IntrinsicLoading, diagnostic.ColumnStart, diagnostic.ColumnEnd, diagnostic.Line, "Error while parsing " + diagEvent.Path + ": " + diagnostic, diagEvent.Path); }; EventHandler <Tools.APIHelpers.DiagnosticsErrorEvent> DependencyErrorEvent = delegate(object sender, Tools.APIHelpers.DiagnosticsErrorEvent diagEvent) { //Delegate Event to handle diagnostics generated while loading dependencies/intrinsics Server.AddError(errorWriter, diagEvent.Path, diagEvent.Diagnostic); }; #endregion depParser.CustomSymbols = Tools.APIHelpers.Helpers.LoadIntrinsic(config.Copies, config.Format, DiagnosticsErrorEvent); //Load intrinsic depParser.CustomSymbols = Tools.APIHelpers.Helpers.LoadDependencies(config.Dependencies, config.Format, depParser.CustomSymbols, config.InputFiles, config.CopyFolders, DependencyErrorEvent); //Load dependencies if (diagDetected) { throw new CopyLoadingException("Diagnostics detected while parsing Intrinsic file", null, null, logged: false, needMail: false); } } baseTable = depParser.CustomSymbols; #endregion var typeCobolOptions = new TypeCobolOptions(config); #if EUROINFO_RULES typeCobolOptions.AutoRemarksEnable = config.AutoRemarks; #endif ReturnCode returnCode = ReturnCode.Success; List <Parser> parsers = new List <Parser>(); List <Compiler.Report.AbstractReport> reports = new List <AbstractReport>(); bool copyAreMissing = false; List <Diagnostic> diagnostics = new List <Diagnostic>(); foreach (var inputFilePath in config.InputFiles) { var parser = new Parser(); parser.CustomSymbols = baseTable; parsers.Add(parser); if (config.ExecToStep > ExecutionStep.SemanticCheck) //If inferior to semantic, use the execstep given by the user. { typeCobolOptions.ExecToStep = ExecutionStep.SemanticCheck; } try { parser.Init(inputFilePath, typeCobolOptions, config.Format, config.CopyFolders); //Init parser create CompilationProject & Compiler before parsing the given file } catch (Exception ex) { throw new ParsingException(MessageCode.ParserInit, ex.Message, inputFilePath, ex); //Make ParsingException trace back to RunOnce() } #region Copy Report Init if (config.ExecToStep >= ExecutionStep.CrossCheck) { if (!string.IsNullOrEmpty(config.ReportCopyMoveInitializeFilePath)) { if (config.UseAntlrProgramParsing) { Compiler.Parser.NodeDispatcher <Antlr4.Runtime.ParserRuleContext> .RegisterStaticNodeListenerFactory( () => { var report = new Compiler.Report.CopyMoveInitializeReport <Antlr4.Runtime.ParserRuleContext>(config.ReportCopyMoveInitializeFilePath); reports.Add(report); return(report); }); } else { Compiler.Parser.NodeDispatcher <Compiler.CodeElements.CodeElement> .RegisterStaticNodeListenerFactory( () => { var report = new Compiler.Report.CopyMoveInitializeReport <Compiler.CodeElements.CodeElement>(config.ReportCopyMoveInitializeFilePath); reports.Add(report); return(report); }); } } if (!string.IsNullOrEmpty(config.ReportZCallFilePath)) { if (config.UseAntlrProgramParsing) { Compiler.Parser.NodeDispatcher <Antlr4.Runtime.ParserRuleContext> .RegisterStaticNodeListenerFactory( () => { var report = new Compiler.Report.ZCallPgmReport <Antlr4.Runtime.ParserRuleContext>(config.ReportZCallFilePath); reports.Add(report); return(report); }); } else { Compiler.Parser.NodeDispatcher <Compiler.CodeElements.CodeElement> .RegisterStaticNodeListenerFactory( () => { var report = new Compiler.Report.ZCallPgmReport <Compiler.CodeElements.CodeElement>(config.ReportZCallFilePath); reports.Add(report); return(report); }); } } } #endregion //Parse input file parser.Parse(inputFilePath); diagnostics.AddRange(parser.Results.AllDiagnostics()); //Get all diags errorWriter.AddErrors(inputFilePath, diagnostics.Take(config.MaximumDiagnostics == 0 ? diagnostics.Count : config.MaximumDiagnostics)); //Write diags into error file if (!string.IsNullOrEmpty(config.HaltOnMissingCopyFilePath)) { if (parser.MissingCopys.Count > 0) { //Collect the missing copies copyAreMissing = true; File.WriteAllLines(config.HaltOnMissingCopyFilePath, parser.MissingCopys); } else { //Delete the file File.Delete(config.HaltOnMissingCopyFilePath); } } if (config.ExecToStep >= ExecutionStep.Preprocessor && !string.IsNullOrEmpty(config.ExtractedCopiesFilePath)) { if (parser.Results.CopyTextNamesVariations.Count > 0) { #if EUROINFO_RULES IEnumerable <string> copiesName; if (config.UseEuroInformationLegacyReplacingSyntax) { copiesName = parser.Results.CopyTextNamesVariations.Select(cp => cp.TextName).Distinct(); //Get copies without suffix } else { copiesName = parser.Results.CopyTextNamesVariations.Select(cp => cp.TextNameWithSuffix).Distinct(); //Get copies with suffix } #else var copiesName = parser.Results.CopyTextNamesVariations.Select(cp => cp.TextNameWithSuffix).Distinct(); //Get copies with suffix #endif //Create an output document of all the copy encountered by the parser File.WriteAllLines(config.ExtractedCopiesFilePath, copiesName); } else { File.Delete(config.ExtractedCopiesFilePath); } } if (copyAreMissing) { throw new MissingCopyException("Some copy are missing", inputFilePath, null, logged: false, needMail: false); } if (parser.Results.CodeElementsDocumentSnapshot == null && config.ExecToStep > ExecutionStep.Preprocessor) { throw new ParsingException(MessageCode.SyntaxErrorInParser, "File \"" + inputFilePath + "\" has syntactic error(s) preventing codegen (CodeElements).", inputFilePath); //Make ParsingException trace back to RunOnce() } else if (parser.Results.TemporaryProgramClassDocumentSnapshot == null && config.ExecToStep > ExecutionStep.SyntaxCheck) { throw new ParsingException(MessageCode.SyntaxErrorInParser, "File \"" + inputFilePath + "\" has semantic error(s) preventing codegen (ProgramClass).", inputFilePath); //Make ParsingException trace back to RunOnce() } if (config.ExecToStep >= ExecutionStep.SemanticCheck) { foreach (var program in parser.Results.TemporaryProgramClassDocumentSnapshot.Root.Programs) { var previousPrograms = baseTable.GetPrograms(); foreach (var previousProgram in previousPrograms) { previousProgram.SymbolTable.GetTableFromScope(SymbolTable.Scope.Namespace).AddProgram(program); } baseTable.AddProgram(program); //Add program to Namespace symbol table } } if (config.ExecToStep >= ExecutionStep.Preprocessor && !string.IsNullOrEmpty(config.ExpandingCopyFilePath)) { try { StringBuilder generatedCobolStringBuilder = new StringBuilder(); var generator = GeneratorFactoryManager.Instance.Create(TypeCobol.Tools.Options_Config.OutputFormat.ExpandingCopy.ToString(), parser.Results, generatedCobolStringBuilder, null, null); var streamWriter = new StreamWriter(config.ExpandingCopyFilePath); generator.Generate(parser.Results, ColumnsLayout.CobolReferenceFormat); streamWriter.Write(generatedCobolStringBuilder); streamWriter.Flush(); streamWriter.Close(); } catch (Exception e) { throw new GenerationException(e.Message, inputFilePath, e); } } } //Then do the CrossCheck when all the programs are loaded in SymbolTable if (config.ExecToStep > ExecutionStep.SemanticCheck) { int fileIndex = 0; foreach (var parser in parsers) { parser.Results.RefreshProgramClassDocumentSnapshot(); //Do Cross Check phase for each file diagnostics.Clear(); diagnostics.AddRange(parser.Results.AllDiagnostics()); //Get all diags errorWriter.Errors.Clear(); //Clear errorWriter because of the potential previous diags errorWriter.AddErrors(config.InputFiles[fileIndex], diagnostics.Take(config.MaximumDiagnostics == 0 ? diagnostics.Count : config.MaximumDiagnostics)); //Write diags into error file if (diagnostics.Count > 0) { foreach (var diag in diagnostics) { if (diag.CatchedException != null) { AnalyticsWrapper.Telemetry.TrackException(diag.CatchedException, config.InputFiles[fileIndex]); AnalyticsWrapper.Telemetry.SendMail(diag.CatchedException, config.InputFiles, config.CopyFolders, config.CommandLine); } } } if (diagnostics.Count == 0) { if (config.ExecToStep >= ExecutionStep.CrossCheck && reports != null && reports.Count > 0) { foreach (var report in reports) { try { report.Report(); string msg = string.Format( "Succeed to emit report '{0}'", report.Filepath); Console.WriteLine(msg); } catch (Exception e) { Console.Error.WriteLine(e.Message); throw new GenerationException(e.Message, report.Filepath, e); } } } } if (diagnostics.Any(d => d.Info.Severity == Compiler.Diagnostics.Severity.Error)) { throw new PresenceOfDiagnostics("Diagnostics Detected", config.InputFiles[fileIndex]); //Make ParsingException trace back to RunOnce() } if (diagnostics.Any(d => d.Info.Severity == Compiler.Diagnostics.Severity.Warning)) { returnCode = ReturnCode.Warning; } if (config.ExecToStep >= ExecutionStep.Generate) { try { //Load skeletons if necessary List <Skeleton> skeletons = null; if (!(string.IsNullOrEmpty(config.skeletonPath))) { skeletons = TypeCobol.Codegen.Config.Config.Parse(config.skeletonPath); } var sb = new StringBuilder(); //Get Generator from specified config.OutputFormat var generator = GeneratorFactoryManager.Instance.Create(config.OutputFormat.ToString(), parser.Results, sb, skeletons, AnalyticsWrapper.Telemetry.TypeCobolVersion); if (generator == null) { throw new GenerationException("Unknown OutputFormat=" + config.OutputFormat + "_", config.InputFiles[fileIndex]); } //Generate and check diagnostics generator.Generate(parser.Results, ColumnsLayout.CobolReferenceFormat); if (generator.Diagnostics != null) { errorWriter.AddErrors(config.InputFiles[fileIndex], generator.Diagnostics); //Write diags into error file throw new PresenceOfDiagnostics("Diagnostics Detected", config.InputFiles[fileIndex]); //Make ParsingException trace back to RunOnce() } var outputDirectory = new FileInfo(config.OutputFiles[fileIndex]).Directory; var lockFilePath = outputDirectory.FullName + Path.DirectorySeparatorChar + "~.lock"; if (File.Exists(lockFilePath)) { errorWriter.AddErrors(config.InputFiles[fileIndex], new Diagnostic(MessageCode.GenerationFailled, 0, 0, 0)); } else { var lockWriter = new StreamWriter(lockFilePath); lockWriter.Flush(); lockWriter.Close(); using (var streamWriter = new StreamWriter(config.OutputFiles[fileIndex])) { try { streamWriter.Write(sb); //Write generated Cobol inside file streamWriter.Flush(); } catch (Exception) { throw; } finally { File.Delete(lockFilePath); //Remove lock to allow watchers to read the file streamWriter.Close(); } } } } catch (PresenceOfDiagnostics) { throw; //Throw the same exception to let runOnce() knows there is a problem } catch (GenerationException) { throw; //Throw the same exception to let runOnce() knows there is a problem } catch (Exception e) { //Otherwise create a new GenerationException throw new GenerationException(e.Message, config.InputFiles[fileIndex], e); } fileIndex++; } } } return(returnCode); }