private static IEnumerable <ErrorInfoAdapter> GetErrorsFromUnparsed(string plogFilename, out string solutionName) { var plogTable = new DataTable(); var solutionPathsTable = new DataTable(); DataTableUtils.CreatePVSDataTable(plogTable, solutionPathsTable, plogTable.DefaultView); var plogSet = new DataSet(); plogSet.Tables.Add(solutionPathsTable); plogSet.Tables.Add(plogTable); var signaller = new ManualResetEventSlim(false); try { var tasksQueue = new ConcurrentQueue <Task <IEnumerable <ErrorInfo> > >(); Exception processingException = null; var processingThread = new Thread(() => { try { while (true) { Task <IEnumerable <ErrorInfo> > currentTask; while (tasksQueue.TryDequeue(out currentTask)) { foreach (var error in currentTask.Result) { DataTableUtils.AppendErrorInfoToDataTable(plogTable, error); } } if (signaller.IsSet && tasksQueue.Count == 0) { return; } Thread.Sleep(1000); } } catch (Exception e) { Volatile.Write <Exception>(ref processingException, e); } }); processingThread.Start(); const int linesToRead = 10000; const int maxTasksCount = 1000000 / linesToRead; //will consume approximately 1GB of memory StringBuilder totalLinesCache = new StringBuilder(linesToRead * 350); //we assume that an average PVS-Studio output line is 350 chars long IList <String> preprocessedFilesDependencies; Func <bool> isProcessingExceptionPresent = () => Volatile.Read <Exception>(ref processingException) != null; using (StreamReader logfileStream = new StreamReader(plogFilename)) { String currentLine; int linesRead = 0; bool isEncoded = false; while (true) { if (isProcessingExceptionPresent()) { break; } currentLine = logfileStream.ReadLine(); if (currentLine == null || linesRead >= linesToRead) { linesRead = 0; var linesText = totalLinesCache.ToString(); totalLinesCache.Clear(); Encoding currentIncodingLocal = logfileStream.CurrentEncoding; bool isIncodedLocal = isEncoded; var errorsTask = new Task <IEnumerable <ErrorInfo> >(() => ErrorInfo.ProcessAnalyzerOutput(String.Empty, String.Empty, String.Empty, linesText, isIncodedLocal, currentIncodingLocal, null, out preprocessedFilesDependencies, String.Empty)); errorsTask.Start(); tasksQueue.Enqueue(errorsTask); while (!isProcessingExceptionPresent() && tasksQueue.Count >= maxTasksCount) { Thread.Sleep(1000); } if (currentLine == null) { signaller.Set(); break; } } if (String.IsNullOrWhiteSpace(currentLine) || currentLine.StartsWith("#")) { continue; } if (currentLine.StartsWith(CppAnalyzerDecoder.EncodeMarker)) { isEncoded = true; continue; } totalLinesCache.Append(currentLine + Environment.NewLine); linesRead++; } } processingThread.Join(); if (isProcessingExceptionPresent()) { throw Volatile.Read <Exception>(ref processingException); } } finally { signaller.Set(); } return(GetErrorsFromXml(out solutionName, plogSet.GetXml())); }
static void Main(string[] args) { String plogFile = ""; int numParts = 0; if (args.Length >= 2) { plogFile = args[0]; int.TryParse(args[1], out numParts); } System.Console.WriteLine("Utility for combining plog-files of PVS-Studio."); if (args.Length != 2 || numParts <= 0 || numParts > 10) { System.Console.WriteLine( "(x) The program was started incorrectly!\n\n" + "Usage: PlogCombiner.exe <plogFile> <numParts>\n" + "<plogFile> - plog-file of PVS-Studio\n" + "<numParts> - number of parts"); Environment.Exit(1); } DataTable messageTable = new DataTable(); DataTable metaTable = new DataTable(); DataTableUtils.CreatePVSDataTable(messageTable, metaTable, messageTable.DefaultView); ApplicationSettings settings = new ApplicationSettings(); bool bHeader = false; for (int i = 1; i <= numParts; i++) { DataTable partMessageTable = new DataTable(); DataTable partMetaTable = new DataTable(); DataTableUtils.CreatePVSDataTable(partMessageTable, partMetaTable, partMessageTable.DefaultView); String partFile = String.Format(plogFile, "_" + i); String lastError; //if (!File.Exists(partFile)) // continue; if (!ReadPlog(partFile, partMessageTable, partMetaTable, out lastError)) { System.Console.WriteLine(lastError); Environment.Exit(1); } if (!bHeader) { bHeader = true; metaTable = partMetaTable.Copy(); String slnPath = metaTable.Rows[0][DataColumnNames.SolutionPath] as String; String slnBase, slnExt; int part; if (!SplitSlnPath(slnPath, out slnBase, out slnExt, out part)) { System.Console.WriteLine(String.Format("Invalid solution path: {0}", slnPath)); Environment.Exit(1); } metaTable.Rows[0][DataColumnNames.SolutionPath] = slnBase + slnExt; metaTable.Rows[0][DataColumnNames.PlogModificationDate] = DateTime.UtcNow.ToString(@"yyyy/MM/ddThh:mm:ss.fffffffZ"); } List <ErrorInfo> lstPartMessages = DataTableUtils.TransformTableToList(partMessageTable); foreach (ErrorInfo msg in lstPartMessages) { DataTableUtils.AppendErrorInfoToDataTable(messageTable, msg, settings); } } // Запись в файл String resFile = String.Format(plogFile, ""); WritePlog(resFile, messageTable, metaTable); }