mirror of
https://github.com/Llewellynvdm/conky.git
synced 2024-11-05 21:07:52 +00:00
Add some basic unit tests.
Introduced the Catch2 unit testing framework.
This commit is contained in:
parent
d422aa47d2
commit
6c09affaf7
10
.travis.yml
10
.travis.yml
@ -9,7 +9,11 @@ matrix:
|
||||
- llvm-toolchain-xenial-7
|
||||
packages:
|
||||
- clang-7
|
||||
- llvm-7
|
||||
- lld-7
|
||||
- libc++-7-dev
|
||||
- libc++abi-7-dev
|
||||
- lcov
|
||||
- cmake
|
||||
- docbook2x
|
||||
- libxdamage-dev
|
||||
@ -204,6 +208,8 @@ matrix:
|
||||
- llvm-toolchain-xenial-6.0
|
||||
packages:
|
||||
- clang-6.0
|
||||
- lld-6.0
|
||||
- libstdc++6
|
||||
- cmake
|
||||
- docbook2x
|
||||
- libxdamage-dev
|
||||
@ -244,7 +250,7 @@ before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then eval "${MATRIX_EVAL}" ; fi
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install freetype gettext lua imlib2 librsvg docbook2x ;
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install freetype gettext lua imlib2 librsvg docbook2x lcov ;
|
||||
fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew link gettext --force ; fi
|
||||
before_script:
|
||||
@ -319,6 +325,8 @@ script:
|
||||
else
|
||||
make -j4 ;
|
||||
fi
|
||||
- make test
|
||||
- if [ "$CXX" = "clang++-7" ] ; then make test-conky-coverage-txt ; fi
|
||||
- cd ../build-no-x11
|
||||
- make -j4
|
||||
- cd ..
|
||||
|
@ -3,19 +3,18 @@
|
||||
#
|
||||
# Please see COPYING for details
|
||||
#
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS) All rights
|
||||
# reserved.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details. You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
@ -42,10 +41,7 @@ include(ConkyCPackSetup)
|
||||
configure_file(${CMAKE_MODULE_PATH}/config.h.in ${CMAKE_BINARY_DIR}/config.h)
|
||||
configure_file(${CMAKE_MODULE_PATH}/build.h.in ${CMAKE_BINARY_DIR}/build.h)
|
||||
|
||||
set(conky_sources
|
||||
${CMAKE_BINARY_DIR}/config.h
|
||||
${CMAKE_BINARY_DIR}/build.h
|
||||
)
|
||||
set(conky_sources ${CMAKE_BINARY_DIR}/config.h ${CMAKE_BINARY_DIR}/build.h)
|
||||
|
||||
# Finally, add some code
|
||||
add_subdirectory(lua)
|
||||
@ -56,28 +52,46 @@ add_subdirectory(doc)
|
||||
add_subdirectory(3rdparty/toluapp)
|
||||
set(conky_libs ${conky_libs} toluapp_lib_static)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
if(USING_CLANG_7)
|
||||
message(STATUS "Detected clang-7, enabling test coverage reports")
|
||||
# Enable coverage checks
|
||||
include(CodeCoverage)
|
||||
append_coverage_compiler_flags()
|
||||
else()
|
||||
message(STATUS "NOT enabling test coverage reports")
|
||||
endif()
|
||||
include(Catch)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
IF(NOT DEFINED DOC_PATH)
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
enable_testing()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED DOC_PATH)
|
||||
set(DOC_PATH "share/doc/${CPACK_PACKAGE_NAME}-${VERSION}")
|
||||
ENDIF(NOT DEFINED DOC_PATH)
|
||||
endif(NOT DEFINED DOC_PATH)
|
||||
set(DOC_FILES extras/convert.lua data/conky_no_x11.conf data/conky.conf)
|
||||
|
||||
set(HTML_PATH "${DOC_PATH}/html")
|
||||
set(HTML_FILES doc/config_settings.html doc/docs.html doc/lua.html doc/variables.html)
|
||||
set(HTML_FILES
|
||||
doc/config_settings.html
|
||||
doc/docs.html
|
||||
doc/lua.html
|
||||
doc/variables.html)
|
||||
|
||||
set(MAN_PATH "share/man/man1")
|
||||
set(MAN_FILES doc/conky.1)
|
||||
|
||||
install(FILES ${DOC_FILES}
|
||||
DESTINATION ${DOC_PATH})
|
||||
install(FILES ${DOC_FILES} DESTINATION ${DOC_PATH})
|
||||
|
||||
if(MAINTAINER_MODE)
|
||||
install(FILES ${HTML_FILES}
|
||||
DESTINATION ${HTML_PATH})
|
||||
install(FILES ${HTML_FILES} DESTINATION ${HTML_PATH})
|
||||
|
||||
install(FILES ${MAN_FILES}
|
||||
DESTINATION ${MAN_PATH})
|
||||
install(FILES ${MAN_FILES} DESTINATION ${MAN_PATH})
|
||||
endif(MAINTAINER_MODE)
|
||||
|
||||
if(CHECK_CODE_QUALITY)
|
||||
@ -86,8 +100,7 @@ if(CHECK_CODE_QUALITY)
|
||||
clang-tidy
|
||||
clang-tidy-5.0
|
||||
clang-tidy-6.0
|
||||
clang-tidy-7.0
|
||||
)
|
||||
clang-tidy-7.0)
|
||||
set(CLANG_TIDY_EXCLUDE_PATTERNS "build/" ${CMAKE_BINARY_DIR})
|
||||
find_package(ClangTidy)
|
||||
endif(CHECK_CODE_QUALITY)
|
||||
|
@ -1,6 +1,5 @@
|
||||
<p align="center"><img src="logo/logotype-horizontal-violet.png"></p>
|
||||
|
||||
[![Build Status](https://travis-ci.org/brndnmtthws/conky.png)](https://travis-ci.org/brndnmtthws/conky) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=conky&metric=alert_status)](https://sonarcloud.io/dashboard/index/conky)
|
||||
[![Build Status](https://travis-ci.org/brndnmtthws/conky.png)](https://travis-ci.org/brndnmtthws/conky) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=conky&metric=alert_status)](https://sonarcloud.io/dashboard/index/conky) [![Maintainability](https://sonarcloud.io/api/project_badges/measure?project=conky&metric=sqale_rating)](https://sonarcloud.io/dashboard/index/conky) [![Code Coverage](https://sonarcloud.io/api/project_badges/measure?project=conky&metric=coverage)](https://sonarcloud.io/dashboard/index/conky) [![Sonarcloud Bugs](https://sonarcloud.io/api/project_badges/measure?project=conky&metric=bugs)](https://sonarcloud.io/dashboard/index/conky)
|
||||
<p align="center"><img width="300" src="logo/logotype-horizontal-violet.png"></p>
|
||||
|
||||
**Conky** is a free, light-weight system monitor for X, that displays
|
||||
any kind of information on your desktop.
|
||||
|
175
cmake/Catch.cmake
Normal file
175
cmake/Catch.cmake
Normal file
@ -0,0 +1,175 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
Catch
|
||||
-----
|
||||
|
||||
This module defines a function to help use the Catch test framework.
|
||||
|
||||
The :command:`catch_discover_tests` discovers tests by asking the compiled test
|
||||
executable to enumerate its tests. This does not require CMake to be re-run
|
||||
when tests change. However, it may not work in a cross-compiling environment,
|
||||
and setting test properties is less convenient.
|
||||
|
||||
This command is intended to replace use of :command:`add_test` to register
|
||||
tests, and will create a separate CTest test for each Catch test case. Note
|
||||
that this is in some cases less efficient, as common set-up and tear-down logic
|
||||
cannot be shared by multiple test cases executing in the same instance.
|
||||
However, it provides more fine-grained pass/fail information to CTest, which is
|
||||
usually considered as more beneficial. By default, the CTest test name is the
|
||||
same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
||||
|
||||
.. command:: catch_discover_tests
|
||||
|
||||
Automatically add tests with CTest by querying the compiled test executable
|
||||
for available tests::
|
||||
|
||||
catch_discover_tests(target
|
||||
[TEST_SPEC arg1...]
|
||||
[EXTRA_ARGS arg1...]
|
||||
[WORKING_DIRECTORY dir]
|
||||
[TEST_PREFIX prefix]
|
||||
[TEST_SUFFIX suffix]
|
||||
[PROPERTIES name1 value1...]
|
||||
[TEST_LIST var]
|
||||
)
|
||||
|
||||
``catch_discover_tests`` sets up a post-build command on the test executable
|
||||
that generates the list of tests by parsing the output from running the test
|
||||
with the ``--list-test-names-only`` argument. This ensures that the full
|
||||
list of tests is obtained. Since test discovery occurs at build time, it is
|
||||
not necessary to re-run CMake when the list of tests changes.
|
||||
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
|
||||
in order to function in a cross-compiling environment.
|
||||
|
||||
Additionally, setting properties on tests is somewhat less convenient, since
|
||||
the tests are not available at CMake time. Additional test properties may be
|
||||
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
|
||||
more fine-grained test control is needed, custom content may be provided
|
||||
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
|
||||
directory property. The set of discovered tests is made accessible to such a
|
||||
script via the ``<target>_TESTS`` variable.
|
||||
|
||||
The options are:
|
||||
|
||||
``target``
|
||||
Specifies the Catch executable, which must be a known CMake executable
|
||||
target. CMake will substitute the location of the built executable when
|
||||
running the test.
|
||||
|
||||
``TEST_SPEC arg1...``
|
||||
Specifies test cases, wildcarded test cases, tags and tag expressions to
|
||||
pass to the Catch executable with the ``--list-test-names-only`` argument.
|
||||
|
||||
``EXTRA_ARGS arg1...``
|
||||
Any extra arguments to pass on the command line to each test case.
|
||||
|
||||
``WORKING_DIRECTORY dir``
|
||||
Specifies the directory in which to run the discovered test cases. If this
|
||||
option is not provided, the current binary directory is used.
|
||||
|
||||
``TEST_PREFIX prefix``
|
||||
Specifies a ``prefix`` to be prepended to the name of each discovered test
|
||||
case. This can be useful when the same test executable is being used in
|
||||
multiple calls to ``catch_discover_tests()`` but with different
|
||||
``TEST_SPEC`` or ``EXTRA_ARGS``.
|
||||
|
||||
``TEST_SUFFIX suffix``
|
||||
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
|
||||
be specified.
|
||||
|
||||
``PROPERTIES name1 value1...``
|
||||
Specifies additional properties to be set on all tests discovered by this
|
||||
invocation of ``catch_discover_tests``.
|
||||
|
||||
``TEST_LIST var``
|
||||
Make the list of tests available in the variable ``var``, rather than the
|
||||
default ``<target>_TESTS``. This can be useful when the same test
|
||||
executable is being used in multiple calls to ``catch_discover_tests()``.
|
||||
Note that this variable is only available in CTest.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
function(catch_discover_tests TARGET)
|
||||
cmake_parse_arguments(
|
||||
""
|
||||
""
|
||||
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST"
|
||||
"TEST_SPEC;EXTRA_ARGS;PROPERTIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if(NOT _WORKING_DIRECTORY)
|
||||
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
if(NOT _TEST_LIST)
|
||||
set(_TEST_LIST ${TARGET}_TESTS)
|
||||
endif()
|
||||
|
||||
## Generate a unique name based on the extra arguments
|
||||
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
|
||||
string(SUBSTRING ${args_hash} 0 7 args_hash)
|
||||
|
||||
# Define rule to generate test list for aforementioned test executable
|
||||
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
|
||||
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
|
||||
get_property(crosscompiling_emulator
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CROSSCOMPILING_EMULATOR
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET} POST_BUILD
|
||||
BYPRODUCTS "${ctest_tests_file}"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "TEST_TARGET=${TARGET}"
|
||||
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
|
||||
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
|
||||
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
|
||||
-D "TEST_SPEC=${_TEST_SPEC}"
|
||||
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
|
||||
-D "TEST_PROPERTIES=${_PROPERTIES}"
|
||||
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||
-D "TEST_LIST=${_TEST_LIST}"
|
||||
-D "CTEST_FILE=${ctest_tests_file}"
|
||||
-P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
file(WRITE "${ctest_include_file}"
|
||||
"if(EXISTS \"${ctest_tests_file}\")\n"
|
||||
" include(\"${ctest_tests_file}\")\n"
|
||||
"else()\n"
|
||||
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
|
||||
"endif()\n"
|
||||
)
|
||||
|
||||
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
|
||||
# Add discovered tests to directory TEST_INCLUDE_FILES
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
|
||||
)
|
||||
else()
|
||||
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
|
||||
get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
|
||||
if (NOT ${test_include_file_set})
|
||||
set_property(DIRECTORY
|
||||
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Cannot set more than one TEST_INCLUDE_FILE"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
###############################################################################
|
||||
|
||||
set(_CATCH_DISCOVER_TESTS_SCRIPT
|
||||
${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
|
||||
)
|
78
cmake/CatchAddTests.cmake
Normal file
78
cmake/CatchAddTests.cmake
Normal file
@ -0,0 +1,78 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
set(prefix "${TEST_PREFIX}")
|
||||
set(suffix "${TEST_SUFFIX}")
|
||||
set(spec ${TEST_SPEC})
|
||||
set(extra_args ${TEST_EXTRA_ARGS})
|
||||
set(properties ${TEST_PROPERTIES})
|
||||
set(script)
|
||||
set(suite)
|
||||
set(tests)
|
||||
|
||||
function(add_command NAME)
|
||||
set(_args "")
|
||||
foreach(_arg ${ARGN})
|
||||
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
|
||||
else()
|
||||
set(_args "${_args} ${_arg}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Run test executable to get list of available tests
|
||||
if(NOT EXISTS "${TEST_EXECUTABLE}")
|
||||
message(FATAL_ERROR
|
||||
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
|
||||
)
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
|
||||
OUTPUT_VARIABLE output
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
|
||||
if(${result} EQUAL 0)
|
||||
message(WARNING
|
||||
"Test executable '${TEST_EXECUTABLE}' contains no tests!\n"
|
||||
)
|
||||
elseif(${result} LESS 0)
|
||||
message(FATAL_ERROR
|
||||
"Error running test executable '${TEST_EXECUTABLE}':\n"
|
||||
" Result: ${result}\n"
|
||||
" Output: ${output}\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" ";" output "${output}")
|
||||
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
set(test ${line})
|
||||
# use escape commas to handle properly test cases with commans inside the name
|
||||
string(REPLACE "," "\\," test_name ${test})
|
||||
# ...and add to script
|
||||
add_command(add_test
|
||||
"${prefix}${test}${suffix}"
|
||||
${TEST_EXECUTOR}
|
||||
"${TEST_EXECUTABLE}"
|
||||
"${test_name}"
|
||||
${extra_args}
|
||||
)
|
||||
add_command(set_tests_properties
|
||||
"${prefix}${test}${suffix}"
|
||||
PROPERTIES
|
||||
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||
${properties}
|
||||
)
|
||||
list(APPEND tests "${prefix}${test}${suffix}")
|
||||
endforeach()
|
||||
|
||||
# Create a list of all discovered tests, which users may use to e.g. set
|
||||
# properties on the tests
|
||||
add_command(set ${TEST_LIST} ${tests})
|
||||
|
||||
# Write CTest script
|
||||
file(WRITE "${CTEST_FILE}" "${script}")
|
392
cmake/CodeCoverage.cmake
Normal file
392
cmake/CodeCoverage.cmake
Normal file
@ -0,0 +1,392 @@
|
||||
# Copyright (c) 2012 - 2017, Lars Bilke All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#
|
||||
# 1. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# 1. Neither the name of the copyright holder nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# CHANGES:
|
||||
#
|
||||
# 2012-01-31, Lars Bilke - Enable Code Coverage
|
||||
#
|
||||
# 2013-09-17, Joakim Söderberg - Added support for Clang. - Some additional
|
||||
# usage instructions.
|
||||
#
|
||||
# 2016-02-03, Lars Bilke - Refactored functions to use named parameters
|
||||
#
|
||||
# 2017-06-02, Lars Bilke - Merged with modified version from github.com/ufz/ogs
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
#
|
||||
# 1. Add the following line to your CMakeLists.txt: include(CodeCoverage)
|
||||
#
|
||||
# 1. Append necessary compiler flags: APPEND_COVERAGE_COMPILER_FLAGS()
|
||||
#
|
||||
# 1. If you need to exclude additional directories from the report, specify them
|
||||
# using the COVERAGE_LCOV_EXCLUDES variable before calling
|
||||
# SETUP_TARGET_FOR_COVERAGE_LCOV. Example: set(COVERAGE_LCOV_EXCLUDES 'dir1/*'
|
||||
# 'dir2/*')
|
||||
#
|
||||
# 1. Use the functions described below to create a custom make target which runs
|
||||
# your test executable and produces a code coverage report.
|
||||
#
|
||||
# 1. Build a Debug build: cmake -DCMAKE_BUILD_TYPE=Debug .. make make
|
||||
# my_coverage_target
|
||||
#
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
# Check prereqs
|
||||
find_program(GCOV_PATH ${CMAKE_SOURCE_DIR}/tests/llvm-gcov.sh gcov)
|
||||
find_program(LCOV_PATH
|
||||
NAMES lcov
|
||||
lcov.bat
|
||||
lcov.exe
|
||||
lcov.perl)
|
||||
find_program(LLVM_COV_PATH NAMES llvm-cov-7 llvm-cov-6 llvm-profdata)
|
||||
find_program(LLVM_PROFDATA_PATH
|
||||
NAMES llvm-profdata-7 llvm-profdata-6 llvm-profdata)
|
||||
find_program(GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat)
|
||||
find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
||||
find_program(SIMPLE_PYTHON_EXECUTABLE python)
|
||||
|
||||
if(NOT GCOV_PATH)
|
||||
message(FATAL_ERROR "gcov not found! Aborting...")
|
||||
endif() # NOT GCOV_PATH
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
|
||||
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
|
||||
endif()
|
||||
elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
|
||||
endif()
|
||||
|
||||
set(
|
||||
COVERAGE_COMPILER_FLAGS
|
||||
"-g -O0 -fprofile-arcs -ftest-coverage -fprofile-instr-generate -fcoverage-mapping"
|
||||
CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE ${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_C_FLAGS_COVERAGE ${COVERAGE_COMPILER_FLAGS}
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE ""
|
||||
CACHE STRING "Flags used for linking binaries during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE ""
|
||||
CACHE STRING
|
||||
"Flags used by the shared libraries linker during coverage builds."
|
||||
FORCE)
|
||||
mark_as_advanced(CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(
|
||||
WARNING
|
||||
"Code coverage results with an optimised (non-Debug) build may be misleading"
|
||||
)
|
||||
endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
link_libraries(gcov)
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS
|
||||
"${CMAKE_EXE_LINKER_FLAGS} -fprofile-instr-generate")
|
||||
endif()
|
||||
|
||||
# Defines a target for running and collection code coverage information Builds
|
||||
# dependencies, runs the given executable and outputs reports. NOTE! The
|
||||
# executable should always have a ZERO as exit code otherwise the coverage
|
||||
# generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_LCOV_HTML( NAME testrunner_coverage # New target
|
||||
# name EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in
|
||||
# PROJECT_BINARY_DIR DEPENDENCIES testrunner # Dependencies
|
||||
# to build first )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_LCOV_HTML)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs
|
||||
EXECUTABLE
|
||||
EXECUTABLE_ARGS
|
||||
DEPENDENCIES
|
||||
LCOV_ARGS
|
||||
GENHTML_ARGS)
|
||||
cmake_parse_arguments(Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT LCOV_PATH)
|
||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
||||
endif() # NOT LCOV_PATH
|
||||
|
||||
if(NOT GENHTML_PATH)
|
||||
message(FATAL_ERROR "genhtml not found! Aborting...")
|
||||
endif() # NOT GENHTML_PATH
|
||||
|
||||
# Setup target
|
||||
add_custom_target(
|
||||
${Coverage_NAME}
|
||||
# Cleanup lcov
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS}
|
||||
--gcov-tool ${GCOV_PATH} -directory .
|
||||
--zerocounters # Create baseline to make sure untouched files show
|
||||
# up in the report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS}
|
||||
--gcov-tool ${GCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base
|
||||
# Run tests
|
||||
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
# Capturing lcov counters and generating report
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS}
|
||||
--gcov-tool ${GCOV_PATH}
|
||||
--directory .
|
||||
--capture
|
||||
--output-file ${Coverage_NAME}.info
|
||||
# add baseline counters
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS}
|
||||
--gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a
|
||||
${Coverage_NAME}.info
|
||||
--output-file ${Coverage_NAME}.total
|
||||
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS}
|
||||
--gcov-tool ${GCOV_PATH}
|
||||
--remove ${Coverage_NAME}.total ${COVERAGE_LCOV_EXCLUDES}
|
||||
--output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
# Generate HTML
|
||||
COMMAND ${GENHTML_PATH} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME}
|
||||
${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
# Clean up
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base
|
||||
${Coverage_NAME}.total
|
||||
${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT
|
||||
"Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
|
||||
)
|
||||
|
||||
# Show where to find the lcov info report
|
||||
add_custom_command(
|
||||
TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info.")
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(
|
||||
TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT
|
||||
"Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV_HTML
|
||||
|
||||
# Defines a target for running and collection code coverage information Builds
|
||||
# dependencies, runs the given executable and outputs reports. NOTE! The
|
||||
# executable should always have a ZERO as exit code otherwise the coverage
|
||||
# generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_LCOV_TXT( NAME testrunner_coverage # New target name
|
||||
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
||||
# DEPENDENCIES testrunner # Dependencies to build first )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_LCOV_TXT)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs
|
||||
EXECUTABLE
|
||||
EXECUTABLE_ARGS
|
||||
DEPENDENCIES
|
||||
LCOV_ARGS
|
||||
GENHTML_ARGS)
|
||||
cmake_parse_arguments(Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT LCOV_PATH)
|
||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
||||
endif() # NOT LCOV_PATH
|
||||
|
||||
# Setup target
|
||||
add_custom_target(
|
||||
${Coverage_NAME}
|
||||
# Run tests
|
||||
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
# Generate coverage.txt for sonar
|
||||
COMMAND ${LLVM_PROFDATA_PATH} merge default.profraw -output
|
||||
${Coverage_NAME}.profdata
|
||||
COMMAND ${LLVM_COV_PATH} show -instr-profile=${Coverage_NAME}.profdata
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${Coverage_EXECUTABLE} >
|
||||
${Coverage_NAME}.txt
|
||||
# Generate HTML
|
||||
# Clean up
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.profdata default.profraw
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT
|
||||
"Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
|
||||
)
|
||||
|
||||
# Show where to find the lcov info report
|
||||
add_custom_command(
|
||||
TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.txt.")
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV_TXT
|
||||
|
||||
# Defines a target for running and collection code coverage information Builds
|
||||
# dependencies, runs the given executable and outputs reports. NOTE! The
|
||||
# executable should always have a ZERO as exit code otherwise the coverage
|
||||
# generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_GCOVR_XML( NAME ctest_coverage #
|
||||
# New target name EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in
|
||||
# PROJECT_BINARY_DIR DEPENDENCIES executable_target # Dependencies to
|
||||
# build first )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT SIMPLE_PYTHON_EXECUTABLE)
|
||||
message(FATAL_ERROR "python not found! Aborting...")
|
||||
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDES "-e")
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(
|
||||
${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH}
|
||||
--xml -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
|
||||
--object-directory=${PROJECT_BINARY_DIR} -o ${Coverage_NAME}.xml
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT "Running gcovr to produce Cobertura code coverage report.")
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(
|
||||
TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml.")
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_XML
|
||||
|
||||
# Defines a target for running and collection code coverage information Builds
|
||||
# dependencies, runs the given executable and outputs reports. NOTE! The
|
||||
# executable should always have a ZERO as exit code otherwise the coverage
|
||||
# generation will not complete.
|
||||
#
|
||||
# SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML( NAME ctest_coverage #
|
||||
# New target name EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in
|
||||
# PROJECT_BINARY_DIR DEPENDENCIES executable_target # Dependencies to
|
||||
# build first )
|
||||
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
|
||||
|
||||
set(options NONE)
|
||||
set(oneValueArgs NAME)
|
||||
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
||||
cmake_parse_arguments(Coverage
|
||||
"${options}"
|
||||
"${oneValueArgs}"
|
||||
"${multiValueArgs}"
|
||||
${ARGN})
|
||||
|
||||
if(NOT SIMPLE_PYTHON_EXECUTABLE)
|
||||
message(FATAL_ERROR "python not found! Aborting...")
|
||||
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
|
||||
|
||||
if(NOT GCOVR_PATH)
|
||||
message(FATAL_ERROR "gcovr not found! Aborting...")
|
||||
endif() # NOT GCOVR_PATH
|
||||
|
||||
# Combine excludes to several -e arguments
|
||||
set(GCOVR_EXCLUDES "")
|
||||
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
|
||||
list(APPEND GCOVR_EXCLUDES "-e")
|
||||
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(
|
||||
${Coverage_NAME}
|
||||
# Run tests
|
||||
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
|
||||
# Create folder
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${PROJECT_BINARY_DIR}/${Coverage_NAME}
|
||||
# Running gcovr
|
||||
COMMAND ${GCOVR_PATH}
|
||||
--html
|
||||
--html-details -r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
|
||||
--object-directory=${PROJECT_BINARY_DIR} -o
|
||||
${Coverage_NAME}/index.html
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
DEPENDS ${Coverage_DEPENDENCIES}
|
||||
COMMENT "Running gcovr to produce HTML code coverage report.")
|
||||
|
||||
# Show info where to find the report
|
||||
add_custom_command(
|
||||
TARGET ${Coverage_NAME} POST_BUILD
|
||||
COMMAND ;
|
||||
COMMENT
|
||||
"Open ${CMAKE_CURRENT_BINARY_DIR}/${Coverage_NAME}/index.html in your browser to view the coverage report."
|
||||
)
|
||||
|
||||
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML
|
||||
|
||||
function(APPEND_COVERAGE_COMPILER_FLAGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}"
|
||||
PARENT_SCOPE)
|
||||
message(
|
||||
STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
|
||||
endfunction() # APPEND_COVERAGE_COMPILER_FLAGS
|
@ -3,52 +3,89 @@
|
||||
#
|
||||
# Please see COPYING for details
|
||||
#
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS) All rights
|
||||
# reserved.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details. You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
if(MAINTAINER_MODE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING
|
||||
set(
|
||||
CMAKE_BUILD_TYPE Debug
|
||||
CACHE
|
||||
STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
else(MAINTAINER_MODE)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
|
||||
set(
|
||||
CMAKE_BUILD_TYPE RelWithDebInfo
|
||||
CACHE
|
||||
STRING
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
endif(MAINTAINER_MODE)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# -std options for all build types
|
||||
set(CMAKE_C_FLAGS "-std=c99" CACHE STRING "Flags used by the C compiler during all build types." FORCE)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++17" CACHE STRING "Flags used by the C++ compiler during all build types." FORCE)
|
||||
set(CMAKE_C_FLAGS "-std=c99"
|
||||
CACHE STRING "Flags used by the C compiler during all build types."
|
||||
FORCE)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++17"
|
||||
CACHE STRING "Flags used by the C++ compiler during all build types."
|
||||
FORCE)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS ON)
|
||||
|
||||
if(MAINTAINER_MODE)
|
||||
set(BUILD_TESTS true)
|
||||
# some extra debug flags when in 'maintainer mode'
|
||||
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||
# Some flags are only supported on GCC >= 7.0, such as -Wimplicit-fallthrough=2
|
||||
set(CMAKE_C_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -pedantic -Werror -Wno-unknown-pragmas -Wno-error=pragmas -Wimplicit-fallthrough=2" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -pedantic -Werror -Wno-format -Wno-unknown-pragmas -Wno-error=pragmas -Wimplicit-fallthrough=2" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||
# Some flags are only supported on GCC >= 7.0, such as -Wimplicit-
|
||||
# fallthrough=2
|
||||
set(
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
"-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -pedantic -Werror -Wno-unknown-pragmas -Wno-error=pragmas -Wimplicit-fallthrough=2"
|
||||
CACHE STRING "Flags used by the compiler during debug builds."
|
||||
FORCE)
|
||||
set(
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
"-ggdb -Wall -W -Wextra -Wunused -pedantic -Werror -Wno-format -Wno-unknown-pragmas -Wno-error=pragmas -Wimplicit-fallthrough=2"
|
||||
CACHE STRING "Flags used by the compiler during debug builds."
|
||||
FORCE)
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -pedantic -Werror -Wno-unknown-pragmas -Wno-error=pragmas" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Wall -W -Wextra -Wunused -pedantic -Werror -Wno-format -Wno-unknown-pragmas -Wno-error=pragmas" CACHE STRING "Flags used by the compiler during debug builds." FORCE)
|
||||
set(
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
"-ggdb -Wall -W -Wextra -Wunused -Wdeclaration-after-statement -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Winline -Wmissing-noreturn -Wmissing-format-attribute -Wredundant-decls -pedantic -Werror -Wno-unknown-pragmas -Wno-error=pragmas"
|
||||
CACHE STRING "Flags used by the compiler during debug builds."
|
||||
FORCE)
|
||||
set(
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
"-ggdb -Wall -W -Wextra -Wunused -pedantic -Werror -Wno-format -Wno-unknown-pragmas -Wno-error=pragmas"
|
||||
CACHE STRING "Flags used by the compiler during debug builds."
|
||||
FORCE)
|
||||
endif()
|
||||
endif(MAINTAINER_MODE)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(USING_CLANG true)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 7.0.0
|
||||
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0.0)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
set(USING_CLANG_7 true)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(CHECK_CODE_QUALITY "Check code formatting/quality with clang" false)
|
||||
|
||||
option(RELEASE "Build release package" false)
|
||||
@ -58,16 +95,21 @@ option(MAINTAINER_MODE "Enable maintainer mode (builds docs)" false)
|
||||
|
||||
option(BUILD_I18N "Enable if you want internationalization support" true)
|
||||
if(BUILD_I18N)
|
||||
set(LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE STRING "Directory containing the locales")
|
||||
set(LOCALE_DIR "${CMAKE_INSTALL_PREFIX}/share/locale"
|
||||
CACHE STRING "Directory containing the locales")
|
||||
endif(BUILD_I18N)
|
||||
|
||||
# Some standard options
|
||||
set(SYSTEM_CONFIG_FILE "/etc/conky/conky.conf" CACHE STRING "Default system-wide Conky configuration file")
|
||||
# use FORCE below to make sure this changes when CMAKE_INSTALL_PREFIX is modified
|
||||
if (NOT LIB_INSTALL_DIR)
|
||||
set (LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
|
||||
endif (NOT LIB_INSTALL_DIR)
|
||||
set(PACKAGE_LIBRARY_DIR "${LIB_INSTALL_DIR}/conky" CACHE STRING "Package library path (where Lua bindings are installed" FORCE)
|
||||
set(SYSTEM_CONFIG_FILE "/etc/conky/conky.conf"
|
||||
CACHE STRING "Default system-wide Conky configuration file")
|
||||
# use FORCE below to make sure this changes when CMAKE_INSTALL_PREFIX is
|
||||
# modified
|
||||
if(NOT LIB_INSTALL_DIR)
|
||||
set(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
|
||||
endif(NOT LIB_INSTALL_DIR)
|
||||
set(PACKAGE_LIBRARY_DIR "${LIB_INSTALL_DIR}/conky"
|
||||
CACHE STRING "Package library path (where Lua bindings are installed"
|
||||
FORCE)
|
||||
set(DEFAULTNETDEV "eth0" CACHE STRING "Default networkdevice")
|
||||
|
||||
# Mac only override
|
||||
@ -75,15 +117,17 @@ if(OS_DARWIN)
|
||||
set(DEFAULTNETDEV "en0" CACHE STRING "Default networkdevice" FORCE)
|
||||
endif(OS_DARWIN)
|
||||
|
||||
set(XDG_CONFIG_FILE "$HOME/.config/conky/conky.conf" CACHE STRING "Configfile of the user (XDG)")
|
||||
set(XDG_CONFIG_FILE "$HOME/.config/conky/conky.conf"
|
||||
CACHE STRING "Configfile of the user (XDG)")
|
||||
set(CONFIG_FILE "$HOME/.conkyrc" CACHE STRING "Configfile of the user")
|
||||
set(MAX_USER_TEXT_DEFAULT "16384" CACHE STRING "Default maximum size of config TEXT buffer, i.e. below TEXT line.")
|
||||
set(DEFAULT_TEXT_BUFFER_SIZE "256" CACHE STRING "Default size used for temporary, static text buffers")
|
||||
set(MAX_USER_TEXT_DEFAULT "16384"
|
||||
CACHE STRING
|
||||
"Default maximum size of config TEXT buffer, i.e. below TEXT line.")
|
||||
set(DEFAULT_TEXT_BUFFER_SIZE "256"
|
||||
CACHE STRING "Default size used for temporary, static text buffers")
|
||||
set(MAX_NET_INTERFACES "64" CACHE STRING "Maximum number of network devices")
|
||||
|
||||
|
||||
# Platform specific options
|
||||
# Linux only
|
||||
# Platform specific options Linux only
|
||||
if(OS_LINUX)
|
||||
option(BUILD_PORT_MONITORS "Build TCP portmon support" true)
|
||||
option(BUILD_IBM "Support for IBM/Lenovo notebooks" true)
|
||||
@ -101,7 +145,10 @@ endif(OS_LINUX)
|
||||
|
||||
# macOS Only
|
||||
if(OS_DARWIN)
|
||||
option(BUILD_IPGFREQ "Enable cpu freq calculation based on Intel® Power Gadget; otherwise use constant factory value" false)
|
||||
option(
|
||||
BUILD_IPGFREQ
|
||||
"Enable cpu freq calculation based on Intel® Power Gadget; otherwise use constant factory value"
|
||||
false)
|
||||
endif(OS_DARWIN)
|
||||
|
||||
# Optional features etc
|
||||
@ -113,15 +160,24 @@ option(BUILD_BUILTIN_CONFIG "Enable builtin default configuration" true)
|
||||
|
||||
option(BUILD_IOSTATS "Enable disk I/O stats" true)
|
||||
|
||||
option(BUILD_OLD_CONFIG "Enable support for the old syntax of configurations" true)
|
||||
option(BUILD_OLD_CONFIG "Enable support for the old syntax of configurations"
|
||||
true)
|
||||
|
||||
option(BUILD_MATH "Enable math support" true)
|
||||
|
||||
option(BUILD_NCURSES "Enable ncurses support" true)
|
||||
if(BUILD_NCURSES)
|
||||
option(LEAKFREE_NCURSES "Enable to hide false ncurses-memleaks in valgrind (works only when ncurses is compiled with --disable-leaks)" false)
|
||||
option(
|
||||
LEAKFREE_NCURSES
|
||||
"Enable to hide false ncurses-memleaks in valgrind (works only when ncurses is compiled with --disable-leaks)"
|
||||
false)
|
||||
else(BUILD_NCURSES)
|
||||
set(LEAKFREE_NCURSES false CACHE BOOL "Enable to hide false ncurses-memleaks in valgrind (works only when ncurses is compiled with --disable-leaks)" FORCE)
|
||||
set(
|
||||
LEAKFREE_NCURSES false
|
||||
CACHE
|
||||
BOOL
|
||||
"Enable to hide false ncurses-memleaks in valgrind (works only when ncurses is compiled with --disable-leaks)"
|
||||
FORCE)
|
||||
endif(BUILD_NCURSES)
|
||||
|
||||
option(BUILD_X11 "Build X11 support" true)
|
||||
@ -153,7 +209,9 @@ endif(BUILD_X11)
|
||||
if(OWN_WINDOW)
|
||||
option(BUILD_ARGB "Build ARGB (real transparency) support" true)
|
||||
else(OWN_WINDOW)
|
||||
set(BUILD_ARGB false CACHE BOOL "Build ARGB (real transparency) support" FORCE)
|
||||
set(BUILD_ARGB false
|
||||
CACHE BOOL "Build ARGB (real transparency) support"
|
||||
FORCE)
|
||||
endif(OWN_WINDOW)
|
||||
|
||||
option(BUILD_LUA_CAIRO "Build cairo bindings for Lua" false)
|
||||
@ -198,23 +256,26 @@ option(BUILD_ICONV "Enable iconv support" false)
|
||||
|
||||
option(BUILD_CMUS "Enable support for cmus music player" true)
|
||||
|
||||
option(BUILD_JOURNAL "Enable support for reading from the systemd journal" false)
|
||||
option(BUILD_JOURNAL "Enable support for reading from the systemd journal"
|
||||
false)
|
||||
|
||||
option(BUILD_PULSEAUDIO "Enable support for Pulseaudio's default sink and source" false)
|
||||
option(BUILD_PULSEAUDIO
|
||||
"Enable support for Pulseaudio's default sink and source" false)
|
||||
|
||||
message( STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS} )
|
||||
message( STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS} )
|
||||
message(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS})
|
||||
message(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS})
|
||||
|
||||
message( STATUS "CMAKE_C_FLAGS_DEBUG: " ${CMAKE_C_FLAGS_DEBUG} )
|
||||
message( STATUS "CMAKE_CXX_FLAGS_DEBUG: " ${CMAKE_CXX_FLAGS_DEBUG} )
|
||||
message(STATUS "CMAKE_C_FLAGS_DEBUG: " ${CMAKE_C_FLAGS_DEBUG})
|
||||
message(STATUS "CMAKE_CXX_FLAGS_DEBUG: " ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
|
||||
message( STATUS "CMAKE_C_FLAGS_MINSIZEREL: " ${CMAKE_C_FLAGS_MINSIZEREL} )
|
||||
message( STATUS "CMAKE_CXX_FLAGS_MINSIZEREL: " ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
||||
message(STATUS "CMAKE_C_FLAGS_MINSIZEREL: " ${CMAKE_C_FLAGS_MINSIZEREL})
|
||||
message(STATUS "CMAKE_CXX_FLAGS_MINSIZEREL: " ${CMAKE_CXX_FLAGS_MINSIZEREL})
|
||||
|
||||
message( STATUS "CMAKE_C_FLAGS_RELEASE: " ${CMAKE_C_FLAGS_RELEASE} )
|
||||
message( STATUS "CMAKE_CXX_FLAGS_RELEASE: " ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
message(STATUS "CMAKE_C_FLAGS_RELEASE: " ${CMAKE_C_FLAGS_RELEASE})
|
||||
message(STATUS "CMAKE_CXX_FLAGS_RELEASE: " ${CMAKE_CXX_FLAGS_RELEASE})
|
||||
|
||||
message( STATUS "CMAKE_C_FLAGS_RELWITHDEBINFO: " ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
||||
message( STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: " ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
||||
message(STATUS "CMAKE_C_FLAGS_RELWITHDEBINFO: " ${CMAKE_C_FLAGS_RELWITHDEBINFO})
|
||||
message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: "
|
||||
${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
|
||||
|
||||
message( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} )
|
||||
message(STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE})
|
||||
|
@ -3,5 +3,6 @@ sonar.projectName=Conky
|
||||
sonar.sources=src
|
||||
sonar.cfamily.build-wrapper-output=build/bw-output
|
||||
sonar.cpp.std=c++17
|
||||
sonar.exclusions=3rdparty/**
|
||||
sonar.exclusions=3rdparty/**,tests/**
|
||||
sonar.cfamily.threads=4
|
||||
sonar.cfamily.llvm-cov.reportPath=build/test-conky-coverage-txt.txt
|
||||
|
@ -3,19 +3,18 @@
|
||||
#
|
||||
# Please see COPYING for details
|
||||
#
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS)
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2005-2018 Brenden Matthews, et. al. (see AUTHORS) All rights
|
||||
# reserved.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details. You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
@ -27,208 +26,199 @@ endif(BUILD_BUILTIN_CONFIG OR BUILD_OLD_CONFIG)
|
||||
|
||||
# ensure build.h and config.h aren't in the way
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/config.h' in order to build with CMake.")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/config.h' in order to build with CMake."
|
||||
)
|
||||
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/config.h)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build.h)
|
||||
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/build.h' in order to build with CMake.")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/build.h' in order to build with CMake."
|
||||
)
|
||||
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build.h)
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h)
|
||||
message(FATAL_ERROR "You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h' in order to build with CMake.")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"You must remove the autotools generated file '${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h' in order to build with CMake."
|
||||
)
|
||||
endif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/defconfig.h)
|
||||
|
||||
set(conky_sources
|
||||
${conky_sources}
|
||||
c++wrap.cc c++wrap.hh
|
||||
colours.cc colours.h
|
||||
combine.cc combine.h
|
||||
common.cc common.h
|
||||
conky.cc conky.h
|
||||
core.cc core.h
|
||||
cpu.cc cpu.h
|
||||
diskio.cc diskio.h
|
||||
entropy.cc entropy.h
|
||||
exec.cc exec.h
|
||||
fs.cc fs.h
|
||||
mail.cc mail.h
|
||||
misc.cc misc.h
|
||||
net_stat.cc net_stat.h
|
||||
template.cc template.h
|
||||
mboxscan.cc mboxscan.h
|
||||
read_tcpip.cc read_tcpip.h
|
||||
scroll.cc scroll.h
|
||||
specials.cc specials.h
|
||||
tailhead.cc tailhead.h
|
||||
temphelper.cc temphelper.h
|
||||
text_object.cc text_object.h
|
||||
timeinfo.cc timeinfo.h
|
||||
top.cc top.h
|
||||
algebra.cc algebra.h
|
||||
prioqueue.cc prioqueue.h
|
||||
proc.cc proc.h
|
||||
user.cc user.h
|
||||
luamm.cc luamm.hh
|
||||
data-source.cc data-source.hh
|
||||
lua-config.cc lua-config.hh
|
||||
setting.cc setting.hh
|
||||
llua.cc llua.h
|
||||
update-cb.cc update-cb.hh
|
||||
c++wrap.cc
|
||||
c++wrap.hh
|
||||
colours.cc
|
||||
colours.h
|
||||
combine.cc
|
||||
combine.h
|
||||
common.cc
|
||||
common.h
|
||||
conky.cc
|
||||
conky.h
|
||||
core.cc
|
||||
core.h
|
||||
cpu.cc
|
||||
cpu.h
|
||||
diskio.cc
|
||||
diskio.h
|
||||
entropy.cc
|
||||
entropy.h
|
||||
exec.cc
|
||||
exec.h
|
||||
fs.cc
|
||||
fs.h
|
||||
mail.cc
|
||||
mail.h
|
||||
misc.cc
|
||||
misc.h
|
||||
net_stat.cc
|
||||
net_stat.h
|
||||
template.cc
|
||||
template.h
|
||||
mboxscan.cc
|
||||
mboxscan.h
|
||||
read_tcpip.cc
|
||||
read_tcpip.h
|
||||
scroll.cc
|
||||
scroll.h
|
||||
specials.cc
|
||||
specials.h
|
||||
tailhead.cc
|
||||
tailhead.h
|
||||
temphelper.cc
|
||||
temphelper.h
|
||||
text_object.cc
|
||||
text_object.h
|
||||
timeinfo.cc
|
||||
timeinfo.h
|
||||
top.cc
|
||||
top.h
|
||||
algebra.cc
|
||||
algebra.h
|
||||
prioqueue.cc
|
||||
prioqueue.h
|
||||
proc.cc
|
||||
proc.h
|
||||
user.cc
|
||||
user.h
|
||||
luamm.cc
|
||||
luamm.hh
|
||||
data-source.cc
|
||||
data-source.hh
|
||||
lua-config.cc
|
||||
lua-config.hh
|
||||
setting.cc
|
||||
setting.hh
|
||||
llua.cc
|
||||
llua.h
|
||||
update-cb.cc
|
||||
update-cb.hh
|
||||
logging.h
|
||||
semaphore.hh
|
||||
)
|
||||
semaphore.hh)
|
||||
|
||||
# Platform specific sources
|
||||
if(OS_LINUX)
|
||||
set(linux
|
||||
linux.cc linux.h
|
||||
users.cc users.h
|
||||
sony.cc sony.h
|
||||
i8k.cc i8k.h
|
||||
)
|
||||
set(linux linux.cc linux.h users.cc users.h sony.cc sony.h i8k.cc i8k.h)
|
||||
set(optional_sources ${optional_sources} ${linux})
|
||||
endif(OS_LINUX)
|
||||
|
||||
if(OS_FREEBSD)
|
||||
set(freebsd
|
||||
freebsd.cc freebsd.h
|
||||
bsdapm.cc bsdapm.h
|
||||
)
|
||||
set(freebsd freebsd.cc freebsd.h bsdapm.cc bsdapm.h)
|
||||
set(optional_sources ${optional_sources} ${freebsd})
|
||||
endif(OS_FREEBSD)
|
||||
|
||||
if(OS_DRAGONFLY)
|
||||
set(dragonfly
|
||||
dragonfly.cc dragonfly.h
|
||||
bsdapm.cc bsdapm.h
|
||||
)
|
||||
set(dragonfly dragonfly.cc dragonfly.h bsdapm.cc bsdapm.h)
|
||||
set(optional_sources ${optional_sources} ${dragonfly})
|
||||
endif(OS_DRAGONFLY)
|
||||
|
||||
if(OS_OPENBSD)
|
||||
set(openbsd
|
||||
openbsd.cc openbsd.h
|
||||
bsdapm.cc bsdapm.h
|
||||
)
|
||||
set(openbsd openbsd.cc openbsd.h bsdapm.cc bsdapm.h)
|
||||
set(optional_sources ${optional_sources} ${openbsd})
|
||||
endif(OS_OPENBSD)
|
||||
|
||||
# These below are not actually supported. No idea what their status is.
|
||||
if(OS_SOLARIS)
|
||||
set(solaris
|
||||
solaris.cc solaris.h
|
||||
)
|
||||
set(solaris solaris.cc solaris.h)
|
||||
set(optional_sources ${optional_sources} ${solaris})
|
||||
endif(OS_SOLARIS)
|
||||
|
||||
if(OS_NETBSD)
|
||||
set(netbsd
|
||||
netbsd.cc netbsd.h
|
||||
)
|
||||
set(netbsd netbsd.cc netbsd.h)
|
||||
set(optional_sources ${optional_sources} ${netbsd})
|
||||
endif(OS_NETBSD)
|
||||
|
||||
if(OS_HAIKU)
|
||||
set(haiku
|
||||
haiku.cc haiku.h
|
||||
)
|
||||
set(haiku haiku.cc haiku.h)
|
||||
set(optional_sources ${optional_sources} ${haiku})
|
||||
endif(OS_HAIKU)
|
||||
|
||||
if(OS_DARWIN)
|
||||
set(darwin
|
||||
darwin.mm darwin.h
|
||||
darwin_sip.h
|
||||
i18n.h
|
||||
)
|
||||
set(darwin darwin.mm darwin.h darwin_sip.h i18n.h)
|
||||
set(optional_sources ${optional_sources} ${darwin})
|
||||
endif(OS_DARWIN)
|
||||
|
||||
# Optional sources
|
||||
if(HAVE_SOME_SOUNDCARD_H)
|
||||
set(mixer
|
||||
mixer.cc mixer.h
|
||||
)
|
||||
set(mixer mixer.cc mixer.h)
|
||||
set(optional_sources ${optional_sources} ${mixer})
|
||||
endif(HAVE_SOME_SOUNDCARD_H)
|
||||
|
||||
if(BUILD_AUDACIOUS)
|
||||
set(audacious
|
||||
audacious.cc audacious.h
|
||||
)
|
||||
set(audacious audacious.cc audacious.h)
|
||||
set(optional_sources ${optional_sources} ${audacious})
|
||||
endif(BUILD_AUDACIOUS)
|
||||
|
||||
if(BUILD_BMPX)
|
||||
set(bmpx
|
||||
bmpx.cc bmpx.h
|
||||
)
|
||||
set(bmpx bmpx.cc bmpx.h)
|
||||
set(optional_sources ${optional_sources} ${bmpx})
|
||||
endif(BUILD_BMPX)
|
||||
|
||||
if(BUILD_IBM)
|
||||
set(ibm
|
||||
ibm.cc ibm.h
|
||||
smapi.cc smapi.h
|
||||
)
|
||||
set(ibm ibm.cc ibm.h smapi.cc smapi.h)
|
||||
set(optional_sources ${optional_sources} ${ibm})
|
||||
endif(BUILD_IBM)
|
||||
|
||||
if(BUILD_MPD)
|
||||
set(mpd
|
||||
mpd.cc mpd.h
|
||||
libmpdclient.cc libmpdclient.h
|
||||
)
|
||||
set(mpd mpd.cc mpd.h libmpdclient.cc libmpdclient.h)
|
||||
set(optional_sources ${optional_sources} ${mpd})
|
||||
endif(BUILD_MPD)
|
||||
|
||||
if(BUILD_MYSQL)
|
||||
set(mysql
|
||||
mysql.cc mysql.h
|
||||
)
|
||||
set(mysql mysql.cc mysql.h)
|
||||
set(optional_sources ${optional_sources} ${mysql})
|
||||
endif(BUILD_MYSQL)
|
||||
|
||||
if(BUILD_MOC)
|
||||
set(moc
|
||||
moc.cc moc.h
|
||||
)
|
||||
set(moc moc.cc moc.h)
|
||||
set(optional_sources ${optional_sources} ${moc})
|
||||
endif(BUILD_MOC)
|
||||
|
||||
if(BUILD_CMUS)
|
||||
set(cmus
|
||||
cmus.cc cmus.h
|
||||
)
|
||||
set(cmus cmus.cc cmus.h)
|
||||
set(optional_sources ${optional_sources} ${cmus})
|
||||
endif(BUILD_CMUS)
|
||||
|
||||
if(BUILD_JOURNAL)
|
||||
set(journal
|
||||
journal.cc journal.h
|
||||
)
|
||||
set(journal journal.cc journal.h)
|
||||
set(optional_sources ${optional_sources} ${journal})
|
||||
endif(BUILD_JOURNAL)
|
||||
|
||||
if(BUILD_XMMS2)
|
||||
set(xmms2
|
||||
xmms2.cc xmms2.h
|
||||
)
|
||||
set(xmms2 xmms2.cc xmms2.h)
|
||||
set(optional_sources ${optional_sources} ${xmms2})
|
||||
endif(BUILD_XMMS2)
|
||||
|
||||
if(BUILD_PORT_MONITORS)
|
||||
add_library(tcp-portmon libtcp-portmon.cc libtcp-portmon.h)
|
||||
set(conky_libs ${conky_libs} tcp-portmon)
|
||||
set(port_monitors
|
||||
tcp-portmon.cc tcp-portmon.h
|
||||
)
|
||||
set(port_monitors tcp-portmon.cc tcp-portmon.h)
|
||||
set(optional_sources ${optional_sources} ${port_monitors})
|
||||
endif(BUILD_PORT_MONITORS)
|
||||
|
||||
if(BUILD_X11)
|
||||
set(x11
|
||||
x11.cc x11.h
|
||||
fonts.cc fonts.h
|
||||
)
|
||||
set(x11 x11.cc x11.h fonts.cc fonts.h)
|
||||
set(optional_sources ${optional_sources} ${x11})
|
||||
|
||||
if(BUILD_XINERAMA)
|
||||
@ -238,107 +228,85 @@ if(BUILD_X11)
|
||||
endif(BUILD_X11)
|
||||
|
||||
if(BUILD_HDDTEMP)
|
||||
set(hddtemp
|
||||
hddtemp.cc hddtemp.h
|
||||
)
|
||||
set(hddtemp hddtemp.cc hddtemp.h)
|
||||
set(optional_sources ${optional_sources} ${hddtemp})
|
||||
endif(BUILD_HDDTEMP)
|
||||
|
||||
if(BUILD_EVE)
|
||||
set(eve
|
||||
eve.cc eve.h
|
||||
)
|
||||
set(eve eve.cc eve.h)
|
||||
set(optional_sources ${optional_sources} ${eve})
|
||||
endif(BUILD_EVE)
|
||||
|
||||
if(BUILD_CURL)
|
||||
set(ccurl_thread
|
||||
ccurl_thread.cc ccurl_thread.h
|
||||
)
|
||||
set(ccurl_thread ccurl_thread.cc ccurl_thread.h)
|
||||
set(optional_sources ${optional_sources} ${ccurl_thread})
|
||||
endif(BUILD_CURL)
|
||||
|
||||
if(BUILD_RSS)
|
||||
set(rss
|
||||
rss.cc rss.h
|
||||
prss.cc prss.h
|
||||
)
|
||||
set(rss rss.cc rss.h prss.cc prss.h)
|
||||
set(optional_sources ${optional_sources} ${rss})
|
||||
endif(BUILD_RSS)
|
||||
|
||||
if(BUILD_WEATHER)
|
||||
set(weather
|
||||
weather.cc weather.h
|
||||
)
|
||||
set(weather weather.cc weather.h)
|
||||
set(optional_sources ${optional_sources} ${weather})
|
||||
endif(BUILD_WEATHER)
|
||||
|
||||
if(BUILD_NVIDIA)
|
||||
set(nvidia
|
||||
nvidia.cc nvidia.h
|
||||
)
|
||||
set(nvidia nvidia.cc nvidia.h)
|
||||
set(optional_sources ${optional_sources} ${nvidia})
|
||||
endif(BUILD_NVIDIA)
|
||||
|
||||
if(BUILD_IMLIB2)
|
||||
set(imlib2
|
||||
imlib2.cc imlib2.h
|
||||
)
|
||||
set(imlib2 imlib2.cc imlib2.h)
|
||||
set(optional_sources ${optional_sources} ${imlib2})
|
||||
endif(BUILD_IMLIB2)
|
||||
|
||||
if(BUILD_APCUPSD)
|
||||
set(apcupsd
|
||||
apcupsd.cc apcupsd.h
|
||||
)
|
||||
set(apcupsd apcupsd.cc apcupsd.h)
|
||||
set(optional_sources ${optional_sources} ${apcupsd})
|
||||
endif(BUILD_APCUPSD)
|
||||
|
||||
if(BUILD_ICAL)
|
||||
set(ical
|
||||
ical.cc ical.h
|
||||
)
|
||||
set(ical ical.cc ical.h)
|
||||
set(optional_sources ${optional_sources} ${ical})
|
||||
endif(BUILD_ICAL)
|
||||
|
||||
if(BUILD_IRC)
|
||||
set(irc
|
||||
irc.cc irc.h
|
||||
)
|
||||
set(irc irc.cc irc.h)
|
||||
set(optional_sources ${optional_sources} ${irc})
|
||||
endif(BUILD_IRC)
|
||||
|
||||
if(BUILD_ICONV)
|
||||
set(iconv
|
||||
iconv_tools.cc iconv_tools.h
|
||||
)
|
||||
set(iconv iconv_tools.cc iconv_tools.h)
|
||||
set(optional_sources ${optional_sources} ${iconv})
|
||||
endif(BUILD_ICONV)
|
||||
|
||||
if(BUILD_NCURSES)
|
||||
set(ncurses_srcs
|
||||
nc.cc nc.h
|
||||
)
|
||||
set(ncurses_srcs nc.cc nc.h)
|
||||
set(optional_sources ${optional_sources} ${ncurses_srcs})
|
||||
endif(BUILD_NCURSES)
|
||||
|
||||
if(BUILD_PULSEAUDIO)
|
||||
set(pulseaudio
|
||||
pulseaudio.cc pulseaudio.h
|
||||
)
|
||||
set(pulseaudio pulseaudio.cc pulseaudio.h)
|
||||
set(optional_sources ${optional_sources} ${pulseaudio})
|
||||
endif(BUILD_PULSEAUDIO)
|
||||
|
||||
add_executable(conky ${conky_sources} ${optional_sources})
|
||||
|
||||
target_link_libraries(conky ${conky_libs})
|
||||
if(BUILD_TESTS)
|
||||
# Create a library strictly for testing
|
||||
add_library(conky_core ${conky_sources} ${optional_sources})
|
||||
target_link_libraries(conky_core ${conky_libs})
|
||||
add_executable(conky main.cc)
|
||||
target_link_libraries(conky conky_core ${conky_libs})
|
||||
else()
|
||||
add_executable(conky main.cc ${conky_sources} ${optional_sources})
|
||||
target_link_libraries(conky ${conky_libs})
|
||||
endif()
|
||||
|
||||
# Install libtcp-portmon too?
|
||||
install(TARGETS
|
||||
conky
|
||||
install(TARGETS conky
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
)
|
||||
ARCHIVE DESTINATION lib)
|
||||
|
||||
print_target_properties(conky)
|
||||
|
187
src/common.cc
187
src/common.cc
@ -43,12 +43,12 @@
|
||||
#include "core.h"
|
||||
#include "fs.h"
|
||||
#include "logging.h"
|
||||
#include "misc.h"
|
||||
#include "net_stat.h"
|
||||
#include "specials.h"
|
||||
#include "temphelper.h"
|
||||
#include "timeinfo.h"
|
||||
#include "top.h"
|
||||
#include "misc.h"
|
||||
|
||||
/* check for OS and include appropriate headers */
|
||||
#if defined(__linux__)
|
||||
@ -134,12 +134,8 @@ double get_time() {
|
||||
* path. If HOME is unset it uses an empty string for substitution */
|
||||
std::string to_real_path(const std::string &source) {
|
||||
const char *homedir = getenv("HOME") != nullptr ? getenv("HOME") : "";
|
||||
if (source.find("~/") == 0) {
|
||||
return homedir + source.substr(1);
|
||||
}
|
||||
if (source.find("$HOME/") == 0) {
|
||||
return homedir + source.substr(5);
|
||||
}
|
||||
if (source.find("~/") == 0) { return homedir + source.substr(1); }
|
||||
if (source.find("$HOME/") == 0) { return homedir + source.substr(5); }
|
||||
return source;
|
||||
}
|
||||
|
||||
@ -151,9 +147,7 @@ int open_fifo(const char *file, int *reported) {
|
||||
if (fd == -1) {
|
||||
if ((reported == nullptr) || *reported == 0) {
|
||||
NORM_ERR("can't open %s: %s", file, strerror(errno));
|
||||
if (reported != nullptr) {
|
||||
*reported = 1;
|
||||
}
|
||||
if (reported != nullptr) { *reported = 1; }
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -169,9 +163,7 @@ FILE *open_file(const char *file, int *reported) {
|
||||
if (fp == nullptr) {
|
||||
if ((reported == nullptr) || *reported == 0) {
|
||||
NORM_ERR("can't open %s: %s", file, strerror(errno));
|
||||
if (reported != nullptr) {
|
||||
*reported = 1;
|
||||
}
|
||||
if (reported != nullptr) { *reported = 1; }
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -182,9 +174,7 @@ FILE *open_file(const char *file, int *reported) {
|
||||
std::string variable_substitute(std::string s) {
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = s.find('$', pos)) != std::string::npos) {
|
||||
if (pos + 1 >= s.size()) {
|
||||
break;
|
||||
}
|
||||
if (pos + 1 >= s.size()) { break; }
|
||||
|
||||
if (s[pos + 1] == '$') {
|
||||
s.erase(pos, 1);
|
||||
@ -195,15 +185,14 @@ std::string variable_substitute(std::string s) {
|
||||
|
||||
if (isalpha((unsigned char)s[pos + 1]) != 0) {
|
||||
l = 1;
|
||||
while (pos + l < s.size() && (isalnum((unsigned char)s[pos + l]) != 0)) {
|
||||
while (pos + l < s.size() &&
|
||||
(isalnum((unsigned char)s[pos + l]) != 0)) {
|
||||
++l;
|
||||
}
|
||||
var = s.substr(pos + 1, l - 1);
|
||||
} else if (s[pos + 1] == '{') {
|
||||
l = s.find('}', pos);
|
||||
if (l == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
if (l == std::string::npos) { break; }
|
||||
l -= pos - 1;
|
||||
var = s.substr(pos + 2, l - 3);
|
||||
} else {
|
||||
@ -273,9 +262,12 @@ void format_seconds_short(char *buf, unsigned int n, long seconds) {
|
||||
}
|
||||
|
||||
conky::simple_config_setting<bool> no_buffers("no_buffers", true, true);
|
||||
conky::simple_config_setting<std::string> bar_fill("console_bar_fill", "#", false);
|
||||
conky::simple_config_setting<std::string> bar_unfill("console_bar_unfill", ".", false);
|
||||
conky::simple_config_setting<std::string> github_token("github_token", "", false);
|
||||
conky::simple_config_setting<std::string> bar_fill("console_bar_fill", "#",
|
||||
false);
|
||||
conky::simple_config_setting<std::string> bar_unfill("console_bar_unfill", ".",
|
||||
false);
|
||||
conky::simple_config_setting<std::string> github_token("github_token", "",
|
||||
false);
|
||||
|
||||
void update_stuff() {
|
||||
/* clear speeds, addresses and up status in case device was removed and
|
||||
@ -310,21 +302,18 @@ void update_stuff() {
|
||||
}
|
||||
|
||||
/* Ohkie to return negative values for temperatures */
|
||||
int round_to_int_temp(float f) {
|
||||
return static_cast<int>(f);
|
||||
}
|
||||
int round_to_int_temp(float f) { return static_cast<int>(f); }
|
||||
/* Don't return negative values for cpugraph, bar, gauge, percentage.
|
||||
* Causes unreasonable numbers to show */
|
||||
unsigned int round_to_int(float f) {
|
||||
if (f >= 0.0) {
|
||||
return static_cast<int>(f + 0.5);
|
||||
}
|
||||
if (f >= 0.0) { return static_cast<int>(f + 0.5); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scan_loadavg_arg(struct text_object *obj, const char *arg) {
|
||||
obj->data.i = 0;
|
||||
if ((arg != nullptr) && (arg[1] == 0) && (isdigit((unsigned char)arg[0]) != 0)) {
|
||||
if ((arg != nullptr) && (arg[1] == 0) &&
|
||||
(isdigit((unsigned char)arg[0]) != 0)) {
|
||||
obj->data.i = atoi(arg);
|
||||
if (obj->data.i > 3 || obj->data.i < 1) {
|
||||
NORM_ERR("loadavg arg needs to be in range (1,3)");
|
||||
@ -354,7 +343,8 @@ void scan_no_update(struct text_object *obj, const char *arg) {
|
||||
|
||||
void free_no_update(struct text_object *obj) { free(obj->data.s); }
|
||||
|
||||
void print_no_update(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_no_update(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
snprintf(p, p_max_size, "%s", obj->data.s);
|
||||
}
|
||||
|
||||
@ -374,7 +364,7 @@ double loadgraphval(struct text_object *obj) {
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
uint8_t cpu_percentage(struct text_object *obj) {
|
||||
if ((unsigned int) obj->data.i > info.cpu_count) {
|
||||
if ((unsigned int)obj->data.i > info.cpu_count) {
|
||||
NORM_ERR("obj->data.i %i info.cpu_count %i", obj->data.i, info.cpu_count);
|
||||
CRIT_ERR(nullptr, nullptr, "attempting to use more CPUs than you have!");
|
||||
}
|
||||
@ -385,9 +375,7 @@ uint8_t cpu_percentage(struct text_object *obj) {
|
||||
}
|
||||
|
||||
double cpu_barval(struct text_object *obj) {
|
||||
if (info.cpu_usage != nullptr) {
|
||||
return info.cpu_usage[obj->data.i];
|
||||
}
|
||||
if (info.cpu_usage != nullptr) { return info.cpu_usage[obj->data.i]; }
|
||||
return 0.;
|
||||
}
|
||||
|
||||
@ -457,7 +445,8 @@ void print_nodename(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
snprintf(p, p_max_size, "%s", info.uname_s.nodename);
|
||||
}
|
||||
|
||||
void print_nodename_short(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_nodename_short(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
(void)obj;
|
||||
snprintf(p, p_max_size, "%s", info.uname_s.nodename);
|
||||
for (int i = 0; p[i] != 0; i++) {
|
||||
@ -485,22 +474,26 @@ void print_uptime(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
format_seconds(p, p_max_size, static_cast<int>(info.uptime));
|
||||
}
|
||||
|
||||
void print_uptime_short(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_uptime_short(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
(void)obj;
|
||||
format_seconds_short(p, p_max_size, static_cast<int>(info.uptime));
|
||||
}
|
||||
|
||||
void print_processes(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_processes(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
(void)obj;
|
||||
spaced_print(p, p_max_size, "%hu", 4, info.procs);
|
||||
}
|
||||
|
||||
void print_running_processes(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_running_processes(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
(void)obj;
|
||||
spaced_print(p, p_max_size, "%hu", 4, info.run_procs);
|
||||
}
|
||||
|
||||
void print_running_threads(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_running_threads(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
(void)obj;
|
||||
spaced_print(p, p_max_size, "%hu", 4, info.run_threads);
|
||||
}
|
||||
@ -511,11 +504,13 @@ void print_threads(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
}
|
||||
|
||||
void print_buffers(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
human_readable(apply_base_multiplier(obj->data.s, info.buffers), p, p_max_size);
|
||||
human_readable(apply_base_multiplier(obj->data.s, info.buffers), p,
|
||||
p_max_size);
|
||||
}
|
||||
|
||||
void print_cached(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
human_readable(apply_base_multiplier(obj->data.s, info.cached), p, p_max_size);
|
||||
human_readable(apply_base_multiplier(obj->data.s, info.cached), p,
|
||||
p_max_size);
|
||||
}
|
||||
|
||||
void print_evaluate(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
@ -530,9 +525,7 @@ int if_empty_iftest(struct text_object *obj) {
|
||||
|
||||
generate_text_internal(&(buf[0]), max_user_text.get(*state), *obj->sub);
|
||||
|
||||
if (strlen(&(buf[0])) != 0) {
|
||||
result = 0;
|
||||
}
|
||||
if (strlen(&(buf[0])) != 0) { result = 0; }
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -561,17 +554,13 @@ int if_existing_iftest(struct text_object *obj) {
|
||||
int result = 0;
|
||||
|
||||
spc = strchr(obj->data.s, ' ');
|
||||
if (spc != nullptr) {
|
||||
*spc = 0;
|
||||
}
|
||||
if (spc != nullptr) { *spc = 0; }
|
||||
if (access(obj->data.s, F_OK) == 0) {
|
||||
if (spc == nullptr || (check_contains(obj->data.s, spc + 1) != 0)) {
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
if (spc != nullptr) {
|
||||
*spc = ' ';
|
||||
}
|
||||
if (spc != nullptr) { *spc = ' '; }
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -596,9 +585,7 @@ void free_acpitemp(struct text_object *obj) { close(obj->data.i); }
|
||||
|
||||
void print_freq(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
static int ok = 1;
|
||||
if (ok != 0) {
|
||||
ok = get_freq(p, p_max_size, "%.0f", 1, obj->data.i);
|
||||
}
|
||||
if (ok != 0) { ok = get_freq(p, p_max_size, "%.0f", 1, obj->data.i); }
|
||||
}
|
||||
|
||||
void print_freq_g(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
@ -619,7 +606,8 @@ void print_acpifan(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
get_acpi_fan(p, p_max_size);
|
||||
}
|
||||
|
||||
void print_acpiacadapter(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_acpiacadapter(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
get_acpi_ac_adapter(p, p_max_size,
|
||||
static_cast<const char *>(obj->data.opaque));
|
||||
}
|
||||
@ -628,7 +616,8 @@ void print_battery(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_STATUS);
|
||||
}
|
||||
|
||||
void print_battery_time(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_battery_time(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_TIME);
|
||||
}
|
||||
|
||||
@ -636,11 +625,13 @@ uint8_t battery_percentage(struct text_object *obj) {
|
||||
return get_battery_perct(obj->data.s);
|
||||
}
|
||||
|
||||
void print_battery_short(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_battery_short(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
get_battery_short_status(p, p_max_size, obj->data.s);
|
||||
}
|
||||
|
||||
void print_battery_status(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_battery_status(struct text_object *obj, char *p,
|
||||
unsigned int p_max_size) {
|
||||
get_battery_stuff(p, p_max_size, obj->data.s, BATTERY_STATUS);
|
||||
if (0 == strncmp("charging", p, 8)) {
|
||||
snprintf(p, p_max_size, "%s", "charging");
|
||||
@ -672,9 +663,7 @@ void print_blink(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
generate_text_internal(&(buf[0]), max_user_text.get(*state), *obj->sub);
|
||||
last_len = strlen(&(buf[0]));
|
||||
} else {
|
||||
for (i = 0; i < last_len; i++) {
|
||||
buf[i] = ' ';
|
||||
}
|
||||
for (i = 0; i < last_len; i++) { buf[i] = ' '; }
|
||||
}
|
||||
|
||||
snprintf(p, p_max_size, "%s", &(buf[0]));
|
||||
@ -684,18 +673,19 @@ void print_blink(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
void print_include(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
std::vector<char> buf(max_user_text.get(*state));
|
||||
|
||||
if (obj->sub == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (obj->sub == nullptr) { return; }
|
||||
|
||||
generate_text_internal(&(buf[0]), max_user_text.get(*state), *obj->sub);
|
||||
snprintf(p, p_max_size, "%s", &(buf[0]));
|
||||
}
|
||||
|
||||
#ifdef BUILD_CURL
|
||||
#define NEW_TOKEN "https://github.com/settings/tokens/new?scopes=notifications&description=conky-query-github\n"
|
||||
#define NEW_TOKEN \
|
||||
"https://github.com/settings/tokens/" \
|
||||
"new?scopes=notifications&description=conky-query-github\n"
|
||||
static size_t read_github_data_cb(char *, size_t, size_t, char *);
|
||||
static size_t read_github_data_cb(char *data, size_t size, size_t nmemb, char *p) {
|
||||
static size_t read_github_data_cb(char *data, size_t size, size_t nmemb,
|
||||
char *p) {
|
||||
char *ptr = data;
|
||||
size_t sz = nmemb * size;
|
||||
size_t z = 0;
|
||||
@ -703,34 +693,37 @@ static size_t read_github_data_cb(char *data, size_t size, size_t nmemb, char *p
|
||||
static unsigned int skip = 0U;
|
||||
|
||||
for (; *ptr; ptr++, z++) {
|
||||
if (z+4 < sz) { /* Verifying up to *(ptr+4) */
|
||||
if ('u' == *ptr && 'n' == *(ptr+1) &&
|
||||
'r' == *(ptr+2) && 'e' == *(ptr+3)) { /* "unread" */
|
||||
if (z + 4 < sz) { /* Verifying up to *(ptr+4) */
|
||||
if ('u' == *ptr && 'n' == *(ptr + 1) && 'r' == *(ptr + 2) &&
|
||||
'e' == *(ptr + 3)) { /* "unread" */
|
||||
++x;
|
||||
skip = 0U;
|
||||
}
|
||||
if ('m' == *ptr && 'e' == *(ptr+1) &&
|
||||
's' == *(ptr+2) && 's' == *(ptr+3) && z+13 < sz) { /* "message": */
|
||||
if ('B' == *(ptr+10) && 'a' == *(ptr+11) &&
|
||||
'd' == *(ptr+12)) { /* "Bad credentials" */
|
||||
if ('m' == *ptr && 'e' == *(ptr + 1) && 's' == *(ptr + 2) &&
|
||||
's' == *(ptr + 3) && z + 13 < sz) { /* "message": */
|
||||
if ('B' == *(ptr + 10) && 'a' == *(ptr + 11) &&
|
||||
'd' == *(ptr + 12)) { /* "Bad credentials" */
|
||||
NORM_ERR("Bad credentials: generate a new token:\n" NEW_TOKEN);
|
||||
snprintf(p, 80, "%s", "GitHub: Bad credentials, generate a new token.");
|
||||
snprintf(p, 80, "%s",
|
||||
"GitHub: Bad credentials, generate a new token.");
|
||||
skip = 1U;
|
||||
break;
|
||||
}
|
||||
if ('M' == *(ptr+10) && 'i' == *(ptr+11) &&
|
||||
's' == *(ptr+12)) { /* Missing the 'notifications' scope. */
|
||||
NORM_ERR("Missing 'notifications' scope. Generate a new token\n" NEW_TOKEN);
|
||||
snprintf(p, 80, "%s", "GitHub: Missing the notifications scope. Generate a new token.");
|
||||
if ('M' == *(ptr + 10) && 'i' == *(ptr + 11) &&
|
||||
's' == *(ptr + 12)) { /* Missing the 'notifications' scope. */
|
||||
NORM_ERR(
|
||||
"Missing 'notifications' scope. Generate a new "
|
||||
"token\n" NEW_TOKEN);
|
||||
snprintf(
|
||||
p, 80, "%s",
|
||||
"GitHub: Missing the notifications scope. Generate a new token.");
|
||||
skip = 1U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0U == skip) {
|
||||
snprintf(p, 49, "%zu", x);
|
||||
}
|
||||
if (0U == skip) { snprintf(p, 49, "%zu", x); }
|
||||
return sz;
|
||||
}
|
||||
|
||||
@ -744,11 +737,12 @@ void print_github(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
CURLcode res;
|
||||
|
||||
if (0 == strcmp(github_token.get(*state).c_str(), "")) {
|
||||
NORM_ERR("${github_notifications} requires token. "
|
||||
"Go ahead and generate one "
|
||||
NEW_TOKEN
|
||||
NORM_ERR(
|
||||
"${github_notifications} requires token. "
|
||||
"Go ahead and generate one " NEW_TOKEN
|
||||
"Insert it in conky.config = { github_token='TOKEN_SHA' }\n");
|
||||
snprintf(p, p_max_size, "%s", "GitHub notifications requires token, generate a new one.");
|
||||
snprintf(p, p_max_size, "%s",
|
||||
"GitHub notifications requires token, generate a new one.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -759,14 +753,13 @@ void print_github(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
}
|
||||
|
||||
snprintf(github_url, 255, "%s%s",
|
||||
"https://api.github.com/notifications?access_token=", github_token.get(*state).c_str());
|
||||
"https://api.github.com/notifications?access_token=",
|
||||
github_token.get(*state).c_str());
|
||||
/* unique string for each conky user, so we dont hit any query limits */
|
||||
snprintf(user_agent, 29, "conky/%s", github_token.get(*state).c_str());
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
if (nullptr == (curl = curl_easy_init())) {
|
||||
goto error;
|
||||
}
|
||||
if (nullptr == (curl = curl_easy_init())) { goto error; }
|
||||
curl_easy_setopt(curl, CURLOPT_URL, github_url);
|
||||
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip");
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent);
|
||||
@ -776,21 +769,15 @@ void print_github(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, p);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if (CURLE_OK != res) {
|
||||
goto error;
|
||||
}
|
||||
if (CURLE_OK != res) { goto error; }
|
||||
snprintf(cached_result, 255, "%s", p);
|
||||
last_update = 60U;
|
||||
|
||||
error:
|
||||
if (nullptr != curl) {
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
if (nullptr != curl) { curl_easy_cleanup(curl); }
|
||||
curl_global_cleanup();
|
||||
|
||||
if (!isdigit((unsigned char)*p)) {
|
||||
last_update = 1U;
|
||||
}
|
||||
if (!isdigit((unsigned char)*p)) { last_update = 1U; }
|
||||
}
|
||||
|
||||
void print_stock(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
@ -835,8 +822,6 @@ void print_updates(struct text_object *obj, char *p, unsigned int p_max_size) {
|
||||
}
|
||||
|
||||
int updatenr_iftest(struct text_object *obj) {
|
||||
if (get_total_updates() % get_updatereset() != obj->data.i - 1) {
|
||||
return 0;
|
||||
}
|
||||
if (get_total_updates() % get_updatereset() != obj->data.i - 1) { return 0; }
|
||||
return 1;
|
||||
}
|
||||
|
@ -175,4 +175,5 @@ void print_github(struct text_object *, char *, unsigned int);
|
||||
void print_stock(struct text_object *, char *, unsigned int);
|
||||
void free_stock(struct text_object *);
|
||||
#endif /* BUILD_CURL */
|
||||
|
||||
#endif /* _COMMON_H */
|
||||
|
443
src/conky.cc
443
src/conky.cc
@ -33,7 +33,6 @@
|
||||
#include <climits>
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <csignal>
|
||||
#include <cstdarg>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
@ -82,7 +81,6 @@
|
||||
#endif
|
||||
|
||||
/* local headers */
|
||||
#include "build.h"
|
||||
#include "colours.h"
|
||||
#include "core.h"
|
||||
#include "diskio.h"
|
||||
@ -203,8 +201,6 @@ int top_io;
|
||||
int top_running;
|
||||
static conky::simple_config_setting<bool> extra_newline("extra_newline", false,
|
||||
false);
|
||||
static volatile sig_atomic_t g_sigterm_pending, g_sighup_pending,
|
||||
g_sigusr2_pending;
|
||||
|
||||
/* Update interval */
|
||||
conky::range_config_setting<double> update_interval(
|
||||
@ -246,177 +242,10 @@ static conky::range_config_setting<unsigned int> max_text_width(
|
||||
extern kvm_t *kd;
|
||||
#endif
|
||||
|
||||
int argc_copy;
|
||||
char **argv_copy;
|
||||
|
||||
/* prototypes for internally used functions */
|
||||
static void signal_handler(int /*sig*/);
|
||||
static void reload_config();
|
||||
|
||||
static void print_version() {
|
||||
std::cout << _(PACKAGE_NAME " " VERSION " compiled " BUILD_DATE
|
||||
" for " BUILD_ARCH
|
||||
"\n"
|
||||
"\nCompiled in features:\n\n"
|
||||
"System config file: " SYSTEM_CONFIG_FILE
|
||||
"\n"
|
||||
"Package library path: " PACKAGE_LIBDIR "\n\n")
|
||||
<< _("\n General:\n")
|
||||
#ifdef HAVE_OPENMP
|
||||
<< _(" * OpenMP\n")
|
||||
#endif /* HAVE_OPENMP */
|
||||
#ifdef BUILD_MATH
|
||||
<< _(" * math\n")
|
||||
#endif /* BUILD_MATH */
|
||||
#ifdef BUILD_HDDTEMP
|
||||
<< _(" * hddtemp\n")
|
||||
#endif /* BUILD_HDDTEMP */
|
||||
#ifdef BUILD_PORT_MONITORS
|
||||
<< _(" * portmon\n")
|
||||
#endif /* BUILD_PORT_MONITORS */
|
||||
#ifdef BUILD_HTTP
|
||||
<< _(" * HTTP\n")
|
||||
#endif /* BUILD_HTTP */
|
||||
#ifdef BUILD_IPV6
|
||||
<< _(" * IPv6\n")
|
||||
#endif /* BUILD_IPV6 */
|
||||
#ifdef BUILD_IRC
|
||||
<< _(" * IRC\n")
|
||||
#endif
|
||||
#ifdef BUILD_CURL
|
||||
<< _(" * Curl\n")
|
||||
#endif /* BUILD_CURL */
|
||||
#ifdef BUILD_RSS
|
||||
<< _(" * RSS\n")
|
||||
#endif /* BUILD_RSS */
|
||||
#ifdef BUILD_ICAL
|
||||
<< _(" * ICal\n")
|
||||
#endif /* BUILD_ICAL */
|
||||
#ifdef BUILD_ICONV
|
||||
<< _(" * iconv\n")
|
||||
#endif /* BUILD_ICONV */
|
||||
#ifdef BUILD_MYSQL
|
||||
<< _(" * MySQL\n")
|
||||
#endif /* BUILD_MYSQL */
|
||||
#ifdef BUILD_WEATHER_METAR
|
||||
<< _(" * Weather (METAR)\n")
|
||||
#endif /* BUILD_WEATHER_METAR */
|
||||
#ifdef BUILD_WLAN
|
||||
<< _(" * wireless\n")
|
||||
#endif /* BUILD_WLAN */
|
||||
#ifdef BUILD_IBM
|
||||
<< _(" * support for IBM/Lenovo notebooks\n")
|
||||
#endif /* BUILD_IBM */
|
||||
#ifdef BUILD_NVIDIA
|
||||
<< _(" * nvidia\n")
|
||||
#endif /* BUILD_NVIDIA */
|
||||
#ifdef BUILD_EVE
|
||||
<< _(" * eve-online\n")
|
||||
#endif /* BUILD_EVE */
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
<< _(" * builtin default configuration\n")
|
||||
#endif /* BUILD_BUILTIN_CONFIG */
|
||||
#ifdef BUILD_OLD_CONFIG
|
||||
<< _(" * old configuration syntax\n")
|
||||
#endif /* BUILD_OLD_CONFIG */
|
||||
#ifdef BUILD_IMLIB2
|
||||
<< _(" * Imlib2\n")
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#ifdef HAVE_SOME_SOUNDCARD_H
|
||||
<< _(" * OSS mixer support\n")
|
||||
#endif /* HAVE_SOME_SOUNDCARD_H */
|
||||
#ifdef BUILD_MIXER_ALSA
|
||||
<< _(" * ALSA mixer support\n")
|
||||
#endif /* BUILD_MIXER_ALSA */
|
||||
#ifdef BUILD_APCUPSD
|
||||
<< _(" * apcupsd\n")
|
||||
#endif /* BUILD_APCUPSD */
|
||||
#ifdef BUILD_IOSTATS
|
||||
<< _(" * iostats\n")
|
||||
#endif /* BUILD_IOSTATS */
|
||||
#ifdef BUILD_NCURSES
|
||||
<< _(" * ncurses\n")
|
||||
#endif /* BUILD_NCURSES */
|
||||
#ifdef BUILD_I18N
|
||||
<< _(" * Internationalization support\n")
|
||||
#endif
|
||||
#ifdef BUILD_PULSEAUDIO
|
||||
<< _(" * PulseAudio\n")
|
||||
#endif /* BUIL_PULSEAUDIO */
|
||||
#ifdef DEBUG
|
||||
<< _(" * Debugging extensions\n")
|
||||
#endif
|
||||
#if defined BUILD_LUA_CAIRO || defined BUILD_LUA_IMLIB2 || BUILD_LUA_RSVG
|
||||
<< _("\n Lua bindings:\n")
|
||||
#endif
|
||||
#ifdef BUILD_LUA_CAIRO
|
||||
<< _(" * Cairo\n")
|
||||
#endif /* BUILD_LUA_CAIRO */
|
||||
#ifdef BUILD_LUA_IMLIB2
|
||||
<< _(" * Imlib2\n")
|
||||
#endif /* BUILD_LUA_IMLIB2 */
|
||||
#ifdef BUILD_LUA_RSVG
|
||||
<< _(" * RSVG\n")
|
||||
#endif /* BUILD_LUA_RSVG */
|
||||
#ifdef BUILD_X11
|
||||
<< _(" X11:\n")
|
||||
#ifdef BUILD_XDAMAGE
|
||||
<< _(" * Xdamage extension\n")
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
#ifdef BUILD_XINERAMA
|
||||
<< _(" * Xinerama extension (virtual display)\n")
|
||||
#endif /* BUILD_XINERAMA */
|
||||
#ifdef BUILD_XSHAPE
|
||||
<< _(" * Xshape extension (click through)\n")
|
||||
#endif /* BUILD_XSHAPE */
|
||||
#ifdef BUILD_XDBE
|
||||
<< _(" * XDBE (double buffer extension)\n")
|
||||
#endif /* BUILD_XDBE */
|
||||
#ifdef BUILD_XFT
|
||||
<< _(" * Xft\n")
|
||||
#endif /* BUILD_XFT */
|
||||
#ifdef BUILD_ARGB
|
||||
<< _(" * ARGB visual\n")
|
||||
#endif /* BUILD_ARGB */
|
||||
#ifdef OWN_WINDOW
|
||||
<< _(" * Own window\n")
|
||||
#endif
|
||||
#endif /* BUILD_X11 */
|
||||
#if defined BUILD_AUDACIOUS || defined BUILD_BMPX || defined BUILD_CMUS || \
|
||||
defined BUILD_MPD || defined BUILD_MOC || defined BUILD_XMMS2
|
||||
<< _("\n Music detection:\n")
|
||||
#endif
|
||||
#ifdef BUILD_AUDACIOUS
|
||||
<< _(" * Audacious\n")
|
||||
#endif /* BUILD_AUDACIOUS */
|
||||
#ifdef BUILD_BMPX
|
||||
<< _(" * BMPx\n")
|
||||
#endif /* BUILD_BMPX */
|
||||
#ifdef BUILD_CMUS
|
||||
<< _(" * CMUS\n")
|
||||
#endif /* BUILD_CMUS */
|
||||
#ifdef BUILD_MPD
|
||||
<< _(" * MPD\n")
|
||||
#endif /* BUILD_MPD */
|
||||
#ifdef BUILD_MOC
|
||||
<< _(" * MOC\n")
|
||||
#endif /* BUILD_MOC */
|
||||
#ifdef BUILD_XMMS2
|
||||
<< _(" * XMMS2\n")
|
||||
#endif /* BUILD_XMMS2 */
|
||||
<< _("\n Default values:\n") << " * Netdevice: " DEFAULTNETDEV "\n"
|
||||
<< " * Local configfile: " CONFIG_FILE "\n"
|
||||
#ifdef BUILD_I18N
|
||||
<< " * Localedir: " LOCALE_DIR "\n"
|
||||
#endif /* BUILD_I18N */
|
||||
#ifdef BUILD_HTTP
|
||||
<< " * HTTP-port: " << HTTPPORT << "\n"
|
||||
#endif /* BUILD_HTTP */
|
||||
<< " * Maximum netdevices: " << MAX_NET_INTERFACES << "\n"
|
||||
<< " * Maximum text size: " << MAX_USER_TEXT_DEFAULT << "\n"
|
||||
<< " * Size text buffer: " << DEFAULT_TEXT_BUFFER_SIZE << "\n";
|
||||
}
|
||||
|
||||
static const char *suffixes[] = {_nop("B"), _nop("KiB"), _nop("MiB"),
|
||||
_nop("GiB"), _nop("TiB"), _nop("PiB"),
|
||||
""};
|
||||
@ -464,7 +293,9 @@ static conky::simple_config_setting<bool> fork_to_background("background",
|
||||
|
||||
/* set to 0 after the first time conky is run, so we don't fork again after the
|
||||
* first forking */
|
||||
static int first_pass = 1;
|
||||
int first_pass = 1;
|
||||
int argc_copy;
|
||||
char **argv_copy;
|
||||
|
||||
conky::range_config_setting<int> cpu_avg_samples("cpu_avg_samples", 1, 14, 2,
|
||||
true);
|
||||
@ -2006,7 +1837,9 @@ bool is_on_battery() { // checks if at least one battery specified in
|
||||
return false;
|
||||
}
|
||||
|
||||
static void main_loop() {
|
||||
volatile sig_atomic_t g_sigterm_pending, g_sighup_pending, g_sigusr2_pending;
|
||||
|
||||
void main_loop() {
|
||||
int terminate = 0;
|
||||
#ifdef SIGNAL_BLOCKING
|
||||
sigset_t newmask, oldmask;
|
||||
@ -2497,8 +2330,6 @@ static void main_loop() {
|
||||
#endif /* HAVE_SYS_INOTIFY_H */
|
||||
}
|
||||
|
||||
void initialisation(int argc, char **argv);
|
||||
|
||||
/* reload the config file */
|
||||
static void reload_config() {
|
||||
struct stat sb {};
|
||||
@ -2716,74 +2547,6 @@ void load_config_file() {
|
||||
l.replace(-2);
|
||||
global_text = strdup(l.tocstring(-1));
|
||||
l.pop();
|
||||
|
||||
// XXX: what does this do?
|
||||
// global_text_lines = line + 1;
|
||||
|
||||
#if 0
|
||||
#if defined(BUILD_NCURSES)
|
||||
#if defined(BUILD_X11)
|
||||
if (out_to_x.get(*state) && out_to_ncurses.get(*state)) {
|
||||
NORM_ERR("out_to_x and out_to_ncurses are incompatible, turning out_to_ncurses off");
|
||||
state->pushboolean(false);
|
||||
out_to_ncurses.lua_set(*state);
|
||||
}
|
||||
#endif /* BUILD_X11 */
|
||||
if ((out_to_stdout.get(*state) || out_to_stderr.get(*state))
|
||||
&& out_to_ncurses.get(*state)) {
|
||||
NORM_ERR("out_to_ncurses conflicts with out_to_console and out_to_stderr, disabling the later ones");
|
||||
// XXX: this will need some rethinking
|
||||
state->pushboolean(false);
|
||||
out_to_stdout.lua_set(*state);
|
||||
state->pushboolean(false);
|
||||
out_to_stderr.lua_set(*state);
|
||||
}
|
||||
#endif /* BUILD_NCURSES */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_help(const char *prog_name) {
|
||||
printf("Usage: %s [OPTION]...\n" PACKAGE_NAME
|
||||
" is a system monitor that renders text on desktop or to own "
|
||||
"transparent\n"
|
||||
"window. Command line options will override configurations defined in "
|
||||
"config\n"
|
||||
"file.\n"
|
||||
" -v, --version version\n"
|
||||
" -q, --quiet quiet mode\n"
|
||||
" -D, --debug increase debugging output, ie. -DD for "
|
||||
"more debugging\n"
|
||||
" -c, --config=FILE config file to load\n"
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
" -C, --print-config print the builtin default config to "
|
||||
"stdout\n"
|
||||
" e.g. 'conky -C > ~/.conkyrc' will "
|
||||
"create a new default config\n"
|
||||
#endif
|
||||
" -d, --daemonize daemonize, fork to background\n"
|
||||
" -h, --help help\n"
|
||||
#ifdef BUILD_X11
|
||||
" -a, --alignment=ALIGNMENT text alignment on screen, "
|
||||
"{top,bottom,middle}_{left,right,middle}\n"
|
||||
" -X, --display=DISPLAY X11 display to use\n"
|
||||
" -m, --xinerama-head=N Xinerama monitor index (0=first)\n"
|
||||
" -f, --font=FONT font to use\n"
|
||||
#ifdef OWN_WINDOW
|
||||
" -o, --own-window create own window to draw\n"
|
||||
#endif
|
||||
" -b, --double-buffer double buffer (prevents flickering)\n"
|
||||
" -w, --window-id=WIN_ID window id to draw\n"
|
||||
" -x X x position\n"
|
||||
" -y Y y position\n"
|
||||
#endif /* BUILD_X11 */
|
||||
" -t, --text=TEXT text to render, remember single quotes, "
|
||||
"like -t '$uptime'\n"
|
||||
" -u, --interval=SECS update interval\n"
|
||||
" -i COUNT number of times to update " PACKAGE_NAME
|
||||
" (and quit)\n"
|
||||
" -p, --pause=SECS pause for SECS seconds at startup "
|
||||
"before doing anything\n",
|
||||
prog_name);
|
||||
}
|
||||
|
||||
inline void reset_optind() {
|
||||
@ -2795,40 +2558,6 @@ inline void reset_optind() {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* : means that character before that takes an argument */
|
||||
static const char *getopt_string =
|
||||
"vVqdDSs:t:u:i:hc:p:"
|
||||
#ifdef BUILD_X11
|
||||
"x:y:w:a:X:m:f:"
|
||||
#ifdef OWN_WINDOW
|
||||
"o"
|
||||
#endif
|
||||
"b"
|
||||
#endif /* BUILD_X11 */
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
"C"
|
||||
#endif
|
||||
;
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{"help", 0, nullptr, 'h'}, {"version", 0, nullptr, 'V'},
|
||||
{"quiet", 0, nullptr, 'q'}, {"debug", 0, nullptr, 'D'},
|
||||
{"config", 1, nullptr, 'c'},
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
{"print-config", 0, nullptr, 'C'},
|
||||
#endif
|
||||
{"daemonize", 0, nullptr, 'd'},
|
||||
#ifdef BUILD_X11
|
||||
{"alignment", 1, nullptr, 'a'}, {"display", 1, nullptr, 'X'},
|
||||
{"xinerama-head", 1, nullptr, 'm'}, {"font", 1, nullptr, 'f'},
|
||||
#ifdef OWN_WINDOW
|
||||
{"own-window", 0, nullptr, 'o'},
|
||||
#endif
|
||||
{"double-buffer", 0, nullptr, 'b'}, {"window-id", 1, nullptr, 'w'},
|
||||
#endif /* BUILD_X11 */
|
||||
{"text", 1, nullptr, 't'}, {"interval", 1, nullptr, 'u'},
|
||||
{"pause", 1, nullptr, 'p'}, {nullptr, 0, nullptr, 0}};
|
||||
|
||||
void set_current_config() {
|
||||
/* load current_config, CONFIG_FILE or SYSTEM_CONFIG_FILE */
|
||||
struct stat s {};
|
||||
@ -2865,6 +2594,51 @@ void set_current_config() {
|
||||
if (current_config == "-") { current_config = "/dev/stdin"; }
|
||||
}
|
||||
|
||||
/* : means that character before that takes an argument */
|
||||
const char *getopt_string =
|
||||
"vVqdDSs:t:u:i:hc:p:"
|
||||
#ifdef BUILD_X11
|
||||
"x:y:w:a:X:m:f:"
|
||||
#ifdef OWN_WINDOW
|
||||
"o"
|
||||
#endif
|
||||
"b"
|
||||
#endif /* BUILD_X11 */
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
"C"
|
||||
#endif
|
||||
;
|
||||
|
||||
const struct option longopts[] = {
|
||||
{"help", 0, nullptr, 'h'}, {"version", 0, nullptr, 'V'},
|
||||
{"quiet", 0, nullptr, 'q'}, {"debug", 0, nullptr, 'D'},
|
||||
{"config", 1, nullptr, 'c'},
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
{"print-config", 0, nullptr, 'C'},
|
||||
#endif
|
||||
{"daemonize", 0, nullptr, 'd'},
|
||||
#ifdef BUILD_X11
|
||||
{"alignment", 1, nullptr, 'a'}, {"display", 1, nullptr, 'X'},
|
||||
{"xinerama-head", 1, nullptr, 'm'}, {"font", 1, nullptr, 'f'},
|
||||
#ifdef OWN_WINDOW
|
||||
{"own-window", 0, nullptr, 'o'},
|
||||
#endif
|
||||
{"double-buffer", 0, nullptr, 'b'}, {"window-id", 1, nullptr, 'w'},
|
||||
#endif /* BUILD_X11 */
|
||||
{"text", 1, nullptr, 't'}, {"interval", 1, nullptr, 'u'},
|
||||
{"pause", 1, nullptr, 'p'}, {nullptr, 0, nullptr, 0}};
|
||||
|
||||
void setup_inotify() {
|
||||
#ifdef HAVE_SYS_INOTIFY_H
|
||||
// the file descriptor will be automatically closed on exit
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd != -1) {
|
||||
fcntl(inotify_fd, F_SETFL, fcntl(inotify_fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
fcntl(inotify_fd, F_SETFD, fcntl(inotify_fd, F_GETFD) | FD_CLOEXEC);
|
||||
}
|
||||
#endif /* HAVE_SYS_INOTIFY_H */
|
||||
}
|
||||
void initialisation(int argc, char **argv) {
|
||||
struct sigaction act {
|
||||
}, oact{};
|
||||
@ -3058,121 +2832,6 @@ void initialisation(int argc, char **argv) {
|
||||
llua_startup_hook();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#ifdef BUILD_I18N
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE_NAME, LOCALE_DIR);
|
||||
textdomain(PACKAGE_NAME);
|
||||
#endif
|
||||
argc_copy = argc;
|
||||
argv_copy = argv;
|
||||
g_sigterm_pending = 0;
|
||||
g_sighup_pending = 0;
|
||||
g_sigusr2_pending = 0;
|
||||
|
||||
#ifdef BUILD_CURL
|
||||
struct curl_global_initializer {
|
||||
curl_global_initializer() {
|
||||
if (curl_global_init(CURL_GLOBAL_ALL))
|
||||
NORM_ERR(
|
||||
"curl_global_init() failed, you may not be able to use curl "
|
||||
"variables");
|
||||
}
|
||||
~curl_global_initializer() { curl_global_cleanup(); }
|
||||
};
|
||||
curl_global_initializer curl_global;
|
||||
#endif
|
||||
|
||||
/* handle command line parameters that don't change configs */
|
||||
#ifdef BUILD_X11
|
||||
if (!setlocale(LC_CTYPE, "")) {
|
||||
NORM_ERR("Can't set the specified locale!\nCheck LANG, LC_CTYPE, LC_ALL.");
|
||||
}
|
||||
#endif /* BUILD_X11 */
|
||||
while (1) {
|
||||
int c = getopt_long(argc, argv, getopt_string, longopts, nullptr);
|
||||
|
||||
if (c == -1) { break; }
|
||||
|
||||
switch (c) {
|
||||
case 'D':
|
||||
global_debug_level++;
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
print_version();
|
||||
return EXIT_SUCCESS;
|
||||
case 'c':
|
||||
current_config = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
if (freopen("/dev/null", "w", stderr) == nullptr)
|
||||
CRIT_ERR(nullptr, nullptr, "could not open /dev/null as stderr!");
|
||||
break;
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
case 'C':
|
||||
std::cout << defconfig;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef BUILD_X11
|
||||
case 'w':
|
||||
window.window = strtol(optarg, nullptr, 0);
|
||||
break;
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
case '?':
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
set_current_config();
|
||||
|
||||
state = std::make_unique<lua::state>();
|
||||
|
||||
conky::export_symbols(*state);
|
||||
|
||||
#ifdef HAVE_SYS_INOTIFY_H
|
||||
// the file descriptor will be automatically closed on exit
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd != -1) {
|
||||
fcntl(inotify_fd, F_SETFL, fcntl(inotify_fd, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
fcntl(inotify_fd, F_SETFD, fcntl(inotify_fd, F_GETFD) | FD_CLOEXEC);
|
||||
}
|
||||
#endif /* HAVE_SYS_INOTIFY_H */
|
||||
|
||||
initialisation(argc, argv);
|
||||
|
||||
first_pass = 0; /* don't ever call fork() again */
|
||||
|
||||
main_loop();
|
||||
} catch (fork_throw &e) {
|
||||
return EXIT_SUCCESS;
|
||||
} catch (unknown_arg_throw &e) {
|
||||
return EXIT_FAILURE;
|
||||
} catch (obj_create_error &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
clean_up(nullptr, nullptr);
|
||||
return EXIT_FAILURE;
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << PACKAGE_NAME ": " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
kvm_close(kd);
|
||||
#endif
|
||||
|
||||
#ifdef LEAKFREE_NCURSES
|
||||
_nc_free_and_exit(0); // hide false memleaks
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void signal_handler(int sig) {
|
||||
/* signal handler is light as a feather, as it should be.
|
||||
* we will poll g_signal_pending with each loop of conky
|
||||
|
17
src/conky.h
17
src/conky.h
@ -35,6 +35,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <config.h> /* defines */
|
||||
#include <sys/utsname.h> /* struct uname_s */
|
||||
#include <csignal>
|
||||
#include <memory>
|
||||
#include "common.h" /* at least for struct dns_data */
|
||||
#include "luamm.hh"
|
||||
@ -361,16 +362,28 @@ void free_and_zero(T *&ptr) {
|
||||
template <class T>
|
||||
void delete_block_and_zero(T *&ptr) {
|
||||
if (ptr) {
|
||||
delete [] ptr;
|
||||
delete[] ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern std::unique_ptr<lua::state> state;
|
||||
|
||||
extern conky::simple_config_setting<bool> out_to_stdout;
|
||||
|
||||
void setup_inotify();
|
||||
void initialisation(int argc, char **argv);
|
||||
void set_current_config();
|
||||
void main_loop();
|
||||
|
||||
extern volatile sig_atomic_t g_sigterm_pending, g_sighup_pending,
|
||||
g_sigusr2_pending;
|
||||
|
||||
extern int first_pass;
|
||||
extern int argc_copy;
|
||||
extern char **argv_copy;
|
||||
|
||||
extern conky::simple_config_setting<bool> out_to_stdout;
|
||||
extern const char *getopt_string;
|
||||
extern const struct option longopts[];
|
||||
|
||||
#endif /* _conky_h_ */
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/types.h>
|
||||
#include <clocale>
|
||||
#include "common.h"
|
||||
#include "conky.h"
|
||||
#include "diskio.h"
|
||||
|
11
src/luamm.cc
11
src/luamm.cc
@ -56,16 +56,7 @@ int exception_to_string(lua_State *l) {
|
||||
} catch (std::exception &e) {
|
||||
lua_pushstring(l, e.what());
|
||||
} catch (...) {
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
// lua_pushstring(l, ptr->__cxa_exception_type()->name());
|
||||
printf(
|
||||
"%s: FIXME: no member named '__cxa_exception_type' in "
|
||||
"'std::exception_ptr' \n",
|
||||
__func__);
|
||||
lua_pushstring(l, "FIXME: in luamm.cc");
|
||||
#else
|
||||
lua_pushstring(l, ptr->__cxa_exception_type()->name());
|
||||
#endif
|
||||
lua_pushstring(l, typeid(*ptr).name());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
376
src/main.cc
Normal file
376
src/main.cc
Normal file
@ -0,0 +1,376 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Any original torsmo code is licensed under the BSD license
|
||||
*
|
||||
* All code written since the fork of torsmo is licensed under the GPL
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
#include "build.h"
|
||||
#include "config.h"
|
||||
#include "conky.h"
|
||||
#include "lua-config.hh"
|
||||
|
||||
#ifdef BUILD_X11
|
||||
#include "x11.h"
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
#ifdef BUILD_CURL
|
||||
#include "ccurl_thread.h"
|
||||
#endif /* BUILD_CURL */
|
||||
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
#include "defconfig.h"
|
||||
|
||||
#ifdef BUILD_OLD_CONFIG
|
||||
#include "convertconf.h"
|
||||
#endif /* BUILD_OLD_CONFIG */
|
||||
#endif /* BUILD_BUILTIN_CONFIG */
|
||||
|
||||
static void print_version() {
|
||||
std::cout << _(PACKAGE_NAME " " VERSION " compiled " BUILD_DATE
|
||||
" for " BUILD_ARCH
|
||||
"\n"
|
||||
"\nCompiled in features:\n\n"
|
||||
"System config file: " SYSTEM_CONFIG_FILE
|
||||
"\n"
|
||||
"Package library path: " PACKAGE_LIBDIR "\n\n")
|
||||
<< _("\n General:\n")
|
||||
#ifdef HAVE_OPENMP
|
||||
<< _(" * OpenMP\n")
|
||||
#endif /* HAVE_OPENMP */
|
||||
#ifdef BUILD_MATH
|
||||
<< _(" * math\n")
|
||||
#endif /* BUILD_MATH */
|
||||
#ifdef BUILD_HDDTEMP
|
||||
<< _(" * hddtemp\n")
|
||||
#endif /* BUILD_HDDTEMP */
|
||||
#ifdef BUILD_PORT_MONITORS
|
||||
<< _(" * portmon\n")
|
||||
#endif /* BUILD_PORT_MONITORS */
|
||||
#ifdef BUILD_HTTP
|
||||
<< _(" * HTTP\n")
|
||||
#endif /* BUILD_HTTP */
|
||||
#ifdef BUILD_IPV6
|
||||
<< _(" * IPv6\n")
|
||||
#endif /* BUILD_IPV6 */
|
||||
#ifdef BUILD_IRC
|
||||
<< _(" * IRC\n")
|
||||
#endif
|
||||
#ifdef BUILD_CURL
|
||||
<< _(" * Curl\n")
|
||||
#endif /* BUILD_CURL */
|
||||
#ifdef BUILD_RSS
|
||||
<< _(" * RSS\n")
|
||||
#endif /* BUILD_RSS */
|
||||
#ifdef BUILD_ICAL
|
||||
<< _(" * ICal\n")
|
||||
#endif /* BUILD_ICAL */
|
||||
#ifdef BUILD_ICONV
|
||||
<< _(" * iconv\n")
|
||||
#endif /* BUILD_ICONV */
|
||||
#ifdef BUILD_MYSQL
|
||||
<< _(" * MySQL\n")
|
||||
#endif /* BUILD_MYSQL */
|
||||
#ifdef BUILD_WEATHER_METAR
|
||||
<< _(" * Weather (METAR)\n")
|
||||
#endif /* BUILD_WEATHER_METAR */
|
||||
#ifdef BUILD_WLAN
|
||||
<< _(" * wireless\n")
|
||||
#endif /* BUILD_WLAN */
|
||||
#ifdef BUILD_IBM
|
||||
<< _(" * support for IBM/Lenovo notebooks\n")
|
||||
#endif /* BUILD_IBM */
|
||||
#ifdef BUILD_NVIDIA
|
||||
<< _(" * nvidia\n")
|
||||
#endif /* BUILD_NVIDIA */
|
||||
#ifdef BUILD_EVE
|
||||
<< _(" * eve-online\n")
|
||||
#endif /* BUILD_EVE */
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
<< _(" * builtin default configuration\n")
|
||||
#endif /* BUILD_BUILTIN_CONFIG */
|
||||
#ifdef BUILD_OLD_CONFIG
|
||||
<< _(" * old configuration syntax\n")
|
||||
#endif /* BUILD_OLD_CONFIG */
|
||||
#ifdef BUILD_IMLIB2
|
||||
<< _(" * Imlib2\n")
|
||||
#endif /* BUILD_IMLIB2 */
|
||||
#ifdef HAVE_SOME_SOUNDCARD_H
|
||||
<< _(" * OSS mixer support\n")
|
||||
#endif /* HAVE_SOME_SOUNDCARD_H */
|
||||
#ifdef BUILD_MIXER_ALSA
|
||||
<< _(" * ALSA mixer support\n")
|
||||
#endif /* BUILD_MIXER_ALSA */
|
||||
#ifdef BUILD_APCUPSD
|
||||
<< _(" * apcupsd\n")
|
||||
#endif /* BUILD_APCUPSD */
|
||||
#ifdef BUILD_IOSTATS
|
||||
<< _(" * iostats\n")
|
||||
#endif /* BUILD_IOSTATS */
|
||||
#ifdef BUILD_NCURSES
|
||||
<< _(" * ncurses\n")
|
||||
#endif /* BUILD_NCURSES */
|
||||
#ifdef BUILD_I18N
|
||||
<< _(" * Internationalization support\n")
|
||||
#endif
|
||||
#ifdef BUILD_PULSEAUDIO
|
||||
<< _(" * PulseAudio\n")
|
||||
#endif /* BUIL_PULSEAUDIO */
|
||||
#ifdef DEBUG
|
||||
<< _(" * Debugging extensions\n")
|
||||
#endif
|
||||
#if defined BUILD_LUA_CAIRO || defined BUILD_LUA_IMLIB2 || BUILD_LUA_RSVG
|
||||
<< _("\n Lua bindings:\n")
|
||||
#endif
|
||||
#ifdef BUILD_LUA_CAIRO
|
||||
<< _(" * Cairo\n")
|
||||
#endif /* BUILD_LUA_CAIRO */
|
||||
#ifdef BUILD_LUA_IMLIB2
|
||||
<< _(" * Imlib2\n")
|
||||
#endif /* BUILD_LUA_IMLIB2 */
|
||||
#ifdef BUILD_LUA_RSVG
|
||||
<< _(" * RSVG\n")
|
||||
#endif /* BUILD_LUA_RSVG */
|
||||
#ifdef BUILD_X11
|
||||
<< _(" X11:\n")
|
||||
#ifdef BUILD_XDAMAGE
|
||||
<< _(" * Xdamage extension\n")
|
||||
#endif /* BUILD_XDAMAGE */
|
||||
#ifdef BUILD_XINERAMA
|
||||
<< _(" * Xinerama extension (virtual display)\n")
|
||||
#endif /* BUILD_XINERAMA */
|
||||
#ifdef BUILD_XSHAPE
|
||||
<< _(" * Xshape extension (click through)\n")
|
||||
#endif /* BUILD_XSHAPE */
|
||||
#ifdef BUILD_XDBE
|
||||
<< _(" * XDBE (double buffer extension)\n")
|
||||
#endif /* BUILD_XDBE */
|
||||
#ifdef BUILD_XFT
|
||||
<< _(" * Xft\n")
|
||||
#endif /* BUILD_XFT */
|
||||
#ifdef BUILD_ARGB
|
||||
<< _(" * ARGB visual\n")
|
||||
#endif /* BUILD_ARGB */
|
||||
#ifdef OWN_WINDOW
|
||||
<< _(" * Own window\n")
|
||||
#endif
|
||||
#endif /* BUILD_X11 */
|
||||
#if defined BUILD_AUDACIOUS || defined BUILD_BMPX || defined BUILD_CMUS || \
|
||||
defined BUILD_MPD || defined BUILD_MOC || defined BUILD_XMMS2
|
||||
<< _("\n Music detection:\n")
|
||||
#endif
|
||||
#ifdef BUILD_AUDACIOUS
|
||||
<< _(" * Audacious\n")
|
||||
#endif /* BUILD_AUDACIOUS */
|
||||
#ifdef BUILD_BMPX
|
||||
<< _(" * BMPx\n")
|
||||
#endif /* BUILD_BMPX */
|
||||
#ifdef BUILD_CMUS
|
||||
<< _(" * CMUS\n")
|
||||
#endif /* BUILD_CMUS */
|
||||
#ifdef BUILD_MPD
|
||||
<< _(" * MPD\n")
|
||||
#endif /* BUILD_MPD */
|
||||
#ifdef BUILD_MOC
|
||||
<< _(" * MOC\n")
|
||||
#endif /* BUILD_MOC */
|
||||
#ifdef BUILD_XMMS2
|
||||
<< _(" * XMMS2\n")
|
||||
#endif /* BUILD_XMMS2 */
|
||||
<< _("\n Default values:\n") << " * Netdevice: " DEFAULTNETDEV "\n"
|
||||
<< " * Local configfile: " CONFIG_FILE "\n"
|
||||
#ifdef BUILD_I18N
|
||||
<< " * Localedir: " LOCALE_DIR "\n"
|
||||
#endif /* BUILD_I18N */
|
||||
#ifdef BUILD_HTTP
|
||||
<< " * HTTP-port: " << HTTPPORT << "\n"
|
||||
#endif /* BUILD_HTTP */
|
||||
<< " * Maximum netdevices: " << MAX_NET_INTERFACES << "\n"
|
||||
<< " * Maximum text size: " << MAX_USER_TEXT_DEFAULT << "\n"
|
||||
<< " * Size text buffer: " << DEFAULT_TEXT_BUFFER_SIZE << "\n";
|
||||
}
|
||||
|
||||
static void print_help(const char *prog_name) {
|
||||
printf("Usage: %s [OPTION]...\n" PACKAGE_NAME
|
||||
" is a system monitor that renders text on desktop or to own "
|
||||
"transparent\n"
|
||||
"window. Command line options will override configurations defined in "
|
||||
"config\n"
|
||||
"file.\n"
|
||||
" -v, --version version\n"
|
||||
" -q, --quiet quiet mode\n"
|
||||
" -D, --debug increase debugging output, ie. -DD for "
|
||||
"more debugging\n"
|
||||
" -c, --config=FILE config file to load\n"
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
" -C, --print-config print the builtin default config to "
|
||||
"stdout\n"
|
||||
" e.g. 'conky -C > ~/.conkyrc' will "
|
||||
"create a new default config\n"
|
||||
#endif
|
||||
" -d, --daemonize daemonize, fork to background\n"
|
||||
" -h, --help help\n"
|
||||
#ifdef BUILD_X11
|
||||
" -a, --alignment=ALIGNMENT text alignment on screen, "
|
||||
"{top,bottom,middle}_{left,right,middle}\n"
|
||||
" -X, --display=DISPLAY X11 display to use\n"
|
||||
" -m, --xinerama-head=N Xinerama monitor index (0=first)\n"
|
||||
" -f, --font=FONT font to use\n"
|
||||
#ifdef OWN_WINDOW
|
||||
" -o, --own-window create own window to draw\n"
|
||||
#endif
|
||||
" -b, --double-buffer double buffer (prevents flickering)\n"
|
||||
" -w, --window-id=WIN_ID window id to draw\n"
|
||||
" -x X x position\n"
|
||||
" -y Y y position\n"
|
||||
#endif /* BUILD_X11 */
|
||||
" -t, --text=TEXT text to render, remember single quotes, "
|
||||
"like -t '$uptime'\n"
|
||||
" -u, --interval=SECS update interval\n"
|
||||
" -i COUNT number of times to update " PACKAGE_NAME
|
||||
" (and quit)\n"
|
||||
" -p, --pause=SECS pause for SECS seconds at startup "
|
||||
"before doing anything\n",
|
||||
prog_name);
|
||||
}
|
||||
|
||||
inline void reset_optind() {
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
optind = optreset = 1;
|
||||
#else
|
||||
optind = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#ifdef BUILD_I18N
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE_NAME, LOCALE_DIR);
|
||||
textdomain(PACKAGE_NAME);
|
||||
#endif
|
||||
argc_copy = argc;
|
||||
argv_copy = argv;
|
||||
g_sigterm_pending = 0;
|
||||
g_sighup_pending = 0;
|
||||
g_sigusr2_pending = 0;
|
||||
|
||||
#ifdef BUILD_CURL
|
||||
struct curl_global_initializer {
|
||||
curl_global_initializer() {
|
||||
if (curl_global_init(CURL_GLOBAL_ALL))
|
||||
NORM_ERR(
|
||||
"curl_global_init() failed, you may not be able to use curl "
|
||||
"variables");
|
||||
}
|
||||
~curl_global_initializer() { curl_global_cleanup(); }
|
||||
};
|
||||
curl_global_initializer curl_global;
|
||||
#endif
|
||||
|
||||
/* handle command line parameters that don't change configs */
|
||||
#ifdef BUILD_X11
|
||||
if (!setlocale(LC_CTYPE, "")) {
|
||||
NORM_ERR("Can't set the specified locale!\nCheck LANG, LC_CTYPE, LC_ALL.");
|
||||
}
|
||||
#endif /* BUILD_X11 */
|
||||
while (1) {
|
||||
int c = getopt_long(argc, argv, getopt_string, longopts, nullptr);
|
||||
|
||||
if (c == -1) { break; }
|
||||
|
||||
switch (c) {
|
||||
case 'D':
|
||||
global_debug_level++;
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
print_version();
|
||||
return EXIT_SUCCESS;
|
||||
case 'c':
|
||||
current_config = optarg;
|
||||
break;
|
||||
case 'q':
|
||||
if (freopen("/dev/null", "w", stderr) == nullptr)
|
||||
CRIT_ERR(nullptr, nullptr, "could not open /dev/null as stderr!");
|
||||
break;
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
#ifdef BUILD_BUILTIN_CONFIG
|
||||
case 'C':
|
||||
std::cout << defconfig;
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef BUILD_X11
|
||||
case 'w':
|
||||
window.window = strtol(optarg, nullptr, 0);
|
||||
break;
|
||||
#endif /* BUILD_X11 */
|
||||
|
||||
case '?':
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
set_current_config();
|
||||
|
||||
state = std::make_unique<lua::state>();
|
||||
|
||||
conky::export_symbols(*state);
|
||||
|
||||
setup_inotify();
|
||||
|
||||
initialisation(argc, argv);
|
||||
|
||||
first_pass = 0; /* don't ever call fork() again */
|
||||
|
||||
main_loop();
|
||||
} catch (fork_throw &e) {
|
||||
return EXIT_SUCCESS;
|
||||
} catch (unknown_arg_throw &e) {
|
||||
return EXIT_FAILURE;
|
||||
} catch (obj_create_error &e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
clean_up(nullptr, nullptr);
|
||||
return EXIT_FAILURE;
|
||||
} catch (std::exception &e) {
|
||||
std::cerr << PACKAGE_NAME ": " << e.what() << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
kvm_close(kd);
|
||||
#endif
|
||||
|
||||
#ifdef LEAKFREE_NCURSES
|
||||
_nc_free_and_exit(0); // hide false memleaks
|
||||
#endif
|
||||
return 0;
|
||||
}
|
32
src/main.h
Normal file
32
src/main.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Any original torsmo code is licensed under the BSD license
|
||||
*
|
||||
* All code written since the fork of torsmo is licensed under the GPL
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _main_h_
|
||||
#define _main_h_
|
||||
|
||||
#endif /* _main_h_ */
|
47
tests/CMakeLists.txt
Normal file
47
tests/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
||||
include(CTest)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
include_directories(${conky_includes})
|
||||
|
||||
set(test_srcs "")
|
||||
|
||||
if(OS_LINUX)
|
||||
set(test_srcs ${test_srcs} test-linux.cc)
|
||||
endif()
|
||||
|
||||
if(OS_DARWIN)
|
||||
set(test_srcs ${test_srcs} test-darwin.cc)
|
||||
endif()
|
||||
|
||||
add_executable(test-conky test-common.cc ${test_srcs})
|
||||
target_link_libraries(test-conky conky_core)
|
||||
|
||||
if(USING_CLANG_7)
|
||||
set(COVERAGE_LCOV_EXCLUDES
|
||||
"v1/*"
|
||||
"/usr/include/**"
|
||||
"/usr/lib/**"
|
||||
"/usr/local/include/**"
|
||||
"/usr/local/lib/**"
|
||||
"/usr/include/libkern/i386/*"
|
||||
"/usr/include/sys/_types/*"
|
||||
"/usr/local/opt/gettext/include/*"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/catch2/*"
|
||||
"${CMAKE_SOURCE_DIR}/3rdparty/*")
|
||||
|
||||
setup_target_for_coverage_lcov_html(NAME
|
||||
test-conky-coverage-html
|
||||
EXECUTABLE
|
||||
test-conky
|
||||
DEPENDENCIES
|
||||
test-conky)
|
||||
setup_target_for_coverage_lcov_txt(NAME
|
||||
test-conky-coverage-txt
|
||||
EXECUTABLE
|
||||
test-conky
|
||||
DEPENDENCIES
|
||||
test-conky)
|
||||
catch_discover_tests(test-conky)
|
||||
endif()
|
14367
tests/catch2/catch.hpp
Normal file
14367
tests/catch2/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
62
tests/catch2/catch_reporter_automake.hpp
Normal file
62
tests/catch2/catch_reporter_automake.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Created by Justin R. Wilson on 2/19/2017.
|
||||
* Copyright 2017 Justin R. Wilson. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct AutomakeReporter : StreamingReporterBase<AutomakeReporter> {
|
||||
AutomakeReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config )
|
||||
{}
|
||||
|
||||
~AutomakeReporter() override;
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in the format of Automake .trs files";
|
||||
}
|
||||
|
||||
void assertionStarting( AssertionInfo const& ) override {}
|
||||
|
||||
bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) override { return true; }
|
||||
|
||||
void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
|
||||
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
|
||||
stream << ":test-result: ";
|
||||
if (_testCaseStats.totals.assertions.allPassed()) {
|
||||
stream << "PASS";
|
||||
} else if (_testCaseStats.totals.assertions.allOk()) {
|
||||
stream << "XFAIL";
|
||||
} else {
|
||||
stream << "FAIL";
|
||||
}
|
||||
stream << ' ' << _testCaseStats.testInfo.name << '\n';
|
||||
StreamingReporterBase::testCaseEnded( _testCaseStats );
|
||||
}
|
||||
|
||||
void skipTest( TestCaseInfo const& testInfo ) override {
|
||||
stream << ":test-result: SKIP " << testInfo.name << '\n';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
AutomakeReporter::~AutomakeReporter() {}
|
||||
#endif
|
||||
|
||||
CATCH_REGISTER_REPORTER( "automake", AutomakeReporter)
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
|
253
tests/catch2/catch_reporter_tap.hpp
Normal file
253
tests/catch2/catch_reporter_tap.hpp
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Created by Colton Wolkins on 2015-08-15.
|
||||
* Copyright 2015 Martin Moene. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
||||
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct TAPReporter : StreamingReporterBase<TAPReporter> {
|
||||
|
||||
using StreamingReporterBase::StreamingReporterBase;
|
||||
|
||||
~TAPReporter() override;
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results in TAP format, suitable for test harnesses";
|
||||
}
|
||||
|
||||
ReporterPreferences getPreferences() const override {
|
||||
return m_reporterPrefs;
|
||||
}
|
||||
|
||||
void noMatchingTestCases( std::string const& spec ) override {
|
||||
stream << "# No test cases matched '" << spec << "'" << std::endl;
|
||||
}
|
||||
|
||||
void assertionStarting( AssertionInfo const& ) override {}
|
||||
|
||||
bool assertionEnded( AssertionStats const& _assertionStats ) override {
|
||||
++counter;
|
||||
|
||||
AssertionPrinter printer( stream, _assertionStats, counter );
|
||||
printer.print();
|
||||
stream << " # " << currentTestCaseInfo->name ;
|
||||
|
||||
stream << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void testRunEnded( TestRunStats const& _testRunStats ) override {
|
||||
printTotals( _testRunStats.totals );
|
||||
stream << "\n" << std::endl;
|
||||
StreamingReporterBase::testRunEnded( _testRunStats );
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t counter = 0;
|
||||
class AssertionPrinter {
|
||||
public:
|
||||
AssertionPrinter& operator= ( AssertionPrinter const& ) = delete;
|
||||
AssertionPrinter( AssertionPrinter const& ) = delete;
|
||||
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, std::size_t _counter )
|
||||
: stream( _stream )
|
||||
, result( _stats.assertionResult )
|
||||
, messages( _stats.infoMessages )
|
||||
, itMessage( _stats.infoMessages.begin() )
|
||||
, printInfoMessages( true )
|
||||
, counter(_counter)
|
||||
{}
|
||||
|
||||
void print() {
|
||||
itMessage = messages.begin();
|
||||
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::Ok:
|
||||
printResultType( passedString() );
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if ( ! result.hasExpression() )
|
||||
printRemainingMessages( Colour::None );
|
||||
else
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExpressionFailed:
|
||||
if (result.isOk()) {
|
||||
printResultType(passedString());
|
||||
} else {
|
||||
printResultType(failedString());
|
||||
}
|
||||
printOriginalExpression();
|
||||
printReconstructedExpression();
|
||||
if (result.isOk()) {
|
||||
printIssue(" # TODO");
|
||||
}
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ThrewException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "unexpected exception with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
printResultType( failedString() );
|
||||
printIssue( "fatal error condition with message:" );
|
||||
printMessage();
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
printResultType( failedString() );
|
||||
printIssue( "expected exception, got none" );
|
||||
printExpressionWas();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Info:
|
||||
printResultType( "info" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::Warning:
|
||||
printResultType( "warning" );
|
||||
printMessage();
|
||||
printRemainingMessages();
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
printResultType( failedString() );
|
||||
printIssue( "explicitly" );
|
||||
printRemainingMessages( Colour::None );
|
||||
break;
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
case ResultWas::Exception:
|
||||
printResultType( "** internal error **" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static Colour::Code dimColour() { return Colour::FileName; }
|
||||
|
||||
static const char* failedString() { return "not ok"; }
|
||||
static const char* passedString() { return "ok"; }
|
||||
|
||||
void printSourceInfo() const {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << result.getSourceInfo() << ":";
|
||||
}
|
||||
|
||||
void printResultType( std::string const& passOrFail ) const {
|
||||
if( !passOrFail.empty() ) {
|
||||
stream << passOrFail << ' ' << counter << " -";
|
||||
}
|
||||
}
|
||||
|
||||
void printIssue( std::string const& issue ) const {
|
||||
stream << " " << issue;
|
||||
}
|
||||
|
||||
void printExpressionWas() {
|
||||
if( result.hasExpression() ) {
|
||||
stream << ";";
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " expression was:";
|
||||
}
|
||||
printOriginalExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printOriginalExpression() const {
|
||||
if( result.hasExpression() ) {
|
||||
stream << " " << result.getExpression();
|
||||
}
|
||||
}
|
||||
|
||||
void printReconstructedExpression() const {
|
||||
if( result.hasExpandedExpression() ) {
|
||||
{
|
||||
Colour colour( dimColour() );
|
||||
stream << " for: ";
|
||||
}
|
||||
std::string expr = result.getExpandedExpression();
|
||||
std::replace( expr.begin(), expr.end(), '\n', ' ');
|
||||
stream << expr;
|
||||
}
|
||||
}
|
||||
|
||||
void printMessage() {
|
||||
if ( itMessage != messages.end() ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
++itMessage;
|
||||
}
|
||||
}
|
||||
|
||||
void printRemainingMessages( Colour::Code colour = dimColour() ) {
|
||||
if (itMessage == messages.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// using messages.end() directly (or auto) yields compilation error:
|
||||
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
|
||||
const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
|
||||
|
||||
{
|
||||
Colour colourGuard( colour );
|
||||
stream << " with " << pluralise( N, "message" ) << ":";
|
||||
}
|
||||
|
||||
for(; itMessage != itEnd; ) {
|
||||
// If this assertion is a warning ignore any INFO messages
|
||||
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
|
||||
stream << " '" << itMessage->message << "'";
|
||||
if ( ++itMessage != itEnd ) {
|
||||
Colour colourGuard( dimColour() );
|
||||
stream << " and";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& stream;
|
||||
AssertionResult const& result;
|
||||
std::vector<MessageInfo> messages;
|
||||
std::vector<MessageInfo>::const_iterator itMessage;
|
||||
bool printInfoMessages;
|
||||
std::size_t counter;
|
||||
};
|
||||
|
||||
void printTotals( const Totals& totals ) const {
|
||||
if( totals.testCases.total() == 0 ) {
|
||||
stream << "1..0 # Skipped: No tests ran.";
|
||||
} else {
|
||||
stream << "1.." << counter;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
TAPReporter::~TAPReporter() {}
|
||||
#endif
|
||||
|
||||
CATCH_REGISTER_REPORTER( "tap", TAPReporter )
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
|
220
tests/catch2/catch_reporter_teamcity.hpp
Normal file
220
tests/catch2/catch_reporter_teamcity.hpp
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Created by Phil Nash on 19th December 2014
|
||||
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
|
||||
|
||||
// Don't #include any Catch headers here - we can assume they are already
|
||||
// included before this header.
|
||||
// This is not good practice in general but is necessary in this case so this
|
||||
// file can be distributed as a single header that works with the main
|
||||
// Catch single header.
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct TeamCityReporter : StreamingReporterBase<TeamCityReporter> {
|
||||
TeamCityReporter( ReporterConfig const& _config )
|
||||
: StreamingReporterBase( _config )
|
||||
{
|
||||
m_reporterPrefs.shouldRedirectStdOut = true;
|
||||
}
|
||||
|
||||
static std::string escape( std::string const& str ) {
|
||||
std::string escaped = str;
|
||||
replaceInPlace( escaped, "|", "||" );
|
||||
replaceInPlace( escaped, "'", "|'" );
|
||||
replaceInPlace( escaped, "\n", "|n" );
|
||||
replaceInPlace( escaped, "\r", "|r" );
|
||||
replaceInPlace( escaped, "[", "|[" );
|
||||
replaceInPlace( escaped, "]", "|]" );
|
||||
return escaped;
|
||||
}
|
||||
~TeamCityReporter() override;
|
||||
|
||||
static std::string getDescription() {
|
||||
return "Reports test results as TeamCity service messages";
|
||||
}
|
||||
|
||||
void skipTest( TestCaseInfo const& /* testInfo */ ) override {
|
||||
}
|
||||
|
||||
void noMatchingTestCases( std::string const& /* spec */ ) override {}
|
||||
|
||||
void testGroupStarting( GroupInfo const& groupInfo ) override {
|
||||
StreamingReporterBase::testGroupStarting( groupInfo );
|
||||
stream << "##teamcity[testSuiteStarted name='"
|
||||
<< escape( groupInfo.name ) << "']\n";
|
||||
}
|
||||
void testGroupEnded( TestGroupStats const& testGroupStats ) override {
|
||||
StreamingReporterBase::testGroupEnded( testGroupStats );
|
||||
stream << "##teamcity[testSuiteFinished name='"
|
||||
<< escape( testGroupStats.groupInfo.name ) << "']\n";
|
||||
}
|
||||
|
||||
|
||||
void assertionStarting( AssertionInfo const& ) override {}
|
||||
|
||||
bool assertionEnded( AssertionStats const& assertionStats ) override {
|
||||
AssertionResult const& result = assertionStats.assertionResult;
|
||||
if( !result.isOk() ) {
|
||||
|
||||
ReusableStringStream msg;
|
||||
if( !m_headerPrintedForThisSection )
|
||||
printSectionHeader( msg.get() );
|
||||
m_headerPrintedForThisSection = true;
|
||||
|
||||
msg << result.getSourceInfo() << "\n";
|
||||
|
||||
switch( result.getResultType() ) {
|
||||
case ResultWas::ExpressionFailed:
|
||||
msg << "expression failed";
|
||||
break;
|
||||
case ResultWas::ThrewException:
|
||||
msg << "unexpected exception";
|
||||
break;
|
||||
case ResultWas::FatalErrorCondition:
|
||||
msg << "fatal error condition";
|
||||
break;
|
||||
case ResultWas::DidntThrowException:
|
||||
msg << "no exception was thrown where one was expected";
|
||||
break;
|
||||
case ResultWas::ExplicitFailure:
|
||||
msg << "explicit failure";
|
||||
break;
|
||||
|
||||
// We shouldn't get here because of the isOk() test
|
||||
case ResultWas::Ok:
|
||||
case ResultWas::Info:
|
||||
case ResultWas::Warning:
|
||||
CATCH_ERROR( "Internal error in TeamCity reporter" );
|
||||
// These cases are here to prevent compiler warnings
|
||||
case ResultWas::Unknown:
|
||||
case ResultWas::FailureBit:
|
||||
case ResultWas::Exception:
|
||||
CATCH_ERROR( "Not implemented" );
|
||||
}
|
||||
if( assertionStats.infoMessages.size() == 1 )
|
||||
msg << " with message:";
|
||||
if( assertionStats.infoMessages.size() > 1 )
|
||||
msg << " with messages:";
|
||||
for( auto const& messageInfo : assertionStats.infoMessages )
|
||||
msg << "\n \"" << messageInfo.message << "\"";
|
||||
|
||||
|
||||
if( result.hasExpression() ) {
|
||||
msg <<
|
||||
"\n " << result.getExpressionInMacro() << "\n"
|
||||
"with expansion:\n" <<
|
||||
" " << result.getExpandedExpression() << "\n";
|
||||
}
|
||||
|
||||
if( currentTestCaseInfo->okToFail() ) {
|
||||
msg << "- failure ignore as test marked as 'ok to fail'\n";
|
||||
stream << "##teamcity[testIgnored"
|
||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||
<< " message='" << escape( msg.str() ) << "'"
|
||||
<< "]\n";
|
||||
}
|
||||
else {
|
||||
stream << "##teamcity[testFailed"
|
||||
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
|
||||
<< " message='" << escape( msg.str() ) << "'"
|
||||
<< "]\n";
|
||||
}
|
||||
}
|
||||
stream.flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
void sectionStarting( SectionInfo const& sectionInfo ) override {
|
||||
m_headerPrintedForThisSection = false;
|
||||
StreamingReporterBase::sectionStarting( sectionInfo );
|
||||
}
|
||||
|
||||
void testCaseStarting( TestCaseInfo const& testInfo ) override {
|
||||
m_testTimer.start();
|
||||
StreamingReporterBase::testCaseStarting( testInfo );
|
||||
stream << "##teamcity[testStarted name='"
|
||||
<< escape( testInfo.name ) << "']\n";
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
void testCaseEnded( TestCaseStats const& testCaseStats ) override {
|
||||
StreamingReporterBase::testCaseEnded( testCaseStats );
|
||||
if( !testCaseStats.stdOut.empty() )
|
||||
stream << "##teamcity[testStdOut name='"
|
||||
<< escape( testCaseStats.testInfo.name )
|
||||
<< "' out='" << escape( testCaseStats.stdOut ) << "']\n";
|
||||
if( !testCaseStats.stdErr.empty() )
|
||||
stream << "##teamcity[testStdErr name='"
|
||||
<< escape( testCaseStats.testInfo.name )
|
||||
<< "' out='" << escape( testCaseStats.stdErr ) << "']\n";
|
||||
stream << "##teamcity[testFinished name='"
|
||||
<< escape( testCaseStats.testInfo.name ) << "' duration='"
|
||||
<< m_testTimer.getElapsedMilliseconds() << "']\n";
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
private:
|
||||
void printSectionHeader( std::ostream& os ) {
|
||||
assert( !m_sectionStack.empty() );
|
||||
|
||||
if( m_sectionStack.size() > 1 ) {
|
||||
os << getLineOfChars<'-'>() << "\n";
|
||||
|
||||
std::vector<SectionInfo>::const_iterator
|
||||
it = m_sectionStack.begin()+1, // Skip first section (test case)
|
||||
itEnd = m_sectionStack.end();
|
||||
for( ; it != itEnd; ++it )
|
||||
printHeaderString( os, it->name );
|
||||
os << getLineOfChars<'-'>() << "\n";
|
||||
}
|
||||
|
||||
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
|
||||
|
||||
if( !lineInfo.empty() )
|
||||
os << lineInfo << "\n";
|
||||
os << getLineOfChars<'.'>() << "\n\n";
|
||||
}
|
||||
|
||||
// if string has a : in first line will set indent to follow it on
|
||||
// subsequent lines
|
||||
static void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) {
|
||||
std::size_t i = _string.find( ": " );
|
||||
if( i != std::string::npos )
|
||||
i+=2;
|
||||
else
|
||||
i = 0;
|
||||
os << Column( _string )
|
||||
.indent( indent+i)
|
||||
.initialIndent( indent ) << "\n";
|
||||
}
|
||||
private:
|
||||
bool m_headerPrintedForThisSection = false;
|
||||
Timer m_testTimer;
|
||||
};
|
||||
|
||||
#ifdef CATCH_IMPL
|
||||
TeamCityReporter::~TeamCityReporter() {}
|
||||
#endif
|
||||
|
||||
CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter )
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
|
2
tests/llvm-gcov.sh
Executable file
2
tests/llvm-gcov.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
exec llvm-cov-7 gcov "$@"
|
38
tests/test-common.cc
Normal file
38
tests/test-common.cc
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Any original torsmo code is licensed under the BSD license
|
||||
*
|
||||
* All code written since the fork of torsmo is licensed under the GPL
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do
|
||||
// this in one cpp file
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include <common.h>
|
||||
|
||||
TEST_CASE("to_real_path becomes homedir", "[to_real_path]") {
|
||||
REQUIRE(to_real_path("~/test") == std::string(getenv("HOME")) + "/test");
|
||||
}
|
36
tests/test-darwin.cc
Normal file
36
tests/test-darwin.cc
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Any original torsmo code is licensed under the BSD license
|
||||
*
|
||||
* All code written since the fork of torsmo is licensed under the GPL
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include <darwin.h>
|
||||
|
||||
TEST_CASE("get_entropy_avail returns 1", "[get_entropy_avail]") {
|
||||
unsigned int unused = 0;
|
||||
REQUIRE(get_entropy_avail(&unused) == 1);
|
||||
}
|
36
tests/test-linux.cc
Normal file
36
tests/test-linux.cc
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
*
|
||||
* Conky, a system monitor, based on torsmo
|
||||
*
|
||||
* Any original torsmo code is licensed under the BSD license
|
||||
*
|
||||
* All code written since the fork of torsmo is licensed under the GPL
|
||||
*
|
||||
* Please see COPYING for details
|
||||
*
|
||||
* Copyright (c) 2005-2018 Brenden Matthews, Philip Kovacs, et. al.
|
||||
* (see AUTHORS)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include <linux.h>
|
||||
|
||||
TEST_CASE("get_entropy_avail returns 0", "[get_entropy_avail]") {
|
||||
unsigned int unused = 0;
|
||||
REQUIRE(get_entropy_avail(&unused) == 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user