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()));
        }
Ejemplo n.º 2
0
        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);
        }