1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-06-10 11:12:21 +00:00

Add some basic unit tests.

Introduced the Catch2 unit testing framework.
This commit is contained in:
Brenden Matthews 2018-12-23 16:38:00 -05:00
parent d422aa47d2
commit 6c09affaf7
26 changed files with 16642 additions and 828 deletions

View File

@ -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 ..

View File

@ -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,38 +52,55 @@ 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)
# Set up clang-tidy
set(CLANG_TIDY_BIN_NAME
clang-tidy
clang-tidy-5.0
clang-tidy-6.0
clang-tidy-7.0
)
set(CLANG_TIDY_EXCLUDE_PATTERNS "build/" ${CMAKE_BINARY_DIR})
clang-tidy
clang-tidy-5.0
clang-tidy-6.0
clang-tidy-7.0)
set(CLANG_TIDY_EXCLUDE_PATTERNS "build/" ${CMAKE_BINARY_DIR})
find_package(ClangTidy)
endif(CHECK_CODE_QUALITY)

View File

@ -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
View 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
View 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
View 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

View File

@ -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
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
else(MAINTAINER_MODE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif(MAINTAINER_MODE)
if(MAINTAINER_MODE)
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
"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)
# 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)
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)
endif()
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)
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)
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)
@ -56,52 +93,62 @@ mark_as_advanced(RELEASE)
option(MAINTAINER_MODE "Enable maintainer mode (builds docs)" false)
option(BUILD_I18N "Enable if you want internationalization support" true)
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
if(OS_DARWIN)
set(DEFAULTNETDEV "en0" CACHE STRING "Default networkdevice" FORCE)
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)
option(BUILD_HDDTEMP "Support for hddtemp" true)
# nvidia may also work on FreeBSD, not sure
option(BUILD_NVIDIA "Enable nvidia support" false)
option(BUILD_IPV6 "Enable if you want IPv6 support" true)
option(BUILD_PORT_MONITORS "Build TCP portmon support" true)
option(BUILD_IBM "Support for IBM/Lenovo notebooks" true)
option(BUILD_HDDTEMP "Support for hddtemp" true)
# nvidia may also work on FreeBSD, not sure
option(BUILD_NVIDIA "Enable nvidia support" false)
option(BUILD_IPV6 "Enable if you want IPv6 support" true)
else(OS_LINUX)
set(BUILD_PORT_MONITORS false)
set(BUILD_IBM false)
set(BUILD_HDDTEMP false)
set(BUILD_NVIDIA false)
set(BUILD_IPV6 false)
set(BUILD_PORT_MONITORS false)
set(BUILD_IBM false)
set(BUILD_HDDTEMP false)
set(BUILD_NVIDIA false)
set(BUILD_IPV6 false)
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,47 +160,58 @@ 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)
if(BUILD_X11)
option(OWN_WINDOW "Enable own_window support" true)
option(OWN_WINDOW "Enable own_window support" true)
# Mac Fix
if(OS_DARWIN)
option(BUILD_XDAMAGE "Build Xdamage support" false)
else(OS_DARWIN)
option(BUILD_XDAMAGE "Build Xdamage support" true)
endif(OS_DARWIN)
# Mac Fix
if(OS_DARWIN)
option(BUILD_XDAMAGE "Build Xdamage support" false)
else(OS_DARWIN)
option(BUILD_XDAMAGE "Build Xdamage support" true)
endif(OS_DARWIN)
option(BUILD_XINERAMA "Build Xinerama support" true)
option(BUILD_XDBE "Build Xdbe (double-buffer) support" true)
option(BUILD_XFT "Build Xft (freetype fonts) support" true)
option(BUILD_IMLIB2 "Enable Imlib2 support" true)
option(BUILD_XSHAPE "Enable Xshape support" true)
option(BUILD_XINERAMA "Build Xinerama support" true)
option(BUILD_XDBE "Build Xdbe (double-buffer) support" true)
option(BUILD_XFT "Build Xft (freetype fonts) support" true)
option(BUILD_IMLIB2 "Enable Imlib2 support" true)
option(BUILD_XSHAPE "Enable Xshape support" true)
else(BUILD_X11)
set(OWN_WINDOW false CACHE BOOL "Enable own_window support" FORCE)
set(BUILD_XDAMAGE false CACHE BOOL "Build Xdamage support" FORCE)
set(BUILD_XINERAMA false CACHE BOOL "Build Xinerama support" FORCE)
set(BUILD_XDBE false CACHE BOOL "Build Xdbe (double-buffer) support" FORCE)
set(BUILD_XFT false CACHE BOOL "Build Xft (freetype fonts) support" FORCE)
set(BUILD_IMLIB2 false CACHE BOOL "Enable Imlib2 support" FORCE)
set(BUILD_XSHAPE false CACHE BOOL "Enable Xshape support" FORCE)
set(OWN_WINDOW false CACHE BOOL "Enable own_window support" FORCE)
set(BUILD_XDAMAGE false CACHE BOOL "Build Xdamage support" FORCE)
set(BUILD_XINERAMA false CACHE BOOL "Build Xinerama support" FORCE)
set(BUILD_XDBE false CACHE BOOL "Build Xdbe (double-buffer) support" FORCE)
set(BUILD_XFT false CACHE BOOL "Build Xft (freetype fonts) support" FORCE)
set(BUILD_IMLIB2 false CACHE BOOL "Enable Imlib2 support" FORCE)
set(BUILD_XSHAPE false CACHE BOOL "Enable Xshape support" FORCE)
endif(BUILD_X11)
if(OWN_WINDOW)
option(BUILD_ARGB "Build ARGB (real transparency) support" true)
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)
@ -180,7 +238,7 @@ option(BUILD_RSS "Enable if you want RSS support" false)
option(BUILD_WEATHER_METAR "Enable METAR weather support" true)
if(BUILD_WEATHER_METAR OR BUILD_RSS)
set(BUILD_CURL true)
set(BUILD_CURL true)
endif(BUILD_WEATHER_METAR OR BUILD_RSS)
option(BUILD_APCUPSD "Enable APCUPSD support" true)
@ -191,30 +249,33 @@ option(BUILD_IRC "Enable if you want IRC support" false)
option(BUILD_HTTP "Enable if you want HTTP support" false)
if(BUILD_HTTP)
set(HTTPPORT "10080" CACHE STRING "Port to use for out_to_http")
set(HTTPPORT "10080" CACHE STRING "Port to use for out_to_http")
endif(BUILD_HTTP)
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})

