LCOV - code coverage report
Current view: top level - layout/tools/layout-debug/src - nsLayoutDebuggingTools.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 265 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 43 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : // vim:cindent:tabstop=4:expandtab:shiftwidth=4:
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsLayoutDebuggingTools.h"
       8             : 
       9             : #include "nsIDocShell.h"
      10             : #include "nsPIDOMWindow.h"
      11             : #include "nsIContentViewer.h"
      12             : 
      13             : #include "nsIServiceManager.h"
      14             : #include "nsIAtom.h"
      15             : #include "nsQuickSort.h"
      16             : 
      17             : #include "nsIContent.h"
      18             : #include "nsIDocument.h"
      19             : #include "nsIDOMDocument.h"
      20             : 
      21             : #include "nsIPresShell.h"
      22             : #include "nsViewManager.h"
      23             : #include "nsIFrame.h"
      24             : 
      25             : #include "nsILayoutDebugger.h"
      26             : #include "nsLayoutCID.h"
      27             : static NS_DEFINE_CID(kLayoutDebuggerCID, NS_LAYOUT_DEBUGGER_CID);
      28             : 
      29             : #include "nsISelectionController.h"
      30             : #include "mozilla/dom/Element.h"
      31             : #include "mozilla/Preferences.h"
      32             : 
      33             : using namespace mozilla;
      34             : 
      35             : static already_AddRefed<nsIContentViewer>
      36           0 : doc_viewer(nsIDocShell *aDocShell)
      37             : {
      38           0 :     if (!aDocShell)
      39           0 :         return nullptr;
      40           0 :     nsCOMPtr<nsIContentViewer> result;
      41           0 :     aDocShell->GetContentViewer(getter_AddRefs(result));
      42           0 :     return result.forget();
      43             : }
      44             : 
      45             : static already_AddRefed<nsIPresShell>
      46           0 : pres_shell(nsIDocShell *aDocShell)
      47             : {
      48           0 :     nsCOMPtr<nsIContentViewer> cv = doc_viewer(aDocShell);
      49           0 :     if (!cv)
      50           0 :         return nullptr;
      51           0 :     nsCOMPtr<nsIPresShell> result;
      52           0 :     cv->GetPresShell(getter_AddRefs(result));
      53           0 :     return result.forget();
      54             : }
      55             : 
      56             : static nsViewManager*
      57           0 : view_manager(nsIDocShell *aDocShell)
      58             : {
      59           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(aDocShell));
      60           0 :     if (!shell)
      61           0 :         return nullptr;
      62           0 :     return shell->GetViewManager();
      63             : }
      64             : 
      65             : #ifdef DEBUG
      66             : static already_AddRefed<nsIDocument>
      67           0 : document(nsIDocShell *aDocShell)
      68             : {
      69           0 :     nsCOMPtr<nsIContentViewer> cv(doc_viewer(aDocShell));
      70           0 :     if (!cv)
      71           0 :         return nullptr;
      72           0 :     nsCOMPtr<nsIDOMDocument> domDoc;
      73           0 :     cv->GetDOMDocument(getter_AddRefs(domDoc));
      74           0 :     if (!domDoc)
      75           0 :         return nullptr;
      76           0 :     nsCOMPtr<nsIDocument> result = do_QueryInterface(domDoc);
      77           0 :     return result.forget();
      78             : }
      79             : #endif
      80             : 
      81           0 : nsLayoutDebuggingTools::nsLayoutDebuggingTools()
      82             :   : mPaintFlashing(false),
      83             :     mPaintDumping(false),
      84             :     mInvalidateDumping(false),
      85             :     mEventDumping(false),
      86             :     mMotionEventDumping(false),
      87             :     mCrossingEventDumping(false),
      88           0 :     mReflowCounts(false)
      89             : {
      90           0 :     NewURILoaded();
      91           0 : }
      92             : 
      93           0 : nsLayoutDebuggingTools::~nsLayoutDebuggingTools()
      94             : {
      95           0 : }
      96             : 
      97           0 : NS_IMPL_ISUPPORTS(nsLayoutDebuggingTools, nsILayoutDebuggingTools)
      98             : 
      99             : NS_IMETHODIMP
     100           0 : nsLayoutDebuggingTools::Init(mozIDOMWindow* aWin)
     101             : {
     102           0 :     if (!Preferences::GetService()) {
     103           0 :         return NS_ERROR_UNEXPECTED;
     104             :     }
     105             : 
     106             :     {
     107           0 :         if (!aWin)
     108           0 :             return NS_ERROR_UNEXPECTED;
     109           0 :         auto* window = nsPIDOMWindowInner::From(aWin);
     110           0 :         mDocShell = window->GetDocShell();
     111             :     }
     112           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_UNEXPECTED);
     113             : 
     114           0 :     mPaintFlashing =
     115           0 :         Preferences::GetBool("nglayout.debug.paint_flashing", mPaintFlashing);
     116           0 :     mPaintDumping =
     117           0 :         Preferences::GetBool("nglayout.debug.paint_dumping", mPaintDumping);
     118           0 :     mInvalidateDumping =
     119           0 :         Preferences::GetBool("nglayout.debug.invalidate_dumping", mInvalidateDumping);
     120           0 :     mEventDumping =
     121           0 :         Preferences::GetBool("nglayout.debug.event_dumping", mEventDumping);
     122           0 :     mMotionEventDumping =
     123           0 :         Preferences::GetBool("nglayout.debug.motion_event_dumping",
     124           0 :                              mMotionEventDumping);
     125           0 :     mCrossingEventDumping =
     126           0 :         Preferences::GetBool("nglayout.debug.crossing_event_dumping",
     127           0 :                              mCrossingEventDumping);
     128           0 :     mReflowCounts =
     129           0 :         Preferences::GetBool("layout.reflow.showframecounts", mReflowCounts);
     130             : 
     131             :     {
     132           0 :         nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
     133           0 :         if (ld) {
     134           0 :             ld->GetShowFrameBorders(&mVisualDebugging);
     135           0 :             ld->GetShowEventTargetFrameBorder(&mVisualEventDebugging);
     136             :         }
     137             :     }
     138             : 
     139           0 :     return NS_OK;
     140             : }
     141             : 
     142             : NS_IMETHODIMP
     143           0 : nsLayoutDebuggingTools::NewURILoaded()
     144             : {
     145           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     146             :     // Reset all the state that should be reset between pages.
     147             : 
     148             :     // XXX Some of these should instead be transferred between pages!
     149           0 :     mEditorMode = false;
     150           0 :     mVisualDebugging = false;
     151           0 :     mVisualEventDebugging = false;
     152             : 
     153           0 :     mReflowCounts = false;
     154             : 
     155           0 :     ForceRefresh();
     156           0 :     return NS_OK;
     157             : }
     158             : 
     159             : NS_IMETHODIMP
     160           0 : nsLayoutDebuggingTools::GetVisualDebugging(bool *aVisualDebugging)
     161             : {
     162           0 :     *aVisualDebugging = mVisualDebugging;
     163           0 :     return NS_OK;
     164             : }
     165             : 
     166             : NS_IMETHODIMP
     167           0 : nsLayoutDebuggingTools::SetVisualDebugging(bool aVisualDebugging)
     168             : {
     169           0 :     nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
     170           0 :     if (!ld)
     171           0 :         return NS_ERROR_UNEXPECTED;
     172           0 :     mVisualDebugging = aVisualDebugging;
     173           0 :     ld->SetShowFrameBorders(aVisualDebugging);
     174           0 :     ForceRefresh();
     175           0 :     return NS_OK;
     176             : }
     177             : 
     178             : NS_IMETHODIMP
     179           0 : nsLayoutDebuggingTools::GetVisualEventDebugging(bool *aVisualEventDebugging)
     180             : {
     181           0 :     *aVisualEventDebugging = mVisualEventDebugging;
     182           0 :     return NS_OK;
     183             : }
     184             : 
     185             : NS_IMETHODIMP
     186           0 : nsLayoutDebuggingTools::SetVisualEventDebugging(bool aVisualEventDebugging)
     187             : {
     188           0 :     nsCOMPtr<nsILayoutDebugger> ld = do_GetService(kLayoutDebuggerCID);
     189           0 :     if (!ld)
     190           0 :         return NS_ERROR_UNEXPECTED;
     191           0 :     mVisualEventDebugging = aVisualEventDebugging;
     192           0 :     ld->SetShowEventTargetFrameBorder(aVisualEventDebugging);
     193           0 :     ForceRefresh();
     194           0 :     return NS_OK;
     195             : }
     196             : 
     197             : NS_IMETHODIMP
     198           0 : nsLayoutDebuggingTools::GetPaintFlashing(bool *aPaintFlashing)
     199             : {
     200           0 :     *aPaintFlashing = mPaintFlashing;
     201           0 :     return NS_OK;
     202             : }
     203             : 
     204             : NS_IMETHODIMP
     205           0 : nsLayoutDebuggingTools::SetPaintFlashing(bool aPaintFlashing)
     206             : {
     207           0 :     mPaintFlashing = aPaintFlashing;
     208           0 :     return SetBoolPrefAndRefresh("nglayout.debug.paint_flashing", mPaintFlashing);
     209             : }
     210             : 
     211             : NS_IMETHODIMP
     212           0 : nsLayoutDebuggingTools::GetPaintDumping(bool *aPaintDumping)
     213             : {
     214           0 :     *aPaintDumping = mPaintDumping;
     215           0 :     return NS_OK;
     216             : }
     217             : 
     218             : NS_IMETHODIMP
     219           0 : nsLayoutDebuggingTools::SetPaintDumping(bool aPaintDumping)
     220             : {
     221           0 :     mPaintDumping = aPaintDumping;
     222           0 :     return SetBoolPrefAndRefresh("nglayout.debug.paint_dumping", mPaintDumping);
     223             : }
     224             : 
     225             : NS_IMETHODIMP
     226           0 : nsLayoutDebuggingTools::GetInvalidateDumping(bool *aInvalidateDumping)
     227             : {
     228           0 :     *aInvalidateDumping = mInvalidateDumping;
     229           0 :     return NS_OK;
     230             : }
     231             : 
     232             : NS_IMETHODIMP
     233           0 : nsLayoutDebuggingTools::SetInvalidateDumping(bool aInvalidateDumping)
     234             : {
     235           0 :     mInvalidateDumping = aInvalidateDumping;
     236           0 :     return SetBoolPrefAndRefresh("nglayout.debug.invalidate_dumping", mInvalidateDumping);
     237             : }
     238             : 
     239             : NS_IMETHODIMP
     240           0 : nsLayoutDebuggingTools::GetEventDumping(bool *aEventDumping)
     241             : {
     242           0 :     *aEventDumping = mEventDumping;
     243           0 :     return NS_OK;
     244             : }
     245             : 
     246             : NS_IMETHODIMP
     247           0 : nsLayoutDebuggingTools::SetEventDumping(bool aEventDumping)
     248             : {
     249           0 :     mEventDumping = aEventDumping;
     250           0 :     return SetBoolPrefAndRefresh("nglayout.debug.event_dumping", mEventDumping);
     251             : }
     252             : 
     253             : NS_IMETHODIMP
     254           0 : nsLayoutDebuggingTools::GetMotionEventDumping(bool *aMotionEventDumping)
     255             : {
     256           0 :     *aMotionEventDumping = mMotionEventDumping;
     257           0 :     return NS_OK;
     258             : }
     259             : 
     260             : NS_IMETHODIMP
     261           0 : nsLayoutDebuggingTools::SetMotionEventDumping(bool aMotionEventDumping)
     262             : {
     263           0 :     mMotionEventDumping = aMotionEventDumping;
     264           0 :     return SetBoolPrefAndRefresh("nglayout.debug.motion_event_dumping", mMotionEventDumping);
     265             : }
     266             : 
     267             : NS_IMETHODIMP
     268           0 : nsLayoutDebuggingTools::GetCrossingEventDumping(bool *aCrossingEventDumping)
     269             : {
     270           0 :     *aCrossingEventDumping = mCrossingEventDumping;
     271           0 :     return NS_OK;
     272             : }
     273             : 
     274             : NS_IMETHODIMP
     275           0 : nsLayoutDebuggingTools::SetCrossingEventDumping(bool aCrossingEventDumping)
     276             : {
     277           0 :     mCrossingEventDumping = aCrossingEventDumping;
     278           0 :     return SetBoolPrefAndRefresh("nglayout.debug.crossing_event_dumping", mCrossingEventDumping);
     279             : }
     280             : 
     281             : NS_IMETHODIMP
     282           0 : nsLayoutDebuggingTools::GetReflowCounts(bool* aShow)
     283             : {
     284           0 :     *aShow = mReflowCounts;
     285           0 :     return NS_OK;
     286             : }
     287             : 
     288             : NS_IMETHODIMP
     289           0 : nsLayoutDebuggingTools::SetReflowCounts(bool aShow)
     290             : {
     291           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     292           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
     293           0 :     if (shell) {
     294             : #ifdef MOZ_REFLOW_PERF
     295           0 :         shell->SetPaintFrameCount(aShow);
     296           0 :         SetBoolPrefAndRefresh("layout.reflow.showframecounts", aShow);
     297           0 :         mReflowCounts = aShow;
     298             : #else
     299             :         printf("************************************************\n");
     300             :         printf("Sorry, you have not built with MOZ_REFLOW_PERF=1\n");
     301             :         printf("************************************************\n");
     302             : #endif
     303             :     }
     304           0 :     return NS_OK;
     305             : }
     306             : 
     307           0 : static void DumpAWebShell(nsIDocShellTreeItem* aShellItem, FILE* out, int32_t aIndent)
     308             : {
     309           0 :     nsString name;
     310           0 :     nsCOMPtr<nsIDocShellTreeItem> parent;
     311             :     int32_t i, n;
     312             : 
     313           0 :     for (i = aIndent; --i >= 0; )
     314           0 :         fprintf(out, "  ");
     315             : 
     316           0 :     fprintf(out, "%p '", static_cast<void*>(aShellItem));
     317           0 :     aShellItem->GetName(name);
     318           0 :     aShellItem->GetSameTypeParent(getter_AddRefs(parent));
     319           0 :     fputs(NS_LossyConvertUTF16toASCII(name).get(), out);
     320           0 :     fprintf(out, "' parent=%p <\n", static_cast<void*>(parent));
     321             : 
     322           0 :     ++aIndent;
     323           0 :     aShellItem->GetChildCount(&n);
     324           0 :     for (i = 0; i < n; ++i) {
     325           0 :         nsCOMPtr<nsIDocShellTreeItem> child;
     326           0 :         aShellItem->GetChildAt(i, getter_AddRefs(child));
     327           0 :         if (child) {
     328           0 :             DumpAWebShell(child, out, aIndent);
     329             :         }
     330             :     }
     331           0 :     --aIndent;
     332           0 :     for (i = aIndent; --i >= 0; )
     333           0 :         fprintf(out, "  ");
     334           0 :     fputs(">\n", out);
     335           0 : }
     336             : 
     337             : NS_IMETHODIMP
     338           0 : nsLayoutDebuggingTools::DumpWebShells()
     339             : {
     340           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     341           0 :     DumpAWebShell(mDocShell, stdout, 0);
     342           0 :     return NS_OK;
     343             : }
     344             : 
     345             : static
     346             : void
     347           0 : DumpContentRecur(nsIDocShell* aDocShell, FILE* out)
     348             : {
     349             : #ifdef DEBUG
     350           0 :     if (nullptr != aDocShell) {
     351           0 :         fprintf(out, "docshell=%p \n", static_cast<void*>(aDocShell));
     352           0 :         nsCOMPtr<nsIDocument> doc(document(aDocShell));
     353           0 :         if (doc) {
     354           0 :             dom::Element *root = doc->GetRootElement();
     355           0 :             if (root) {
     356           0 :                 root->List(out);
     357             :             }
     358             :         }
     359             :         else {
     360           0 :             fputs("no document\n", out);
     361             :         }
     362             :         // dump the frames of the sub documents
     363             :         int32_t i, n;
     364           0 :         aDocShell->GetChildCount(&n);
     365           0 :         for (i = 0; i < n; ++i) {
     366           0 :             nsCOMPtr<nsIDocShellTreeItem> child;
     367           0 :             aDocShell->GetChildAt(i, getter_AddRefs(child));
     368           0 :             nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
     369           0 :             if (child) {
     370           0 :                 DumpContentRecur(childAsShell, out);
     371             :             }
     372             :         }
     373             :     }
     374             : #endif
     375           0 : }
     376             : 
     377             : NS_IMETHODIMP
     378           0 : nsLayoutDebuggingTools::DumpContent()
     379             : {
     380           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     381           0 :     DumpContentRecur(mDocShell, stdout);
     382           0 :     return NS_OK;
     383             : }
     384             : 
     385             : static void
     386           0 : DumpFramesRecur(nsIDocShell* aDocShell, FILE* out)
     387             : {
     388             : #ifdef DEBUG
     389           0 :     fprintf(out, "webshell=%p \n", static_cast<void*>(aDocShell));
     390           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(aDocShell));
     391           0 :     if (shell) {
     392           0 :         nsIFrame* root = shell->GetRootFrame();
     393           0 :         if (root) {
     394           0 :             root->List(out);
     395             :         }
     396             :     }
     397             :     else {
     398           0 :         fputs("null pres shell\n", out);
     399             :     }
     400             : 
     401             :     // dump the frames of the sub documents
     402             :     int32_t i, n;
     403           0 :     aDocShell->GetChildCount(&n);
     404           0 :     for (i = 0; i < n; ++i) {
     405           0 :         nsCOMPtr<nsIDocShellTreeItem> child;
     406           0 :         aDocShell->GetChildAt(i, getter_AddRefs(child));
     407           0 :         nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
     408           0 :         if (childAsShell) {
     409           0 :             DumpFramesRecur(childAsShell, out);
     410             :         }
     411             :     }
     412             : #endif
     413           0 : }
     414             : 
     415             : NS_IMETHODIMP
     416           0 : nsLayoutDebuggingTools::DumpFrames()
     417             : {
     418           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     419           0 :     DumpFramesRecur(mDocShell, stdout);
     420           0 :     return NS_OK;
     421             : }
     422             : 
     423             : static
     424             : void
     425           0 : DumpViewsRecur(nsIDocShell* aDocShell, FILE* out)
     426             : {
     427             : #ifdef DEBUG
     428           0 :     fprintf(out, "docshell=%p \n", static_cast<void*>(aDocShell));
     429           0 :     RefPtr<nsViewManager> vm(view_manager(aDocShell));
     430           0 :     if (vm) {
     431           0 :         nsView* root = vm->GetRootView();
     432           0 :         if (root) {
     433           0 :             root->List(out);
     434             :         }
     435             :     }
     436             :     else {
     437           0 :         fputs("null view manager\n", out);
     438             :     }
     439             : 
     440             :     // dump the views of the sub documents
     441             :     int32_t i, n;
     442           0 :     aDocShell->GetChildCount(&n);
     443           0 :     for (i = 0; i < n; i++) {
     444           0 :         nsCOMPtr<nsIDocShellTreeItem> child;
     445           0 :         aDocShell->GetChildAt(i, getter_AddRefs(child));
     446           0 :         nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
     447           0 :         if (childAsShell) {
     448           0 :             DumpViewsRecur(childAsShell, out);
     449             :         }
     450             :     }
     451             : #endif // DEBUG
     452           0 : }
     453             : 
     454             : NS_IMETHODIMP
     455           0 : nsLayoutDebuggingTools::DumpViews()
     456             : {
     457           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     458           0 :     DumpViewsRecur(mDocShell, stdout);
     459           0 :     return NS_OK;
     460             : }
     461             : 
     462             : NS_IMETHODIMP
     463           0 : nsLayoutDebuggingTools::DumpStyleSheets()
     464             : {
     465           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     466             : #ifdef DEBUG
     467           0 :     FILE *out = stdout;
     468           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
     469           0 :     if (shell)
     470           0 :         shell->ListStyleSheets(out);
     471             :     else
     472           0 :         fputs("null pres shell\n", out);
     473             : #endif
     474           0 :     return NS_OK;
     475             : }
     476             : 
     477             : NS_IMETHODIMP
     478           0 : nsLayoutDebuggingTools::DumpStyleContexts()
     479             : {
     480           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     481             : #ifdef DEBUG
     482           0 :     FILE *out = stdout;
     483           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
     484           0 :     if (shell) {
     485           0 :         shell->ListStyleContexts(out);
     486             :     } else {
     487           0 :         fputs("null pres shell\n", out);
     488             :     }
     489             : #endif
     490           0 :     return NS_OK;
     491             : }
     492             : 
     493             : NS_IMETHODIMP
     494           0 : nsLayoutDebuggingTools::DumpReflowStats()
     495             : {
     496           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     497             : #ifdef DEBUG
     498           0 :     nsCOMPtr<nsIPresShell> shell(pres_shell(mDocShell));
     499           0 :     if (shell) {
     500             : #ifdef MOZ_REFLOW_PERF
     501           0 :         shell->DumpReflows();
     502             : #else
     503             :         printf("************************************************\n");
     504             :         printf("Sorry, you have not built with MOZ_REFLOW_PERF=1\n");
     505             :         printf("************************************************\n");
     506             : #endif
     507             :     }
     508             : #endif
     509           0 :     return NS_OK;
     510             : }
     511             : 
     512           0 : void nsLayoutDebuggingTools::ForceRefresh()
     513             : {
     514           0 :     RefPtr<nsViewManager> vm(view_manager(mDocShell));
     515           0 :     if (!vm)
     516           0 :         return;
     517           0 :     nsView* root = vm->GetRootView();
     518           0 :     if (root) {
     519           0 :         vm->InvalidateView(root);
     520             :     }
     521             : }
     522             : 
     523             : nsresult
     524           0 : nsLayoutDebuggingTools::SetBoolPrefAndRefresh(const char * aPrefName,
     525             :                                               bool aNewVal)
     526             : {
     527           0 :     NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
     528             : 
     529           0 :     nsIPrefService* prefService = Preferences::GetService();
     530           0 :     NS_ENSURE_TRUE(prefService && aPrefName, NS_OK);
     531             : 
     532           0 :     Preferences::SetBool(aPrefName, aNewVal);
     533           0 :     prefService->SavePrefFile(nullptr);
     534             : 
     535           0 :     ForceRefresh();
     536             : 
     537           0 :     return NS_OK;
     538             : }

Generated by: LCOV version 1.13