fix(tools/cppcheck): fail build if errors detected

If the XML generated by Cppcheck contains error tags
detected by Cppcheck and the installed Cppcheck version
matches or exceeds the minimum recommended version, then
fail the build. Otherwise, if the installed version is
less than the recommended version, generate only a warning.

NOTE: The minimum recommended Cppcheck version is
now updated to 2.14.0.

Change-Id: Ibffbc555dcc6a7a1ad33a197a180fdb52a581412
Signed-off-by: Sona Mathew <sonarebecca.mathew@arm.com>
diff --git a/docs/getting_started/getting-started.rst b/docs/getting_started/getting-started.rst
index 4b8bfbc..910023a 100644
--- a/docs/getting_started/getting-started.rst
+++ b/docs/getting_started/getting-started.rst
@@ -55,7 +55,7 @@
    "docutils",">v2.38.0","Documentation"
    "gcovr",">=v4.2","Tools(Coverage analysis)"
    "CBMC",">=5.84.0","Tools(CBMC analysis)"
-   "Cppcheck",">=2.13.4","Tools(Cppcheck)"
+   "Cppcheck",">=2.14.0","Tools(Cppcheck)"
 
 .. _getting_started_toolchain:
 
diff --git a/docs/resources/application-notes/cppcheck.rst b/docs/resources/application-notes/cppcheck.rst
index 13647b6..2ffc8c9 100644
--- a/docs/resources/application-notes/cppcheck.rst
+++ b/docs/resources/application-notes/cppcheck.rst
@@ -71,6 +71,13 @@
 
 This will generate `cppcheck_misra.xml` in `build/tools/cppcheck` folder.
 
+If the above generated xml contains error tags detected by Cppcheck and
+if the installed version of Cppcheck matches or exceeds the recommended
+version mentioned in :ref:`tool_dependencies`, the build fails and prints
+the error count. However, if the installed version is less than the
+recommended version, a warning is generated and the output is not parsed
+for errors.
+
 Generating the Cppcheck HTML report
 ===================================
 
diff --git a/tools/cppcheck/CPPCheck.cmake b/tools/cppcheck/CPPCheck.cmake
index 688433c..12d1700 100644
--- a/tools/cppcheck/CPPCheck.cmake
+++ b/tools/cppcheck/CPPCheck.cmake
@@ -7,6 +7,18 @@
 
 if(NOT RMM_CPPCHECK_EXE)
   message(FATAL_ERROR "Could not find cppcheck executable.")
+else()
+  message(cppcheck_path: "${RMM_CPPCHECK_EXE}")
+  execute_process(COMMAND ${RMM_CPPCHECK_EXE} --version
+			OUTPUT_VARIABLE CPPCHECK_INSTALLED_VERSION)
+  string(REGEX MATCH "([0-9]+\\.[0-9]+(\\.[0-9]+)?)" CPPCHECK_INSTALLED ${CPPCHECK_INSTALLED_VERSION})
+  message(Installed version: "${CPPCHECK_INSTALLED}")
+  set(CPPCHECK_MIN_REQD "2.14.0")
+endif()
+
+if("${CPPCHECK_INSTALLED}" VERSION_LESS "${CPPCHECK_MIN_REQD}")
+  message(WARNING "Cppcheck installed version is: ${CPPCHECK_INSTALLED}, minimum required version is ${CPPCHECK_MIN_REQD}.")
+  message(WARNING "Cppcheck output will not be checked for errors.")
 endif()
 
 #
@@ -87,3 +99,15 @@
           --project=${COMPILE_COMMANDS_FILE} ${cppcheck-flags}
     )
 endif()
+
+if((EXISTS "${CPPCHECK_OUTPUT}") AND ("${CPPCHECK_INSTALLED}" VERSION_GREATER_EQUAL "${CPPCHECK_MIN_REQD}"))
+    file(READ "${CPPCHECK_OUTPUT}" cppcheck_xml)
+    string(REGEX MATCHALL "<error id" errtag "${cppcheck_xml}")
+    list(LENGTH errtag errcount)
+
+    if (${errcount} EQUAL 0)
+        message("Good work! No Cppcheck errors detected")
+    else()
+        message(FATAL_ERROR "Cppcheck failed with error count: ${errcount}")
+    endif()
+endif()