View File

@ -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

View File

@ -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
logging.h
semaphore.hh
)
${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
logging.h
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
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install(TARGETS conky
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
print_target_properties(conky)

View File

@ -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,13 +134,9 @@ 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);
}
return source;
if (source.find("~/") == 0) { return homedir + source.substr(1); }
if (source.find("$HOME/") == 0) { return homedir + source.substr(5); }
return source;
}
int open_fifo(const char *file, int *reported) {
@ -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);
}
return 0;
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,28 +364,26 @@ 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!");
}
if (info.cpu_usage != nullptr) {
return round_to_int(info.cpu_usage[obj->data.i] * 100.0);
}
return 0;
return 0;
}
double cpu_barval(struct text_object *obj) {
if (info.cpu_usage != nullptr) {
return info.cpu_usage[obj->data.i];
}
return 0.;
if (info.cpu_usage != nullptr) { return info.cpu_usage[obj->data.i]; }
return 0.;
}
#define PRINT_HR_GENERATOR(name) \
void print_##name(struct text_object *obj, char *p, \
unsigned int p_max_size) { \
human_readable(apply_base_multiplier(obj->data.s, info.name), p, \
p_max_size); \
#define PRINT_HR_GENERATOR(name) \
void print_##name(struct text_object *obj, char *p, \
unsigned int p_max_size) { \
human_readable(apply_base_multiplier(obj->data.s, info.name), p, \
p_max_size); \
}
PRINT_HR_GENERATOR(mem)
@ -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,21 +625,23 @@ 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");
} else if (0 == strncmp("discharging", p, 11) ||
0 == strncmp("remaining", p, 9)) {
0 == strncmp("remaining", p, 9)) {
snprintf(p, p_max_size, "%s", "discharging");
} else if (0 == strncmp("charged", p, 7)) {
snprintf(p, p_max_size, "%s", "charged");
} else if (0 == strncmp("not present", p, 11) ||
0 == strncmp("absent/on AC", p, 12)) {
0 == strncmp("absent/on AC", p, 12)) {
snprintf(p, p_max_size, "%s", "not present");
} else if (0 == strncmp("empty", p, 5)) {
snprintf(p, p_max_size, "%s", "empty");
@ -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
"Insert it in conky.config = { github_token='TOKEN_SHA' }\n");
snprintf(p, p_max_size, "%s", "GitHub notifications requires token, generate a new one.");
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.");
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;
}

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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"

View File

@ -49,23 +49,14 @@ const char this_cpp_object[] = "lua::this_cpp_object";
// converts C++ exceptions to strings, so lua can do something with them
int exception_to_string(lua_State *l) {
auto *ptr = static_cast<std::exception_ptr *>(lua_touserdata(l, -1));
assert(ptr);
try {
std::rethrow_exception(*ptr);
} 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
auto *ptr = static_cast<std::exception_ptr *>(lua_touserdata(l, -1));
assert(ptr);
try {
std::rethrow_exception(*ptr);
} catch (std::exception &e) {
lua_pushstring(l, e.what());
} catch (...) {
lua_pushstring(l, typeid(*ptr).name());
}
return 1;
}

376
src/main.cc Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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
View File

@ -0,0 +1,2 @@
#!/bin/bash
exec llvm-cov-7 gcov "$@"

38
tests/test-common.cc Normal file
View 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
View 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
View 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);
}