Showing preview only (1,524K chars total). Download the full file or copy to clipboard to get everything.
Repository: tycho-kirchner/shournal
Branch: master
Commit: f7c511243968
Files: 332
Total size: 1.4 MB
Directory structure:
gitextract_hf3qq4ys/
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README-compile.md
├── README-shell-integration.md
├── README.md
├── cmake/
│ └── FindShournalUtil.cmake
├── extern/
│ ├── folly/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── UninitializedMemoryHacks.h
│ ├── tsl-ordered-map/
│ │ ├── CMakeLists.txt
│ │ ├── LICENSE
│ │ ├── ordered_hash.h
│ │ ├── ordered_map.h
│ │ └── ordered_set.h
│ └── xxHash/
│ ├── .gitattributes
│ ├── .gitignore
│ ├── .travis.yml
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── appveyor.yml
│ ├── cmake_unofficial/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ └── README.md
│ ├── doc/
│ │ └── xxhash_spec.md
│ ├── xxhash.c
│ ├── xxhash.h
│ ├── xxhsum.1
│ ├── xxhsum.1.md
│ └── xxhsum.c
├── html-export/
│ ├── dist/
│ │ ├── htmlexportres.qrc
│ │ ├── index.html
│ │ ├── main.js
│ │ └── main.licenses.txt
│ ├── package.json
│ ├── src/
│ │ ├── annotation_line_render.js
│ │ ├── command_list.js
│ │ ├── command_manipulation.js
│ │ ├── command_timeline.js
│ │ ├── conversions.js
│ │ ├── d3js_util.js
│ │ ├── generic_text_dialog.js
│ │ ├── globals.js
│ │ ├── html_util.js
│ │ ├── index.js
│ │ ├── limited_queue.js
│ │ ├── map_extended.js
│ │ ├── plot_cmdcount_per_cwd.js
│ │ ├── plot_cmdcount_per_session.js
│ │ ├── plot_io_per_dir.js
│ │ ├── plot_most_written_files.js
│ │ ├── plot_simple_bar.js
│ │ ├── session_timeline.js
│ │ ├── stats.js
│ │ ├── timeline_group_find.js
│ │ ├── tooltip.js
│ │ ├── util.js
│ │ └── zoom_buttons.js
│ └── webpack.config.js
├── install/
│ ├── 90-shournaladd.rules.in
│ ├── CMakeLists.txt
│ ├── postinst-dkms.in
│ ├── postinst.in
│ ├── prerm-dkms.in
│ ├── prerm.in
│ └── shournalk-load.conf
├── kernel/
│ ├── CMakeLists.txt
│ ├── Kbuild
│ ├── LICENSE
│ ├── cmake/
│ │ └── FindKernelHeaders.cmake
│ ├── dkms.conf.in
│ ├── event_consumer.c
│ ├── event_consumer.h
│ ├── event_consumer_cache.c
│ ├── event_consumer_cache.h
│ ├── event_handler.c
│ ├── event_handler.h
│ ├── event_queue.c
│ ├── event_queue.h
│ ├── event_target.c
│ ├── event_target.h
│ ├── hash_table_str.c
│ ├── hash_table_str.h
│ ├── kfileextensions.c
│ ├── kfileextensions.h
│ ├── kpathtree.c
│ ├── kpathtree.h
│ ├── kutil.c
│ ├── kutil.h
│ ├── shournal_kio.c
│ ├── shournal_kio.h
│ ├── shournalk_global.c
│ ├── shournalk_global.h
│ ├── shournalk_main.c
│ ├── shournalk_sysfs.c
│ ├── shournalk_sysfs.h
│ ├── shournalk_test.c
│ ├── shournalk_test.h
│ ├── shournalk_user.h
│ ├── tracepoint_helper.c
│ ├── tracepoint_helper.h
│ ├── xxhash_shournalk.c
│ └── xxhash_shournalk.h
├── shell-integration-scripts/
│ ├── CMakeLists.txt
│ ├── _source_me_generic.sh
│ ├── integration_fan.sh
│ ├── integration_ko.sh
│ ├── integration_main.sh.in
│ └── util.sh
├── src/
│ ├── CMakeLists.txt
│ ├── common/
│ │ ├── CMakeLists.txt
│ │ ├── app.cpp
│ │ ├── app.h
│ │ ├── cefd.cpp
│ │ ├── cefd.h
│ │ ├── console_dialog.cpp
│ │ ├── console_dialog.h
│ │ ├── cxxhash.cpp
│ │ ├── cxxhash.h
│ │ ├── database/
│ │ │ ├── command_query_iterator.cpp
│ │ │ ├── command_query_iterator.h
│ │ │ ├── commandinfo.cpp
│ │ │ ├── commandinfo.h
│ │ │ ├── db_connection.cpp
│ │ │ ├── db_connection.h
│ │ │ ├── db_controller.cpp
│ │ │ ├── db_controller.h
│ │ │ ├── db_conversions.cpp
│ │ │ ├── db_conversions.h
│ │ │ ├── db_globals.cpp
│ │ │ ├── db_globals.h
│ │ │ ├── file_query_helper.cpp
│ │ │ ├── file_query_helper.h
│ │ │ ├── fileinfos.cpp
│ │ │ ├── fileinfos.h
│ │ │ ├── insertifnotexist.cpp
│ │ │ ├── insertifnotexist.h
│ │ │ ├── qexcdatabase.cpp
│ │ │ ├── qexcdatabase.h
│ │ │ ├── qsqlquerythrow.cpp
│ │ │ ├── qsqlquerythrow.h
│ │ │ ├── query_columns.h
│ │ │ ├── sessioninfo.cpp
│ │ │ ├── sessioninfo.h
│ │ │ ├── sqlite_database_scheme.cpp
│ │ │ ├── sqlite_database_scheme.h
│ │ │ ├── sqlite_database_scheme_updates.cpp
│ │ │ ├── sqlite_database_scheme_updates.h
│ │ │ ├── sqlquery.cpp
│ │ │ ├── sqlquery.h
│ │ │ ├── storedfiles.cpp
│ │ │ └── storedfiles.h
│ │ ├── fdcommunication.cpp
│ │ ├── fdcommunication.h
│ │ ├── fileeventhandler.cpp
│ │ ├── fileeventhandler.h
│ │ ├── fileevents.cpp
│ │ ├── fileevents.h
│ │ ├── generic_container.h
│ │ ├── groupcontrol.cpp
│ │ ├── groupcontrol.h
│ │ ├── hashcontrol.cpp
│ │ ├── hashcontrol.h
│ │ ├── hashmeta.cpp
│ │ ├── hashmeta.h
│ │ ├── idmapentry.h
│ │ ├── interrupt_handler.cpp
│ │ ├── interrupt_handler.h
│ │ ├── limited_priority_queue.h
│ │ ├── logger.cpp
│ │ ├── logger.h
│ │ ├── oscpp/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cflock.cpp
│ │ │ ├── cflock.h
│ │ │ ├── excos.cpp
│ │ │ ├── excos.h
│ │ │ ├── fdentries.cpp
│ │ │ ├── fdentries.h
│ │ │ ├── os.cpp
│ │ │ ├── os.h
│ │ │ ├── oscaps.cpp
│ │ │ ├── oscaps.h
│ │ │ ├── osutil.cpp
│ │ │ └── osutil.h
│ │ ├── pathtree.cpp
│ │ ├── pathtree.h
│ │ ├── pidcontrol.cpp
│ │ ├── pidcontrol.h
│ │ ├── qfddummydevice.cpp
│ │ ├── qfddummydevice.h
│ │ ├── qfilethrow.cpp
│ │ ├── qfilethrow.h
│ │ ├── qoptargparse/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── excoptargparse.cpp
│ │ │ ├── excoptargparse.h
│ │ │ ├── qoptarg.cpp
│ │ │ ├── qoptarg.h
│ │ │ ├── qoptargparse.cpp
│ │ │ ├── qoptargparse.h
│ │ │ ├── qoptargtrigger.cpp
│ │ │ ├── qoptargtrigger.h
│ │ │ ├── qoptsqlarg.cpp
│ │ │ ├── qoptsqlarg.h
│ │ │ ├── qoptvarlenarg.cpp
│ │ │ └── qoptvarlenarg.h
│ │ ├── qresource_helper.cpp
│ │ ├── qresource_helper.h
│ │ ├── qsimplecfg/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cfg.cpp
│ │ │ ├── cfg.h
│ │ │ ├── exccfg.cpp
│ │ │ ├── exccfg.h
│ │ │ ├── section.cpp
│ │ │ └── section.h
│ │ ├── safe_file_update.h
│ │ ├── settings.cpp
│ │ ├── settings.h
│ │ ├── shournal_run_common.cpp
│ │ ├── shournal_run_common.h
│ │ ├── socket_message.cpp
│ │ ├── socket_message.h
│ │ ├── stdiocpp.cpp
│ │ ├── stdiocpp.h
│ │ ├── stupidinject.cpp
│ │ ├── stupidinject.h
│ │ ├── subprocess.cpp
│ │ ├── subprocess.h
│ │ ├── user_kernerl.h
│ │ ├── util/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cleanupresource.h
│ │ │ ├── compareoperator.cpp
│ │ │ ├── compareoperator.h
│ │ │ ├── compat.h
│ │ │ ├── conversions.cpp
│ │ │ ├── conversions.h
│ │ │ ├── cpp_exit.cpp
│ │ │ ├── cpp_exit.h
│ │ │ ├── exccommon.cpp
│ │ │ ├── exccommon.h
│ │ │ ├── nullable_value.h
│ │ │ ├── qformattedstream.cpp
│ │ │ ├── qformattedstream.h
│ │ │ ├── qoutstream.cpp
│ │ │ ├── qoutstream.h
│ │ │ ├── staticinitializer.h
│ │ │ ├── strlight.cpp
│ │ │ ├── strlight.h
│ │ │ ├── strlight_util.cpp
│ │ │ ├── strlight_util.h
│ │ │ ├── sys_ioprio.h
│ │ │ ├── translation.cpp
│ │ │ ├── translation.h
│ │ │ ├── util.cpp
│ │ │ ├── util.h
│ │ │ ├── util_performance.cpp
│ │ │ └── util_performance.h
│ │ ├── xxhash_common.c
│ │ └── xxhash_common.h
│ ├── shell-integration-fanotify/
│ │ ├── CMakeLists.txt
│ │ ├── attached_bash.cpp
│ │ ├── attached_bash.h
│ │ ├── attached_shell.cpp
│ │ ├── attached_shell.h
│ │ ├── event_open.cpp
│ │ ├── event_open.h
│ │ ├── event_process.cpp
│ │ ├── event_process.h
│ │ ├── libshellwatch.version
│ │ ├── libshournal-shellwatch.cpp
│ │ ├── shell_globals.cpp
│ │ ├── shell_globals.h
│ │ ├── shell_logger.cpp
│ │ ├── shell_logger.h
│ │ ├── shell_request_handler.cpp
│ │ └── shell_request_handler.h
│ ├── shournal/
│ │ ├── CMakeLists.txt
│ │ ├── argcontrol_dbdelete.cpp
│ │ ├── argcontrol_dbdelete.h
│ │ ├── argcontrol_dbquery.cpp
│ │ ├── argcontrol_dbquery.h
│ │ ├── cmd_stats.cpp
│ │ ├── cmd_stats.h
│ │ ├── command_printer.cpp
│ │ ├── command_printer.h
│ │ ├── command_printer_html.cpp
│ │ ├── command_printer_html.h
│ │ ├── command_printer_human.cpp
│ │ ├── command_printer_human.h
│ │ ├── command_printer_json.cpp
│ │ ├── command_printer_json.h
│ │ └── shournal.cpp
│ ├── shournal-run/
│ │ ├── CMakeLists.txt
│ │ ├── fifocom.cpp
│ │ ├── fifocom.h
│ │ ├── filewatcher_shournalk.cpp
│ │ ├── filewatcher_shournalk.h
│ │ ├── mark_helper.cpp
│ │ ├── mark_helper.h
│ │ ├── shournal-run.cpp
│ │ ├── shournalk_ctrl.c
│ │ └── shournalk_ctrl.h
│ └── shournal-run-fanotify/
│ ├── CMakeLists.txt
│ ├── fanotify_controller.cpp
│ ├── fanotify_controller.h
│ ├── filewatcher_fan.cpp
│ ├── filewatcher_fan.h
│ ├── mount_controller.cpp
│ ├── mount_controller.h
│ ├── msenter.cpp
│ ├── msenter.h
│ ├── orig_mountspace_process.cpp
│ ├── orig_mountspace_process.h
│ └── shournal-run-fanotify.cpp
└── test/
├── CMakeLists.txt
├── autotest.h
├── helper_for_test.cpp
├── helper_for_test.h
├── integration_test_shell.cpp
├── main.cpp
├── sqlite_sample_db_v2_2/
│ └── readFiles/
│ ├── 3
│ └── 4
├── test_cfg.cpp
├── test_cxxhash.cpp
├── test_db_controller.cpp
├── test_fdcommunication.cpp
├── test_fileeventhandler.cpp
├── test_osutil.cpp
├── test_pathtree.cpp
├── test_qformattedstream.cpp
├── test_qoptargparse.cpp
└── test_util.cpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
CMakeLists.txt.user*
*.geany
*.autosave
package-lock.json
html-export/node_modules
html-export/dist/SAMPLE_DATA.js
html-export/.vscode
.eslintrc.js
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.6)
if (NOT (CMAKE_VERSION VERSION_LESS "3.20"))
cmake_policy( SET CMP0115 NEW )
endif()
# version applies to all released files: shournal, shournal-run, libshournal-shellwatch.so
# and shell-integration-scripts (e.g. integration_ko.bash)
set(shournal_version "3.3")
cmake_policy( SET CMP0048 NEW )
project(shournal VERSION ${shournal_version} LANGUAGES CXX C)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(ShournalUtil REQUIRED)
if (NOT DEFINED MSENTER_GROUPNAME)
set(MSENTER_GROUPNAME "shournalmsenter")
endif()
add_definitions( -DSHOURNAL_MSENTERGROUP="${MSENTER_GROUPNAME}")
# No need to make configurable - user can override in /etc/shournal.d/kgroup
# (or, not recommended, use a custom rule in /etc/udev/rules.d).
# DO NOT CHANGE, it is documented in the README.
set(GROUPNAME_SHOURNALK "shournalk")
# Inside docker no kernel module may be installed,
# but we default to using the host's kernel-module.
# When only shournal-run-fanotify is desired, no need to
# compile shournal-run.
# -DSHOURNAL_EDITION={full, docker, ko, fanotify}
if(NOT DEFINED SHOURNAL_EDITION)
set(SHOURNAL_EDITION "full")
endif()
if(NOT ${SHOURNAL_EDITION} MATCHES "full|docker|ko|fanotify")
message( FATAL_ERROR "invalid SHOURNAL_EDITION passed: ${SHOURNAL_EDITION}" )
endif()
set (CMAKE_CXX_STANDARD 11)
if(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
message(FATAL_ERROR "GCC version must be at least 5.0!")
endif()
else()
message(WARNING "You are using an unsupported compiler. Compilation was only tested with GCC.")
endif()
if ( CMAKE_COMPILER_IS_GNUCXX )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wunused-result -Werror=return-type")
endif()
add_definitions( -DSHOURNAL_VERSION="${shournal_version}" )
if (NOT EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt)
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
endif()
IF(CMAKE_BUILD_TYPE MATCHES Release)
ADD_DEFINITIONS( -DQT_NO_DEBUG_OUTPUT=1)
SET(CMAKE_AR "gcc-ar")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
ENDIF()
# Profile purposes
IF(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
ADD_DEFINITIONS( -DQT_NO_DEBUG_OUTPUT=1)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g -DNDEBUG")
ENDIF()
# Meaningful stacktraces:
SET (CMAKE_ENABLE_EXPORTS TRUE)
# cmake policy: allow for hidden symbols in static libs
cmake_policy( SET CMP0063 NEW )
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
function(hide_static_lib_symbols staticLib)
set_target_properties(${staticLib} PROPERTIES CXX_VISIBILITY_PRESET hidden)
set_target_properties(${staticLib} PROPERTIES CMAKE_VISIBILITY_INLINES_HIDDEN 1)
endfunction(hide_static_lib_symbols)
# append the content of f2 to f1
function(append_to_file f1 f2)
file(READ ${f2} CONTENTS)
file(APPEND ${f1} "${CONTENTS}")
endfunction()
# Below code could be used to strip *all* symbols, however, we do it only
# for the shared lib to allow for meaningful stacktraces in shournal and shournal-run
# CMP0063 NEW allows hiding symbols also in static libraries
# If cmake is too old, try to use compiler optinons directly or
# print warning, if that also fails.
# if (CMAKE_VERSION VERSION_LESS "3.3")
# IF (CMAKE_COMPILER_IS_GNUCXX OR
# "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# else()
# message("Warning - cannot hide all symbols of libshournal.so.")
# message("Please upgrade cmake or use clang/gcc")
# ENDIF()
# else()
# cmake_policy( SET CMP0063 NEW )
# set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
# set(CMAKE_CXX_VISIBILITY_PRESET hidden)
# set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# endif()
include(GNUInstallDirs)
set(shournal_install_dir_script ${CMAKE_INSTALL_FULL_DATAROOTDIR}/${PROJECT_NAME})
set(shournal_install_dir_lib ${CMAKE_INSTALL_FULL_LIBDIR}/${PROJECT_NAME})
set(shournal_install_dir_shournalk_src /usr/src/shournalk-${shournal_version})
set(libshournal_fullname "libshournal-shellwatch.so")
set(full_path_libshournal ${shournal_install_dir_lib}/${libshournal_fullname})
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
# qt resource files (.qrc):
set(CMAKE_AUTORCC ON)
find_package(Qt5 COMPONENTS Core Sql Network REQUIRED)
include_directories(
extern/tsl-ordered-map
extern/folly
extern/xxHash
)
add_subdirectory("extern/tsl-ordered-map")
set(XXHASH_BUNDLED_MODE ON)
add_subdirectory(extern/xxHash/cmake_unofficial EXCLUDE_FROM_ALL)
add_subdirectory("src")
add_subdirectory("shell-integration-scripts")
add_subdirectory("install")
# Kernel module
if(${SHOURNAL_EDITION} MATCHES "full|ko")
add_subdirectory("kernel")
endif()
# Turn on tests with 'cmake -Dtest=ON'.
# To run the tests enter directory "test" within the build directory
# and enter "ctest".
option(test "Build all tests." OFF)
if (test)
add_subdirectory("test")
endif()
# install license
install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
RENAME copyright # following Lintian
DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}
)
############## Package creation using 'cpack' ##############
# generic
set(CPACK_GENERATOR "DEB")
set(CPACK_PACKAGE_VERSION ${shournal_version})
set(CPACK_PACKAGE_CONTACT "Tycho Kirchner <tychokirchner@mail.de>")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
# If CPACK_INSTALL_PREFIX is not set, let it default to CMAKE_INSTALL_PREFIX
# see also: https://stackoverflow.com/a/7363073/7015849
# set(CPACK_SET_DESTDIR true)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
"File-journal for your shell"
)
set(SHOURNAL_CONFLICTS_LIST
"shournal" "shournal-docker"
"shournal-ko" "shournal-fanotify"
)
if(${SHOURNAL_EDITION} STREQUAL "full")
set(CPACK_PACKAGE_NAME "shournal")
set(edition_description "full suite (all backends)")
elseif(${SHOURNAL_EDITION} STREQUAL "ko")
set(CPACK_PACKAGE_NAME "shournal-ko")
set(edition_description "kernel backend only (fanotify backend not included)")
elseif(${SHOURNAL_EDITION} STREQUAL "fanotify")
set(CPACK_PACKAGE_NAME "shournal-fanotify")
set(edition_description "fanotify backend only (no kernel module included)")
elseif(${SHOURNAL_EDITION} STREQUAL "docker")
set(CPACK_PACKAGE_NAME "shournal-docker")
set(edition_description "docker-version to be installed inside containers")
else()
message( FATAL_ERROR "invalid cpack COMPONENT: ${SHOURNAL_EDITION}" )
endif()
list(REMOVE_ITEM SHOURNAL_CONFLICTS_LIST
"${CPACK_PACKAGE_NAME}"
)
JOIN("${SHOURNAL_CONFLICTS_LIST}" ", " SHOURNAL_CONFLICTS)
# CPACK_DEBIAN_PACKAGE_DESCRIPTION requires newlines
# be indented by one space. For the sake of simplicity:
# No new lines here:
set(CPACK_PACKAGE_DESCRIPTION
"Integrated tool to increase the reproducibility \
of your work on the shell: what did you do when and \
where and what files were modified/read. This package \
provides the ${edition_description}.")
# deb specific
# set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_PACKAGE_DESCRIPTION}")
execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE DEB_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_DEBIAN_FILE_NAME
${CPACK_PACKAGE_NAME}_${shournal_version}_${DEB_ARCH}.deb)
set(CPACK_DEBIAN_PACKAGE_CONFLICTS "${SHOURNAL_CONFLICTS}")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/tycho-kirchner/shournal")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.2), libstdc++6 (>= 5.0), libgcc1, \
libqt5core5a (>= 5.6), libqt5network5, libqt5sql5-sqlite, libcap2, uuid-runtime"
)
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
# generate the postinst based on the groupname
set(debPostinstPath "${CMAKE_BINARY_DIR}/debian/postinst")
set(debPrermPath "${CMAKE_BINARY_DIR}/debian/prerm")
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${debPostinstPath}"
"${debPrermPath}"
)
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
if(${SHOURNAL_EDITION} MATCHES "full|ko")
set(CPACK_DEBIAN_PACKAGE_DEPENDS
"${CPACK_DEBIAN_PACKAGE_DEPENDS}, dkms")
append_to_file( "${debPostinstPath}" ${CMAKE_BINARY_DIR}/install/postinst-dkms )
append_to_file( "${debPrermPath}" ${CMAKE_BINARY_DIR}/install/prerm-dkms )
endif()
# call it *after* setting above variables, otherwise
# generic .gz's are generated.
include(CPack)
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
================================================
FILE: README-compile.md
================================================
# Compile and install from source
* Install gcc >= 5.0. Other compilers might work but are untested.
* Install cmake >= 3.6 and make
* For safe generation of uuids it is recommend to install uuidd (uuid-runtime)
* Install qt-dev, uuid-dev, qt-sqlite-driver, Qt version >= 5.6.
*With a little effort, shournal could be modified to
support Qt version >= 5.3. Please open an issue, if that would
be helpful to you.*
* To build the kernel-module the headers are also required
(linux-headers-$(uname -r))
*Packages lists*:
Debian:
~~~
apt-get install g++ cmake make qtbase5-dev libqt5sql5-sqlite \
uuid-dev libcap-dev uuid-runtime linux-headers-$(dpkg --print-architecture) dkms
~~~
Ubuntu:
~~~
apt-get install g++ cmake make qtbase5-dev libqt5sql5-sqlite \
uuid-dev libcap-dev uuid-runtime dkms \
linux-headers-generic # or linux-headers-generic-hwe-$(lsb_release -rs) on HWE
~~~
Opensuse:
~~~
zypper install gcc-c++ cmake make libqt5-qtbase-devel \
libQt5Sql5-sqlite libuuid-devel libcap-devel uuidd \
kernel-default-devel dkms
~~~
Arch Linux:
~~~
yay -S gcc cmake make qt5-base uuid libcap linux-headers dkms
~~~
CentOS (note: CentOS 7 as of July 2019 only ships with gcc 4.8
-> compile gcc >= 5.0 yourself. cmake3 and cmake are seperate packages
where cmake in version 2 is the default. Please ensure to compile with
cmake3. The kernel 3.10 is too old for *shournal*'s kernel-module.
Either install a newer one or stick with the fanotify-edition):
~~~
yum install gcc-c++ cmake3 make qt5-qtbase-devel libuuid-devel \
libcap-devel uuidd kernel-devel dkms
~~~
* In the source-tree-directory, enter the following commands to
compile and install. By default `SHOURNAL_EDITION` `full` is built (see below).
Supported options include `full, docker, ko, fanotify`.
The `ko` (kernel module) edition does not install the fanotify backend
which may be desirable for security reasons as the setuid-binary
`shournal-run-fanotify` is omitted. For a description of the other editions
refer to [Binary releases](./README.md#binary-releases).
~~~
mkdir -p build
cd build
# If you later want to generate a deb-package, it is recommended
# to use /usr as prefix: -DCMAKE_INSTALL_PREFIX=/usr
cmake -DSHOURNAL_EDITION=full ..
make
# as root:
make install
# or if using a Debian-based distribution, generate a .deb-package:
cpack -G DEB
~~~
* To also compile unit- and integration-tests, run cmake with
`-Dtest=ON` (debugging symbols via `-DCMAKE_BUILD_TYPE=Debug`). This generates
a `test/runTests` binary in the build dir. Without any arguments, it runs
unit-tests. Integrations-tests are, for instance, executed using:
~~~
# SHOURNAL_BACKEND=fanotify|ko
SHOURNAL_BACKEND=fanotify test/runTests --integration --shell 'bash -i'
~~~
**After compile and install**: <br>
If you created a .deb-package, please see
[Binary releases](./README.md#binary-releases). **Otherwise:**
**Kernel-module backend** <br>
For a quick test, the module can be loaded right from the build-tree:
`$ insmod kernel/shournalk.ko`. <br>
To install the kernel-module (not built in SHOURNAL_EDITION's
*docker* and *fanotify*) it is recommended to install it using dkms, e.g.:
~~~
dkms build shournalk/2.4 # adjust version as needed.
dkms install shournalk/2.4
# and load it with
modprobe shournalk
~~~
Depending on your distribution the dkms service may be disabled, thus
after a kernel-update shournal stops working. At least on
Opensuse Tumbleweed it can be enabled with
~~~
systemctl enable dkms
~~~
**fanotify backend** <br>
Add a group to your system, which is primarily needed for
the shell-integration:
```groupadd shournalmsenter```
However, *do not add any users to that group*. It is part of a permission
check, where root adopts that gid (within shournal).
If you don't like the default group name, you can specify your own: at
build time pass the following to cmake:
```-DMSENTER_GROUPNAME=$your_group_name```
For **further post-install steps** please see
[Binary releases](./README.md#binary-releases). Please note
that file-paths may need to be adjusted, e.g. the location of
the `SOURCE_ME.$shell_name` scripts after `make install` is typically
`/usr/local/share/shournal/`, not `/usr/share/shournal/`.
To **uninstall**, after having installed with `make install`, you can
execute <br>
`xargs rm < install_manifest.txt`, but see
[here](https://stackoverflow.com/a/44649542/7015849) for the
limitations. <br>
To uninstall the kernel-module backend: <br>
`sudo dkms remove shournalk/2.4` (adjust version as needed).
================================================
FILE: README-shell-integration.md
================================================
# Shell integration for shournal
## Basic setup (interactive)
After installation, to start observing your *interactive* shell-sessions
append the following to your shell's rc: <br>
**~/.bashrc** <br>
~~~
HISTCONTROL=ignoredups:erasedups # NOT ALLOWED: ignorespace,ignoreboth
source /usr/share/shournal/SOURCE_ME.bash
SHOURNAL_ENABLE
~~~
**~/.zshrc** <br>
~~~
source /usr/share/shournal/SOURCE_ME.zsh
SHOURNAL_ENABLE
~~~
Launch a new shell afterwards and check whether it's working:
~~~
$ echo foo > bar
$ shournal --query --wfile bar
cmd-id 66075 $?=0 2021-11-02 14:23 $ echo foo > bar
Working directory: /home/tycho
session-uuid 3hIZtDwhEey5WPDVv9W/Cw==
1 written file:
/home/tycho/bar (4 bytes) Hash: 8087352826690557229
$ # or just look into the history:
$ shournal --query --history 3
# ...
~~~
The shell-integration injects code into
`PROMPT_COMMAND`, `PS0` and `PS1` (bash) or the `preexec/precmd_functions`
(zsh), so please do not overwrite those after having enabled shournal.
Further basic history functionality must be available, e.g. in bash
HISTCONTROL must not ignore commands with leading spaces (see above).
shournal's shell integration checks the typical variables and gives
hints, if there is need for action.
Other commands include <br>
`SHOURNAL_DISABLE` to disable the observation <br>
`SHOURNAL_PRINT_VERSIONS` to print the version of each component <br>
`SHOURNAL_SET_VERBOSITY` to change the default verbosity ("dbg, info,
warning, critical"). For dbg, shournal must have been compiled with
debugging symbols. A verbosity higher than *warning* is not recommended.
## Advanced setup (non-interactive)
To also observe non-interactive commands executed via ssh
~~~
ssh localhost echo foo
~~~
or the *Sun Grid Engine* (SGE) the following setup is recommended:
<br> <br>
**bash** <br>
Put the following near the **beginning** of your bashrc:
~~~
if [[ -n ${SGE_O_WORKDIR+x} || (
-n ${BASH_EXECUTION_STRING+x} &&
( -n ${SSH_CLIENT+x} || -n ${SSH_TTY+x} )
) ]]; then
source /usr/share/shournal/SOURCE_ME.bash
SHOURNAL_ENABLE
fi
~~~
In particular that code has to run before the sourcing of ~/.bashrc
stops due to a negative interactive-check. For example, some distributions
place the following near the top of the bashrc:
~~~
case $- in
*i*) ;;
*) return;;
esac
~~~
**zsh** <br>
Put the following into ~/.zprofile
~~~
if [[ -n ${SGE_O_WORKDIR+x} || (
-n ${ZSH_EXECUTION_STRING+x} &&
( -n ${SSH_CLIENT+x} || -n ${SSH_TTY+x} )
) ]]; then
source /usr/share/shournal/SOURCE_ME.zsh
SHOURNAL_ENABLE
fi
~~~
Note that depending on your server environment, this requires zsh to be
executed as login shell, e.g. <br>
`ssh HOST zsh -l -c command`. Alternatively
you may use ~/.zshenv but beware that this file is always sourced, also
during `zsh -c ':'` invocations on the interactive command-line, so at least
an additional check for <br>
`[ $SHLVL -eq 1 ]` is recommended.
For cluster software systems other than SGE, you may
`export SHOURNAL_IS_CLUSTERJOB=true`, before `SHOURNAL_ENABLE`, if and
only if the shell is about to execute a cluster job. Note
that in this case, shournal performs a re-execution of the current
command and only returns control flow after flushing the database, because
cluster software systems tend to kill background processes, once the
main job script finished. To totally disable cluster job detection,
set `SHOURNAL_NO_CLUSTER_JOB_DETECT=true` before `SHOURNAL_ENABLE`.
## Prerequisites of the fanotify backend
If the *fanotify* backend is used, please ensure the following:
* The shell must be linked dynamically against (g)libc (default case,
can be tested e.g. with <br>
`file $(which bash) | grep "dynamically linked"` ).
* Sourcing of SOURCE_ME.$shell must be within the shell's rc-file.
* `SHOURNAL_ENABLE` should be within the shell's rc, because
on the very first enable the shell is re-executed, purging all non-exported
variables.
* For non-interactive commands `SHOURNAL_ENABLE` must be called
before the actual execution begins.
Note that the kernel module backend does not have those prerequisites
and should be preferred in most cases.
## Updates
If the shell-integration is running while shournal is updated, it is recommended,
to restart your shell. A more elegant way than logout-login might be to `exec` your $shell.
## FAQ
* **How to obtain the value of variables?**. <br>
If shell-variables are used within a command, shournal's reports might
not seem to be very helpful. However, the shell-integration assigns
each shell-session a unique identifier (uuid).
In the likely case that the variable was
assigned *during that session*, you might be able to obtain its value.
This of course only works, if SHOURNAL_ENABLE was called, *before*
a variable was assigned. Example: <br>
`shournal --query --shell-session-id 'L/932KZTEemRB/dOGB9LOA==' | grep var_name`
* **What about new, nested shell-sessions**? <br>
By *new shell-sessions* it is meant to call e.g. `bash` within an already
running bash-process. What happens next really depends on whether the
shell is itself **observed** by shournal or not (e.g. whether
`SHOURNAL_ENABLE` is within the .bashrc or not). On calling
`SHOURNAL_ENABLE` file-events are then considered to belong to the
new shell-session and are no longer reported to the original
observation-process of the caller. If a **non-observed** shell
is a called, shournal's later report will not be very helpful: all
file-modifications caused by that process will yield the plain
shell-command (and not individual commands possibly entered
within the new shell session).
## Limitations
* File-operations (redirections) which spread over **multiple** command-sequences
within the **interactive shell** might lead to surprising (*kernel module backend*)
or incorrect (*fanotify backend*) results. <br>
Example:
~~~
$ exec 3> /tmp/foo # open fd 3
$ echo "test" >&3
$ exec 3>&- # close fd 3.
~~~
In case of the *kernel module backend* as usual the close event is
tracked, however `shournal -q -wf /tmp/foo` prints only the command
`exec 3>&-`. By using the shell-session uuid it should be possible
to reconstruct those cases. <br>
In case of the *fanotify backend* the close-event is lost.
* **Additional limitations of the fanotify-backend**: <br>
Filesystem-events of asynchronously launched processes, which close the inherited
shournal-socket, might be lost, because an external shournal-run process
waits until all instances of that socket are closed.
Steps to reproduce: In an *observed* shell-session enter <br>
`bash -c 'eval "exec $_SHOURNAL_SOCKET_NB>&-"; sleep 1; echo foo > bar' &` <br>
Note that e.g. in *Python* processes launched via its
*subprocess*-module do not inherit file descriptors by default.
There seems to be no general solution to this problem, but in most cases
there should be some mechanism to wait for the processes to finish,
within the interactive shell-session or a script.
* For further limitations please also read the general
[README](/../../).
## Motivation
For a general introduction about the data and meta-data *shournal* stores
please visit the general [README](/../../).
Having to type *shournal* before every single command one wants
to observe can be tiresome. Another typing-overhead would be
introduced by using pipes or redirections.
Consider the following **broken** example:
shournal --exec echo hi > foo # Don't do this.
As many shell users know the redirection applies to the whole command,
while shournal itself only observes "echo hi". The file modification event ('hi'
written to 'foo')
is hence **not** tracked by shournal.
To actually observe such a command
one must rather type
shournal --exec sh -c 'echo hi > foo'
That's annoying, right?
Therefore before observing one or multiple commands,
`source` the respective integration-file within your shell's rc
(e.g. .bashrc) and type
SHOURNAL_ENABLE
That's (almost) all. Forget about *shournal* until needed
( e.g. you want to know how a certain file was created).
================================================
FILE: README.md
================================================

## A (file-) journal for your shell
**Log shell-commands and used files. Snapshot executed scripts. Fully automatic.** <br>
*There are two kinds of people: those who backup, and those who have never
lost their data.* <br>
~~~
$ SHOURNAL_ENABLE
$ cat demo.sh
#!/usr/bin/env bash
echo hi | tee out.log
$ ./demo.sh
hi
$ shournal -q --wfile out.log
cmd-id 2 $?=0 2022-11-08 08:46 $ ./demo.sh
Working directory: /home/user
1 written file:
/home/user/out.log (3 bytes) Hash: 15349503233279147316
1 read file:
/home/user/demo.sh (42 bytes) Hash: 13559791986335963073 id 1
#!/usr/bin/env bash
echo hi | tee out.log
~~~
***shournal* records that `out.log` was written by the command `./demo.sh` and
created a backup of the script `demo.sh` because it was read by
the bash interpreter.**
*shournal* does not guess the files - it asks the Linux kernel. It's fast enough,
see [Overhead](#overhead).
After installation and easy setup of the
[shell-integration](./README-shell-integration.md) the following questions
may be answered within seconds:
* What files were modified, read or executed by a command? Or reverse: What shell-commands
were used to create/modify or read from a certain file?
* You executed a script. What was the script-content by the time it was called?
* The command read a config-file - which one, and what was in it?
* The command ran for a long time - can a re-execution be avoided (s. `--stat`)?
* What other commands were executed during the same shell-session?
* What about working directory, command start- and end-time or the
exit status ($?) ?
Besides output on the command-line in a human-readable format (or JSON)
you can export (parts of) your command-history into
a standalone html-file where it is displayed in an interactive
time-line-plot. Further miscellaneous statistics are displayed in
bar-plots, e.g. the commands with most file-modifications.
Using the external software
[shournal-to-snakemake]( https://github.com/snakemake/shournal-to-snakemake)
an observed shell-command-series can be directly transformed into rules for
the [*Snakemake workflow engine*](https://github.com/snakemake/snakemake),
a tool to *create reproducible and scalable data analyses*.
*shournal* runs on GNU/Linux or Microsoft Windows via
the Windows Subsystem for Linux (WSL) using its *fanotify* edition.
For a more formal description please also check out our paper <br>
Kirchner, T., Riege, K. & Hoffmann, S. *Bashing irreproducibility with shournal*.
Sci Rep 14, 4872 (2024). https://doi.org/10.1038/s41598-024-53811-9
<br>

## Examples
Please note: below examples make use of the
[shell-integration](./README-shell-integration.md). <br>
* Create a file and ask shournal, how it came to be:
~~~
$ SHOURNAL_ENABLE # monitor all commands using the shell-integration
$ echo hi > foo
$ shournal --query --wfile foo
cmd-id 1 $?=0 2019-05-14 10:19 $ echo hi > foo
1 written file:
/home/user/foo (3 bytes) Hash: 15349503233279147316
~~~
* shournal can be configured, to store *specific* read files, like shell-scripts,
within it's database. Sometimes old script versions are of interest. Query
by **read filename** and optionally restore the files with `--restore-rfiles`:
~~~
$ shournal -q --rname demo.sh
cmd-id 34 $?=0 2022-04-21 15:15 $ ./demo.sh
1 read file:
/home/user/demo.sh (34 bytes) Hash: 16696055267278105544 id 3
#!/usr/bin/env bash
echo version1
cmd-id 35 $?=0 2022-04-21 15:15 $ ./demo.sh
1 read file:
/home/user/demo.sh (34 bytes) Hash: 17683376525180966954 id 4
#!/usr/bin/env bash
echo version2
$ shournal -q --rname demo.sh --restore-rfiles # restore read files
...
2 file(s) restored at /tmp/shournal-restore-user
~~~
* List all commands which contained the string `demo` (<kbd>%</kbd> is wildcard):
~~~
$ shournal -q -cmdtxt %demo%
cmd-id 1 $?=0 2022-04-20 15:46 $ cat demo.sh
...
cmd-id 2 $?=0 2022-04-20 15:46 $ ./demo.sh
...
~~~
* Are input files up to date, such that re-execution of the command can be
avoided? Add `--stat` to the query, reporting current file statuses as
U (up to date), M (modified), N (not exist) ERROR (in case of an error) or NA
(not queried, only using json).
~~~
$ cat foo > bar
$ shournal -q -wf bar --stat
cmd-id 1 $?=0 2025-02-10 11:38-11:38 $ cat foo > bar
...
1 written file:
/home/tycho/bar (3 bytes) Hash: 15349503233279147316 U
1 read file:
/home/tycho/foo (3 bytes) Hash: 15349503233279147316 id 404002 U
~~~
To query only for changed input files, execute
~~~
shournal -q -wf bar --stat --output-format json | grep -F 'COMMAND:' | \
sed -n 's/COMMAND://p' | \
jq -r '.fileReadEvents | .[] | .status + " " + .path' | grep -v ^U
~~~
* What commands were executed at the current working directory?
~~~
shournal --query -cwd "$PWD"
~~~
* What commands were executed within a specific shell-session? The
uuid can be taken from the command output of a previous query.
~~~
shournal --query --shell-session-id $uuid
~~~
* Find out the value of a variable.
For instance, the command `echo $foo > bar` was executed in the shell-session
with id `puLvkEizEe6CgvXjQlmnIQ==`. If `foo` was set within that shell
session, its value can often be retrieved by
~~~
shournal -q -sid puLvkEizEe6CgvXjQlmnIQ== | fgrep 'foo='
~~~
* For the full list of query-options, please enter
~~~
shournal --query --help
~~~
Instead of printing the `--query`-results to terminal, you can also create
fancy html-plots, by appending `--output-format html -o out.html`.
Use an ordinary web-browser for display.
## Installation
### Binary releases
For **Debian/Ubuntu-based** distributions .deb-packages are available on the
[release-page](https://github.com/tycho-kirchner/shournal/releases/latest).
Three different editions are provided for different use-cases: most users will
want to install *shournal* on a real host (or virtual machine) and
*shournal-docker* [inside Docker](#running-inside-docker)
(or another container platform).
*shournal-fanotify* does not contain the kernel backend and
is targeted at institutions where the usage of *out-of-tree kernel-modules*
is discouraged. <br>
Only LTS-releases are officially supported, the packages are known to work
from Debian 10 (Buster) and Ubuntu 18.04 (Bionic) onwards.
Before installing *shournal* including its kernel backend, make
sure, the kernel headers are installed: <br>
**Ubuntu**: `apt install linux-headers-generic` <br>
**Ubuntu** with [HWE](https://askubuntu.com/questions/248914/what-is-hardware-enablement-hwe):
`apt install linux-headers-generic-hwe-$(lsb_release -rs)` <br>
**Debian**: `apt install linux-headers-$(dpkg --print-architecture)` <br>
Install deb-packages as usual, e.g. <br>
`sudo apt install ./shournal_2.2_amd64.deb` <br>
To enable the shell-integration:
* for *bash*: put the following to the end of your ~/.bashrc <br>
`source /usr/share/shournal/SOURCE_ME.bash` <br>
* for *zsh*: put the following to the end of your ~/.zshrc <br>
`source /usr/share/shournal/SOURCE_ME.zsh` <br>
and run `SHOURNAL_ENABLE` afterwards.
For **any Linux**, a flat binary is available on the
[release-page](https://github.com/tycho-kirchner/shournal/releases/latest)
to be used without installation:
~~~
tar -xf shournal-fanotify*.tar.xz
cd shournal-fanotify/
sudo groupadd shournalmsenter
sudo chown root shournal-run-fanotify && sudo chmod u+s shournal-run-fanotify
./shournal-run-fanotify -e echo Hello World
# Source shournal's shell integration from bashrc/zshrc, e.g.
# echo "source '$PWD/SOURCE_ME.bash'" >> ~/.bashrc
# echo "source '$PWD/SOURCE_ME.zsh'" >> ~/.zshrc
# Enable with: SHOURNAL_ENABLE.
~~~
An **update** of *shournal* should be performed after all users have
logged out, because the shell integrations need to be resourced.
Further in case of the *kernel module* backend unloading the old
version stops all running observations.
**After installation**:
Depending on your distribution, additional steps might be necessary to
enable the (recommended) uuidd-daemon. If systemd is in use, one
may need to:
systemctl enable uuidd
systemctl start uuidd
Add yourself or other users to the group *shournalk*: <br>
`sudo adduser $USER shournalk` (relogin to take affect). <br>
You may override this group:
~~~
mkdir -p /etc/shournal.d/
echo GROUPNAME > /etc/shournal.d/kgroup
~~~
replacing GROUPNAME with the value of your choice. This rule takes
into effect the next time shournal's kernel module is loaded ( so
call e.g. `modprobe -r shournalk; modprobe shournalk` or reboot).
More details and advanced options (logging commands executed via ssh)
can be found [here](./README-shell-integration.md).
### Compile and install from source
Please refer to the instructions found within the
[compile-README](./README-compile.md).
## FAQ
* **Does shournal track file rename/move operations?** <br>
No, but most often it should not be a problem. Using the
`--wfile` commandline-query-option, shournal finds the stored command
by content (size, hash) and mtime, not by its name.
For the name, `--wname` can be used.
More concrete:
~~~
shournal --exec sh -c 'echo foo > bar; mv bar bar_old'
~~~
Querying for bar_old by content (`--wfile`-option) yields exactly
the given command, however, `--wname bar_old` does **not** work
(`--wname bar` of course works). To use the bar_old *file name*
(and not content) as basis for a successful query, in this case
`--command-text -like '%bar_old%'` can be used.
* **What happens to an appended file?** <br>
How to get a "modification history"?
Please read above rename/move-text first.
Appending to a file is currently handled as if a new one was created -
only the last command, which modified a given file can be found with
good certainty (by file **content**).
However, querying by path/file**name** works.
If the file was appended *and* renamed, things get more complicated.
* **To track files, they can be hashed. Is that slow for big files?** <br>
No, because per default only certain small parts of the file are hashed.
* **What does the following message mean and how to get rid of it?**: <br>
`fanotify_mark: failed to add path /foobar ... Permission denied`.
This message might be printed on executing a command with shournal.
Most probably the administrator mounted a filesystem object for which you don't have
permissions, thus you cannot *monitor* file events.
In this case you cannot perform file operations at this path
anyway, so it should be safe to silence this warning by adding the
path within the config-file in section `[mounts]`. If you want to ignore all
fanotify_mark permission errors, you can set the flag in section
`[mounts]`:
~~~
[mounts]
ignore_no_permission = true
~~~
## Configuration
shournal stores a self-documenting config-file typically at
~/.config/shournal
which is created on first run. It can be edited either directly with
a plain text editor or via `--edit-cfg`.
For completeness, the most important points are listed here as well.
* Write- and read events can be configured, so only events occurring at
specific (include-)paths are stored. Put each path into a separate
line, all paths being enclosed
by triple quotes:
~~~
include_paths = '''
/home/me
/media
'''
~~~
Each exclude_path should be a sub-path of an include path.
* Note that by default, there
is a limit on the number of logged events per command (max_event_count).
Read files (e.g. scripts) can **further** be configured
to be stored within shournal's database.
Files are only stored, if the configured max. file-size, file extension
(e.g. sh) and mimetype (e.g. application/x-shellscript) matches.
To find a mimetype for a given file you should use <br>
`shournal --print-mime test.sh`.
The correspondence of mimetype and file extension
is explained in more detail within the config-file.
Further, at your wish, read files are only stored if *you* have write permission for them
(not only read) - often system-provided scripts (owned by root) are not of particular
interest.
shournal will not store more read files per command, than max_count_of_files.
Matching files coming first have precedence.
## Running inside Docker
To use *shournal* within Docker (or another container platform),
depending on the backend the following steps are necessary: <br>
**kernel module backend** <br>
Install *shournal* on the host and *shournal-docker* inside the container.
For *unprivileged* containers *sysfs* is mounted readonly. In this case
create a bindmount from /sys/kernel/shournalk_root to
/tmp/shournalk-sysfs, e.g. <br>
`docker run ... -v /sys/kernel/shournalk_root:/tmp/shournalk-sysfs`.
**fanotify backend** <br>
Install *shournal-docker* (or *shournal-fanotify*) inside docker.
For *unprivileged* containers the capabilities SYS_ADMIN, SYS_PTRACE and
SYS_NICE are required, e.g. <br>
`docker run ... --cap-add SYS_ADMIN --cap-add SYS_PTRACE --cap-add SYS_NICE`. <br>
You may need to [configure the backend](#backend-configuration).
## Running on a Amazon AWS EC2 instance
In order to run *shournal* on a Amazon AWS EC2 instance it may be
necessary, to enable additional software package repositories. For
Ubuntu 22.04 on a t3.micro instance enter the following commands before
installing *shournal*
~~~
sudo add-apt-repository universe
sudo apt update
~~~
## Backend configuration
shournal provides two backends, a custom *kernel module* and *fanotify*.
The *kernel module* is used by default, except the *shournal-fanotify*
edition is installed, where only the *fanotify* backend is
available. In general it is recommended to stick with the *kernel module*
as it is faster and has less interference with the process environment -
for example no new mount namespaces have to be created and no file
descriptor inheritance is necessary to wait for the end of a process
tree. See also:
[shell-integration](./README-shell-integration.md#limitations). <br>
If both backends are installed you may configure the default one globally
by creating the file `/etc/shournal.d/backend` or for each user by creating
`~/.config/shournal/backend` with content `ko` or `fanotify`.
## Disk-space - get rid of obsolete file-events
Depending on the file-activity of the observed commands, shournal's
database will sooner or later grow. When you feel that enough time
has passed and want to get rid of old events, this can be done by e.g.
`shournal --delete --older-than 1y`
which deletes all commands (and file-events) older than one year.
More options are available, see also
`shournal --delete --help`
## Remote file-systems
* *shournal* is able to monitor file events of specific processes (PID's).
Therefore, remote filesystems such as NFS or sshfs can be observed as
long as *shournal* runs on the same (virtual) machine as the observed
process. Consequently file events *another kernel* performs are lost.
* For sshfs in case of the *fanotify* backend it is necessary,
to add ```-o allow_root``` to the sshfs-options,
otherwise permission errors during ```fanotify_mark``` are raised.
See also: https://serverfault.com/a/188896
## Security
### kernel-module backend
In the kernel module it is ensured that each user is only allowed to
monitor his/her own processes. Further, the kernel thread, which processes
file events, runs with effective caller credentials and checks
allowed accesses on a per-file basis. Memory allocations are cgroup-aware,
even for reading (in case of hashing) and writing (in case of logging)
files.
### fanotify backend
*shournal-run-fanotify* is a so called "setuid"-program: whenever a regular user calls it, it runs
with root-permissions in the first place. As soon as possible, it runs effectively with user
permissions though.
It must be setuid for two reaons:
* fanotify requires root for initializing, because it is in
principle able, to **forbid** a process to access a file. shournal does not make use
of this feature so this is not a real security concern.
* unsharing the *mount namespace* requires root, because setuid-programs *could* still refer
to seemingly obsolete mounts. This means that under awkward circumstances an unmount-event,
which has security-relevant consequences (e.g. mounting a new file to /etc/shadow) might not
propagate to processes which run in other mount namespaces.
To make sure mount-propagation applies, **all mounts, which carry setuid-binaries
or files they refer to, should be mounted *shared***, or no (security-relevant)
mount/unmount events should occur, after the first shournal-process started.
Shared mounts are the default in all recent distributions I know of.
See also
man 7 mount_namespaces and
[shared subtrees](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).
## Limitations
Processes can communicate via IPC (inter-process-communication).
If the observed process *A* instructs the **not** observed process *B*
via IPC to modify a file, the filesystem-event is not registered by
*shournal*.
For performance reasons, all files opened with write-permissions
are reported as *written* by shournal, irrespective of whether
the process actually wrote to it. By using file size and content (hash)
you should be able to cover those cases.
The provided timestamp is determined shortly after a file was
closed. Note that it is possible that some other process has
written to it in between. This however is only a
problem, if that other process was itself **not** observed.
Whether memory mapped (see mmap(2) ) file-events are reported correctly
depends on **when** the underlying file-descriptor is closed. It is thus
application dependent and does not work in general.
### Additional limitations of the fanotify backend
The file observation only works, if the process does not unshare the
mount-namespace itself, e.g. monitoring a program started
via *flatpak* fails.
For further limitations please visit the fanotify manpage.
## Known Issues
* on NFS-storages: file events are lost, if the user does not have
read-permissions while a file is closed.
Steps to reproduce:
- open a file readable for you on a NFS storage
- chmod it 000
- close it --> the event is lost
## How does it work?
shournal attempts to deterministically associate files and shell-
commands without changing the users workflow. Under Linux file operations are
performed by the kernel, tracing these operations thus requires OS-level support.
During the execution of a shell-command, shournal instruments the kernel to
trace files used by the shell-process and any of it’s descendant processes. More
particular, to keep the tracing-overhead low, only the closing of files is traced
and (meta-)data collection starts afterwards in an asynchronous manner.
**shournalk** as a kernel module runs directly in *kernel space* and is based on
[tracepoints](https://www.kernel.org/doc/html/latest/trace/tracepoints.html)
and the
[ftrace-framework](https://www.kernel.org/doc/Documentation/trace/ftrace.txt)
which basically allow for custom code to be run at certain kernel
execution paths without recompilation of the kernel itself. Only three
events are traced: closing of files, fork and exit. (Meta-)data collection
also takes place entirely in kernel space.
The **fanotify backend** employs the kernel-native
[fanotify filesystem API]( https://man7.org/linux/man-pages/man7/fanotify.7.html)
to register for close-events of whole
mount-points which are isolated against unrelated
processes using unshared
[mount namespaces](https://man7.org/linux/man-pages/man7/mount_namespaces.7.html).
shournal thereby ensures that all file-operations during the execution of a shell-
command refer to the same, unique mount namespace. While the process-filtering
takes place in kernel space — so only file-events of observed processes
are copied to user-space — the (meta-)data collection happens in user
space.
## Overhead
File tracing imposes a **runtime overhead**.
For a detailed performance evaluation please refer to our
[paper](https://doi.org/10.1038/s41598-024-53811-9) . In brief:
We measured the following command executions with shournal v2.9:
* compile elfutils-0.176
* git checkout — checkout the Linux kernel’s source code from v4.19 to v3.10.
* kernel copy — cp of the 4.19 Linux source.
The relative runtime-overheads are shown in below table,
strace is listed for comparison with ptrace-based solutions:
| Backend | compile | checkout | cp |
| ------------- | ------- | -------- | ----- |
| kernel module | 0.05% | 0.49% | 0.29% |
| fanotify | 1.2% | 1.3% | 6.2% |
| (strace) | 140% | 41% | 100% |
The benchmark involves tracing, (meta-)data collection and saving to
a binary temporary file. As this file can be kept indefinitely, the
final storing into the SQL-database is not part of the runtime-measurement.
For the `cp` benchmark, where ~120.000 file-events occurred
in ~4 seconds, the runtime overhead of the fanotify backend may become
noticeable. Note that many file-events in short time constitute a
worst-case. Where performance is critical, the kernel module backend
should be used.
The **storage overhead** largely depends on configuration, e.g. the number
of stored scripts and file-metadata is limited by default, to avoid e.g.
a backup-script from flooding the database. For the cp-test
the average disk-usage per file-event is approx. 174 bytes which already
includes indexes to speed up queries. So one GiB of disk-space is
sufficient for approx. 6 million events. Based on the experience of real-world
users the database is typically not larger than a few hundred megabytes
after months of usage.
## Credits
shournal makes use of great tools and libraries, most importantly the Qt-framework,
xxhash, tsl::ordered_map and cmake and also the Linux-Kernel's *fanotify*.
For the html-plot d3js, jquery, popper.js, bootstrap, webpack
and others are used.
Thanks to the developers!
The project arose in the Hoffmann Research
Group: Computational Biology of Aging
at the Fritz Lipmann Institute in Jena (Germany).
Special thanks to
Steve Hoffmann
and Konstantin Riege - without you this project
couldn't have been accomplished.
# License
The whole project is licensed under the GPL, v3 or later
(see LICENSE file for details) <br>
**except**
* The kernel module within `kernel/` which is licensed under
the GNU General Public License version 2 only.
* The libraries within
`extern/` → Please refer to the licenses within their
respective directories.
* The javascript-libraries in the auto-generated
`html-export/dist/main.js` → the licenses are
stored in `html-export/dist/main.licenses.txt`.
Copyleft (C) 2021, Tycho Kirchner
================================================
FILE: cmake/FindShournalUtil.cmake
================================================
# Join a list of strings using seperator sep
# and store the output in result.
function(JOIN vals sep result)
string (REGEX REPLACE "([^\\]|^);" "\\1${sep}" _tmp_str "${vals}")
string (REGEX REPLACE "[\\](.)" "\\1" _tmp_str "${_tmp_str}")
set (${result} "${_tmp_str}" PARENT_SCOPE)
endfunction()
================================================
FILE: extern/folly/LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Files in folly/external/farmhash licensed as follows
Copyright (c) 2014 Google, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: extern/folly/README.md
================================================
Folly: Facebook Open-source Library
-----------------------------------
[](https://travis-ci.org/facebook/folly)
### What is `folly`?
Folly (acronymed loosely after Facebook Open Source Library) is a
library of C++14 components designed with practicality and efficiency
in mind. **Folly contains a variety of core library components used extensively
at Facebook**. In particular, it's often a dependency of Facebook's other
open source C++ efforts and place where those projects can share code.
It complements (as opposed to competing against) offerings
such as Boost and of course `std`. In fact, we embark on defining our
own component only when something we need is either not available, or
does not meet the needed performance profile. We endeavor to remove
things from folly if or when `std` or Boost obsoletes them.
Performance concerns permeate much of Folly, sometimes leading to
designs that are more idiosyncratic than they would otherwise be (see
e.g. `PackedSyncPtr.h`, `SmallLocks.h`). Good performance at large
scale is a unifying theme in all of Folly.
### Logical Design
Folly is a collection of relatively independent components, some as
simple as a few symbols. There is no restriction on internal
dependencies, meaning that a given folly module may use any other
folly components.
All symbols are defined in the top-level namespace `folly`, except of
course macros. Macro names are ALL_UPPERCASE and should be prefixed
with `FOLLY_`. Namespace `folly` defines other internal namespaces
such as `internal` or `detail`. User code should not depend on symbols
in those namespaces.
Folly has an `experimental` directory as well. This designation connotes
primarily that we feel the API may change heavily over time. This code,
typically, is still in heavy use and is well tested.
### Physical Design
At the top level Folly uses the classic "stuttering" scheme
`folly/folly` used by Boost and others. The first directory serves as
an installation root of the library (with possible versioning a la
`folly-1.0/`), and the second is to distinguish the library when
including files, e.g. `#include <folly/FBString.h>`.
The directory structure is flat (mimicking the namespace structure),
i.e. we don't have an elaborate directory hierarchy (it is possible
this will change in future versions). The subdirectory `experimental`
contains files that are used inside folly and possibly at Facebook but
not considered stable enough for client use. Your code should not use
files in `folly/experimental` lest it may break when you update Folly.
The `folly/folly/test` subdirectory includes the unittests for all
components, usually named `ComponentXyzTest.cpp` for each
`ComponentXyz.*`. The `folly/folly/docs` directory contains
documentation.
### What's in it?
Because of folly's fairly flat structure, the best way to see what's in it
is to look at the headers in [top level `folly/` directory](https://github.com/facebook/folly/tree/master/folly). You can also
check the [`docs` folder](folly/docs) for documentation, starting with the
[overview](folly/docs/Overview.md).
Folly is published on GitHub at https://github.com/facebook/folly
### Build Notes
#### Dependencies
folly supports gcc (5.1+), clang, or MSVC. It should run on Linux (x86-32,
x86-64, and ARM), iOS, macOS, and Windows (x86-64). The CMake build is only
tested on some of these platforms; at a minimum, we aim to support macOS and
Linux (on the latest Ubuntu LTS release or newer.)
folly requires a version of boost compiled with C++14 support.
googletest is required to build and run folly's tests. You can download
it from https://github.com/google/googletest/archive/release-1.8.0.tar.gz
The following commands can be used to download and install it:
```
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz && \
tar zxf release-1.8.0.tar.gz && \
rm -f release-1.8.0.tar.gz && \
cd googletest-release-1.8.0 && \
cmake . && \
make && \
make install
```
#### Finding dependencies in non-default locations
If you have boost, gtest, or other dependencies installed in a non-default
location, you can use the `CMAKE_INCLUDE_PATH` and `CMAKE_LIBRARY_PATH`
variables to make CMAKE look also look for header files and libraries in
non-standard locations. For example, to also search the directories
`/alt/include/path1` and `/alt/include/path2` for header files and the
directories `/alt/lib/path1` and `/alt/lib/path2` for libraries, you can invoke
`cmake` as follows:
```
cmake \
-DCMAKE_INCLUDE_PATH=/alt/include/path1:/alt/include/path2 \
-DCMAKE_LIBRARY_PATH=/alt/lib/path1:/alt/lib/path2 ...
```
#### Building tests
By default, building the tests is disabled as part of the CMake `all` target.
To build the tests, specify `-DBUILD_TESTS=ON` to CMake at configure time.
#### Ubuntu 16.04 LTS
The following packages are required (feel free to cut and paste the apt-get
command below):
```
sudo apt-get install \
g++ \
cmake \
libboost-all-dev \
libevent-dev \
libdouble-conversion-dev \
libgoogle-glog-dev \
libgflags-dev \
libiberty-dev \
liblz4-dev \
liblzma-dev \
libsnappy-dev \
make \
zlib1g-dev \
binutils-dev \
libjemalloc-dev \
libssl-dev \
pkg-config \
libunwind-dev
```
Folly relies on [fmt](https://github.com/fmtlib/fmt) which needs to be installed from source.
The following commands will download, compile, and install fmt.
```
git clone https://github.com/fmtlib/fmt.git && cd fmt
mkdir _build && cd _build
cmake ..
make -j$(nproc)
sudo make install
```
If advanced debugging functionality is required, use:
```
sudo apt-get install \
libunwind8-dev \
libelf-dev \
libdwarf-dev
```
In the folly directory (e.g. the checkout root or the archive unpack root), run:
```
mkdir _build && cd _build
cmake ..
make -j $(nproc)
make install # with either sudo or DESTDIR as necessary
```
#### OS X (Homebrew)
folly is available as a Formula and releases may be built via `brew install folly`.
You may also use `folly/build/bootstrap-osx-homebrew.sh` to build against `master`:
```
./folly/build/bootstrap-osx-homebrew.sh
```
This will create a build directory `_build` in the top-level.
#### OS X (MacPorts)
Install the required packages from MacPorts:
```
sudo port install \
boost \
cmake \
gflags \
git \
google-glog \
libevent \
libtool \
lz4 \
lzma \
openssl \
snappy \
xz \
zlib
```
Download and install double-conversion:
```
git clone https://github.com/google/double-conversion.git
cd double-conversion
cmake -DBUILD_SHARED_LIBS=ON .
make
sudo make install
```
Download and install folly with the parameters listed below:
```
git clone https://github.com/facebook/folly.git
cd folly
mkdir _build
cd _build
cmake ..
make
sudo make install
```
#### Windows (Vcpkg)
folly is available in [Vcpkg](https://github.com/Microsoft/vcpkg#vcpkg) and releases may be built via `vcpkg install folly:x64-windows`.
You may also use `vcpkg install folly:x64-windows --head` to build against `master`.
#### Other Linux distributions
- double-conversion (https://github.com/google/double-conversion)
Download and build double-conversion.
You may need to tell cmake where to find it.
[double-conversion/] `ln -s src double-conversion`
[folly/] `mkdir build && cd build`
[folly/build/] `cmake "-DCMAKE_INCLUDE_PATH=$DOUBLE_CONVERSION_HOME/include" "-DCMAKE_LIBRARY_PATH=$DOUBLE_CONVERSION_HOME/lib" ..`
[folly/build/] `make`
- additional platform specific dependencies:
Fedora >= 21 64-bit (last tested on Fedora 28 64-bit)
- gcc
- gcc-c++
- cmake
- automake
- boost-devel
- libtool
- lz4-devel
- lzma-devel
- snappy-devel
- zlib-devel
- glog-devel
- gflags-devel
- scons
- double-conversion-devel
- openssl-devel
- libevent-devel
- fmt-devel
- libsodium-devel
Optional
- libdwarf-devel
- elfutils-libelf-devel
- libunwind-devel
================================================
FILE: extern/folly/UninitializedMemoryHacks.h
================================================
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <string>
#include <type_traits>
#include <vector>
namespace {
// This struct is different in every translation unit. We use template
// instantiations to define inline freestanding methods. Since the
// methods are inline it is fine to define them in multiple translation
// units, but the instantiation itself would be an ODR violation if it is
// present in the program more than once. By tagging the instantiations
// with this struct, we avoid ODR problems for the instantiation while
// allowing the resulting methods to be inline-able. If you think that
// seems hacky keep reading...
struct FollyMemoryDetailTranslationUnitTag {};
} // namespace
namespace folly {
namespace detail {
template <typename T>
void unsafeStringSetLargerSize(std::basic_string<T>& s, std::size_t n);
template <typename T>
void unsafeVectorSetLargerSize(std::vector<T>& v, std::size_t n);
} // namespace detail
/*
* This file provides helper functions resizeWithoutInitialization()
* that can resize std::basic_string or std::vector without constructing
* or initializing new elements.
*
* IMPORTANT: These functions can be unsafe if used improperly. If you
* don't write to an element with index >= oldSize and < newSize, reading
* the element can expose arbitrary memory contents to the world, including
* the contents of old strings. If you're lucky you'll get a segfault,
* because the kernel is only required to fault in new pages on write
* access. MSAN should be able to catch problems in the common case that
* the string or vector wasn't previously shrunk.
*
* Pay extra attention to your failure paths. For example, if you try
* to read directly into a caller-provided string, make sure to clear
* the string when you get an I/O error.
*
* You should only use this if you have profiling data from production
* that shows that this is not a premature optimization. This code is
* designed for retroactively optimizing code where touching every element
* twice (or touching never-used elements once) shows up in profiling,
* and where restructuring the code to use fixed-length arrays or IOBuf-s
* would be difficult.
*
* NOTE: Just because .resize() shows up in your profile (probably
* via one of the intrinsic memset implementations) doesn't mean that
* these functions will make your program faster. A lot of the cost
* of memset comes from cache misses, so avoiding the memset can mean
* that the cache miss cost just gets pushed to the following code.
* resizeWithoutInitialization can be a win when the contents are bigger
* than a cache level, because the second access isn't free in that case.
* It can be a win when the memory is already cached, so touching it
* doesn't help later code. It can also be a win if the final length
* of the string or vector isn't actually known, so the suffix will be
* chopped off with a second call to .resize().
*/
/**
* Like calling s.resize(n), but when growing the string does not
* initialize new elements. It is undefined behavior to read from
* any element added to the string by this method unless it has been
* written to by an operation that follows this call.
*
* Use the FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(T) macro to
* declare (and inline define) the internals required to call
* resizeWithoutInitialization for a std::basic_string<T>.
* See detailed description of a similar macro for std::vector<T> below.
*
* IMPORTANT: Read the warning at the top of this header file.
*/
template <
typename T,
typename =
typename std::enable_if<std::is_trivially_destructible<T>::value>::type>
inline void resizeWithoutInitialization(
std::basic_string<T>& s,
std::size_t n) {
if (n <= s.size()) {
s.resize(n);
} else {
// careful not to call reserve unless necessary, as it causes
// shrink_to_fit on many platforms
if (n > s.capacity()) {
s.reserve(n);
}
detail::unsafeStringSetLargerSize(s, n);
}
}
/**
* Like calling v.resize(n), but when growing the vector does not construct
* or initialize new elements. It is undefined behavior to read from any
* element added to the vector by this method unless it has been written
* to by an operation that follows this call.
*
* Use the FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(T) macro to
* declare (and inline define) the internals required to call
* resizeWithoutInitialization for a std::vector<T>. This must
* be done exactly once in each translation unit that wants to call
* resizeWithoutInitialization(std::vector<T>&,size_t). char and unsigned
* char are provided by default. If you don't do this you will get linker
* errors about folly::detail::unsafeVectorSetLargerSize. Requiring that
* T be trivially_destructible is only an approximation of the property
* required of T. In fact what is required is that any random sequence of
* bytes may be safely reinterpreted as a T and passed to T's destructor.
*
* std::vector<bool> has specialized internals and is not supported.
*
* IMPORTANT: Read the warning at the top of this header file.
*/
template <
typename T,
typename = typename std::enable_if<
std::is_trivially_destructible<T>::value &&
!std::is_same<T, bool>::value>::type>
void resizeWithoutInitialization(std::vector<T>& v, std::size_t n) {
if (n <= v.size()) {
v.resize(n);
} else {
if (n > v.capacity()) {
v.reserve(n);
}
detail::unsafeVectorSetLargerSize(v, n);
}
}
namespace detail {
// This machinery bridges template expansion and macro expansion
#define FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT_IMPL(TYPE) \
namespace folly { \
namespace detail { \
void unsafeStringSetLargerSizeImpl(std::basic_string<TYPE>& s, std::size_t); \
template <> \
inline void unsafeStringSetLargerSize<TYPE>( \
std::basic_string<TYPE> & s, \
std::size_t n) { \
unsafeStringSetLargerSizeImpl(s, n); \
} \
} \
}
#if defined(_LIBCPP_STRING)
// libc++
template <typename Tag, typename T, typename A, A Ptr__set_size>
struct MakeUnsafeStringSetLargerSize {
friend void unsafeStringSetLargerSizeImpl(
std::basic_string<T>& s,
std::size_t n) {
// s.__set_size(n);
(s.*Ptr__set_size)(n);
(&s[0])[n] = '\0';
}
};
#define FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(TYPE) \
template void std::basic_string<TYPE>::__set_size(std::size_t); \
template struct folly::detail::MakeUnsafeStringSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
void (std::basic_string<TYPE>::*)(std::size_t), \
&std::basic_string<TYPE>::__set_size>; \
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_GLIBCXX_STRING) && _GLIBCXX_USE_CXX11_ABI
// libstdc++ new implementation with SSO
template <typename Tag, typename T, typename A, A Ptr_M_set_length>
struct MakeUnsafeStringSetLargerSize {
friend void unsafeStringSetLargerSizeImpl(
std::basic_string<T>& s,
std::size_t n) {
// s._M_set_length(n);
(s.*Ptr_M_set_length)(n);
}
};
#define FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(TYPE) \
template void std::basic_string<TYPE>::_M_set_length(std::size_t); \
template struct folly::detail::MakeUnsafeStringSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
void (std::basic_string<TYPE>::*)(std::size_t), \
&std::basic_string<TYPE>::_M_set_length>; \
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_GLIBCXX_STRING)
// libstdc++ old implementation
template <
typename Tag,
typename T,
typename A,
A Ptr_M_rep,
typename B,
B Ptr_M_set_length_and_sharable>
struct MakeUnsafeStringSetLargerSize {
friend void unsafeStringSetLargerSizeImpl(
std::basic_string<T>& s,
std::size_t n) {
// s._M_rep()->_M_set_length_and_sharable(n);
auto rep = (s.*Ptr_M_rep)();
(rep->*Ptr_M_set_length_and_sharable)(n);
}
};
#define FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(TYPE) \
template std::basic_string<TYPE>::_Rep* std::basic_string<TYPE>::_M_rep() \
const; \
template void std::basic_string<TYPE>::_Rep::_M_set_length_and_sharable( \
std::size_t); \
template struct folly::detail::MakeUnsafeStringSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
std::basic_string<TYPE>::_Rep* (std::basic_string<TYPE>::*)() const, \
&std::basic_string<TYPE>::_M_rep, \
void (std::basic_string<TYPE>::_Rep::*)(std::size_t), \
&std::basic_string<TYPE>::_Rep::_M_set_length_and_sharable>; \
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_MSC_VER)
// MSVC
template <typename Tag, typename T, typename A, A Ptr_Eos>
struct MakeUnsafeStringSetLargerSize {
friend void unsafeStringSetLargerSizeImpl(
std::basic_string<T>& s,
std::size_t n) {
// _Eos method is public for _MSC_VER <= 1916, private after
// s._Eos(n);
(s.*Ptr_Eos)(n);
}
};
#define FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(TYPE) \
template void std::basic_string<TYPE>::_Eos(std::size_t); \
template struct folly::detail::MakeUnsafeStringSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
void (std::basic_string<TYPE>::*)(std::size_t), \
&std::basic_string<TYPE>::_Eos>; \
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#else
#warning \
"No implementation for resizeWithoutInitialization of std::basic_string"
#endif
} // namespace detail
} // namespace folly
#if defined(FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT)
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(char)
FOLLY_DECLARE_STRING_RESIZE_WITHOUT_INIT(wchar_t)
#endif
namespace folly {
namespace detail {
// This machinery bridges template expansion and macro expansion
#define FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT_IMPL(TYPE) \
namespace folly { \
namespace detail { \
void unsafeVectorSetLargerSizeImpl(std::vector<TYPE>& v, std::size_t); \
template <> \
inline void unsafeVectorSetLargerSize<TYPE>( \
std::vector<TYPE> & v, \
std::size_t n) { \
unsafeVectorSetLargerSizeImpl(v, n); \
} \
} \
}
#if defined(_LIBCPP_VECTOR)
// libc++
template <
typename Tag,
typename T,
typename A,
A Ptr__end_,
typename B,
B Ptr__annotate_contiguous_container_>
struct MakeUnsafeVectorSetLargerSize {
friend void unsafeVectorSetLargerSizeImpl(std::vector<T>& v, std::size_t n) {
// v.__end_ += (n - v.size());
using Base = std::__vector_base<T, std::allocator<T>>;
static_assert(
std::is_standard_layout<std::vector<T>>::value &&
sizeof(std::vector<T>) == sizeof(Base),
"reinterpret_cast safety conditions not met");
const auto old_size = v.size();
reinterpret_cast<Base&>(v).*Ptr__end_ += (n - v.size());
// libc++ contiguous containers use special annotation functions that help
// the address sanitizer to detect improper memory accesses. When ASAN is
// enabled we need to call the appropriate annotation functions in order to
// stop ASAN from reporting false positives. When ASAN is disabled, the
// annotation function is a no-op.
(v.*Ptr__annotate_contiguous_container_)(
v.data(),
v.data() + v.capacity(),
v.data() + old_size,
v.data() + v.size());
}
};
#define FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(TYPE) \
template struct folly::detail::MakeUnsafeVectorSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
TYPE*(std::__vector_base<TYPE, std::allocator<TYPE>>::*), \
&std::vector<TYPE>::__end_, \
void (std::vector<TYPE>::*)( \
const void*, const void*, const void*, const void*) const, \
&std::vector<TYPE>::__annotate_contiguous_container>; \
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_GLIBCXX_VECTOR)
// libstdc++
template <
typename Tag,
typename T,
typename A,
A Ptr_M_impl,
typename B,
B Ptr_M_finish>
struct MakeUnsafeVectorSetLargerSize : std::vector<T> {
friend void unsafeVectorSetLargerSizeImpl(std::vector<T>& v, std::size_t n) {
// v._M_impl._M_finish += (n - v.size());
(v.*Ptr_M_impl).*Ptr_M_finish += (n - v.size());
}
};
#define FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(TYPE) \
template struct folly::detail::MakeUnsafeVectorSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
decltype(&std::vector<TYPE>::_M_impl), \
&std::vector<TYPE>::_M_impl, \
decltype(&std::vector<TYPE>::_Vector_impl::_M_finish), \
&std::vector<TYPE>::_Vector_impl::_M_finish>; \
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_MSC_VER) && _MSC_VER <= 1916
// MSVC <= VS2017
template <typename Tag, typename T>
struct MakeUnsafeVectorSetLargerSize : std::vector<T> {
friend void unsafeVectorSetLargerSizeImpl(std::vector<T>& v, std::size_t n) {
v._Mylast() += (n - v.size());
}
};
#define FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(TYPE) \
template struct folly::detail::MakeUnsafeVectorSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE>; \
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#elif defined(_MSC_VER) && _MSC_VER > 1916
// MSVC >= VS2019
template <
typename Tag,
typename T,
typename A,
A Ptr_Mypair,
typename B,
B Ptr_Myval2,
typename C,
C Ptr_Mylast>
struct MakeUnsafeVectorSetLargerSize : std::vector<T> {
friend void unsafeVectorSetLargerSizeImpl(std::vector<T>& v, std::size_t n) {
// v._Mypair._Myval2._Mylast += (n - v.size());
((v.*Ptr_Mypair).*Ptr_Myval2).*Ptr_Mylast += (n - v.size());
}
};
#define FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(TYPE) \
template struct folly::detail::MakeUnsafeVectorSetLargerSize< \
FollyMemoryDetailTranslationUnitTag, \
TYPE, \
decltype(&std::vector<TYPE>::_Mypair), \
&std::vector<TYPE>::_Mypair, \
decltype(&decltype(std::declval<std::vector<TYPE>>()._Mypair)::_Myval2), \
&decltype(std::declval<std::vector<TYPE>>()._Mypair)::_Myval2, \
decltype(&decltype( \
std::declval<std::vector<TYPE>>()._Mypair._Myval2)::_Mylast), \
&decltype(std::declval<std::vector<TYPE>>()._Mypair._Myval2)::_Mylast>; \
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT_IMPL(TYPE)
#else
#warning "No implementation for resizeWithoutInitialization of std::vector"
#endif
} // namespace detail
} // namespace folly
#if defined(FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT)
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(char)
FOLLY_DECLARE_VECTOR_RESIZE_WITHOUT_INIT(unsigned char)
#endif
================================================
FILE: extern/tsl-ordered-map/CMakeLists.txt
================================================
add_library(lib_orderedmap
ordered_hash.h
ordered_map.h
ordered_set.h
)
set_target_properties(lib_orderedmap PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(lib_orderedmap
Qt5::Core
)
================================================
FILE: extern/tsl-ordered-map/LICENSE
================================================
MIT License
Copyright (c) 2017 Tessil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: extern/tsl-ordered-map/ordered_hash.h
================================================
/**
* MIT License
*
* Copyright (c) 2017 Tessil
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TSL_ORDERED_HASH_H
#define TSL_ORDERED_HASH_H
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <exception>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <stdexcept>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
/**
* Macros for compatibility with GCC 4.8
*/
#if (defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 9))
# define TSL_OH_NO_CONTAINER_ERASE_CONST_ITERATOR
# define TSL_OH_NO_CONTAINER_EMPLACE_CONST_ITERATOR
#endif
/**
* Only activate tsl_oh_assert if TSL_DEBUG is defined.
* This way we avoid the performance hit when NDEBUG is not defined with assert as tsl_oh_assert is used a lot
* (people usually compile with "-O3" and not "-O3 -DNDEBUG").
*/
#ifdef TSL_DEBUG
# define tsl_oh_assert(expr) assert(expr)
#else
# define tsl_oh_assert(expr) (static_cast<void>(0))
#endif
/**
* If exceptions are enabled, throw the exception passed in parameter, otherwise call std::terminate.
*/
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (defined (_MSC_VER) && defined (_CPPUNWIND))) && !defined(TSL_NO_EXCEPTIONS)
# define TSL_OH_THROW_OR_TERMINATE(ex, msg) throw ex(msg)
#else
# define TSL_OH_NO_EXCEPTIONS
# ifdef NDEBUG
# define TSL_OH_THROW_OR_TERMINATE(ex, msg) std::terminate()
# else
# include <iostream>
# define TSL_OH_THROW_OR_TERMINATE(ex, msg) do { std::cerr << msg << std::endl; std::terminate(); } while(0)
# endif
#endif
namespace tsl {
namespace detail_ordered_hash {
template<typename T>
struct make_void {
using type = void;
};
template<typename T, typename = void>
struct has_is_transparent: std::false_type {
};
template<typename T>
struct has_is_transparent<T, typename make_void<typename T::is_transparent>::type>: std::true_type {
};
template<typename T, typename = void>
struct is_vector: std::false_type {
};
template<typename T>
struct is_vector<T, typename std::enable_if<
std::is_same<T, std::vector<typename T::value_type, typename T::allocator_type>>::value
>::type>: std::true_type {
};
template<typename T, typename U>
static T numeric_cast(U value, const char* error_message = "numeric_cast() failed.") {
T ret = static_cast<T>(value);
if(static_cast<U>(ret) != value) {
TSL_OH_THROW_OR_TERMINATE(std::runtime_error, error_message);
}
const bool is_same_signedness = (std::is_unsigned<T>::value && std::is_unsigned<U>::value) ||
(std::is_signed<T>::value && std::is_signed<U>::value);
if(!is_same_signedness && (ret < T{}) != (value < U{})) {
TSL_OH_THROW_OR_TERMINATE(std::runtime_error, error_message);
}
return ret;
}
/**
* Fixed size type used to represent size_type values on serialization. Need to be big enough
* to represent a std::size_t on 32 and 64 bits platforms, and must be the same size on both platforms.
*/
using slz_size_type = std::uint64_t;
static_assert(std::numeric_limits<slz_size_type>::max() >= std::numeric_limits<std::size_t>::max(),
"slz_size_type must be >= std::size_t");
template<class T, class Deserializer>
static T deserialize_value(Deserializer& deserializer) {
// MSVC < 2017 is not conformant, circumvent the problem by removing the template keyword
#if defined (_MSC_VER) && _MSC_VER < 1910
return deserializer.Deserializer::operator()<T>();
#else
return deserializer.Deserializer::template operator()<T>();
#endif
}
/**
* Each bucket entry stores an index which is the index in m_values corresponding to the bucket's value
* and a hash (which may be truncated to 32 bits depending on IndexType) corresponding to the hash of the value.
*
* The size of IndexType limits the size of the hash table to std::numeric_limits<IndexType>::max() - 1 elements (-1 due to
* a reserved value used to mark a bucket as empty).
*/
template<class IndexType>
class bucket_entry {
static_assert(std::is_unsigned<IndexType>::value, "IndexType must be an unsigned value.");
static_assert(std::numeric_limits<IndexType>::max() <= std::numeric_limits<std::size_t>::max(),
"std::numeric_limits<IndexType>::max() must be <= std::numeric_limits<std::size_t>::max().");
public:
using index_type = IndexType;
using truncated_hash_type = typename std::conditional<std::numeric_limits<IndexType>::max() <=
std::numeric_limits<std::uint_least32_t>::max(),
std::uint_least32_t,
std::size_t>::type;
bucket_entry() noexcept: m_index(EMPTY_MARKER_INDEX), m_hash(0) {
}
bool empty() const noexcept {
return m_index == EMPTY_MARKER_INDEX;
}
void clear() noexcept {
m_index = EMPTY_MARKER_INDEX;
}
index_type index() const noexcept {
tsl_oh_assert(!empty());
return m_index;
}
index_type& index_ref() noexcept {
tsl_oh_assert(!empty());
return m_index;
}
void set_index(index_type index) noexcept {
tsl_oh_assert(index <= max_size());
m_index = index;
}
truncated_hash_type truncated_hash() const noexcept {
tsl_oh_assert(!empty());
return m_hash;
}
truncated_hash_type& truncated_hash_ref() noexcept {
tsl_oh_assert(!empty());
return m_hash;
}
void set_hash(std::size_t hash) noexcept {
m_hash = truncate_hash(hash);
}
template<class Serializer>
void serialize(Serializer& serializer) const {
const slz_size_type index = m_index;
serializer(index);
const slz_size_type hash = m_hash;
serializer(hash);
}
template<class Deserializer>
static bucket_entry deserialize(Deserializer& deserializer) {
const slz_size_type index = deserialize_value<slz_size_type>(deserializer);
const slz_size_type hash = deserialize_value<slz_size_type>(deserializer);
bucket_entry bentry;
bentry.m_index = numeric_cast<index_type>(index, "Deserialized index is too big.");
bentry.m_hash = numeric_cast<truncated_hash_type>(hash, "Deserialized hash is too big.");
return bentry;
}
static truncated_hash_type truncate_hash(std::size_t hash) noexcept {
return truncated_hash_type(hash);
}
static std::size_t max_size() noexcept {
return static_cast<std::size_t>(std::numeric_limits<index_type>::max()) - NB_RESERVED_INDEXES;
}
private:
static const index_type EMPTY_MARKER_INDEX = std::numeric_limits<index_type>::max();
static const std::size_t NB_RESERVED_INDEXES = 1;
index_type m_index;
truncated_hash_type m_hash;
};
/**
* Internal common class used by ordered_map and ordered_set.
*
* ValueType is what will be stored by ordered_hash (usually std::pair<Key, T> for map and Key for set).
*
* KeySelect should be a FunctionObject which takes a ValueType in parameter and return a reference to the key.
*
* ValueSelect should be a FunctionObject which takes a ValueType in parameter and return a reference to the value.
* ValueSelect should be void if there is no value (in set for example).
*
* ValueTypeContainer is the container which will be used to store ValueType values.
* Usually a std::deque<ValueType, Allocator> or std::vector<ValueType, Allocator>.
*
*
*
* The orderd_hash structure is a hash table which preserves the order of insertion of the elements.
* To do so, it stores the values in the ValueTypeContainer (m_values) using emplace_back at each
* insertion of a new element. Another structure (m_buckets of type std::vector<bucket_entry>) will
* serve as buckets array for the hash table part. Each bucket stores an index which corresponds to
* the index in m_values where the bucket's value is and the (truncated) hash of this value. An index
* is used instead of a pointer to the value to reduce the size of each bucket entry.
*
* To resolve collisions in the buckets array, the structures use robin hood linear probing with
* backward shift deletion.
*/
template<class ValueType,
class KeySelect,
class ValueSelect,
class Hash,
class KeyEqual,
class Allocator,
class ValueTypeContainer,
class IndexType>
class ordered_hash: private Hash, private KeyEqual {
private:
template<typename U>
using has_mapped_type = typename std::integral_constant<bool, !std::is_same<U, void>::value>;
static_assert(std::is_same<typename ValueTypeContainer::value_type, ValueType>::value,
"ValueTypeContainer::value_type != ValueType. "
"Check that the ValueTypeContainer has 'Key' as type for a set or 'std::pair<Key, T>' as type for a map.");
static_assert(std::is_same<typename ValueTypeContainer::allocator_type, Allocator>::value,
"ValueTypeContainer::allocator_type != Allocator. "
"Check that the allocator for ValueTypeContainer is the same as Allocator.");
static_assert(std::is_same<typename Allocator::value_type, ValueType>::value,
"Allocator::value_type != ValueType. "
"Check that the allocator has 'Key' as type for a set or 'std::pair<Key, T>' as type for a map.");
public:
template<bool IsConst>
class ordered_iterator;
using key_type = typename KeySelect::key_type;
using value_type = ValueType;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using hasher = Hash;
using key_equal = KeyEqual;
using allocator_type = Allocator;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using iterator = ordered_iterator<false>;
using const_iterator = ordered_iterator<true>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using values_container_type = ValueTypeContainer;
public:
template<bool IsConst>
class ordered_iterator {
friend class ordered_hash;
private:
using iterator = typename std::conditional<IsConst,
typename values_container_type::const_iterator,
typename values_container_type::iterator>::type;
ordered_iterator(iterator it) noexcept: m_iterator(it) {
}
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = const typename ordered_hash::value_type;
using difference_type = typename iterator::difference_type;
using reference = value_type&;
using pointer = value_type*;
ordered_iterator() noexcept {
}
// Copy constructor from iterator to const_iterator.
template<bool TIsConst = IsConst, typename std::enable_if<TIsConst>::type* = nullptr>
ordered_iterator(const ordered_iterator<!TIsConst>& other) noexcept: m_iterator(other.m_iterator) {
}
ordered_iterator(const ordered_iterator& other) = default;
ordered_iterator(ordered_iterator&& other) = default;
ordered_iterator& operator=(const ordered_iterator& other) = default;
ordered_iterator& operator=(ordered_iterator&& other) = default;
const typename ordered_hash::key_type& key() const {
return KeySelect()(*m_iterator);
}
template<class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value && IsConst>::type* = nullptr>
const typename U::value_type& value() const {
return U()(*m_iterator);
}
template<class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value && !IsConst>::type* = nullptr>
typename U::value_type& value() {
return U()(*m_iterator);
}
reference operator*() const { return *m_iterator; }
pointer operator->() const { return m_iterator.operator->(); }
ordered_iterator& operator++() { ++m_iterator; return *this; }
ordered_iterator& operator--() { --m_iterator; return *this; }
ordered_iterator operator++(int) { ordered_iterator tmp(*this); ++(*this); return tmp; }
ordered_iterator operator--(int) { ordered_iterator tmp(*this); --(*this); return tmp; }
reference operator[](difference_type n) const { return m_iterator[n]; }
ordered_iterator& operator+=(difference_type n) { m_iterator += n; return *this; }
ordered_iterator& operator-=(difference_type n) { m_iterator -= n; return *this; }
ordered_iterator operator+(difference_type n) { ordered_iterator tmp(*this); tmp += n; return tmp; }
ordered_iterator operator-(difference_type n) { ordered_iterator tmp(*this); tmp -= n; return tmp; }
friend bool operator==(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator == rhs.m_iterator;
}
friend bool operator!=(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator != rhs.m_iterator;
}
friend bool operator<(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator < rhs.m_iterator;
}
friend bool operator>(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator > rhs.m_iterator;
}
friend bool operator<=(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator <= rhs.m_iterator;
}
friend bool operator>=(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator >= rhs.m_iterator;
}
friend ordered_iterator operator+(difference_type n, const ordered_iterator& it) {
return n + it.m_iterator;
}
friend difference_type operator-(const ordered_iterator& lhs, const ordered_iterator& rhs) {
return lhs.m_iterator - rhs.m_iterator;
}
private:
iterator m_iterator;
};
private:
using bucket_entry = tsl::detail_ordered_hash::bucket_entry<IndexType>;
using buckets_container_allocator = typename
std::allocator_traits<allocator_type>::template rebind_alloc<bucket_entry>;
using buckets_container_type = std::vector<bucket_entry, buckets_container_allocator>;
using truncated_hash_type = typename bucket_entry::truncated_hash_type;
using index_type = typename bucket_entry::index_type;
public:
ordered_hash(size_type bucket_count,
const Hash& hash,
const KeyEqual& equal,
const Allocator& alloc,
float max_load_factor): Hash(hash),
KeyEqual(equal),
m_buckets_data(alloc),
m_buckets(static_empty_bucket_ptr()),
m_mask(0),
m_values(alloc),
m_grow_on_next_insert(false)
{
if(bucket_count > max_bucket_count()) {
TSL_OH_THROW_OR_TERMINATE(std::length_error, "The map exceeds its maxmimum size.");
}
if(bucket_count > 0) {
bucket_count = round_up_to_power_of_two(bucket_count);
m_buckets_data.resize(bucket_count);
m_buckets = m_buckets_data.data(),
m_mask = bucket_count - 1;
}
this->max_load_factor(max_load_factor);
}
ordered_hash(const ordered_hash& other): Hash(other),
KeyEqual(other),
m_buckets_data(other.m_buckets_data),
m_buckets(m_buckets_data.empty()?static_empty_bucket_ptr():
m_buckets_data.data()),
m_mask(other.m_mask),
m_values(other.m_values),
m_grow_on_next_insert(other.m_grow_on_next_insert),
m_max_load_factor(other.m_max_load_factor),
m_load_threshold(other.m_load_threshold)
{
}
ordered_hash(ordered_hash&& other) noexcept(std::is_nothrow_move_constructible<Hash>::value &&
std::is_nothrow_move_constructible<KeyEqual>::value &&
std::is_nothrow_move_constructible<buckets_container_type>::value &&
std::is_nothrow_move_constructible<values_container_type>::value)
: Hash(std::move(static_cast<Hash&>(other))),
KeyEqual(std::move(static_cast<KeyEqual&>(other))),
m_buckets_data(std::move(other.m_buckets_data)),
m_buckets(m_buckets_data.empty()?static_empty_bucket_ptr():
m_buckets_data.data()),
m_mask(other.m_mask),
m_values(std::move(other.m_values)),
m_grow_on_next_insert(other.m_grow_on_next_insert),
m_max_load_factor(other.m_max_load_factor),
m_load_threshold(other.m_load_threshold)
{
other.m_buckets_data.clear();
other.m_buckets = static_empty_bucket_ptr();
other.m_mask = 0;
other.m_values.clear();
other.m_grow_on_next_insert = false;
other.m_load_threshold = 0;
}
ordered_hash& operator=(const ordered_hash& other) {
if(&other != this) {
Hash::operator=(other);
KeyEqual::operator=(other);
m_buckets_data = other.m_buckets_data;
m_buckets = m_buckets_data.empty()?static_empty_bucket_ptr():
m_buckets_data.data();
m_mask = other.m_mask;
m_values = other.m_values;
m_grow_on_next_insert = other.m_grow_on_next_insert;
m_max_load_factor = other.m_max_load_factor;
m_load_threshold = other.m_load_threshold;
}
return *this;
}
ordered_hash& operator=(ordered_hash&& other) {
other.swap(*this);
other.clear();
return *this;
}
allocator_type get_allocator() const {
return m_values.get_allocator();
}
/*
* Iterators
*/
iterator begin() noexcept {
return iterator(m_values.begin());
}
const_iterator begin() const noexcept {
return cbegin();
}
const_iterator cbegin() const noexcept {
return const_iterator(m_values.cbegin());
}
iterator end() noexcept {
return iterator(m_values.end());
}
const_iterator end() const noexcept {
return cend();
}
const_iterator cend() const noexcept {
return const_iterator(m_values.cend());
}
reverse_iterator rbegin() noexcept {
return reverse_iterator(m_values.end());
}
const_reverse_iterator rbegin() const noexcept {
return rcbegin();
}
const_reverse_iterator rcbegin() const noexcept {
return const_reverse_iterator(m_values.cend());
}
reverse_iterator rend() noexcept {
return reverse_iterator(m_values.begin());
}
const_reverse_iterator rend() const noexcept {
return rcend();
}
const_reverse_iterator rcend() const noexcept {
return const_reverse_iterator(m_values.cbegin());
}
/*
* Capacity
*/
bool empty() const noexcept {
return m_values.empty();
}
size_type size() const noexcept {
return m_values.size();
}
size_type max_size() const noexcept {
return std::min(bucket_entry::max_size(), m_values.max_size());
}
/*
* Modifiers
*/
void clear() noexcept {
for(auto& bucket: m_buckets_data) {
bucket.clear();
}
m_values.clear();
m_grow_on_next_insert = false;
}
template<typename P>
std::pair<iterator, bool> insert(P&& value) {
return insert_impl(KeySelect()(value), std::forward<P>(value));
}
template<typename P>
iterator insert_hint(const_iterator hint, P&& value) {
if(hint != cend() && compare_keys(KeySelect()(*hint), KeySelect()(value))) {
return mutable_iterator(hint);
}
return insert(std::forward<P>(value)).first;
}
template<class InputIt>
void insert(InputIt first, InputIt last) {
if(std::is_base_of<std::forward_iterator_tag,
typename std::iterator_traits<InputIt>::iterator_category>::value)
{
const auto nb_elements_insert = std::distance(first, last);
const size_type nb_free_buckets = m_load_threshold - size();
tsl_oh_assert(m_load_threshold >= size());
if(nb_elements_insert > 0 && nb_free_buckets < size_type(nb_elements_insert)) {
reserve(size() + size_type(nb_elements_insert));
}
}
for(; first != last; ++first) {
insert(*first);
}
}
template<class K, class M>
std::pair<iterator, bool> insert_or_assign(K&& key, M&& value) {
auto it = try_emplace(std::forward<K>(key), std::forward<M>(value));
if(!it.second) {
it.first.value() = std::forward<M>(value);
}
return it;
}
template<class K, class M>
iterator insert_or_assign(const_iterator hint, K&& key, M&& obj) {
if(hint != cend() && compare_keys(KeySelect()(*hint), key)) {
auto it = mutable_iterator(hint);
it.value() = std::forward<M>(obj);
return it;
}
return insert_or_assign(std::forward<K>(key), std::forward<M>(obj)).first;
}
template<class... Args>
std::pair<iterator, bool> emplace(Args&&... args) {
return insert(value_type(std::forward<Args>(args)...));
}
template<class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) {
return insert_hint(hint, value_type(std::forward<Args>(args)...));
}
template<class K, class... Args>
std::pair<iterator, bool> try_emplace(K&& key, Args&&... value_args) {
return insert_impl(key, std::piecewise_construct,
std::forward_as_tuple(std::forward<K>(key)),
std::forward_as_tuple(std::forward<Args>(value_args)...));
}
template<class K, class... Args>
iterator try_emplace_hint(const_iterator hint, K&& key, Args&&... args) {
if(hint != cend() && compare_keys(KeySelect()(*hint), key)) {
return mutable_iterator(hint);
}
return try_emplace(std::forward<K>(key), std::forward<Args>(args)...).first;
}
/**
* Here to avoid `template<class K> size_type erase(const K& key)` being used when
* we use an `iterator` instead of a `const_iterator`.
*/
iterator erase(iterator pos) {
return erase(const_iterator(pos));
}
iterator erase(const_iterator pos) {
tsl_oh_assert(pos != cend());
const std::size_t index_erase = iterator_to_index(pos);
auto it_bucket = find_key(pos.key(), hash_key(pos.key()));
tsl_oh_assert(it_bucket != m_buckets_data.end());
erase_value_from_bucket(it_bucket);
/*
* One element was removed from m_values, due to the left shift the next element
* is now at the position of the previous element (or end if none).
*/
return begin() + index_erase;
}
iterator erase(const_iterator first, const_iterator last) {
if(first == last) {
return mutable_iterator(first);
}
tsl_oh_assert(std::distance(first, last) > 0);
const std::size_t start_index = iterator_to_index(first);
const std::size_t nb_values = std::size_t(std::distance(first, last));
const std::size_t end_index = start_index + nb_values;
// Delete all values
#ifdef TSL_OH_NO_CONTAINER_ERASE_CONST_ITERATOR
auto next_it = m_values.erase(mutable_iterator(first).m_iterator, mutable_iterator(last).m_iterator);
#else
auto next_it = m_values.erase(first.m_iterator, last.m_iterator);
#endif
/*
* Mark the buckets corresponding to the values as empty and do a backward shift.
*
* Also, the erase operation on m_values has shifted all the values on the right of last.m_iterator.
* Adapt the indexes for these values.
*/
std::size_t ibucket = 0;
while(ibucket < m_buckets_data.size()) {
if(m_buckets[ibucket].empty()) {
ibucket++;
}
else if(m_buckets[ibucket].index() >= start_index && m_buckets[ibucket].index() < end_index) {
m_buckets[ibucket].clear();
backward_shift(ibucket);
// Don't increment ibucket, backward_shift may have replaced current bucket.
}
else if(m_buckets[ibucket].index() >= end_index) {
m_buckets[ibucket].set_index(index_type(m_buckets[ibucket].index() - nb_values));
ibucket++;
}
else {
ibucket++;
}
}
return iterator(next_it);
}
template<class K>
size_type erase(const K& key) {
return erase(key, hash_key(key));
}
template<class K>
size_type erase(const K& key, std::size_t hash) {
return erase_impl(key, hash);
}
void swap(ordered_hash& other) {
using std::swap;
swap(static_cast<Hash&>(*this), static_cast<Hash&>(other));
swap(static_cast<KeyEqual&>(*this), static_cast<KeyEqual&>(other));
swap(m_buckets_data, other.m_buckets_data);
swap(m_buckets, other.m_buckets);
swap(m_mask, other.m_mask);
swap(m_values, other.m_values);
swap(m_grow_on_next_insert, other.m_grow_on_next_insert);
swap(m_max_load_factor, other.m_max_load_factor);
swap(m_load_threshold, other.m_load_threshold);
}
/*
* Lookup
*/
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& at(const K& key) {
return at(key, hash_key(key));
}
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& at(const K& key, std::size_t hash) {
return const_cast<typename U::value_type&>(static_cast<const ordered_hash*>(this)->at(key, hash));
}
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
const typename U::value_type& at(const K& key) const {
return at(key, hash_key(key));
}
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
const typename U::value_type& at(const K& key, std::size_t hash) const {
auto it = find(key, hash);
if(it != end()) {
return it.value();
}
else {
TSL_OH_THROW_OR_TERMINATE(std::out_of_range, "Couldn't find the key.");
}
}
template<class K, class U = ValueSelect, typename std::enable_if<has_mapped_type<U>::value>::type* = nullptr>
typename U::value_type& operator[](K&& key) {
return try_emplace(std::forward<K>(key)).first.value();
}
template<class K>
size_type count(const K& key) const {
return count(key, hash_key(key));
}
template<class K>
size_type count(const K& key, std::size_t hash) const {
if(find(key, hash) == cend()) {
return 0;
}
else {
return 1;
}
}
template<class K>
iterator find(const K& key) {
return find(key, hash_key(key));
}
template<class K>
iterator find(const K& key, std::size_t hash) {
auto it_bucket = find_key(key, hash);
return (it_bucket != m_buckets_data.end())?iterator(m_values.begin() + it_bucket->index()):end();
}
template<class K>
const_iterator find(const K& key) const {
return find(key, hash_key(key));
}
template<class K>
const_iterator find(const K& key, std::size_t hash) const {
auto it_bucket = find_key(key, hash);
return (it_bucket != m_buckets_data.cend())?const_iterator(m_values.begin() + it_bucket->index()):end();
}
template<class K>
std::pair<iterator, iterator> equal_range(const K& key) {
return equal_range(key, hash_key(key));
}
template<class K>
std::pair<iterator, iterator> equal_range(const K& key, std::size_t hash) {
iterator it = find(key, hash);
return std::make_pair(it, (it == end())?it:std::next(it));
}
template<class K>
std::pair<const_iterator, const_iterator> equal_range(const K& key) const {
return equal_range(key, hash_key(key));
}
template<class K>
std::pair<const_iterator, const_iterator> equal_range(const K& key, std::size_t hash) const {
const_iterator it = find(key, hash);
return std::make_pair(it, (it == cend())?it:std::next(it));
}
/*
* Bucket interface
*/
size_type bucket_count() const {
return m_buckets_data.size();
}
size_type max_bucket_count() const {
return m_buckets_data.max_size();
}
/*
* Hash policy
*/
float load_factor() const {
if(bucket_count() == 0) {
return 0;
}
return float(size())/float(bucket_count());
}
float max_load_factor() const {
return m_max_load_factor;
}
void max_load_factor(float ml) {
m_max_load_factor = std::max(0.1f, std::min(ml, 0.95f));
m_load_threshold = size_type(float(bucket_count())*m_max_load_factor);
}
void rehash(size_type count) {
count = std::max(count, size_type(std::ceil(float(size())/max_load_factor())));
rehash_impl(count);
}
void reserve(size_type count) {
reserve_space_for_values(count);
count = size_type(std::ceil(float(count)/max_load_factor()));
rehash(count);
}
/*
* Observers
*/
hasher hash_function() const {
return static_cast<const Hash&>(*this);
}
key_equal key_eq() const {
return static_cast<const KeyEqual&>(*this);
}
/*
* Other
*/
iterator mutable_iterator(const_iterator pos) {
return iterator(m_values.begin() + iterator_to_index(pos));
}
iterator nth(size_type index) {
tsl_oh_assert(index <= size());
return iterator(m_values.begin() + index);
}
const_iterator nth(size_type index) const {
tsl_oh_assert(index <= size());
return const_iterator(m_values.cbegin() + index);
}
const_reference front() const {
tsl_oh_assert(!empty());
return m_values.front();
}
const_reference back() const {
tsl_oh_assert(!empty());
return m_values.back();
}
const values_container_type& values_container() const noexcept {
return m_values;
}
template<class U = values_container_type, typename std::enable_if<is_vector<U>::value>::type* = nullptr>
const typename values_container_type::value_type* data() const noexcept {
return m_values.data();
}
template<class U = values_container_type, typename std::enable_if<is_vector<U>::value>::type* = nullptr>
size_type capacity() const noexcept {
return m_values.capacity();
}
void shrink_to_fit() {
m_values.shrink_to_fit();
}
template<typename P>
std::pair<iterator, bool> insert_at_position(const_iterator pos, P&& value) {
return insert_at_position_impl(pos.m_iterator, KeySelect()(value), std::forward<P>(value));
}
template<class... Args>
std::pair<iterator, bool> emplace_at_position(const_iterator pos, Args&&... args) {
return insert_at_position(pos, value_type(std::forward<Args>(args)...));
}
template<class K, class... Args>
std::pair<iterator, bool> try_emplace_at_position(const_iterator pos, K&& key, Args&&... value_args) {
return insert_at_position_impl(pos.m_iterator, key,
std::piecewise_construct,
std::forward_as_tuple(std::forward<K>(key)),
std::forward_as_tuple(std::forward<Args>(value_args)...));
}
void pop_back() {
tsl_oh_assert(!empty());
erase(std::prev(end()));
}
/**
* Here to avoid `template<class K> size_type unordered_erase(const K& key)` being used when
* we use a iterator instead of a const_iterator.
*/
iterator unordered_erase(iterator pos) {
return unordered_erase(const_iterator(pos));
}
iterator unordered_erase(const_iterator pos) {
const std::size_t index_erase = iterator_to_index(pos);
unordered_erase(pos.key());
/*
* One element was deleted, index_erase now points to the next element as the elements after
* the deleted value were shifted to the left in m_values (will be end() if we deleted the last element).
*/
return begin() + index_erase;
}
template<class K>
size_type unordered_erase(const K& key) {
return unordered_erase(key, hash_key(key));
}
template<class K>
size_type unordered_erase(const K& key, std::size_t hash) {
auto it_bucket_key = find_key(key, hash);
if(it_bucket_key == m_buckets_data.end()) {
return 0;
}
/**
* If we are not erasing the last element in m_values, we swap
* the element we are erasing with the last element. We then would
* just have to do a pop_back() in m_values.
*/
if(!compare_keys(key, KeySelect()(back()))) {
auto it_bucket_last_elem = find_key(KeySelect()(back()), hash_key(KeySelect()(back())));
tsl_oh_assert(it_bucket_last_elem != m_buckets_data.end());
tsl_oh_assert(it_bucket_last_elem->index() == m_values.size() - 1);
using std::swap;
swap(m_values[it_bucket_key->index()], m_values[it_bucket_last_elem->index()]);
swap(it_bucket_key->index_ref(), it_bucket_last_elem->index_ref());
}
erase_value_from_bucket(it_bucket_key);
return 1;
}
template<class Serializer>
void serialize(Serializer& serializer) const {
serialize_impl(serializer);
}
template<class Deserializer>
void deserialize(Deserializer& deserializer, bool hash_compatible) {
deserialize_impl(deserializer, hash_compatible);
}
friend bool operator==(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values == rhs.m_values;
}
friend bool operator!=(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values != rhs.m_values;
}
friend bool operator<(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values < rhs.m_values;
}
friend bool operator<=(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values <= rhs.m_values;
}
friend bool operator>(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values > rhs.m_values;
}
friend bool operator>=(const ordered_hash& lhs, const ordered_hash& rhs) {
return lhs.m_values >= rhs.m_values;
}
private:
template<class K>
std::size_t hash_key(const K& key) const {
return Hash::operator()(key);
}
template<class K1, class K2>
bool compare_keys(const K1& key1, const K2& key2) const {
return KeyEqual::operator()(key1, key2);
}
template<class K>
typename buckets_container_type::iterator find_key(const K& key, std::size_t hash) {
auto it = static_cast<const ordered_hash*>(this)->find_key(key, hash);
return m_buckets_data.begin() + std::distance(m_buckets_data.cbegin(), it);
}
/**
* Return bucket which has the key 'key' or m_buckets_data.end() if none.
*
* From the bucket_for_hash, search for the value until we either find an empty bucket
* or a bucket which has a value with a distance from its ideal bucket longer
* than the probe length for the value we are looking for.
*/
template<class K>
typename buckets_container_type::const_iterator find_key(const K& key, std::size_t hash) const {
for(std::size_t ibucket = bucket_for_hash(hash), dist_from_ideal_bucket = 0; ;
ibucket = next_bucket(ibucket), dist_from_ideal_bucket++)
{
if(m_buckets[ibucket].empty()) {
return m_buckets_data.end();
}
else if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) &&
compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()])))
{
return m_buckets_data.begin() + ibucket;
}
else if(dist_from_ideal_bucket > distance_from_ideal_bucket(ibucket)) {
return m_buckets_data.end();
}
}
}
void rehash_impl(size_type bucket_count) {
tsl_oh_assert(bucket_count >= size_type(std::ceil(float(size())/max_load_factor())));
if(bucket_count > max_bucket_count()) {
TSL_OH_THROW_OR_TERMINATE(std::length_error, "The map exceeds its maxmimum size.");
}
if(bucket_count > 0) {
bucket_count = round_up_to_power_of_two(bucket_count);
}
if(bucket_count == this->bucket_count()) {
return;
}
buckets_container_type old_buckets(bucket_count);
m_buckets_data.swap(old_buckets);
m_buckets = m_buckets_data.empty()?static_empty_bucket_ptr():
m_buckets_data.data();
// Everything should be noexcept from here.
m_mask = (bucket_count > 0)?(bucket_count - 1):0;
this->max_load_factor(m_max_load_factor);
m_grow_on_next_insert = false;
for(const bucket_entry& old_bucket: old_buckets) {
if(old_bucket.empty()) {
continue;
}
truncated_hash_type insert_hash = old_bucket.truncated_hash();
index_type insert_index = old_bucket.index();
for(std::size_t ibucket = bucket_for_hash(insert_hash), dist_from_ideal_bucket = 0; ;
ibucket = next_bucket(ibucket), dist_from_ideal_bucket++)
{
if(m_buckets[ibucket].empty()) {
m_buckets[ibucket].set_index(insert_index);
m_buckets[ibucket].set_hash(insert_hash);
break;
}
const std::size_t distance = distance_from_ideal_bucket(ibucket);
if(dist_from_ideal_bucket > distance) {
std::swap(insert_index, m_buckets[ibucket].index_ref());
std::swap(insert_hash, m_buckets[ibucket].truncated_hash_ref());
dist_from_ideal_bucket = distance;
}
}
}
}
template<class T = values_container_type, typename std::enable_if<is_vector<T>::value>::type* = nullptr>
void reserve_space_for_values(size_type count) {
m_values.reserve(count);
}
template<class T = values_container_type, typename std::enable_if<!is_vector<T>::value>::type* = nullptr>
void reserve_space_for_values(size_type /*count*/) {
}
/**
* Swap the empty bucket with the values on its right until we cross another empty bucket
* or if the other bucket has a distance_from_ideal_bucket == 0.
*/
void backward_shift(std::size_t empty_ibucket) noexcept {
tsl_oh_assert(m_buckets[empty_ibucket].empty());
std::size_t previous_ibucket = empty_ibucket;
for(std::size_t current_ibucket = next_bucket(previous_ibucket);
!m_buckets[current_ibucket].empty() && distance_from_ideal_bucket(current_ibucket) > 0;
previous_ibucket = current_ibucket, current_ibucket = next_bucket(current_ibucket))
{
std::swap(m_buckets[current_ibucket], m_buckets[previous_ibucket]);
}
}
void erase_value_from_bucket(typename buckets_container_type::iterator it_bucket) {
tsl_oh_assert(it_bucket != m_buckets_data.end() && !it_bucket->empty());
m_values.erase(m_values.begin() + it_bucket->index());
/*
* m_values.erase shifted all the values on the right of the erased value,
* shift the indexes by -1 in the buckets array for these values.
*/
if(it_bucket->index() != m_values.size()) {
shift_indexes_in_buckets(it_bucket->index(), -1);
}
// Mark the bucket as empty and do a backward shift of the values on the right
it_bucket->clear();
backward_shift(std::size_t(std::distance(m_buckets_data.begin(), it_bucket)));
}
/**
* Go through each value from [from_ivalue, m_values.size()) in m_values and for each
* bucket corresponding to the value, shift the index by delta.
*
* delta must be equal to 1 or -1.
*/
void shift_indexes_in_buckets(index_type from_ivalue, int delta) noexcept {
tsl_oh_assert(delta == 1 || delta == -1);
for(std::size_t ivalue = from_ivalue; ivalue < m_values.size(); ivalue++) {
// All the values in m_values have been shifted by delta. Find the bucket corresponding
// to the value m_values[ivalue]
const index_type old_index = static_cast<index_type>(ivalue - delta);
std::size_t ibucket = bucket_for_hash(hash_key(KeySelect()(m_values[ivalue])));
while(m_buckets[ibucket].index() != old_index) {
ibucket = next_bucket(ibucket);
}
m_buckets[ibucket].set_index(index_type(ivalue));
}
}
template<class K>
size_type erase_impl(const K& key, std::size_t hash) {
auto it_bucket = find_key(key, hash);
if(it_bucket != m_buckets_data.end()) {
erase_value_from_bucket(it_bucket);
return 1;
}
else {
return 0;
}
}
/**
* Insert the element at the end.
*/
template<class K, class... Args>
std::pair<iterator, bool> insert_impl(const K& key, Args&&... value_type_args) {
const std::size_t hash = hash_key(key);
std::size_t ibucket = bucket_for_hash(hash);
std::size_t dist_from_ideal_bucket = 0;
while(!m_buckets[ibucket].empty() && dist_from_ideal_bucket <= distance_from_ideal_bucket(ibucket)) {
if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) &&
compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()])))
{
return std::make_pair(begin() + m_buckets[ibucket].index(), false);
}
ibucket = next_bucket(ibucket);
dist_from_ideal_bucket++;
}
if(size() >= max_size()) {
TSL_OH_THROW_OR_TERMINATE(std::length_error, "We reached the maximum size for the hash table.");
}
if(grow_on_high_load()) {
ibucket = bucket_for_hash(hash);
dist_from_ideal_bucket = 0;
}
m_values.emplace_back(std::forward<Args>(value_type_args)...);
insert_index(ibucket, dist_from_ideal_bucket,
index_type(m_values.size() - 1), bucket_entry::truncate_hash(hash));
return std::make_pair(std::prev(end()), true);
}
/**
* Insert the element before insert_position.
*/
template<class K, class... Args>
std::pair<iterator, bool> insert_at_position_impl(typename values_container_type::const_iterator insert_position,
const K& key, Args&&... value_type_args)
{
const std::size_t hash = hash_key(key);
std::size_t ibucket = bucket_for_hash(hash);
std::size_t dist_from_ideal_bucket = 0;
while(!m_buckets[ibucket].empty() && dist_from_ideal_bucket <= distance_from_ideal_bucket(ibucket)) {
if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) &&
compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()])))
{
return std::make_pair(begin() + m_buckets[ibucket].index(), false);
}
ibucket = next_bucket(ibucket);
dist_from_ideal_bucket++;
}
if(size() >= max_size()) {
TSL_OH_THROW_OR_TERMINATE(std::length_error, "We reached the maximum size for the hash table.");
}
if(grow_on_high_load()) {
ibucket = bucket_for_hash(hash);
dist_from_ideal_bucket = 0;
}
const index_type index_insert_position = index_type(std::distance(m_values.cbegin(), insert_position));
#ifdef TSL_OH_NO_CONTAINER_EMPLACE_CONST_ITERATOR
m_values.emplace(m_values.begin() + std::distance(m_values.cbegin(), insert_position), std::forward<Args>(value_type_args)...);
#else
m_values.emplace(insert_position, std::forward<Args>(value_type_args)...);
#endif
insert_index(ibucket, dist_from_ideal_bucket,
index_insert_position, bucket_entry::truncate_hash(hash));
/*
* The insertion didn't happend at the end of the m_values container,
* we need to shift the indexes in m_buckets_data.
*/
if(index_insert_position != m_values.size() - 1) {
shift_indexes_in_buckets(index_insert_position + 1, 1);
}
return std::make_pair(iterator(m_values.begin() + index_insert_position), true);
}
void insert_index(std::size_t ibucket, std::size_t dist_from_ideal_bucket,
index_type index_insert, truncated_hash_type hash_insert) noexcept
{
while(!m_buckets[ibucket].empty()) {
const std::size_t distance = distance_from_ideal_bucket(ibucket);
if(dist_from_ideal_bucket > distance) {
std::swap(index_insert, m_buckets[ibucket].index_ref());
std::swap(hash_insert, m_buckets[ibucket].truncated_hash_ref());
dist_from_ideal_bucket = distance;
}
ibucket = next_bucket(ibucket);
dist_from_ideal_bucket++;
if(dist_from_ideal_bucket > REHASH_ON_HIGH_NB_PROBES__NPROBES && !m_grow_on_next_insert &&
load_factor() >= REHASH_ON_HIGH_NB_PROBES__MIN_LOAD_FACTOR)
{
// We don't want to grow the map now as we need this method to be noexcept.
// Do it on next insert.
m_grow_on_next_insert = true;
}
}
m_buckets[ibucket].set_index(index_insert);
m_buckets[ibucket].set_hash(hash_insert);
}
std::size_t distance_from_ideal_bucket(std::size_t ibucket) const noexcept {
const std::size_t ideal_bucket = bucket_for_hash(m_buckets[ibucket].truncated_hash());
if(ibucket >= ideal_bucket) {
return ibucket - ideal_bucket;
}
// If the bucket is smaller than the ideal bucket for the value, there was a wrapping at the end of the
// bucket array due to the modulo.
else {
return (bucket_count() + ibucket) - ideal_bucket;
}
}
std::size_t next_bucket(std::size_t index) const noexcept {
tsl_oh_assert(index < m_buckets_data.size());
index++;
return (index < m_buckets_data.size())?index:0;
}
std::size_t bucket_for_hash(std::size_t hash) const noexcept {
return hash & m_mask;
}
std::size_t iterator_to_index(const_iterator it) const noexcept {
const auto dist = std::distance(cbegin(), it);
tsl_oh_assert(dist >= 0);
return std::size_t(dist);
}
/**
* Return true if the map has been rehashed.
*/
bool grow_on_high_load() {
if(m_grow_on_next_insert || size() >= m_load_threshold) {
rehash_impl(std::max(size_type(1), bucket_count() * 2));
m_grow_on_next_insert = false;
return true;
}
else {
return false;
}
}
template<class Serializer>
void serialize_impl(Serializer& serializer) const {
const slz_size_type version = SERIALIZATION_PROTOCOL_VERSION;
serializer(version);
const slz_size_type nb_elements = m_values.size();
serializer(nb_elements);
const slz_size_type bucket_count = m_buckets_data.size();
serializer(bucket_count);
const float max_load_factor = m_max_load_factor;
serializer(max_load_factor);
for(const value_type& value: m_values) {
serializer(value);
}
for(const bucket_entry& bucket: m_buckets_data) {
bucket.serialize(serializer);
}
}
template<class Deserializer>
void deserialize_impl(Deserializer& deserializer, bool hash_compatible) {
tsl_oh_assert(m_buckets_data.empty()); // Current hash table must be empty
const slz_size_type version = deserialize_value<slz_size_type>(deserializer);
// For now we only have one version of the serialization protocol.
// If it doesn't match there is a problem with the file.
if(version != SERIALIZATION_PROTOCOL_VERSION) {
TSL_OH_THROW_OR_TERMINATE(std::runtime_error, "Can't deserialize the ordered_map/set. "
"The protocol version header is invalid.");
}
const slz_size_type nb_elements = deserialize_value<slz_size_type>(deserializer);
const slz_size_type bucket_count_ds = deserialize_value<slz_size_type>(deserializer);
const float max_load_factor = deserialize_value<float>(deserializer);
this->max_load_factor(max_load_factor);
if(bucket_count_ds == 0) {
tsl_oh_assert(nb_elements == 0);
return;
}
if(!hash_compatible) {
reserve(numeric_cast<size_type>(nb_elements, "Deserialized nb_elements is too big."));
for(slz_size_type el = 0; el < nb_elements; el++) {
insert(deserialize_value<value_type>(deserializer));
}
}
else {
m_buckets_data.reserve(numeric_cast<size_type>(bucket_count_ds, "Deserialized bucket_count is too big."));
m_buckets = m_buckets_data.data(),
m_mask = m_buckets_data.capacity() - 1;
reserve_space_for_values(numeric_cast<size_type>(nb_elements, "Deserialized nb_elements is too big."));
for(slz_size_type el = 0; el < nb_elements; el++) {
m_values.push_back(deserialize_value<value_type>(deserializer));
}
for(slz_size_type b = 0; b < bucket_count_ds; b++) {
m_buckets_data.push_back(bucket_entry::deserialize(deserializer));
}
if(load_factor() > this->max_load_factor()) {
TSL_OH_THROW_OR_TERMINATE(std::runtime_error, "Invalid max_load_factor. Check that the serializer "
"and deserializer supports floats correctly as they "
"can be converted implicitely to ints.");
}
}
}
static std::size_t round_up_to_power_of_two(std::size_t value) {
if(is_power_of_two(value)) {
return value;
}
if(value == 0) {
return 1;
}
--value;
for(std::size_t i = 1; i < sizeof(std::size_t) * CHAR_BIT; i *= 2) {
value |= value >> i;
}
return value + 1;
}
static constexpr bool is_power_of_two(std::size_t value) {
return value != 0 && (value & (value - 1)) == 0;
}
public:
static const size_type DEFAULT_INIT_BUCKETS_SIZE = 0;
static constexpr float DEFAULT_MAX_LOAD_FACTOR = 0.75f;
private:
static const size_type REHASH_ON_HIGH_NB_PROBES__NPROBES = 128;
static constexpr float REHASH_ON_HIGH_NB_PROBES__MIN_LOAD_FACTOR = 0.15f;
/**
* Protocol version currenlty used for serialization.
*/
static const slz_size_type SERIALIZATION_PROTOCOL_VERSION = 1;
/**
* Return an always valid pointer to an static empty bucket_entry with last_bucket() == true.
*/
bucket_entry* static_empty_bucket_ptr() {
static bucket_entry empty_bucket;
return &empty_bucket;
}
private:
buckets_container_type m_buckets_data;
/**
* Points to m_buckets_data.data() if !m_buckets_data.empty() otherwise points to static_empty_bucket_ptr.
* This variable is useful to avoid the cost of checking if m_buckets_data is empty when trying
* to find an element.
*
* TODO Remove m_buckets_data and only use a pointer+size instead of a pointer+vector to save some space in the ordered_hash object.
*/
bucket_entry* m_buckets;
size_type m_mask;
values_container_type m_values;
bool m_grow_on_next_insert;
float m_max_load_factor;
size_type m_load_threshold;
};
} // end namespace detail_ordered_hash
} // end namespace tsl
#endif
================================================
FILE: extern/tsl-ordered-map/ordered_map.h
================================================
/**
* MIT License
*
* Copyright (c) 2017 Tessil
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TSL_ORDERED_MAP_H
#define TSL_ORDERED_MAP_H
#include <cstddef>
#include <cstdint>
#include <deque>
#include <functional>
#include <initializer_list>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
#include "ordered_hash.h"
namespace tsl {
/**
* Implementation of an hash map using open adressing with robin hood with backshift delete to resolve collisions.
*
* The particularity of this hash map is that it remembers the order in which the elements were added and
* provide a way to access the structure which stores these values through the 'values_container()' method.
* The used container is defined by ValueTypeContainer, by default a std::deque is used (grows faster) but
* a std::vector may be used. In this case the map provides a 'data()' method which give a direct access
* to the memory used to store the values (which can be usefull to communicate with C API's).
*
* The Key and T must be copy constructible and/or move constructible. To use `unordered_erase` they both
* must be swappable.
*
* The behaviour of the hash map is undefinded if the destructor of Key or T throws an exception.
*
* By default the maximum size of a map is limited to 2^32 - 1 values, if needed this can be changed through
* the IndexType template parameter. Using an `uint64_t` will raise this limit to 2^64 - 1 values but each
* bucket will use 16 bytes instead of 8 bytes in addition to the space needed to store the values.
*
* Iterators invalidation:
* - clear, operator=, reserve, rehash: always invalidate the iterators (also invalidate end()).
* - insert, emplace, emplace_hint, operator[]: when a std::vector is used as ValueTypeContainer
* and if size() < capacity(), only end().
* Otherwise all the iterators are invalidated if an insert occurs.
* - erase, unordered_erase: when a std::vector is used as ValueTypeContainer invalidate the iterator of
* the erased element and all the ones after the erased element (including end()).
* Otherwise all the iterators are invalidated if an erase occurs.
*/
template<class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key, T>>,
class ValueTypeContainer = std::deque<std::pair<Key, T>, Allocator>,
class IndexType = std::uint_least32_t>
class ordered_map {
private:
template<typename U>
using has_is_transparent = tsl::detail_ordered_hash::has_is_transparent<U>;
class KeySelect {
public:
using key_type = Key;
const key_type& operator()(const std::pair<Key, T>& key_value) const noexcept {
return key_value.first;
}
key_type& operator()(std::pair<Key, T>& key_value) noexcept {
return key_value.first;
}
};
class ValueSelect {
public:
using value_type = T;
const value_type& operator()(const std::pair<Key, T>& key_value) const noexcept {
return key_value.second;
}
value_type& operator()(std::pair<Key, T>& key_value) noexcept {
return key_value.second;
}
};
using ht = detail_ordered_hash::ordered_hash<std::pair<Key, T>, KeySelect, ValueSelect,
Hash, KeyEqual, Allocator, ValueTypeContainer, IndexType>;
public:
using key_type = typename ht::key_type;
using mapped_type = T;
using value_type = typename ht::value_type;
using size_type = typename ht::size_type;
using difference_type = typename ht::difference_type;
using hasher = typename ht::hasher;
using key_equal = typename ht::key_equal;
using allocator_type = typename ht::allocator_type;
using reference = typename ht::reference;
using const_reference = typename ht::const_reference;
using pointer = typename ht::pointer;
using const_pointer = typename ht::const_pointer;
using iterator = typename ht::iterator;
using const_iterator = typename ht::const_iterator;
using reverse_iterator = typename ht::reverse_iterator;
using const_reverse_iterator = typename ht::const_reverse_iterator;
using values_container_type = typename ht::values_container_type;
/*
* Constructors
*/
ordered_map(): ordered_map(ht::DEFAULT_INIT_BUCKETS_SIZE) {
}
explicit ordered_map(size_type bucket_count,
const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual(),
const Allocator& alloc = Allocator()):
m_ht(bucket_count, hash, equal, alloc, ht::DEFAULT_MAX_LOAD_FACTOR)
{
}
ordered_map(size_type bucket_count,
const Allocator& alloc): ordered_map(bucket_count, Hash(), KeyEqual(), alloc)
{
}
ordered_map(size_type bucket_count,
const Hash& hash,
const Allocator& alloc): ordered_map(bucket_count, hash, KeyEqual(), alloc)
{
}
explicit ordered_map(const Allocator& alloc): ordered_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) {
}
template<class InputIt>
ordered_map(InputIt first, InputIt last,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual(),
const Allocator& alloc = Allocator()): ordered_map(bucket_count, hash, equal, alloc)
{
insert(first, last);
}
template<class InputIt>
ordered_map(InputIt first, InputIt last,
size_type bucket_count,
const Allocator& alloc): ordered_map(first, last, bucket_count, Hash(), KeyEqual(), alloc)
{
}
template<class InputIt>
ordered_map(InputIt first, InputIt last,
size_type bucket_count,
const Hash& hash,
const Allocator& alloc): ordered_map(first, last, bucket_count, hash, KeyEqual(), alloc)
{
}
ordered_map(std::initializer_list<value_type> init,
size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE,
const Hash& hash = Hash(),
const KeyEqual& equal = KeyEqual(),
const Allocator& alloc = Allocator()):
ordered_map(init.begin(), init.end(), bucket_count, hash, equal, alloc)
{
}
ordered_map(std::initializer_list<value_type> init,
size_type bucket_count,
const Allocator& alloc):
ordered_map(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc)
{
}
ordered_map(std::initializer_list<value_type> init,
size_type bucket_count,
const Hash& hash,
const Allocator& alloc):
ordered_map(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc)
{
}
ordered_map& operator=(std::initializer_list<value_type> ilist) {
m_ht.clear();
m_ht.reserve(ilist.size());
m_ht.insert(ilist.begin(), ilist.end());
return *this;
}
allocator_type get_allocator() const { return m_ht.get_allocator(); }
/*
* Iterators
*/
iterator begin() noexcept { return m_ht.begin(); }
const_iterator begin() const noexcept { return m_ht.begin(); }
const_iterator cbegin() const noexcept { return m_ht.cbegin(); }
iterator end() noexcept { return m_ht.end(); }
const_iterator end() const noexcept { return m_ht.end(); }
const_iterator cend() const noexcept { return m_ht.cend(); }
reverse_iterator rbegin() noexcept { return m_ht.rbegin(); }
const_reverse_iterator rbegin() const noexcept { return m_ht.rbegin(); }
const_reverse_iterator rcbegin() const noexcept { return m_ht.rcbegin(); }
reverse_iterator rend() noexcept { return m_ht.rend(); }
const_reverse_iterator rend() const noexcept { return m_ht.rend(); }
const_reverse_iterator rcend() const noexcept { return m_ht.rcend(); }
/*
* Capacity
*/
bool empty() const noexcept { return m_ht.empty(); }
size_type size() const noexcept { return m_ht.size(); }
size_type max_size() const noexcept { return m_ht.max_size(); }
/*
* Modifiers
*/
void clear() noexcept { m_ht.clear(); }
std::pair<iterator, bool> insert(const value_type& value) { return m_ht.insert(value); }
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
std::pair<iterator, bool> insert(P&& value) { return m_ht.emplace(std::forward<P>(value)); }
std::pair<iterator, bool> insert(value_type&& value) { return m_ht.insert(std::move(value)); }
iterator insert(const_iterator hint, const value_type& value) {
return m_ht.insert_hint(hint, value);
}
template<class P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type* = nullptr>
iterator insert(const_iterator hint, P&& value) {
return m_ht.emplace_hint(hint, std::forward<P>(value));
}
iterator insert(const_iterator hint, value_type&& value) {
return m_ht.insert_hint(hint, std::move(value));
}
template<class InputIt>
void insert(InputIt first, InputIt last) { m_ht.insert(first, last); }
void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist.begin(), ilist.end()); }
template<class M>
std::pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj) {
return m_ht.insert_or_assign(k, std::forward<M>(obj));
}
template<class M>
std::pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj) {
return m_ht.insert_or_assign(std::move(k), std::forward<M>(obj));
}
template<class M>
iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) {
return m_ht.insert_or_assign(hint, k, std::forward<M>(obj));
}
template<class M>
iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) {
return m_ht.insert_or_assign(hint, std::move(k), std::forward<M>(obj));
}
/**
* Due to the way elements are stored, emplace will need to move or copy the key-value once.
* The method is equivalent to insert(value_type(std::forward<Args>(args)...));
*
* Mainly here for compatibility with the std::unordered_map interface.
*/
template<class... Args>
std::pair<iterator, bool> emplace(Args&&... args) { return m_ht.emplace(std::forward<Args>(args)...); }
/**
* Due to the way elements are stored, emplace_hint will need to move or copy the key-value once.
* The method is equivalent to insert(hint, value_type(std::forward<Args>(args)...));
*
* Mainly here for compatibility with the std::unordered_map interface.
*/
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args) {
return m_ht.emplace_hint(hint, std::forward<Args>(args)...);
}
template<class... Args>
std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args) {
return m_ht.try_emplace(k, std::forward<Args>(args)...);
}
template<class... Args>
std::pair<iterator, bool> try_emplace(key_type&& k, Args&&... args) {
return m_ht.try_emplace(std::move(k), std::forward<Args>(args)...);
}
template<class... Args>
iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) {
return m_ht.try_emplace_hint(hint, k, std::forward<Args>(args)...);
}
template<class... Args>
iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) {
return m_ht.try_emplace_hint(hint, std::move(k), std::forward<Args>(args)...);
}
/**
* When erasing an element, the insert order will be preserved and no holes will be present in the container
* returned by 'values_container()'.
*
* The method is in O(n), if the order is not important 'unordered_erase(...)' method is faster with an O(1)
* average complexity.
*/
iterator erase(iterator pos) { return m_ht.erase(pos); }
/**
* @copydoc erase(iterator pos)
*/
iterator erase(const_iterator pos) { return m_ht.erase(pos); }
/**
* @copydoc erase(iterator pos)
*/
iterator erase(const_iterator first, const_iterator last) { return m_ht.erase(first, last); }
/**
* @copydoc erase(iterator pos)
*/
size_type erase(const key_type& key) { return m_ht.erase(key); }
/**
* @copydoc erase(iterator pos)
*
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash.
*/
size_type erase(const key_type& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash);
}
/**
* @copydoc erase(iterator pos)
*
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key) { return m_ht.erase(key); }
/**
* @copydoc erase(const key_type& key, std::size_t precalculated_hash)
*
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type erase(const K& key, std::size_t precalculated_hash) {
return m_ht.erase(key, precalculated_hash);
}
void swap(ordered_map& other) { other.m_ht.swap(m_ht); }
/*
* Lookup
*/
T& at(const Key& key) { return m_ht.at(key); }
/**
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
T& at(const Key& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); }
const T& at(const Key& key) const { return m_ht.at(key); }
/**
* @copydoc at(const Key& key, std::size_t precalculated_hash)
*/
const T& at(const Key& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); }
/**
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
T& at(const K& key) { return m_ht.at(key); }
/**
* @copydoc at(const K& key)
*
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); }
/**
* @copydoc at(const K& key)
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const T& at(const K& key) const { return m_ht.at(key); }
/**
* @copydoc at(const K& key, std::size_t precalculated_hash)
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); }
T& operator[](const Key& key) { return m_ht[key]; }
T& operator[](Key&& key) { return m_ht[std::move(key)]; }
size_type count(const Key& key) const { return m_ht.count(key); }
/**
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
size_type count(const Key& key, std::size_t precalculated_hash) const {
return m_ht.count(key, precalculated_hash);
}
/**
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key) const { return m_ht.count(key); }
/**
* @copydoc count(const K& key) const
*
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
size_type count(const K& key, std::size_t precalculated_hash) const {
return m_ht.count(key, precalculated_hash);
}
iterator find(const Key& key) { return m_ht.find(key); }
/**
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
iterator find(const Key& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
const_iterator find(const Key& key) const { return m_ht.find(key); }
/**
* @copydoc find(const Key& key, std::size_t precalculated_hash)
*/
const_iterator find(const Key& key, std::size_t precalculated_hash) const {
return m_ht.find(key, precalculated_hash);
}
/**
* This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists.
* If so, K must be hashable and comparable to Key.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key) { return m_ht.find(key); }
/**
* @copydoc find(const K& key)
*
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
/**
* @copydoc find(const K& key)
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key) const { return m_ht.find(key); }
/**
* @copydoc find(const K& key)
*
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
template<class K, class KE = KeyEqual, typename std::enable_if<has_is_transparent<KE>::value>::type* = nullptr>
const_iterator find(const K& key, std::size_t precalculated_hash) const {
return m_ht.find(key, precalculated_hash);
}
std::pair<iterator, iterator> equal_range(const Key& key) { return m_ht.equal_range(key); }
/**
* Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same
* as hash_function()(key). Usefull to speed-up the lookup if you already have the hash.
*/
std::pair<iterator, iterator> equal_range(const Key& key, std::size_t precalculated_hash) {
return m_ht.equal_range(key, precalculated_hash);
}
std::pair<const_iterator, const_iterator> equal_range(const Key& key) const { return m_ht.
gitextract_hf3qq4ys/
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README-compile.md
├── README-shell-integration.md
├── README.md
├── cmake/
│ └── FindShournalUtil.cmake
├── extern/
│ ├── folly/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ └── UninitializedMemoryHacks.h
│ ├── tsl-ordered-map/
│ │ ├── CMakeLists.txt
│ │ ├── LICENSE
│ │ ├── ordered_hash.h
│ │ ├── ordered_map.h
│ │ └── ordered_set.h
│ └── xxHash/
│ ├── .gitattributes
│ ├── .gitignore
│ ├── .travis.yml
│ ├── LICENSE
│ ├── Makefile
│ ├── README.md
│ ├── appveyor.yml
│ ├── cmake_unofficial/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ └── README.md
│ ├── doc/
│ │ └── xxhash_spec.md
│ ├── xxhash.c
│ ├── xxhash.h
│ ├── xxhsum.1
│ ├── xxhsum.1.md
│ └── xxhsum.c
├── html-export/
│ ├── dist/
│ │ ├── htmlexportres.qrc
│ │ ├── index.html
│ │ ├── main.js
│ │ └── main.licenses.txt
│ ├── package.json
│ ├── src/
│ │ ├── annotation_line_render.js
│ │ ├── command_list.js
│ │ ├── command_manipulation.js
│ │ ├── command_timeline.js
│ │ ├── conversions.js
│ │ ├── d3js_util.js
│ │ ├── generic_text_dialog.js
│ │ ├── globals.js
│ │ ├── html_util.js
│ │ ├── index.js
│ │ ├── limited_queue.js
│ │ ├── map_extended.js
│ │ ├── plot_cmdcount_per_cwd.js
│ │ ├── plot_cmdcount_per_session.js
│ │ ├── plot_io_per_dir.js
│ │ ├── plot_most_written_files.js
│ │ ├── plot_simple_bar.js
│ │ ├── session_timeline.js
│ │ ├── stats.js
│ │ ├── timeline_group_find.js
│ │ ├── tooltip.js
│ │ ├── util.js
│ │ └── zoom_buttons.js
│ └── webpack.config.js
├── install/
│ ├── 90-shournaladd.rules.in
│ ├── CMakeLists.txt
│ ├── postinst-dkms.in
│ ├── postinst.in
│ ├── prerm-dkms.in
│ ├── prerm.in
│ └── shournalk-load.conf
├── kernel/
│ ├── CMakeLists.txt
│ ├── Kbuild
│ ├── LICENSE
│ ├── cmake/
│ │ └── FindKernelHeaders.cmake
│ ├── dkms.conf.in
│ ├── event_consumer.c
│ ├── event_consumer.h
│ ├── event_consumer_cache.c
│ ├── event_consumer_cache.h
│ ├── event_handler.c
│ ├── event_handler.h
│ ├── event_queue.c
│ ├── event_queue.h
│ ├── event_target.c
│ ├── event_target.h
│ ├── hash_table_str.c
│ ├── hash_table_str.h
│ ├── kfileextensions.c
│ ├── kfileextensions.h
│ ├── kpathtree.c
│ ├── kpathtree.h
│ ├── kutil.c
│ ├── kutil.h
│ ├── shournal_kio.c
│ ├── shournal_kio.h
│ ├── shournalk_global.c
│ ├── shournalk_global.h
│ ├── shournalk_main.c
│ ├── shournalk_sysfs.c
│ ├── shournalk_sysfs.h
│ ├── shournalk_test.c
│ ├── shournalk_test.h
│ ├── shournalk_user.h
│ ├── tracepoint_helper.c
│ ├── tracepoint_helper.h
│ ├── xxhash_shournalk.c
│ └── xxhash_shournalk.h
├── shell-integration-scripts/
│ ├── CMakeLists.txt
│ ├── _source_me_generic.sh
│ ├── integration_fan.sh
│ ├── integration_ko.sh
│ ├── integration_main.sh.in
│ └── util.sh
├── src/
│ ├── CMakeLists.txt
│ ├── common/
│ │ ├── CMakeLists.txt
│ │ ├── app.cpp
│ │ ├── app.h
│ │ ├── cefd.cpp
│ │ ├── cefd.h
│ │ ├── console_dialog.cpp
│ │ ├── console_dialog.h
│ │ ├── cxxhash.cpp
│ │ ├── cxxhash.h
│ │ ├── database/
│ │ │ ├── command_query_iterator.cpp
│ │ │ ├── command_query_iterator.h
│ │ │ ├── commandinfo.cpp
│ │ │ ├── commandinfo.h
│ │ │ ├── db_connection.cpp
│ │ │ ├── db_connection.h
│ │ │ ├── db_controller.cpp
│ │ │ ├── db_controller.h
│ │ │ ├── db_conversions.cpp
│ │ │ ├── db_conversions.h
│ │ │ ├── db_globals.cpp
│ │ │ ├── db_globals.h
│ │ │ ├── file_query_helper.cpp
│ │ │ ├── file_query_helper.h
│ │ │ ├── fileinfos.cpp
│ │ │ ├── fileinfos.h
│ │ │ ├── insertifnotexist.cpp
│ │ │ ├── insertifnotexist.h
│ │ │ ├── qexcdatabase.cpp
│ │ │ ├── qexcdatabase.h
│ │ │ ├── qsqlquerythrow.cpp
│ │ │ ├── qsqlquerythrow.h
│ │ │ ├── query_columns.h
│ │ │ ├── sessioninfo.cpp
│ │ │ ├── sessioninfo.h
│ │ │ ├── sqlite_database_scheme.cpp
│ │ │ ├── sqlite_database_scheme.h
│ │ │ ├── sqlite_database_scheme_updates.cpp
│ │ │ ├── sqlite_database_scheme_updates.h
│ │ │ ├── sqlquery.cpp
│ │ │ ├── sqlquery.h
│ │ │ ├── storedfiles.cpp
│ │ │ └── storedfiles.h
│ │ ├── fdcommunication.cpp
│ │ ├── fdcommunication.h
│ │ ├── fileeventhandler.cpp
│ │ ├── fileeventhandler.h
│ │ ├── fileevents.cpp
│ │ ├── fileevents.h
│ │ ├── generic_container.h
│ │ ├── groupcontrol.cpp
│ │ ├── groupcontrol.h
│ │ ├── hashcontrol.cpp
│ │ ├── hashcontrol.h
│ │ ├── hashmeta.cpp
│ │ ├── hashmeta.h
│ │ ├── idmapentry.h
│ │ ├── interrupt_handler.cpp
│ │ ├── interrupt_handler.h
│ │ ├── limited_priority_queue.h
│ │ ├── logger.cpp
│ │ ├── logger.h
│ │ ├── oscpp/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cflock.cpp
│ │ │ ├── cflock.h
│ │ │ ├── excos.cpp
│ │ │ ├── excos.h
│ │ │ ├── fdentries.cpp
│ │ │ ├── fdentries.h
│ │ │ ├── os.cpp
│ │ │ ├── os.h
│ │ │ ├── oscaps.cpp
│ │ │ ├── oscaps.h
│ │ │ ├── osutil.cpp
│ │ │ └── osutil.h
│ │ ├── pathtree.cpp
│ │ ├── pathtree.h
│ │ ├── pidcontrol.cpp
│ │ ├── pidcontrol.h
│ │ ├── qfddummydevice.cpp
│ │ ├── qfddummydevice.h
│ │ ├── qfilethrow.cpp
│ │ ├── qfilethrow.h
│ │ ├── qoptargparse/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── excoptargparse.cpp
│ │ │ ├── excoptargparse.h
│ │ │ ├── qoptarg.cpp
│ │ │ ├── qoptarg.h
│ │ │ ├── qoptargparse.cpp
│ │ │ ├── qoptargparse.h
│ │ │ ├── qoptargtrigger.cpp
│ │ │ ├── qoptargtrigger.h
│ │ │ ├── qoptsqlarg.cpp
│ │ │ ├── qoptsqlarg.h
│ │ │ ├── qoptvarlenarg.cpp
│ │ │ └── qoptvarlenarg.h
│ │ ├── qresource_helper.cpp
│ │ ├── qresource_helper.h
│ │ ├── qsimplecfg/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cfg.cpp
│ │ │ ├── cfg.h
│ │ │ ├── exccfg.cpp
│ │ │ ├── exccfg.h
│ │ │ ├── section.cpp
│ │ │ └── section.h
│ │ ├── safe_file_update.h
│ │ ├── settings.cpp
│ │ ├── settings.h
│ │ ├── shournal_run_common.cpp
│ │ ├── shournal_run_common.h
│ │ ├── socket_message.cpp
│ │ ├── socket_message.h
│ │ ├── stdiocpp.cpp
│ │ ├── stdiocpp.h
│ │ ├── stupidinject.cpp
│ │ ├── stupidinject.h
│ │ ├── subprocess.cpp
│ │ ├── subprocess.h
│ │ ├── user_kernerl.h
│ │ ├── util/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── cleanupresource.h
│ │ │ ├── compareoperator.cpp
│ │ │ ├── compareoperator.h
│ │ │ ├── compat.h
│ │ │ ├── conversions.cpp
│ │ │ ├── conversions.h
│ │ │ ├── cpp_exit.cpp
│ │ │ ├── cpp_exit.h
│ │ │ ├── exccommon.cpp
│ │ │ ├── exccommon.h
│ │ │ ├── nullable_value.h
│ │ │ ├── qformattedstream.cpp
│ │ │ ├── qformattedstream.h
│ │ │ ├── qoutstream.cpp
│ │ │ ├── qoutstream.h
│ │ │ ├── staticinitializer.h
│ │ │ ├── strlight.cpp
│ │ │ ├── strlight.h
│ │ │ ├── strlight_util.cpp
│ │ │ ├── strlight_util.h
│ │ │ ├── sys_ioprio.h
│ │ │ ├── translation.cpp
│ │ │ ├── translation.h
│ │ │ ├── util.cpp
│ │ │ ├── util.h
│ │ │ ├── util_performance.cpp
│ │ │ └── util_performance.h
│ │ ├── xxhash_common.c
│ │ └── xxhash_common.h
│ ├── shell-integration-fanotify/
│ │ ├── CMakeLists.txt
│ │ ├── attached_bash.cpp
│ │ ├── attached_bash.h
│ │ ├── attached_shell.cpp
│ │ ├── attached_shell.h
│ │ ├── event_open.cpp
│ │ ├── event_open.h
│ │ ├── event_process.cpp
│ │ ├── event_process.h
│ │ ├── libshellwatch.version
│ │ ├── libshournal-shellwatch.cpp
│ │ ├── shell_globals.cpp
│ │ ├── shell_globals.h
│ │ ├── shell_logger.cpp
│ │ ├── shell_logger.h
│ │ ├── shell_request_handler.cpp
│ │ └── shell_request_handler.h
│ ├── shournal/
│ │ ├── CMakeLists.txt
│ │ ├── argcontrol_dbdelete.cpp
│ │ ├── argcontrol_dbdelete.h
│ │ ├── argcontrol_dbquery.cpp
│ │ ├── argcontrol_dbquery.h
│ │ ├── cmd_stats.cpp
│ │ ├── cmd_stats.h
│ │ ├── command_printer.cpp
│ │ ├── command_printer.h
│ │ ├── command_printer_html.cpp
│ │ ├── command_printer_html.h
│ │ ├── command_printer_human.cpp
│ │ ├── command_printer_human.h
│ │ ├── command_printer_json.cpp
│ │ ├── command_printer_json.h
│ │ └── shournal.cpp
│ ├── shournal-run/
│ │ ├── CMakeLists.txt
│ │ ├── fifocom.cpp
│ │ ├── fifocom.h
│ │ ├── filewatcher_shournalk.cpp
│ │ ├── filewatcher_shournalk.h
│ │ ├── mark_helper.cpp
│ │ ├── mark_helper.h
│ │ ├── shournal-run.cpp
│ │ ├── shournalk_ctrl.c
│ │ └── shournalk_ctrl.h
│ └── shournal-run-fanotify/
│ ├── CMakeLists.txt
│ ├── fanotify_controller.cpp
│ ├── fanotify_controller.h
│ ├── filewatcher_fan.cpp
│ ├── filewatcher_fan.h
│ ├── mount_controller.cpp
│ ├── mount_controller.h
│ ├── msenter.cpp
│ ├── msenter.h
│ ├── orig_mountspace_process.cpp
│ ├── orig_mountspace_process.h
│ └── shournal-run-fanotify.cpp
└── test/
├── CMakeLists.txt
├── autotest.h
├── helper_for_test.cpp
├── helper_for_test.h
├── integration_test_shell.cpp
├── main.cpp
├── sqlite_sample_db_v2_2/
│ └── readFiles/
│ ├── 3
│ └── 4
├── test_cfg.cpp
├── test_cxxhash.cpp
├── test_db_controller.cpp
├── test_fdcommunication.cpp
├── test_fileeventhandler.cpp
├── test_osutil.cpp
├── test_pathtree.cpp
├── test_qformattedstream.cpp
├── test_qoptargparse.cpp
└── test_util.cpp
SYMBOL INDEX (1497 symbols across 235 files)
FILE: extern/folly/UninitializedMemoryHacks.h
type FollyMemoryDetailTranslationUnitTag (line 32) | struct FollyMemoryDetailTranslationUnitTag {}
function namespace (line 34) | namespace folly {
function namespace (line 279) | namespace folly {
function friend (line 373) | friend void unsafeVectorSetLargerSizeImpl(std::vector<T>& v, std::size_t...
FILE: extern/tsl-ordered-map/ordered_hash.h
function namespace (line 81) | namespace tsl {
function iterator (line 533) | iterator begin() noexcept {
function const_iterator (line 537) | const_iterator begin() const noexcept {
function iterator (line 545) | iterator end() noexcept {
function const_iterator (line 549) | const_iterator end() const noexcept {
function reverse_iterator (line 558) | reverse_iterator rbegin() noexcept {
function const_reverse_iterator (line 562) | const_reverse_iterator rbegin() const noexcept {
function reverse_iterator (line 570) | reverse_iterator rend() noexcept {
function const_reverse_iterator (line 574) | const_reverse_iterator rend() const noexcept {
function size_type (line 594) | size_type max_size() const noexcept {
function iterator (line 704) | iterator erase(iterator pos) {
function iterator (line 708) | iterator erase(const_iterator pos) {
function iterator (line 725) | iterator erase(const_iterator first, const_iterator last) {
function hash (line 777) | size_t hash) {
function swap (line 781) | void swap(ordered_hash& other) {
function typename (line 812) | typename U::value_type& at(const K& key) const {
function typename (line 817) | typename U::value_type& at(const K& key, std::size_t hash) const {
function max_load_factor (line 921) | void max_load_factor(float ml) {
function rehash (line 926) | void rehash(size_type count) {
function reserve (line 931) | void reserve(size_type count) {
function iterator (line 954) | iterator mutable_iterator(const_iterator pos) {
function iterator (line 958) | iterator nth(size_type index) {
function const_iterator (line 963) | const_iterator nth(size_type index) const {
function values_container_type (line 978) | const values_container_type& values_container() const noexcept {
function shrink_to_fit (line 992) | void shrink_to_fit() {
function pop_back (line 1016) | void pop_back() {
function iterator (line 1026) | iterator unordered_erase(iterator pos) {
function iterator (line 1030) | iterator unordered_erase(const_iterator pos) {
function rehash_impl (line 1151) | void rehash_impl(size_type bucket_count) {
function reserve_space_for_values (line 1212) | reserve_space_for_values(size_type /*count*/) {
function backward_shift (line 1219) | void backward_shift(std::size_t empty_ibucket) noexcept {
function erase_value_from_bucket (line 1231) | void erase_value_from_bucket(typename buckets_container_type::iterator i...
function shift_indexes_in_buckets (line 1255) | void shift_indexes_in_buckets(index_type from_ivalue, int delta) noexcep...
function insert_index (line 1381) | void insert_index(std::size_t ibucket, std::size_t dist_from_ideal_bucket,
function grow_on_high_load (line 1446) | bool grow_on_high_load() {
function round_up_to_power_of_two (line 1535) | static std::size_t round_up_to_power_of_two(std::size_t value) {
function is_power_of_two (line 1552) | static constexpr bool is_power_of_two(std::size_t value) {
function bucket_entry (line 1573) | bucket_entry* static_empty_bucket_ptr() {
FILE: extern/tsl-ordered-map/ordered_map.h
function namespace (line 40) | namespace tsl {
function iterator (line 226) | iterator begin() noexcept { return m_ht.begin(); }
function iterator (line 230) | iterator end() noexcept { return m_ht.end(); }
function reverse_iterator (line 234) | reverse_iterator rbegin() noexcept { return m_ht.rbegin(); }
function reverse_iterator (line 238) | reverse_iterator rend() noexcept { return m_ht.rend(); }
function clear (line 253) | void clear() noexcept { m_ht.clear(); }
function iterator (line 265) | iterator insert(const_iterator hint, const value_type& value) {
function iterator (line 274) | iterator insert(const_iterator hint, value_type&& value) {
function insert (line 281) | void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist...
function iterator (line 360) | iterator erase(iterator pos) { return m_ht.erase(pos); }
function iterator (line 365) | iterator erase(const_iterator pos) { return m_ht.erase(pos); }
function iterator (line 370) | iterator erase(const_iterator first, const_iterator last) { return m_ht....
function size_type (line 375) | size_type erase(const key_type& key) { return m_ht.erase(key); }
function size_type (line 383) | size_type erase(const key_type& key, std::size_t precalculated_hash) {
function precalculated_hash (line 403) | size_t precalculated_hash) {
function swap (line 409) | void swap(ordered_map& other) { other.m_ht.swap(m_ht); }
function T (line 423) | const T& at(const Key& key) const { return m_ht.at(key); }
function T (line 428) | const T& at(const Key& key, std::size_t precalculated_hash) const { retu...
function size_type (line 466) | size_type count(const Key& key) const { return m_ht.count(key); }
function size_type (line 472) | size_type count(const Key& key, std::size_t precalculated_hash) const {
function iterator (line 496) | iterator find(const Key& key) { return m_ht.find(key); }
function iterator (line 502) | iterator find(const Key& key, std::size_t precalculated_hash) { return m...
function const_iterator (line 504) | const_iterator find(const Key& key) const { return m_ht.find(key); }
function const_iterator (line 509) | const_iterator find(const Key& key, std::size_t precalculated_hash) const {
function precalculated_hash (line 527) | size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
function max_load_factor (line 613) | void max_load_factor(float ml) { m_ht.max_load_factor(ml); }
function rehash (line 615) | void rehash(size_type count) { m_ht.rehash(count); }
function reserve (line 616) | void reserve(size_type count) { m_ht.reserve(count); }
function iterator (line 634) | iterator mutable_iterator(const_iterator pos) {
function iterator (line 643) | iterator nth(size_type index) { return m_ht.nth(index); }
function const_iterator (line 648) | const_iterator nth(size_type index) const { return m_ht.nth(index); }
function typename (line 666) | typename values_container_type::value_type* data() const noexcept { retu...
function shrink_to_fit (line 677) | void shrink_to_fit() { m_ht.shrink_to_fit(); }
function pop_back (line 727) | void pop_back() { m_ht.pop_back(); }
function iterator (line 734) | iterator unordered_erase(iterator pos) { return m_ht.unordered_erase(pos...
function iterator (line 739) | iterator unordered_erase(const_iterator pos) { return m_ht.unordered_era...
function size_type (line 744) | size_type unordered_erase(const key_type& key) { return m_ht.unordered_e...
function size_type (line 752) | size_type unordered_erase(const key_type& key, std::size_t precalculated...
function precalculated_hash (line 772) | size_t precalculated_hash) {
FILE: extern/tsl-ordered-map/ordered_set.h
function namespace (line 40) | namespace tsl {
function iterator (line 209) | iterator begin() noexcept { return m_ht.begin(); }
function iterator (line 213) | iterator end() noexcept { return m_ht.end(); }
function reverse_iterator (line 217) | reverse_iterator rbegin() noexcept { return m_ht.rbegin(); }
function reverse_iterator (line 221) | reverse_iterator rend() noexcept { return m_ht.rend(); }
function clear (line 236) | void clear() noexcept { m_ht.clear(); }
function iterator (line 243) | iterator insert(const_iterator hint, const value_type& value) {
function iterator (line 247) | iterator insert(const_iterator hint, value_type&& value) {
function insert (line 253) | void insert(std::initializer_list<value_type> ilist) { m_ht.insert(ilist...
function iterator (line 284) | iterator erase(iterator pos) { return m_ht.erase(pos); }
function iterator (line 289) | iterator erase(const_iterator pos) { return m_ht.erase(pos); }
function iterator (line 294) | iterator erase(const_iterator first, const_iterator last) { return m_ht....
function size_type (line 299) | size_type erase(const key_type& key) { return m_ht.erase(key); }
function size_type (line 307) | size_type erase(const key_type& key, std::size_t precalculated_hash) {
function precalculated_hash (line 327) | size_t precalculated_hash) {
function swap (line 333) | void swap(ordered_set& other) { other.m_ht.swap(m_ht); }
function size_type (line 338) | size_type count(const Key& key) const { return m_ht.count(key); }
function size_type (line 344) | size_type count(const Key& key, std::size_t precalculated_hash) const {
function iterator (line 369) | iterator find(const Key& key) { return m_ht.find(key); }
function iterator (line 375) | iterator find(const Key& key, std::size_t precalculated_hash) { return m...
function const_iterator (line 377) | const_iterator find(const Key& key) const { return m_ht.find(key); }
function const_iterator (line 382) | const_iterator find(const Key& key, std::size_t precalculated_hash) const {
function precalculated_hash (line 400) | size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); }
function max_load_factor (line 485) | void max_load_factor(float ml) { m_ht.max_load_factor(ml); }
function rehash (line 487) | void rehash(size_type count) { m_ht.rehash(count); }
function reserve (line 488) | void reserve(size_type count) { m_ht.reserve(count); }
function iterator (line 505) | iterator mutable_iterator(const_iterator pos) {
function iterator (line 514) | iterator nth(size_type index) { return m_ht.nth(index); }
function const_iterator (line 519) | const_iterator nth(size_type index) const { return m_ht.nth(index); }
function typename (line 537) | typename values_container_type::value_type* data() const noexcept { retu...
function shrink_to_fit (line 548) | void shrink_to_fit() { m_ht.shrink_to_fit(); }
function pop_back (line 582) | void pop_back() { m_ht.pop_back(); }
function iterator (line 589) | iterator unordered_erase(iterator pos) { return m_ht.unordered_erase(pos...
function iterator (line 594) | iterator unordered_erase(const_iterator pos) { return m_ht.unordered_era...
function size_type (line 599) | size_type unordered_erase(const key_type& key) { return m_ht.unordered_e...
function size_type (line 607) | size_type unordered_erase(const key_type& key, std::size_t precalculated...
function precalculated_hash (line 627) | size_t precalculated_hash) {
FILE: extern/xxHash/xxhash.c
function XXH_free (line 109) | static void XXH_free (void* p) { free(p); }
type BYTE (line 147) | typedef uint8_t BYTE;
type U16 (line 148) | typedef uint16_t U16;
type U32 (line 149) | typedef uint32_t U32;
type BYTE (line 151) | typedef unsigned char BYTE;
type U16 (line 152) | typedef unsigned short U16;
type U32 (line 153) | typedef unsigned int U32;
function U32 (line 160) | static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
type unalign (line 166) | typedef union { U32 u32; } __attribute__((packed)) unalign;
function U32 (line 167) | static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u...
function U32 (line 174) | static U32 XXH_read32(const void* memPtr)
function U32 (line 203) | static U32 XXH_swap32 (U32 x)
type XXH_endianess (line 216) | typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
function XXH_isLittleEndian (line 220) | static int XXH_isLittleEndian(void)
type XXH_alignment (line 232) | typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
function FORCE_INLINE (line 234) | FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endia...
function FORCE_INLINE (line 242) | FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
function U32 (line 247) | static U32 XXH_readBE32(const void* ptr)
function XXH_versionNumber (line 257) | XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NU...
function U32 (line 269) | static U32 XXH32_round(U32 seed, U32 input)
function U32 (line 278) | static U32 XXH32_avalanche(U32 h32)
function U32 (line 290) | static U32
function FORCE_INLINE (line 351) | FORCE_INLINE U32
function XXH32 (line 392) | XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsign...
function XXH_PUBLIC_API (line 422) | XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
function XXH_PUBLIC_API (line 426) | XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
function XXH_PUBLIC_API (line 432) | XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32...
function XXH_PUBLIC_API (line 437) | XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsign...
function FORCE_INLINE (line 451) | FORCE_INLINE
function XXH_PUBLIC_API (line 514) | XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, cons...
function FORCE_INLINE (line 525) | FORCE_INLINE U32
function XXH32_digest (line 545) | XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
function XXH_PUBLIC_API (line 564) | XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH3...
function XXH_PUBLIC_API (line 571) | XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonica...
type U64 (line 591) | typedef uint64_t U64;
type U64 (line 594) | typedef unsigned long long U64;
function U64 (line 602) | static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
type unalign64 (line 608) | typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;
function U64 (line 609) | static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)-...
function U64 (line 617) | static U64 XXH_read64(const void* memPtr)
function U64 (line 631) | static U64 XXH_swap64 (U64 x)
function FORCE_INLINE (line 644) | FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endia...
function FORCE_INLINE (line 652) | FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
function U64 (line 657) | static U64 XXH_readBE64(const void* ptr)
function U64 (line 671) | static U64 XXH64_round(U64 acc, U64 input)
function U64 (line 679) | static U64 XXH64_mergeRound(U64 acc, U64 val)
function U64 (line 687) | static U64 XXH64_avalanche(U64 h64)
function U64 (line 700) | static U64
function FORCE_INLINE (line 810) | FORCE_INLINE U64
function XXH64 (line 855) | XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, ...
function XXH_PUBLIC_API (line 883) | XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
function XXH_PUBLIC_API (line 887) | XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
function XXH_PUBLIC_API (line 893) | XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64...
function XXH_PUBLIC_API (line 898) | XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsign...
function FORCE_INLINE (line 911) | FORCE_INLINE
function XXH_PUBLIC_API (line 970) | XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, cons...
function FORCE_INLINE (line 980) | FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_en...
function XXH64_digest (line 1004) | XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* sta...
function XXH_PUBLIC_API (line 1017) | XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH6...
function XXH_PUBLIC_API (line 1024) | XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonica...
FILE: extern/xxHash/xxhash.h
type XXH_errorcode (line 79) | typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
type XXH32_hash_t (line 162) | typedef unsigned int XXH32_hash_t;
type XXH32_state_t (line 172) | typedef struct XXH32_state_s XXH32_state_t;
type XXH32_canonical_t (line 204) | typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
type XXH64_hash_t (line 219) | typedef unsigned long long XXH64_hash_t;
type XXH64_state_t (line 229) | typedef struct XXH64_state_s XXH64_state_t;
type XXH64_canonical_t (line 239) | typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
type XXH32_state_s (line 264) | struct XXH32_state_s {
type XXH64_state_s (line 276) | struct XXH64_state_s {
type XXH32_state_s (line 289) | struct XXH32_state_s {
type XXH64_state_s (line 302) | struct XXH64_state_s {
FILE: extern/xxHash/xxhsum.c
type BYTE (line 89) | typedef uint8_t BYTE;
type U16 (line 90) | typedef uint16_t U16;
type U32 (line 91) | typedef uint32_t U32;
type S32 (line 92) | typedef int32_t S32;
type U64 (line 93) | typedef uint64_t U64;
type BYTE (line 95) | typedef unsigned char BYTE;
type U16 (line 96) | typedef unsigned short U16;
type U32 (line 97) | typedef unsigned int U32;
type S32 (line 98) | typedef signed int S32;
type U64 (line 99) | typedef unsigned long long U64;
function BMK_isLittleEndian (line 103) | static unsigned BMK_isLittleEndian(void)
type algoType (line 139) | typedef enum { algo_xxh32, algo_xxh64 } algoType;
function clock_t (line 168) | static clock_t BMK_clockSpan( clock_t start )
function BMK_findMaxMem (line 174) | static size_t BMK_findMaxMem(U64 requiredMem)
function U64 (line 198) | static U64 BMK_GetFileSize(const char* infilename)
type U32 (line 212) | typedef U32 (*hashFunction)(const void* buffer, size_t bufferSize, U32 s...
function U32 (line 214) | static U32 localXXH32(const void* buffer, size_t bufferSize, U32 seed) {...
function U32 (line 216) | static U32 localXXH64(const void* buffer, size_t bufferSize, U32 seed) {...
function BMK_benchHash (line 218) | static void BMK_benchHash(hashFunction h, const char* hName, const void*...
function BMK_benchMem (line 263) | static int BMK_benchMem(const void* buffer, size_t bufferSize, U32 speci...
function BMK_selectBenchedSize (line 291) | static size_t BMK_selectBenchedSize(const char* fileName)
function BMK_benchFiles (line 302) | static int BMK_benchFiles(const char** fileNamesTable, int nbFiles, U32 ...
function BMK_benchInternal (line 347) | static int BMK_benchInternal(size_t keySize, int specificTest)
function BMK_checkResult (line 372) | static void BMK_checkResult(U32 r1, U32 r2)
function BMK_checkResult64 (line 385) | static void BMK_checkResult64(U64 r1, U64 r2)
function BMK_testSequence64 (line 397) | static void BMK_testSequence64(void* sentence, size_t len, U64 seed, U64...
function BMK_testSequence (line 419) | static void BMK_testSequence(const void* sequence, size_t len, U32 seed,...
function BMK_sanityCheck (line 442) | static void BMK_sanityCheck(void)
function BMK_display_LittleEndian (line 481) | static void BMK_display_LittleEndian(const void* ptr, size_t length)
function BMK_display_BigEndian (line 489) | static void BMK_display_BigEndian(const void* ptr, size_t length)
function BMK_hashStream (line 497) | static void BMK_hashStream(void* xxhHashValue, const algoType hashType, ...
type endianess (line 542) | typedef enum { big_endian, little_endian} endianess;
function BMK_hash (line 544) | static int BMK_hash(const char* fileName,
function BMK_hashFiles (line 630) | static int BMK_hashFiles(const char** fnList, int fnTotal,
type GetLineResult (line 646) | typedef enum {
type CanonicalFromStringResult (line 653) | typedef enum {
type ParseLineResult (line 658) | typedef enum {
type LineStatus (line 663) | typedef enum {
type Canonical (line 669) | typedef union {
type ParsedLine (line 674) | typedef struct {
type ParseFileReport (line 680) | typedef struct {
type ParseFileArg (line 690) | typedef struct {
function GetLineResult (line 711) | static GetLineResult getLine(char** lineBuf, int* lineMax, FILE* inFile)
function charToHex (line 762) | static int charToHex(char c)
function CanonicalFromStringResult (line 780) | static CanonicalFromStringResult canonicalFromString(unsigned char* dst,
function ParseLineResult (line 813) | static ParseLineResult parseLine(ParsedLine* parsedLine, const char* line)
function parseFile1 (line 857) | static void parseFile1(ParseFileArg* parseFileArg)
function checkFile (line 1015) | static int checkFile(const char* inFileName,
function checkFiles (line 1095) | static int checkFiles(const char** fnList, int fnTotal,
function usage (line 1121) | static int usage(const char* exename)
function usage_advanced (line 1135) | static int usage_advanced(const char* exename)
function badusage (line 1153) | static int badusage(const char* exename)
function readU32FromChar (line 1166) | static unsigned readU32FromChar(const char** stringPtr)
function main (line 1181) | int main(int argc, const char** argv)
FILE: html-export/dist/main.js
function __webpack_require__ (line 6) | function __webpack_require__(moduleId) {
function Mutex (line 106) | function Mutex() {
class GenericTextDialog (line 165) | class GenericTextDialog {
method constructor (line 166) | constructor() {
method show (line 169) | show(title, content){
function init (line 192) | function init(){
function prepareCommands (line 210) | function prepareCommands(commands){
function compareStartDates (line 224) | function compareStartDates(cmd1, cmd2) {
function compareEndDates (line 234) | function compareEndDates(cmd1, cmd2) {
function _fillCommandSessionColors (line 245) | function _fillCommandSessionColors(commands){
function insertAfter (line 274) | function insertAfter(newNode, referenceNode) {
function isScrolledIntoView (line 287) | function isScrolledIntoView(element, container, partial) {
class ErrorNotImplemented (line 308) | class ErrorNotImplemented extends Error {
method constructor (line 309) | constructor() {
function sleep (line 314) | function sleep(ms) {
function getTime (line 318) | function getTime() {
function date_max (line 322) | function date_max(d1, d2){
function date_min (line 326) | function date_min(d1, d2){
function windowWidth (line 330) | function windowWidth() {
function windowHeight (line 337) | function windowHeight() {
function assert (line 344) | function assert(condition, message) {
function timedForEach (line 357) | async function timedForEach(array, func) {
function binarySearch (line 392) | function binarySearch(ar, el, compareFn, clipIdx=false) {
function getDirFromAbsPath (line 428) | function getDirFromAbsPath(path){
function bytesToHuman (line 441) | function bytesToHuman(bytes, si = false) {
class command_list_CommandList (line 464) | class command_list_CommandList {
method constructor (line 465) | constructor(commands) {
method scrollToCmd (line 516) | scrollToCmd(cmd) {
method _selectCmdEntry (line 530) | _selectCmdEntry(cmd){
method _computeCmdBackground (line 534) | _computeCmdBackground(cmd){
method _handleClickOnCmd (line 540) | _handleClickOnCmd(cmd, idx){
class MapExtended (line 641) | class MapExtended extends Map {
method getDefault (line 651) | getDefault(key, defaultFactory) {
class TinyQueue (line 667) | class TinyQueue {
method constructor (line 668) | constructor(data = [], compare = defaultCompare) {
method push (line 678) | push(item) {
method pop (line 684) | pop() {
method peek (line 699) | peek() {
method _up (line 703) | _up(pos) {
method _down (line 718) | _down(pos) {
function defaultCompare (line 742) | function defaultCompare(a, b) {
class timeline_group_find_TimelineGroupFind (line 758) | class timeline_group_find_TimelineGroupFind {
method constructor (line 760) | constructor(){
method findNextFreeGroup (line 770) | findNextFreeGroup(startDate, endDate){
class _LastEndDateGroup (line 787) | class _LastEndDateGroup {
method constructor (line 788) | constructor(group, endTime){
class annotation_line_render_AnnotationLineRender (line 808) | class annotation_line_render_AnnotationLineRender {
method constructor (line 809) | constructor(plot) {
method addAnnotationGroup (line 831) | addAnnotationGroup(group) {
method update (line 836) | async update(xScale) {
method setOnNoteClick (line 856) | setOnNoteClick(func){
method _compareStartX (line 862) | _compareStartX(prev, current) {
method _compareEndX (line 866) | _compareEndX(prev, current) {
method _preRenderAnnotations (line 870) | async _preRenderAnnotations(xScale, currentUpdateDummy ) {
method _calcAnnotationCenter (line 935) | _calcAnnotationCenter(annotation, xScale) {
method _generateAnnotationTxt (line 944) | _generateAnnotationTxt(textspace, txt) {
method _appendAnnotations (line 965) | _appendAnnotations(annotations) {
class ZoomButtons (line 1022) | class ZoomButtons {
method constructor (line 1031) | constructor(containerDiv, zoomArea, d3Zoom) {
method _appendZoomButton (line 1061) | _appendZoomButton(container, text) {
class session_timeline_SessionTimeline (line 1076) | class session_timeline_SessionTimeline {
method constructor (line 1077) | constructor(commands, cmdFinalEndDate) {
method getSvg (line 1238) | getSvg(){
method _generateCommandsPerSession (line 1242) | _generateCommandsPerSession(commands) {
method _prerenderSessions (line 1326) | _prerenderSessions(groupedSessions){
method _preRenderAnnotations (line 1374) | _preRenderAnnotations(groupedSessions){
method _createAnnotation (line 1392) | _createAnnotation(cmdWithMeta, y){
method _calcRectXPosition (line 1410) | _calcRectXPosition(cmd, xScale) {
method _calcRectWidth (line 1423) | _calcRectWidth(cmd, xScale) {
method _handleZoom (line 1432) | _handleZoom(transform) {
class _CommandWithMeta (line 1459) | class _CommandWithMeta{
method constructor (line 1465) | constructor(cmd, group){
method getGroup (line 1474) | getGroup(){
method setCountOfParallelGroups (line 1478) | setCountOfParallelGroups(val){
method getCountOfParallelGroups (line 1482) | getCountOfParallelGroups(){
method setHeight (line 1486) | setHeight(val){
method getHeight (line 1490) | getHeight(){
method setY (line 1494) | setY(val){
method getY (line 1498) | getY(){
method setAnnotation (line 1502) | setAnnotation(val){
method getAnnotation (line 1506) | getAnnotation(){
class session_timeline_Session (line 1512) | class session_timeline_Session {
method constructor (line 1513) | constructor() {
method addCmd (line 1528) | addCmd(cmd) {
method setMaxCountOfParallelCommands (line 1542) | setMaxCountOfParallelCommands(val){
method getMaxCountOfParallelCommands (line 1546) | getMaxCountOfParallelCommands(){
method getSessionStartDate (line 1551) | getSessionStartDate(){
method getSessionEndDate (line 1555) | getSessionEndDate(){
method setSessionGroup (line 1559) | setSessionGroup(val){
method getSessionGroup (line 1563) | getSessionGroup(){
method getCmdsWithMeta (line 1567) | getCmdsWithMeta(){
method setHeight (line 1571) | setHeight(val){
method getHeight (line 1575) | getHeight(){
method setY (line 1579) | setY(val){
method getY (line 1583) | getY(){
function wrapTextLabels (line 1602) | function wrapTextLabels(tickTexts, width, splitStr=/(?=\s)/) {
function _truncateAndSetLabelTxt (line 1642) | function _truncateAndSetLabelTxt(labelTxt, tspan, width) {
class plot_simple_bar_PlotSimpleBar (line 1661) | class plot_simple_bar_PlotSimpleBar {
method constructor (line 1662) | constructor() {
method generatePlot (line 1670) | generatePlot(data, siblingElement) {
method _chartTitle (line 1766) | _chartTitle(){ throw new ErrorNotImplemented(); }
method _yScaleBandDomain (line 1767) | _yScaleBandDomain(){ throw new ErrorNotImplemented(); }
method _xValue (line 1769) | _xValue(d){ throw new ErrorNotImplemented(); }
method _yValue (line 1771) | _yValue(d){ throw new ErrorNotImplemented(); }
method _yAxisTicksFilter (line 1774) | _yAxisTicksFilter(tick){ return true; }
method _yAxisTickFormat (line 1775) | _yAxisTickFormat() { return undefined; }
method _modifyTickText (line 1776) | _modifyTickText(tickTxt, data) {}
method _xTxtLabelSplitStr (line 1778) | _xTxtLabelSplitStr() { return /(?=\s)/; }
method _barTooltipTxt (line 1779) | _barTooltipTxt(dataElement){
method _xAxisTooltipTxt (line 1782) | _xAxisTooltipTxt(dataElement){
method _barColor (line 1785) | _barColor(dataElement){
method _modifyBars (line 1789) | _modifyBars(bars){}
class plot_most_written_files_PlotMostWrittenFiles (line 1805) | class plot_most_written_files_PlotMostWrittenFiles extends plot_simple_b...
method generatePlot (line 1807) | generatePlot(commands, siblingElement){
method _chartTitle (line 1823) | _chartTitle(){ return 'Commands with most file-modifications'; }
method _yScaleBandDomain (line 1828) | _yScaleBandDomain(){ return [0, this._maxCountOfWfileEvents]; }
method _xValue (line 1833) | _xValue(cmd) {
method _yValue (line 1841) | _yValue(cmd) {
method _yAxisTicksFilter (line 1848) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 1853) | _yAxisTickFormat() { return d3.format('d'); }
method _barColor (line 1856) | _barColor(cmd){
method _modifyBars (line 1860) | _modifyBars(bars){
method _modifyTickText (line 1868) | _modifyTickText(tickTxt, cmd) {
class plot_cmdcount_per_cwd_PlotCmdCountPerCwd (line 1888) | class plot_cmdcount_per_cwd_PlotCmdCountPerCwd extends plot_simple_bar_P...
method generatePlot (line 1890) | generatePlot(commands, siblingElement){
method _chartTitle (line 1897) | _chartTitle(){ return 'Working directories with most commands'; }
method _yScaleBandDomain (line 1903) | _yScaleBandDomain(){ return [0, cwdCmdCounts[0].countOfCommands]; }
method _xValue (line 1908) | _xValue(cwdCmdCount) {
method _yValue (line 1915) | _yValue(cwdCmdCount) {
method _yAxisTicksFilter (line 1922) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 1927) | _yAxisTickFormat() { return d3.format('d'); }
method _xTxtLabelSplitStr (line 1930) | _xTxtLabelSplitStr() { return /(?=\/)/; }
class plot_io_per_dir_PlotIoPerDir (line 1945) | class plot_io_per_dir_PlotIoPerDir extends plot_simple_bar_PlotSimpleBar {
method generatePlot (line 1947) | generatePlot(commands, siblingElement){
method _chartTitle (line 1954) | _chartTitle(){ return 'Directories with most input-output-activity'; }
method _yScaleBandDomain (line 1960) | _yScaleBandDomain(){ return [0, dirIoCounts[0].readCount + dirIoCounts...
method _xValue (line 1965) | _xValue(ioStat) {
method _yValue (line 1972) | _yValue(ioStat) {
method _yAxisTicksFilter (line 1979) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 1984) | _yAxisTickFormat() { return d3.format('d'); }
method _xTxtLabelSplitStr (line 1989) | _xTxtLabelSplitStr() { return /(?=\/)/; }
class plot_cmdcount_per_session_PlotCmdCountPerSession (line 2002) | class plot_cmdcount_per_session_PlotCmdCountPerSession extends plot_simp...
method generatePlot (line 2004) | generatePlot(commands, siblingElement) {
method _chartTitle (line 2024) | _chartTitle(){ return 'Sessions with most commands'; }
method _yScaleBandDomain (line 2030) | _yScaleBandDomain(){ return [0, this._maxCountOfCmdsInSession]; }
method _xValue (line 2035) | _xValue(session) {
method _yValue (line 2042) | _yValue(session) {
method _yAxisTicksFilter (line 2049) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 2054) | _yAxisTickFormat() { return d3.format('d'); }
method _compareBySessionCmdCount (line 2062) | _compareBySessionCmdCount(cmds1, cmds2) {
method _barColor (line 2066) | _barColor(session){
method _modifyBars (line 2070) | _modifyBars(bars){
method _modifyTickText (line 2078) | _modifyTickText(tickTxt, session) {
class _SessionMostCmdsEntry (line 2089) | class _SessionMostCmdsEntry {
method constructor (line 2090) | constructor(firstCmd, countOfCommands){
function generateMiscStats (line 2107) | async function generateMiscStats() {
function displayErrorAtTop (line 2169) | function displayErrorAtTop(msg){
function main (line 2177) | function main() {
FILE: html-export/src/annotation_line_render.js
class AnnotationLineRender (line 11) | class AnnotationLineRender {
method constructor (line 12) | constructor(plot) {
method addAnnotationGroup (line 34) | addAnnotationGroup(group) {
method update (line 39) | async update(xScale) {
method setOnNoteClick (line 59) | setOnNoteClick(func){
method _compareStartX (line 65) | _compareStartX(prev, current) {
method _compareEndX (line 69) | _compareEndX(prev, current) {
method _preRenderAnnotations (line 73) | async _preRenderAnnotations(xScale, currentUpdateDummy ) {
method _calcAnnotationCenter (line 138) | _calcAnnotationCenter(annotation, xScale) {
method _generateAnnotationTxt (line 147) | _generateAnnotationTxt(textspace, txt) {
method _appendAnnotations (line 168) | _appendAnnotations(annotations) {
FILE: html-export/src/command_list.js
class CommandList (line 7) | class CommandList {
method constructor (line 8) | constructor(commands) {
method scrollToCmd (line 59) | scrollToCmd(cmd) {
method _selectCmdEntry (line 73) | _selectCmdEntry(cmd){
method _computeCmdBackground (line 77) | _computeCmdBackground(cmd){
method _handleClickOnCmd (line 83) | _handleClickOnCmd(cmd, idx){
FILE: html-export/src/command_manipulation.js
function prepareCommands (line 8) | function prepareCommands(commands){
function compareStartDates (line 22) | function compareStartDates(cmd1, cmd2) {
function compareEndDates (line 32) | function compareEndDates(cmd1, cmd2) {
function _fillCommandSessionColors (line 43) | function _fillCommandSessionColors(commands){
FILE: html-export/src/command_timeline.js
class CommandTimeline (line 5) | class CommandTimeline {
method constructor (line 6) | constructor(commands, countOfCmdGroups,
method getSvg (line 146) | getSvg(){
method setCommandList (line 150) | setCommandList(commandList){
method _setupAnnotations (line 154) | _setupAnnotations(){
method _generateCommandsPerGroup (line 190) | _generateCommandsPerGroup() {
method _generateCommandGroupOffsets (line 203) | _generateCommandGroupOffsets() {
method _calcRectXPosition (line 215) | _calcRectXPosition(cmd, xScale) {
method _calcRectWidth (line 228) | _calcRectWidth(cmd, xScale) {
method _handleZoom (line 237) | _handleZoom(transform) {
class _CmdRectHeights (line 263) | class _CmdRectHeights {
method NO_MOD (line 264) | static get NO_MOD() { return 7; }
method FEW_MOD (line 265) | static get FEW_MOD() { return 14; }
method MANY_MOD (line 266) | static get MANY_MOD() { return 20; }
method VERY_MANY_MOD (line 267) | static get VERY_MANY_MOD() { return 24; }
FILE: html-export/src/conversions.js
function bytesToHuman (line 7) | function bytesToHuman(bytes, si = false) {
FILE: html-export/src/d3js_util.js
function wrapTextLabels (line 12) | function wrapTextLabels(tickTexts, width, splitStr=/(?=\s)/) {
function _truncateAndSetLabelTxt (line 52) | function _truncateAndSetLabelTxt(labelTxt, tspan, width) {
FILE: html-export/src/generic_text_dialog.js
class GenericTextDialog (line 3) | class GenericTextDialog {
method constructor (line 4) | constructor() {
method show (line 7) | show(title, content){
FILE: html-export/src/globals.js
function init (line 16) | function init(){
FILE: html-export/src/html_util.js
function insertAfter (line 3) | function insertAfter(newNode, referenceNode) {
function isScrolledIntoView (line 16) | function isScrolledIntoView(element, container, partial) {
FILE: html-export/src/index.js
function displayErrorAtTop (line 9) | function displayErrorAtTop(msg){
function main (line 17) | function main() {
FILE: html-export/src/limited_queue.js
class LimitedQueue (line 9) | class LimitedQueue extends TinyQueue {
method setMaxLength (line 11) | setMaxLength(l){
method push (line 18) | push(item) {
method popAll (line 25) | popAll(){
FILE: html-export/src/map_extended.js
class MapExtended (line 3) | class MapExtended extends Map {
method getDefault (line 13) | getDefault(key, defaultFactory) {
FILE: html-export/src/plot_cmdcount_per_cwd.js
class PlotCmdCountPerCwd (line 9) | class PlotCmdCountPerCwd extends PlotSimpleBar {
method generatePlot (line 11) | generatePlot(commands, siblingElement){
method _chartTitle (line 18) | _chartTitle(){ return 'Working directories with most commands'; }
method _yScaleBandDomain (line 24) | _yScaleBandDomain(){ return [0, cwdCmdCounts[0].countOfCommands]; }
method _xValue (line 29) | _xValue(cwdCmdCount) {
method _yValue (line 36) | _yValue(cwdCmdCount) {
method _yAxisTicksFilter (line 43) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 48) | _yAxisTickFormat() { return d3.format('d'); }
method _xTxtLabelSplitStr (line 51) | _xTxtLabelSplitStr() { return /(?=\/)/; }
FILE: html-export/src/plot_cmdcount_per_session.js
class PlotCmdCountPerSession (line 10) | class PlotCmdCountPerSession extends PlotSimpleBar {
method generatePlot (line 12) | generatePlot(commands, siblingElement) {
method _chartTitle (line 32) | _chartTitle(){ return 'Sessions with most commands'; }
method _yScaleBandDomain (line 38) | _yScaleBandDomain(){ return [0, this._maxCountOfCmdsInSession]; }
method _xValue (line 43) | _xValue(session) {
method _yValue (line 50) | _yValue(session) {
method _yAxisTicksFilter (line 57) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 62) | _yAxisTickFormat() { return d3.format('d'); }
method _compareBySessionCmdCount (line 70) | _compareBySessionCmdCount(cmds1, cmds2) {
method _barColor (line 74) | _barColor(session){
method _modifyBars (line 78) | _modifyBars(bars){
method _modifyTickText (line 86) | _modifyTickText(tickTxt, session) {
class _SessionMostCmdsEntry (line 97) | class _SessionMostCmdsEntry {
method constructor (line 98) | constructor(firstCmd, countOfCommands){
FILE: html-export/src/plot_io_per_dir.js
class PlotIoPerDir (line 9) | class PlotIoPerDir extends PlotSimpleBar {
method generatePlot (line 11) | generatePlot(commands, siblingElement){
method _chartTitle (line 18) | _chartTitle(){ return 'Directories with most input-output-activity'; }
method _yScaleBandDomain (line 24) | _yScaleBandDomain(){ return [0, dirIoCounts[0].readCount + dirIoCounts...
method _xValue (line 29) | _xValue(ioStat) {
method _yValue (line 36) | _yValue(ioStat) {
method _yAxisTicksFilter (line 43) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 48) | _yAxisTickFormat() { return d3.format('d'); }
method _xTxtLabelSplitStr (line 53) | _xTxtLabelSplitStr() { return /(?=\/)/; }
FILE: html-export/src/plot_most_written_files.js
class PlotMostWrittenFiles (line 11) | class PlotMostWrittenFiles extends PlotSimpleBar {
method generatePlot (line 13) | generatePlot(commands, siblingElement){
method _chartTitle (line 29) | _chartTitle(){ return 'Commands with most file-modifications'; }
method _yScaleBandDomain (line 34) | _yScaleBandDomain(){ return [0, this._maxCountOfWfileEvents]; }
method _xValue (line 39) | _xValue(cmd) {
method _yValue (line 47) | _yValue(cmd) {
method _yAxisTicksFilter (line 54) | _yAxisTicksFilter(tick){ return Number.isInteger(tick); }
method _yAxisTickFormat (line 59) | _yAxisTickFormat() { return d3.format('d'); }
method _barColor (line 62) | _barColor(cmd){
method _modifyBars (line 66) | _modifyBars(bars){
method _modifyTickText (line 74) | _modifyTickText(tickTxt, cmd) {
FILE: html-export/src/plot_simple_bar.js
class PlotSimpleBar (line 9) | class PlotSimpleBar {
method constructor (line 10) | constructor() {
method generatePlot (line 18) | generatePlot(data, siblingElement) {
method _chartTitle (line 114) | _chartTitle(){ throw new ErrorNotImplemented(); }
method _yScaleBandDomain (line 115) | _yScaleBandDomain(){ throw new ErrorNotImplemented(); }
method _xValue (line 117) | _xValue(d){ throw new ErrorNotImplemented(); }
method _yValue (line 119) | _yValue(d){ throw new ErrorNotImplemented(); }
method _yAxisTicksFilter (line 122) | _yAxisTicksFilter(tick){ return true; }
method _yAxisTickFormat (line 123) | _yAxisTickFormat() { return undefined; }
method _modifyTickText (line 124) | _modifyTickText(tickTxt, data) {}
method _xTxtLabelSplitStr (line 126) | _xTxtLabelSplitStr() { return /(?=\s)/; }
method _barTooltipTxt (line 127) | _barTooltipTxt(dataElement){
method _xAxisTooltipTxt (line 130) | _xAxisTooltipTxt(dataElement){
method _barColor (line 133) | _barColor(dataElement){
method _modifyBars (line 137) | _modifyBars(bars){}
FILE: html-export/src/session_timeline.js
class SessionTimeline (line 8) | class SessionTimeline {
method constructor (line 9) | constructor(commands, cmdFinalEndDate) {
method getSvg (line 170) | getSvg(){
method _generateCommandsPerSession (line 174) | _generateCommandsPerSession(commands) {
method _prerenderSessions (line 258) | _prerenderSessions(groupedSessions){
method _preRenderAnnotations (line 306) | _preRenderAnnotations(groupedSessions){
method _createAnnotation (line 324) | _createAnnotation(cmdWithMeta, y){
method _calcRectXPosition (line 342) | _calcRectXPosition(cmd, xScale) {
method _calcRectWidth (line 355) | _calcRectWidth(cmd, xScale) {
method _handleZoom (line 364) | _handleZoom(transform) {
class _CommandWithMeta (line 391) | class _CommandWithMeta{
method constructor (line 397) | constructor(cmd, group){
method getGroup (line 406) | getGroup(){
method setCountOfParallelGroups (line 410) | setCountOfParallelGroups(val){
method getCountOfParallelGroups (line 414) | getCountOfParallelGroups(){
method setHeight (line 418) | setHeight(val){
method getHeight (line 422) | getHeight(){
method setY (line 426) | setY(val){
method getY (line 430) | getY(){
method setAnnotation (line 434) | setAnnotation(val){
method getAnnotation (line 438) | getAnnotation(){
class _Session (line 444) | class _Session {
method constructor (line 445) | constructor() {
method addCmd (line 460) | addCmd(cmd) {
method setMaxCountOfParallelCommands (line 474) | setMaxCountOfParallelCommands(val){
method getMaxCountOfParallelCommands (line 478) | getMaxCountOfParallelCommands(){
method getSessionStartDate (line 483) | getSessionStartDate(){
method getSessionEndDate (line 487) | getSessionEndDate(){
method setSessionGroup (line 491) | setSessionGroup(val){
method getSessionGroup (line 495) | getSessionGroup(){
method getCmdsWithMeta (line 499) | getCmdsWithMeta(){
method setHeight (line 503) | setHeight(val){
method getHeight (line 507) | getHeight(){
method setY (line 511) | setY(val){
method getY (line 515) | getY(){
FILE: html-export/src/stats.js
function generateMiscStats (line 9) | async function generateMiscStats() {
FILE: html-export/src/timeline_group_find.js
class TimelineGroupFind (line 12) | class TimelineGroupFind {
method constructor (line 14) | constructor(){
method findNextFreeGroup (line 24) | findNextFreeGroup(startDate, endDate){
class _LastEndDateGroup (line 41) | class _LastEndDateGroup {
method constructor (line 42) | constructor(group, endTime){
FILE: html-export/src/tooltip.js
class Tooltip (line 3) | class Tooltip {
method constructor (line 5) | constructor(){
method show (line 19) | show(txt, x, y) {
method hide (line 29) | hide() {
FILE: html-export/src/util.js
class ErrorNotImplemented (line 2) | class ErrorNotImplemented extends Error {
method constructor (line 3) | constructor() {
function sleep (line 8) | function sleep(ms) {
function getTime (line 12) | function getTime() {
function date_max (line 16) | function date_max(d1, d2){
function date_min (line 20) | function date_min(d1, d2){
function windowWidth (line 24) | function windowWidth() {
function windowHeight (line 31) | function windowHeight() {
function assert (line 38) | function assert(condition, message) {
constant DATE_MIN (line 44) | const DATE_MIN = new Date(-8640000000000000);
function timedForEach (line 51) | async function timedForEach(array, func) {
function binarySearch (line 86) | function binarySearch(ar, el, compareFn, clipIdx=false) {
function getDirFromAbsPath (line 122) | function getDirFromAbsPath(path){
FILE: html-export/src/zoom_buttons.js
class ZoomButtons (line 3) | class ZoomButtons {
method constructor (line 12) | constructor(containerDiv, zoomArea, d3Zoom) {
method _appendZoomButton (line 42) | _appendZoomButton(container, text) {
FILE: kernel/event_consumer.c
function __path_is_hidden (line 31) | static inline bool __path_is_hidden(const char* pathname, int path_len){
type file (line 35) | struct file
type path (line 36) | struct path
type cred (line 36) | struct cred
function __dbg_print_event (line 45) | static void __dbg_print_event(struct event_target* t __attribute__ ((unu...
function __dbg_print_event (line 64) | static void __dbg_print_event(struct event_target* t __attribute__ ((unu...
function __write_to_target_file_safe (line 71) | static bool __write_to_target_file_safe(struct event_target* event_target,
function __do_hash_file (line 94) | static void __do_hash_file(struct partial_xxhash* part_hash,
function __correct_file_event_at_pos (line 133) | static bool
function __write_file_content (line 154) | static bool
function __do_log_file_event (line 190) | static bool __do_log_file_event(struct event_target* t,
function __handle_read_event (line 270) | static void
function __handle_write_event (line 381) | static void
function event_consumer_init (line 452) | long event_consumer_init(struct event_consumer* consumer){
function event_consumer_cleanup (line 489) | void event_consumer_cleanup(struct event_consumer* c){
function event_consumer_thread_create (line 500) | long event_consumer_thread_create(struct event_target* event_target,
function event_consumer_thread_setup (line 527) | void event_consumer_thread_setup(struct event_target* event_target){
function event_consumer_thread_cleanup (line 579) | void event_consumer_thread_cleanup(struct event_target* event_target){
function event_consumer_thread_stop (line 593) | void event_consumer_thread_stop(struct event_consumer* consumer){
function event_consumer_flush_target_file_safe (line 600) | bool event_consumer_flush_target_file_safe(struct event_target *t)
function close_event_consume (line 614) | void close_event_consume(struct event_target* event_target, struct close...
function close_event_cleanup (line 650) | void close_event_cleanup(struct close_event* event){
FILE: kernel/event_consumer.h
type event_target (line 17) | struct event_target
type consumer_cache (line 18) | struct consumer_cache
type close_event (line 20) | struct close_event {
type event_consumer (line 25) | struct event_consumer {
type event_consumer (line 45) | struct event_consumer
type event_consumer (line 46) | struct event_consumer
type event_target (line 48) | struct event_target
type event_target (line 50) | struct event_target
type event_target (line 51) | struct event_target
type event_consumer (line 53) | struct event_consumer
type event_target (line 55) | struct event_target
type event_target (line 58) | struct event_target
type close_event (line 58) | struct close_event
type close_event (line 59) | struct close_event
FILE: kernel/event_consumer_cache.c
function d_path_len (line 9) | static inline size_t
function __cache_entry_init (line 14) | static void __cache_entry_init(struct consumer_cache_entry* e){
function __cache_entry_hit (line 23) | static bool __cache_entry_hit(const struct consumer_cache_entry*e,
function __append_dname_to_parent (line 33) | static bool __append_dname_to_parent(struct consumer_cache_entry* parent,
function consumer_cache_init (line 60) | void consumer_cache_init(struct consumer_cache* c){
type consumer_cache_entry (line 70) | struct consumer_cache_entry
type consumer_cache (line 71) | struct consumer_cache
type vfsmount (line 71) | struct vfsmount
type dentry (line 71) | struct dentry
type consumer_cache_entry (line 74) | struct consumer_cache_entry
type dentry (line 75) | struct dentry
type kutil_name_snapshot (line 85) | struct kutil_name_snapshot
type consumer_cache_entry (line 110) | struct consumer_cache_entry
FILE: kernel/event_consumer_cache.h
type consumer_cache_entry (line 29) | struct consumer_cache_entry {
type consumer_cache (line 38) | struct consumer_cache {
type consumer_cache (line 43) | struct consumer_cache
type consumer_cache_entry (line 45) | struct consumer_cache_entry
type consumer_cache (line 46) | struct consumer_cache
type vfsmount (line 46) | struct vfsmount
type dentry (line 46) | struct dentry
FILE: kernel/event_handler.c
type task_entry (line 19) | struct task_entry {
type kmem_cache (line 26) | struct kmem_cache
type workqueue_struct (line 29) | struct workqueue_struct
type task_entry (line 31) | struct task_entry
function __task_entry_destroy (line 37) | static void
function __task_entry_destroy_work (line 43) | static void __task_entry_destroy_work(struct work_struct *work){
function u32 (line 50) | static inline u32
type task_entry (line 56) | struct task_entry
type task_struct (line 57) | struct task_struct
type task_entry (line 59) | struct task_entry
type event_target (line 71) | struct event_target
type task_struct (line 72) | struct task_struct
type task_entry (line 73) | struct task_entry
type event_target (line 74) | struct event_target
function __handle_exit_tsk_remove (line 90) | static inline void
function __insert_task_into_table_safe (line 114) | static long
function __remove_task_from_table_safe (line 177) | static bool
function __fput_is_interesting (line 209) | static inline bool __fput_is_interesting(const struct file* file,
function __task_check_same_owner (line 225) | static bool __task_check_same_owner(struct task_struct *task)
type task_struct (line 239) | struct task_struct
type task_struct (line 240) | struct task_struct
function event_handler_constructor (line 260) | int event_handler_constructor(void) {
function event_handler_destructor (line 274) | void event_handler_destructor(void)
type event_target (line 298) | struct event_target
type task_struct (line 300) | struct task_struct
type event_target (line 301) | struct event_target
type event_target (line 304) | struct event_target
function event_handler_add_pid (line 321) | long event_handler_add_pid(struct event_target* event_target, pid_t pid,
function event_handler_remove_pid (line 348) | long event_handler_remove_pid(pid_t pid){
function event_handler_fput (line 370) | void event_handler_fput(unsigned long ip __attribute__ ((unused)),
function event_handler_process_exit (line 416) | void event_handler_process_exit(struct task_struct *task)
function event_handler_process_fork (line 432) | void event_handler_process_fork(struct task_struct *parent,
FILE: kernel/event_handler.h
type event_target (line 7) | struct event_target
type ftrace_ops (line 8) | struct ftrace_ops
type pt_regs (line 9) | struct pt_regs
type event_target (line 14) | struct event_target
type event_target (line 16) | struct event_target
type ftrace_ops (line 21) | struct ftrace_ops
type pt_regs (line 21) | struct pt_regs
type task_struct (line 23) | struct task_struct
type task_struct (line 25) | struct task_struct
type task_struct (line 26) | struct task_struct
FILE: kernel/event_queue.c
function __consume_close_events (line 30) | static int
function event_queue_consume_thread (line 74) | int event_queue_consume_thread(void* data){
FILE: kernel/event_queue.h
function event_queue_add (line 20) | static inline void event_queue_add(struct event_target* event_target, st...
FILE: kernel/event_target.c
type file (line 23) | struct file
type file (line 24) | struct file
type file (line 62) | struct file
type file (line 63) | struct file
type file (line 64) | struct file
type event_target (line 116) | struct event_target
type file (line 117) | struct file
type file (line 117) | struct file
type shournalk_mark_struct (line 118) | struct shournalk_mark_struct
type event_target (line 119) | struct event_target
type kbuffered_file (line 120) | struct kbuffered_file
type mem_cgroup (line 121) | struct mem_cgroup
type pid_namespace (line 122) | struct pid_namespace
type mm_struct (line 125) | struct mm_struct
type event_target (line 144) | struct event_target
type xxh64_state (line 157) | struct xxh64_state
function __event_target_free (line 236) | static void __event_target_free(struct event_target* t){
function __envent_target_destroy_work (line 260) | static void __envent_target_destroy_work(struct work_struct *work){
type event_target (line 279) | struct event_target
type shournalk_mark_struct (line 280) | struct shournalk_mark_struct
type event_target (line 282) | struct event_target
type file (line 283) | struct file
type file (line 284) | struct file
function event_target_commit (line 323) | long event_target_commit(struct event_target* t){
function event_target_is_commited (line 345) | bool event_target_is_commited(const struct event_target* t){
function __event_target_put (line 351) | void __event_target_put(struct event_target* event_target){
function event_target_write_result_to_user_ONCE (line 417) | void event_target_write_result_to_user_ONCE(struct event_target* event_t...
FILE: kernel/event_target.h
type cred (line 21) | struct cred
type file (line 22) | struct file
type kbuffered_file (line 23) | struct kbuffered_file
type pid_namespace (line 24) | struct pid_namespace
type user_namespace (line 25) | struct user_namespace
type shournalk_mark_struct (line 26) | struct shournalk_mark_struct
type dentry (line 27) | struct dentry
type event_target (line 30) | struct event_target {
type event_target (line 85) | struct event_target
type shournalk_mark_struct (line 85) | struct shournalk_mark_struct
type event_target (line 86) | struct event_target
type event_target (line 87) | struct event_target
type event_target (line 91) | struct event_target
type event_target (line 92) | struct event_target
type event_target (line 99) | struct event_target
function event_target_put (line 101) | static inline void
type event_target (line 113) | struct event_target
FILE: kernel/hash_table_str.c
type hash_entry_str (line 11) | struct hash_entry_str
type hash_entry_str (line 13) | struct hash_entry_str
type hash_entry_str (line 13) | struct hash_entry_str
function hash_entry_str_free (line 30) | void hash_entry_str_free(struct hash_entry_str* entry){
FILE: kernel/hash_table_str.h
function u32 (line 12) | static inline u32
type hash_entry_str (line 17) | struct hash_entry_str {
type hash_entry_str (line 24) | struct hash_entry_str
type hash_entry_str (line 26) | struct hash_entry_str
FILE: kernel/kfileextensions.c
function file_extensions_init (line 8) | void file_extensions_init(struct file_extensions* extensions){
function file_extensions_cleanup (line 14) | void file_extensions_cleanup(struct file_extensions* extensions){
function file_extensions_add (line 19) | long file_extensions_add(struct file_extensions* extensions,
function file_extensions_add_multiple (line 39) | long file_extensions_add_multiple(struct file_extensions* extensions,
function file_extensions_contain (line 69) | bool file_extensions_contain(struct file_extensions* extensions,
FILE: kernel/kfileextensions.h
type file_extensions (line 10) | struct file_extensions {
type file_extensions (line 15) | struct file_extensions
type file_extensions (line 16) | struct file_extensions
type file_extensions (line 18) | struct file_extensions
type file_extensions (line 20) | struct file_extensions
type file_extensions (line 23) | struct file_extensions
FILE: kernel/kpathtree.c
function __compare_ints (line 14) | static int __compare_ints(const void *lhs, const void *rhs) {
function __path_len_exists (line 23) | static bool __path_len_exists(struct kpathtree* pathtree, int path_len){
type kpathtree (line 41) | struct kpathtree
type kpathtree (line 42) | struct kpathtree
type kpathtree (line 42) | struct kpathtree
function kpathtree_free (line 50) | void kpathtree_free(struct kpathtree* pathtree){
function kpathtree_init (line 57) | void kpathtree_init(struct kpathtree* pathtree){
function kpathtree_cleanup (line 67) | void kpathtree_cleanup(struct kpathtree* pathtree){
function kpathtree_add (line 78) | long kpathtree_add(struct kpathtree* pathtree, const char* path, int pat...
function kpathtree_is_subpath (line 100) | bool kpathtree_is_subpath(struct kpathtree* pathtree, const char* path,
FILE: kernel/kpathtree.h
type kpathtree (line 20) | struct kpathtree {
type kpathtree (line 30) | struct kpathtree
type kpathtree (line 31) | struct kpathtree
type kpathtree (line 33) | struct kpathtree
type kpathtree (line 34) | struct kpathtree
type kpathtree (line 36) | struct kpathtree
type kpathtree (line 37) | struct kpathtree
FILE: kernel/kutil.c
type files_struct (line 54) | struct files_struct
type file (line 55) | struct file
type path (line 59) | struct path
function kutil_kernel_write (line 83) | ssize_t kutil_kernel_write(struct file *file, const void *buf, size_t co...
function kutil_kernel_write_locked (line 99) | ssize_t kutil_kernel_write_locked(struct file * file, const void *buf, s...
function kutil_kernel_read_locked (line 112) | ssize_t kutil_kernel_read_locked(struct file *file, void *buf, size_t co...
function kutil_kernel_read_cachefriendly (line 147) | ssize_t
function kutil_take_name_snapshot (line 177) | void kutil_take_name_snapshot(struct kutil_name_snapshot* snapshot,
function kutil_release_name_snapshot (line 207) | void kutil_release_name_snapshot(struct kutil_name_snapshot *name __attr...
type mm_struct (line 217) | struct mm_struct
type mm_struct (line 218) | struct mm_struct
type mm_struct (line 219) | struct mm_struct
type mm_struct (line 220) | struct mm_struct
function kutil_use_mm (line 223) | void kutil_use_mm(struct mm_struct *mm) {
function kutil_unuse_mm (line 232) | void kutil_unuse_mm(struct mm_struct *mm) {
type completion (line 248) | struct completion
type completion (line 249) | struct completion
function kutil_kthread_exit (line 251) | void kutil_kthread_exit(struct completion *comp, long code){
function rcu_work_rcufn (line 263) | static void rcu_work_rcufn(struct rcu_head *rcu)
function queue_rcu_work (line 269) | bool queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork)
type mem_cgroup (line 280) | struct mem_cgroup
type mm_struct (line 280) | struct mm_struct
type mem_cgroup (line 282) | struct mem_cgroup
FILE: kernel/kutil.h
function _mmgrab_backport (line 20) | static inline void _mmgrab_backport(struct mm_struct *mm) {
type pipe_inode_info (line 27) | struct pipe_inode_info
function kutil_kthread_be_nice (line 69) | static inline int kutil_kthread_be_nice(void){
type files_struct (line 73) | struct files_struct
type file (line 74) | struct file
type file (line 77) | struct file
type file (line 78) | struct file
function kutil_kernel_read (line 81) | static inline ssize_t
type file (line 97) | struct file
type file (line 99) | struct file
function kutil_get_first_arg_from_reg (line 102) | static inline unsigned long kutil_get_first_arg_from_reg(struct pt_regs ...
type kutil_name_snapshot (line 113) | struct kutil_name_snapshot {
type kutil_name_snapshot (line 118) | struct kutil_name_snapshot
type dentry (line 118) | struct dentry
type kutil_name_snapshot (line 119) | struct kutil_name_snapshot
type mem_cgroup (line 131) | struct mem_cgroup
type mem_cgroup (line 132) | struct mem_cgroup
type mem_cgroup (line 134) | struct mem_cgroup
type mem_cgroup (line 145) | struct mem_cgroup
type mem_cgroup (line 146) | struct mem_cgroup
type mm_struct (line 159) | struct mm_struct
type mm_struct (line 160) | struct mm_struct
type completion (line 172) | struct completion
type rcu_work (line 181) | struct rcu_work {
type rcu_work (line 188) | struct rcu_work
type work_struct (line 188) | struct work_struct
type workqueue_struct (line 196) | struct workqueue_struct
type rcu_work (line 196) | struct rcu_work
type mem_cgroup (line 205) | struct mem_cgroup
type mm_struct (line 205) | struct mm_struct
function _mem_cgroup_put_backport (line 208) | static inline void _mem_cgroup_put_backport(struct mem_cgroup *memcg) {
function _vfs_fadvise_dummy (line 217) | static inline int
function kutil_inode_permission (line 231) | static inline int
function time64_t (line 243) | static inline time64_t kutil_get_mtime_sec(const struct inode *inode){
function time64_t (line 247) | static inline time64_t kutil_get_mtime_sec(const struct inode *inode){
FILE: kernel/shournal_kio.c
type kbuffered_file (line 10) | struct kbuffered_file
type file (line 10) | struct file
type kbuffered_file (line 12) | struct kbuffered_file
type kbuffered_file (line 18) | struct kbuffered_file
function shournal_kio_close (line 31) | void shournal_kio_close(struct kbuffered_file* file){
function shournal_kio_write (line 39) | ssize_t shournal_kio_write(struct kbuffered_file* file, const void *buf,...
function shournal_kio_flush (line 60) | ssize_t shournal_kio_flush(struct kbuffered_file* file){
FILE: kernel/shournal_kio.h
type file (line 9) | struct file
type kbuffered_file (line 11) | struct kbuffered_file {
type kbuffered_file (line 19) | struct kbuffered_file
type file (line 19) | struct file
type kbuffered_file (line 20) | struct kbuffered_file
type kbuffered_file (line 22) | struct kbuffered_file
type kbuffered_file (line 23) | struct kbuffered_file
FILE: kernel/shournalk_global.c
type kpathtree (line 7) | struct kpathtree
function shournalk_global_constructor (line 9) | long shournalk_global_constructor(void){
function shournalk_global_destructor (line 15) | void shournalk_global_destructor(void){
FILE: kernel/shournalk_global.h
type kpathtree (line 13) | struct kpathtree
FILE: kernel/shournalk_main.c
function shournalk_init (line 24) | static int __init shournalk_init(void)
function shournalk_exit (line 51) | static void __exit shournalk_exit(void)
FILE: kernel/shournalk_sysfs.c
type shournal_obj (line 25) | struct shournal_obj {
type shournal_attr (line 30) | struct shournal_attr {
function shournal_attr_show (line 39) | static ssize_t shournal_attr_show(struct kobject *kobj,
function shournal_attr_store (line 54) | static ssize_t shournal_attr_store(struct kobject *kobj,
type sysfs_ops (line 67) | struct sysfs_ops
type shournal_obj (line 74) | struct shournal_obj
type shournal_attr (line 74) | struct shournal_attr
function __show_version (line 75) | static ssize_t __show_version(struct shournal_obj *o __attribute__ ((unu...
type shournal_attr (line 82) | struct shournal_attr
type shournal_attr (line 83) | struct shournal_attr
type attribute (line 86) | struct attribute
function shournal_obj_release (line 96) | static void shournal_obj_release(struct kobject *kobj){
type kobj_type (line 102) | struct kobj_type
type attribute (line 107) | struct attribute
type kset (line 112) | struct kset
type shournal_obj (line 113) | struct shournal_obj
function shournalk_sysfs_constructor (line 118) | int shournalk_sysfs_constructor(void){
function shournalk_sysfs_destructor (line 156) | void shournalk_sysfs_destructor(void){
function verify_hash_settings (line 165) | static long verify_hash_settings(struct shournalk_mark_struct * mark_str...
function __handle_pid_add (line 190) | static long __handle_pid_add(struct shournalk_mark_struct* mark_struct){
function __handle_pid_remove (line 228) | static long __handle_pid_remove(const struct shournalk_mark_struct * mar...
function __copy_path_from_user (line 234) | static ssize_t __copy_path_from_user(char* buf, const char* __user src){
function __add_user_path (line 251) | static long __add_user_path(struct kpathtree* pathtree, const char* __us...
function __copy_file_extensions_from_user (line 268) | static ssize_t
function __add_user_file_extensions (line 287) | static long __add_user_file_extensions(struct file_extensions* exts, con...
function __handle_mark_add (line 305) | static long __handle_mark_add(struct shournalk_mark_struct mark_struct){
function __handle_mark_remove (line 354) | static long __handle_mark_remove(struct shournalk_mark_struct mark_struct){
function __handle_commit (line 365) | static long __handle_commit(struct shournalk_mark_struct mark_struct){
function __mark (line 386) | static ssize_t __mark(struct shournal_obj* obj __attribute__ ((unused)),
FILE: kernel/shournalk_test.c
function test_kpathtree (line 17) | static bool test_kpathtree(void){
function test_hash_table_str (line 98) | static bool test_hash_table_str(void){
function run_tests (line 126) | bool run_tests(void){
FILE: kernel/shournalk_user.h
type shounalk_settings (line 54) | struct shounalk_settings {
type shournalk_mark_struct (line 74) | struct shournalk_mark_struct {
type shournalk_close_event (line 92) | struct shournalk_close_event {
type shournalk_run_result (line 107) | struct shournalk_run_result {
FILE: kernel/tracepoint_helper.c
type ftrace_ops (line 11) | struct ftrace_ops
function __probe_sched_process_fork (line 27) | static void
function __probe_process_exit (line 34) | static void
type trace_entry (line 46) | struct trace_entry {
type trace_entry (line 70) | struct trace_entry
function init_ftrace_entry (line 103) | static void init_ftrace_entry(struct trace_entry* e){
function init_interests (line 112) | static void init_interests(void){
function lookup_tracepoints (line 125) | static void lookup_tracepoints(struct tracepoint *tp,
function __register_tracepoint (line 137) | static int __register_tracepoint(struct trace_entry * entry){
function __unregister_tracepoint (line 152) | static int __unregister_tracepoint(struct trace_entry * entry){
function __register_ftrace (line 164) | static int __register_ftrace(struct trace_entry * entry){
function __unregister_ftrace (line 176) | static int __unregister_ftrace(struct trace_entry * entry){
function cleanup (line 185) | static void cleanup(void) {
function tracepoint_helper_constructor (line 208) | int tracepoint_helper_constructor(void) {
function tracepoint_helper_destructor (line 235) | void tracepoint_helper_destructor(void) {
FILE: kernel/tracepoint_helper.h
type pt_regs (line 6) | struct pt_regs
type pt_regs (line 12) | struct pt_regs
type pt_regs (line 13) | struct pt_regs
type ftrace_regs (line 22) | struct ftrace_regs
type ftrace_regs (line 22) | struct ftrace_regs
FILE: kernel/xxhash_shournalk.c
function xxh32_copy_state (line 87) | void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state ...
function xxh64_copy_state (line 93) | void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state ...
function xxh32_round (line 102) | static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
function xxh32 (line 110) | uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
function xxh64_round (line 164) | static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
function xxh64_merge_round (line 172) | static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
function xxh64 (line 180) | uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
function xxh32_reset (line 250) | void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
function xxh64_reset (line 264) | void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
function xxh32_update (line 278) | int xxh32_update(struct xxh32_state *state, const void *input, const siz...
function xxh32_digest (line 347) | uint32_t xxh32_digest(const struct xxh32_state *state)
function xxh64_update (line 385) | int xxh64_update(struct xxh64_state *state, const void *input, const siz...
function xxh64_digest (line 452) | uint64_t xxh64_digest(const struct xxh64_state *state)
FILE: kernel/xxhash_shournalk.h
type xxh32_state (line 132) | struct xxh32_state {
type xxh64_state (line 146) | struct xxh64_state {
type xxh32_state (line 164) | struct xxh32_state
type xxh32_state (line 177) | struct xxh32_state
type xxh32_state (line 190) | struct xxh32_state
type xxh64_state (line 198) | struct xxh64_state
type xxh64_state (line 210) | struct xxh64_state
type xxh64_state (line 223) | struct xxh64_state
type xxh32_state (line 235) | struct xxh32_state
type xxh32_state (line 235) | struct xxh32_state
type xxh64_state (line 243) | struct xxh64_state
type xxh64_state (line 243) | struct xxh64_state
FILE: src/common/app.cpp
function QVersionNumber (line 79) | const QVersionNumber &app::version()
function QVersionNumber (line 86) | const QVersionNumber &app::initialVersion()
FILE: src/common/app.h
function namespace (line 6) | namespace app {
FILE: src/common/cefd.h
function class (line 8) | class CEfd {
FILE: src/common/console_dialog.h
function namespace (line 5) | namespace console_dialog {
FILE: src/common/cxxhash.cpp
type partial_xxhash_result (line 47) | struct partial_xxhash_result
function partial_xxhash_result (line 52) | partial_xxhash_result CXXHash::digestFile(int fd, int chunksize,
FILE: src/common/cxxhash.h
function class (line 18) | class CXXHash
FILE: src/common/database/command_query_iterator.cpp
function CommandInfo (line 30) | CommandInfo &CommandQueryIterator::value()
FILE: src/common/database/command_query_iterator.h
function class (line 9) | class CommandQueryIterator
FILE: src/common/database/commandinfo.cpp
function CommandInfo (line 19) | CommandInfo CommandInfo::fromLocalEnv()
FILE: src/common/database/commandinfo.h
type QVector (line 12) | typedef QVector<FileWriteInfo> FileWriteInfos;
type QVector (line 13) | typedef QVector<FileReadInfo> FileReadInfos;
type CmdJsonWriteCfg (line 18) | struct CmdJsonWriteCfg {
function maxCountRFiles (line 48) | int maxCountRFiles{std::numeric_limits<int>::max()};
FILE: src/common/database/db_connection.cpp
function versionTableExists (line 29) | static bool versionTableExists(QSqlQueryThrow& query){
function QVersionNumber (line 35) | static QVersionNumber queryVersion(QSqlQueryThrow& query){
function newSqliteDbIfNeeded (line 41) | static void newSqliteDbIfNeeded(){
function updateDbScheme (line 56) | static void updateDbScheme(QSqlQueryThrow& query, const QVersionNumber& ...
function createOrUpDateDb (line 101) | static void
function openAndPrepareSqliteDb (line 145) | static void openAndPrepareSqliteDb()
function QString (line 178) | QString db_connection::getDatabaseDir(){
function QString (line 184) | QString db_connection::mkDbPath()
function QueryPtr (line 197) | QueryPtr db_connection::mkQuery()
FILE: src/common/database/db_connection.h
type std (line 7) | typedef std::shared_ptr<QSqlQueryThrow> QueryPtr;
function namespace (line 9) | namespace db_connection {
FILE: src/common/database/db_controller.cpp
function insertFileWriteEvent (line 31) | static void
function copyToStoredFiles (line 57) | static void
function insertFileReadEvent (line 79) | static void
function deleteChildlessParents (line 126) | static void
function FileReadInfos (line 167) | static FileReadInfos
function qint64 (line 201) | qint64 db_controller::addCommand(const CommandInfo &cmd)
function FileReadInfo (line 392) | FileReadInfo db_controller::queryReadInfo_byId(const qint64 id, const Qu...
function FileReadInfos (line 404) | FileReadInfos db_controller::queryReadInfos_byCmdId(qint64 cmdId, const ...
function qint64 (line 463) | qint64
FILE: src/common/database/db_controller.h
function namespace (line 15) | namespace db_controller {
FILE: src/common/database/db_conversions.cpp
function QVariant (line 6) | QVariant db_conversions::fromMtime(time_t mtime)
function QVariant (line 12) | QVariant db_conversions::fromHashValue(const HashValue &val)
function HashValue (line 18) | HashValue db_conversions::toHashValue(const QVariant &var)
FILE: src/common/database/db_conversions.h
function namespace (line 8) | namespace db_conversions {
FILE: src/common/database/db_globals.h
function namespace (line 5) | namespace db {
FILE: src/common/database/file_query_helper.cpp
type FileQueryColumns (line 23) | struct FileQueryColumns {
method FileQueryColumns (line 24) | FileQueryColumns(bool readFile) : readFile(readFile){ // readFile, els...
type HashMetaValuePair (line 49) | struct HashMetaValuePair {
function addToHashQuery (line 55) | static void
function addToHashQuery (line 71) | static void
function addToHashQuery (line 81) | static void
function addToHashQuery (line 87) | static void
function generateHashMetaValuePairs (line 101) | static vector<HashMetaValuePair>
function entriesExists (line 132) | static bool
function HashMetaValuePair (line 142) | static HashMetaValuePair
function SqlQuery (line 193) | SqlQuery
function SqlQuery (line 256) | SqlQuery file_query_helper::buildFileQuery(const QString &filename,
FILE: src/common/database/file_query_helper.h
function namespace (line 9) | namespace file_query_helper {
FILE: src/common/database/fileinfos.cpp
function QString (line 12) | QString FileInfo::currentStatus(const CommandInfo &cmd) const
FILE: src/common/database/fileinfos.h
type CommandInfo (line 10) | struct CommandInfo
type FileInfo (line 12) | struct FileInfo {
function qint64 (line 18) | qint64 size {}
function FileInfo (line 28) | struct FileWriteInfo : public FileInfo
function FileInfo (line 37) | struct FileReadInfo : public FileInfo
FILE: src/common/database/insertifnotexist.cpp
function QVariant (line 45) | QVariant db_controller::InsertIfNotExist::exec(bool *existed)
FILE: src/common/database/insertifnotexist.h
function namespace (line 10) | namespace db_controller {
FILE: src/common/database/qexcdatabase.h
function class (line 7) | class QExcDatabase : public QExcCommon
FILE: src/common/database/qsqlquerythrow.cpp
type SQLITE_ERR (line 13) | enum SQLITE_ERR { SQLITE_ERR_BUSY= 5 }
function QString (line 27) | static QString mkInsertIgnorePreamble(const QString& driverName)
function sqlerrToNumber (line 39) | static int sqlerrToNumber(const QSqlError & err){
function QString (line 170) | QString QSqlQueryThrow::generateExcMsgExec(const QString &queryStr)
function QString (line 207) | const QString &QSqlQueryThrow::insertIgnorePreamble() const
FILE: src/common/database/qsqlquerythrow.h
function class (line 7) | class QSqlQueryThrow : public QSqlQuery
FILE: src/common/database/query_columns.h
function class (line 8) | class QueryColumns {
function QString (line 40) | const QString session_id {"session.id"};
FILE: src/common/database/sessioninfo.h
type SessionInfo (line 5) | struct SessionInfo
FILE: src/common/database/sqlite_database_scheme_updates.h
function namespace (line 5) | namespace sqlite_database_scheme_updates {
FILE: src/common/database/sqlquery.cpp
function QString (line 8) | const QString &SqlQuery::query() const
function QString (line 13) | QString &SqlQuery::query()
function QVariantList (line 18) | const QVariantList &SqlQuery::values() const
function QString (line 260) | QString SqlQuery::mkLimitString() const
function QString (line 270) | const QString &SqlQuery::ascendingStr() const
function SqlQuery (line 284) | SqlQuery mkInertSqlQuery()
FILE: src/common/database/sqlquery.h
function class (line 15) | class SqlQuery
FILE: src/common/database/storedfiles.cpp
function QString (line 9) | const QString& StoredFiles::getReadFilesDir()
function QString (line 18) | const QString& StoredFiles::mkpath()
function QString (line 35) | QString StoredFiles::mkPathStringToStoredReadFile(const FileReadInfo &info)
function QString (line 40) | QString StoredFiles::mkPathStringToStoredReadFile(qint64 idInDb)
FILE: src/common/database/storedfiles.h
function class (line 7) | class StoredFiles
FILE: src/common/fdcommunication.cpp
type MessageHeader (line 16) | struct MessageHeader {
type msghdr (line 43) | struct msghdr
type cmsghdr (line 63) | struct cmsghdr
type msghdr (line 134) | struct msghdr
type cmsghdr (line 144) | struct cmsghdr
FILE: src/common/fdcommunication.h
function namespace (line 8) | namespace fdcommunication {
FILE: src/common/fileeventhandler.cpp
function QString (line 23) | static QString buildFilecacheDir(){
type stat (line 83) | struct stat
type stat (line 92) | struct stat
function QString (line 158) | QString FileEventHandler::getTmpDirPath() const
function FileEvents (line 169) | FileEvents &FileEventHandler::fileEvents()
FILE: src/common/fileeventhandler.h
function class (line 24) | class FileEventHandler
FILE: src/common/fileevents.cpp
function HashValue (line 36) | HashValue FileEvent::hash() const
function off_t (line 43) | off_t FileEvent::fileContentSize() const
function off_t (line 48) | off_t FileEvent::fileContentStart() const
function FILE (line 58) | FILE *FileEvent::file() const
function freadCstring (line 74) | static int freadCstring(FILE* file, char* buf){
type stat (line 119) | struct stat
function FileEvent (line 192) | FileEvent *FileEvents::read()
function FILE (line 223) | FILE *FileEvents::file() const
function uint (line 234) | uint FileEvents::wEventCount() const
function uint (line 239) | uint FileEvents::wDroppedCount() const
function uint (line 245) | uint FileEvents::rEventCount() const
function uint (line 250) | uint FileEvents::rDroppedCount() const
function uint (line 256) | uint FileEvents::rStoredFilesCount() const
function uint (line 261) | uint FileEvents::wStoredFilesCount() const
FILE: src/common/fileevents.h
function class (line 10) | class FileEvent {
FILE: src/common/groupcontrol.h
function namespace (line 8) | namespace groupcontrol {
FILE: src/common/hashcontrol.cpp
function HashValue (line 8) | HashValue HashControl::genPartlyHash(int fd, qint64 filesize, const Hash...
function CXXHash (line 28) | CXXHash &HashControl::getXXHash()
FILE: src/common/hashcontrol.h
function class (line 8) | class HashControl
FILE: src/common/hashmeta.h
type HashMeta (line 8) | struct HashMeta
function size_type (line 15) | size_type maxCountOfReads {}
function qint64 (line 16) | qint64 idInDb {db::INVALID_INT_ID} ;
FILE: src/common/interrupt_handler.cpp
function ip_dummySighandler (line 21) | void ip_dummySighandler(int signum){
type sigaction (line 78) | struct sigaction
FILE: src/common/interrupt_handler.h
function class (line 13) | class InterruptProtect
FILE: src/common/limited_priority_queue.h
function container (line 9) | container, compare>
FILE: src/common/logger.cpp
function messageHandler (line 29) | void messageHandler(QtMsgType msgType, const QMessageLogContext &context...
function QtMsgType (line 105) | QtMsgType logger::getVerbosityLevel()
function QString (line 121) | const QString& logger::logDir()
function QtMsgType (line 169) | QtMsgType logger::strToMsgType(const char *str)
function QTextStream (line 199) | QTextStream &logger::LogRotate::stream()
function QFile (line 205) | const QFile& logger::LogRotate::file() const
FILE: src/common/logger.h
function namespace (line 25) | namespace logger {
FILE: src/common/oscpp/cflock.cpp
function checkFdFlockFlags (line 10) | static bool checkFdFlockFlags(int fd, int operation){
function doLockNB (line 37) | static void doLockNB(int fd, int operation){
FILE: src/common/oscpp/cflock.h
function m_isLockedEX (line 30) | bool m_isLockedEX{false};
FILE: src/common/oscpp/excos.h
function namespace (line 6) | namespace os {
FILE: src/common/oscpp/fdentries.cpp
type dirent (line 21) | struct dirent
FILE: src/common/oscpp/fdentries.h
function namespace (line 7) | namespace osutil {
FILE: src/common/oscpp/os.cpp
type stat (line 56) | struct stat
function pid_t (line 212) | pid_t os::fork()
function uid_t (line 266) | uid_t os::getuid()
function gid_t (line 271) | gid_t os::getgid()
function uid_t (line 277) | uid_t os::getsuid()
function gid_t (line 285) | gid_t os::getsgid()
function uid_t (line 355) | uid_t os::geteuid()
function gid_t (line 360) | gid_t os::getegid()
type dirent (line 430) | struct dirent
function pid_t (line 451) | pid_t os::getpid()
function pid_t (line 459) | pid_t os::waitpid(pid_t pid, int *status, int options, bool cleanStatusO...
function off_t (line 537) | off_t os::lseek (int fd, off_t offset, int whence)
function off_t (line 549) | off_t os::ltell(int fd)
function pid_t (line 595) | pid_t os::setsid()
type stat (line 608) | struct stat
type sigaction (line 680) | struct sigaction
type sigaction (line 681) | struct sigaction
function sighandler_t (line 712) | sighandler_t os::signal(int sig, sighandler_t handler)
function off_t (line 815) | off_t os::sendfile(int out_fd, int in_fd, size_t count, off_t offset)
FILE: src/common/oscpp/os.h
function namespace (line 23) | namespace __os {
function namespace (line 33) | namespace os {
FILE: src/common/oscpp/oscaps.cpp
function cap_set_flag_wrapper (line 10) | static void cap_set_flag_wrapper(cap_t caps,
FILE: src/common/oscpp/oscaps.h
function namespace (line 9) | namespace os {
FILE: src/common/oscpp/osutil.cpp
function intertSighandler (line 36) | void intertSighandler(int){}
function rlim_t (line 52) | rlim_t osutil::getMaxCountOpenFiles()
function QByteArray (line 255) | QByteArray osutil::readWholeFile(int fd, int bufSize)
type sigaction (line 306) | struct sigaction
FILE: src/common/oscpp/osutil.h
function namespace (line 15) | namespace osutil {
FILE: src/common/pathtree.h
function class (line 18) | class PathTree
FILE: src/common/pidcontrol.h
function namespace (line 7) | namespace pidcontrol {
FILE: src/common/qfddummydevice.cpp
function qint64 (line 25) | qint64 QFdDummyDevice::readData(char *data, qint64 maxlen) {
function qint64 (line 29) | qint64 QFdDummyDevice::writeData(const char *data, qint64 len) {
FILE: src/common/qfddummydevice.h
function class (line 8) | class QFdDummyDevice : public QIODevice
FILE: src/common/qfilethrow.cpp
function qint64 (line 52) | qint64 QFileThrow::readData(char *data, qint64 maxSize){
function qint64 (line 61) | qint64 QFileThrow::readLineData(char *data, qint64 maxlen){
function qint64 (line 71) | qint64 QFileThrow::writeData(const char *data, qint64 len)
FILE: src/common/qfilethrow.h
function class (line 5) | class QFileThrow : public QFile
FILE: src/common/qoptargparse/excoptargparse.h
function class (line 5) | class ExcOptArgParse : public QExcCommon
FILE: src/common/qoptargparse/qoptarg.cpp
function QString (line 66) | const QString &QOptArg::shortName() const
function QString (line 71) | const QString& QOptArg::name() const
function QString (line 76) | QString QOptArg::description() const
function QOptArgTrigger (line 94) | const QOptArgTrigger &QOptArg::optTrigger() const
function QString (line 102) | QString QOptArg::preprocessTrigger(const char *str) const
function QString (line 107) | const QString &QOptArg::parsedTrigger() const
function QStringList (line 119) | QStringList QOptArg::getOptions(int maxCount) const
function QVariantList (line 149) | QVariantList QOptArg::getVariantByteSizes(const QVariantList &defaultVal...
function QVariantList (line 165) | QVariantList QOptArg::getVariantRelativeDateTimes(const QVariantList &de...
function QString (line 215) | const QString &QOptArg::defaultTriggerStr() const
function QString (line 290) | const QString &QOptArg::allowedOptionsDelimeter() const
FILE: src/common/qoptargparse/qoptarg.h
function class (line 12) | class QOptArg {
FILE: src/common/qoptargparse/qoptargparse.cpp
function consumeOptArgs (line 23) | void consumeOptArgs(int argc, char *argv[], int& i, QOptArg& arg){
function consumeVarLenArg (line 63) | void consumeVarLenArg(int argc, char *argv[], int& i, QOptVarLenArg* arg){
type winsize (line 236) | struct winsize
FILE: src/common/qoptargparse/qoptargparse.h
function class (line 10) | class QOptArgParse
FILE: src/common/qoptargparse/qoptargtrigger.h
function class (line 13) | class QOptArgTrigger
FILE: src/common/qoptargparse/qoptsqlarg.cpp
function QOptArgTrigger (line 13) | const QOptArgTrigger& allArgTrigger(){
function QString (line 118) | QString QOptSqlArg::preprocessTrigger(const char *str) const
function QString (line 123) | QString QOptSqlArg::description() const
function E_CompareOperator (line 135) | E_CompareOperator QOptSqlArg::parsedOperator() const
FILE: src/common/qoptargparse/qoptsqlarg.h
function class (line 9) | class QOptSqlArg : public QOptArg
FILE: src/common/qoptargparse/qoptvarlenarg.h
function class (line 5) | class QOptVarLenArg : public QOptArg
FILE: src/common/qresource_helper.cpp
function QByteArray (line 9) | QByteArray qresource_helper::data_safe(QResource &r)
FILE: src/common/qresource_helper.h
function namespace (line 5) | namespace qresource_helper {
FILE: src/common/qsimplecfg/cfg.cpp
function setStreamCommentMode (line 23) | void setStreamCommentMode(QFormattedStream& s){
function unsetStreamCommentMode (line 28) | void unsetStreamCommentMode(QFormattedStream& s){
function writeMultiLineKey (line 33) | void writeMultiLineKey(QFormattedStream& stream, const QString& keyname,
function QString (line 294) | QString
FILE: src/common/qsimplecfg/cfg.h
function namespace (line 16) | namespace qsimplecfg {
FILE: src/common/qsimplecfg/exccfg.h
function namespace (line 7) | namespace qsimplecfg {
FILE: src/common/qsimplecfg/section.cpp
function qint64 (line 20) | qint64 qsimplecfg::Section::getFileSize(const QString &key, const qint64...
function QString (line 51) | const QString& qsimplecfg::Section::comments() const
function QString (line 97) | const QString& qsimplecfg::Section::sectionName() const
FILE: src/common/qsimplecfg/section.h
function namespace (line 19) | namespace qsimplecfg {
FILE: src/common/safe_file_update.h
function class (line 25) | class SafeFileUpdate
function m_isLocked (line 133) | bool m_isLocked{false};
FILE: src/common/settings.cpp
function Settings (line 41) | Settings &Settings::instance()
function QStringList (line 58) | const QStringList &Settings::defaultIgnoreCmds()
function QString (line 70) | QString Settings::cfgAppDir()
function QString (line 81) | QString Settings::cfgFilepath()
function QString (line 87) | QString Settings::dataDir()
function QString (line 97) | static QString legacyCfgVersionFilePath(){
function QString (line 113) | static QString ignoreCmdLineToFullCmdAndArgs(const QString& str){
function QVersionNumber (line 241) | static QVersionNumber readLegacyConfigFileVersion(){
function cleanExcludePaths (line 264) | static void cleanExcludePaths(const QVector<const PathTree*>& includePat...
function cleanExcludePaths (line 290) | static void cleanExcludePaths(const std::shared_ptr<PathTree>& includePa...
function QString (line 730) | QString Settings::chooseShournalRunBackend()
FILE: src/common/settings.h
type std (line 21) | typedef std::unordered_set<StrLight> StrLightSet;
type std (line 22) | typedef std::unordered_set<QString> MimeSet;
type HashSettings (line 26) | struct HashSettings {
type WriteFileSettings (line 31) | struct WriteFileSettings {
type ScriptFileSettings (line 67) | struct ScriptFileSettings {
FILE: src/common/shournal_run_common.cpp
function QOptArg (line 26) | QOptArg shournal_run_common::mkarg_cfgdir()
function QOptArg (line 32) | QOptArg shournal_run_common::mkarg_datadir()
FILE: src/common/shournal_run_common.h
function namespace (line 8) | namespace shournal_run_common {
FILE: src/common/socket_message.h
function namespace (line 4) | namespace socket_message {
FILE: src/common/stdiocpp.cpp
function FILE (line 35) | FILE *stdiocpp::tmpfile(int o_flags __attribute__ ((unused)))
function FILE (line 51) | FILE *stdiocpp::fopen(const char *pathname, const char *mode)
function FILE (line 61) | FILE *stdiocpp::fdopen(int fd, const char *mode){
FILE: src/common/stdiocpp.h
function namespace (line 7) | namespace stdiocpp {
FILE: src/common/stupidinject.h
function class (line 10) | class EqcInjectTriggerNotFound : public QExcCommon
function class (line 20) | class StupidInject
FILE: src/common/subprocess.cpp
type LaunchMsgType (line 22) | enum class LaunchMsgType { PID, EXCEPTION, ENUM_END }
type LaunchMsg (line 24) | struct LaunchMsg{
function readMsg (line 38) | bool readMsg(int fd, LaunchMsg* msg){
function throwFailedToLaunchEx (line 52) | [[noreturn]]
function toPointerVect (line 69) | std::vector<char*> toPointerVect(const subprocess::Args_t& args){
function pid_t (line 379) | pid_t subprocess::Subprocess::lastPid() const
FILE: src/common/subprocess.h
function namespace (line 9) | namespace subprocess {
FILE: src/common/util/cleanupresource.h
function namespace (line 7) | namespace private_namesapce {
function setEnabled (line 29) | void setEnabled(bool val){
FILE: src/common/util/compareoperator.cpp
function QString (line 45) | QString CompareOperator::asSql() const
function QString (line 62) | QString CompareOperator::asTerminal() const
function E_CompareOperator (line 79) | E_CompareOperator CompareOperator::asEnum() const
FILE: src/common/util/compareoperator.h
function E_CompareOperator (line 8) | enum class E_CompareOperator { GT,GE,LT,LE,EQ,NE,LIKE,BETWEEN,ENUM_END };
FILE: src/common/util/compat.h
function namespace (line 10) | namespace Qt
function namespace (line 21) | namespace Qt
function namespace (line 31) | namespace Qt
function namespace (line 38) | namespace Qt
FILE: src/common/util/conversions.cpp
function validTimeUnitHash (line 11) | static QHash<QString, char> validTimeUnitHash(){
function QString (line 33) | const QString &Conversions::relativeDateTimeUnitDescriptions()
function qint64 (line 42) | qint64 Conversions::bytesFromHuman(QString str)
function QString (line 106) | QString Conversions::bytesToHuman(const qint64 bytes)
function QDateTime (line 128) | QDateTime Conversions::relativeDateTimeFromHuman(const QString &str, boo...
function QString (line 170) | const QString &Conversions::dateIsoFormatWithMilliseconds()
FILE: src/common/util/conversions.h
function class (line 8) | class ExcConversion : public QExcCommon
function class (line 16) | class Conversions
FILE: src/common/util/cpp_exit.cpp
function cpp_exit (line 6) | void cpp_exit(int ret)
FILE: src/common/util/cpp_exit.h
function class (line 4) | class ExcCppExit
FILE: src/common/util/exccommon.cpp
function QString (line 43) | QString QExcCommon::descrip() const
FILE: src/common/util/exccommon.h
function class (line 7) | class ExcCommon : public std::exception
function class (line 21) | class QExcCommon : public std::exception
FILE: src/common/util/nullable_value.h
function class (line 7) | class QExcNullDeref : public QExcCommon
function m_isNull (line 20) | m_isNull(true){}
function setValue (line 30) | void setValue(const T& val){
function setNull (line 39) | void setNull(){
type NullableValue (line 89) | typedef NullableValue<uint64_t> HashValue;
FILE: src/common/util/qformattedstream.cpp
function QFormattedStream (line 45) | QFormattedStream &QFormattedStream::operator<<(const QString &str)
function QFormattedStream (line 51) | QFormattedStream &QFormattedStream::operator<<(const QStringRef &str) {
function QString (line 158) | const QString &QFormattedStream::lineStart() const
function QChar (line 168) | QChar QFormattedStream::streamChunkSep() const
FILE: src/common/util/qformattedstream.h
function class (line 14) | class QFormattedStream
FILE: src/common/util/qoutstream.h
function class (line 9) | class QOut
function class (line 33) | class QErr
function class (line 62) | class QIErr
FILE: src/common/util/staticinitializer.h
function class (line 7) | class StaticInitializer
FILE: src/common/util/strlight.cpp
function StrLight (line 79) | StrLight StrLight::deepCopy() const {
function StrLight (line 90) | StrLight &StrLight::operator=(StrLight other)
function StrLight (line 96) | StrLight &StrLight::operator=(char c)
function StrLight (line 103) | StrLight &StrLight::operator+=(const StrLight &rhs){
function StrLight (line 108) | StrLight &StrLight::operator+=(const char rhs){
function StrLight (line 178) | StrLight StrLight::left(int len) const {
function StrLight (line 184) | StrLight StrLight::mid(int pos) const {
function swap (line 290) | void swap(StrLight &first, StrLight &second)
function uint (line 303) | uint qHash(const StrLight &key, uint seed)
function QDebug (line 333) | QDebug operator<<(QDebug debug, const StrLight &c)
function StrLight (line 342) | const StrLight operator+(const StrLight &s1, const StrLight &s2)
function StrLight (line 351) | const StrLight operator+(const StrLight &s1, const char &c)
FILE: src/common/util/strlight.h
function class (line 19) | class StrLight {
FILE: src/common/util/strlight_util.h
function namespace (line 6) | namespace strlight_util {
FILE: src/common/util/translation.h
function QString (line 19) | const QString shournalShellIntegration {qtr("shournal shell-integration")};
FILE: src/common/util/util.cpp
function readLineInto (line 14) | bool readLineInto(QTextStream& stream, QString *line, qint64 maxlen){
function QTextStream (line 29) | QTextStream& operator<<(QTextStream& stream, const QStringRef &string){
function shournal_common_init (line 40) | bool shournal_common_init()
function QDebug (line 67) | QDebug &operator<<(QDebug &out, const std::string &str)
function StrLight (line 74) | StrLight toStrLight(const QString &str){
function bytesCombine (line 79) | void bytesCombine(std::string &){}
function hasEnding (line 82) | bool hasEnding(const std::string &fullString, const std::string &ending) {
function QString (line 94) | QString absPath(const QString &path)
function QByteArray (line 110) | QByteArray make_uuid(bool *madeSafe){
function strFromCString (line 163) | std::string strFromCString(const char *cstr)
function splitAbsPath (line 169) | QPair<std::string, std::string> splitAbsPath(const std::string &fullPath)
function getFileExtension (line 197) | std::string getFileExtension(const std::string &fname)
function generate_trace_string (line 209) | std::string generate_trace_string(int startIdx)
function QString (line 227) | QString argvToQStr(int argc, char * const argv[]){
function argvToStr (line 235) | std::string argvToStr(int argc, char *const argv[])
function argvToStr (line 250) | std::string argvToStr(char *const argv[])
function indexOfNonWhiteSpace (line 268) | int indexOfNonWhiteSpace(const QString &str)
function qVariantTo (line 280) | bool qVariantTo(const std::string &str, QString *result) {
function qVariantTo (line 285) | bool qVariantTo(const StrLight& str, QString* result){
FILE: src/common/util/util.h
function namespace (line 77) | namespace std {
function string (line 114) | string bytesFromVar(const T& t)
function dropFromTime (line 224) | static inline void dropFromTime(QTime& t, char c){
function dropFromTime (line 236) | static inline void dropFromTime(QDateTime& d, char c){
function class (line 260) | class ExcQVariantConvert : public QExcCommon
FILE: src/common/util/util_performance.h
function namespace (line 6) | namespace util_performance {
FILE: src/common/xxhash_common.c
function __do_read (line 34) | static ssize_t __do_read(xxh_common_file_t file, void *buf, size_t nbytes){
function loff_t (line 47) | static loff_t __do_seek(xxh_common_file_t file, loff_t offset){
function __read_and_hash (line 62) | static ssize_t __read_and_hash(xxh_common_file_t file,
function __read_chunk (line 81) | static ssize_t __read_chunk(xxh_common_file_t file,
function partial_xxh_digest_file (line 130) | long partial_xxh_digest_file(xxh_common_file_t file,
FILE: src/common/xxhash_common.h
type file (line 12) | struct file
type file (line 15) | struct file
type xxh_common_file_t (line 24) | typedef int xxh_common_file_t;
type partial_xxhash (line 33) | struct partial_xxhash {
type partial_xxhash_result (line 42) | struct partial_xxhash_result {
type partial_xxhash (line 49) | struct partial_xxhash
type partial_xxhash_result (line 50) | struct partial_xxhash_result
FILE: src/shell-integration-fanotify/attached_bash.cpp
function read_seq (line 11) | static int read_seq(){
FILE: src/shell-integration-fanotify/attached_bash.h
function class (line 19) | class AttachedBash : public AttachedShell
FILE: src/shell-integration-fanotify/attached_shell.h
function class (line 6) | class AttachedShell
FILE: src/shell-integration-fanotify/event_open.cpp
function mkAbsPath (line 26) | static std::string mkAbsPath(const char* path){
function writerTriggerResponse (line 62) | static int writerTriggerResponse(bool success){
FILE: src/shell-integration-fanotify/event_open.h
function namespace (line 6) | namespace event_open {
FILE: src/shell-integration-fanotify/event_process.cpp
function execveUnobserved (line 31) | static int execveUnobserved(const char *filename, char * const argv[], c...
function pid_t (line 52) | pid_t event_process::handleFork()
type stat (line 97) | struct stat
FILE: src/shell-integration-fanotify/event_process.h
function namespace (line 5) | namespace event_process {
FILE: src/shell-integration-fanotify/libshournal-shellwatch.cpp
function initSymIfNeeded (line 29) | static void initSymIfNeeded(){
function LIBSHOURNAL_SHELLWATCH_EXPORT (line 72) | LIBSHOURNAL_SHELLWATCH_EXPORT
function LIBSHOURNAL_SHELLWATCH_EXPORT (line 85) | LIBSHOURNAL_SHELLWATCH_EXPORT
function LIBSHOURNAL_SHELLWATCH_EXPORT (line 133) | LIBSHOURNAL_SHELLWATCH_EXPORT
function LIBSHOURNAL_SHELLWATCH_EXPORT (line 145) | LIBSHOURNAL_SHELLWATCH_EXPORT
FILE: src/shell-integration-fanotify/shell_globals.cpp
function updateShouranlRunVerbosityFromEnv (line 11) | static bool updateShouranlRunVerbosityFromEnv(bool verboseIfUnset){
function ShellGlobals (line 33) | ShellGlobals &ShellGlobals::instance()
FILE: src/shell-integration-fanotify/shell_globals.h
type pid_t (line 18) | typedef pid_t (*fork_func_t)();
type class (line 28) | enum class
function fork_func_t (line 40) | fork_func_t orig_fork {}
function execve_func_t (line 41) | execve_func_t orig_execve {}
function open_func_t (line 42) | open_func_t orig_open {}
function strcpy_func_t (line 43) | strcpy_func_t orig_strcpy {}
function origSigintAction (line 52) | struct sigaction origSigintAction{}
function AttachedShell (line 55) | AttachedShell* pAttchedShell {}
function pid_t (line 63) | pid_t shellParentPid {0}
FILE: src/shell-integration-fanotify/shell_logger.cpp
type ShellLogState (line 19) | struct ShellLogState {
function ShellLogState (line 24) | ShellLogState& sLogState(){
function sendViaSock (line 30) | void sendViaSock(QByteArray& msg){
function messageHandler (line 40) | void messageHandler(QtMsgType msgType, const QMessageLogContext &context...
function __shell_earlydbg (line 115) | void __shell_earlydbg(const char* file, int line, const char *format, ...)
FILE: src/shell-integration-fanotify/shell_logger.h
function namespace (line 11) | namespace shell_logger {
FILE: src/shell-integration-fanotify/shell_request_handler.cpp
function initializeAttachedShellIfNeeded (line 65) | static bool initializeAttachedShellIfNeeded(){
function loadSettings (line 97) | static bool loadSettings(){
function verbose_findHighestFreeFd (line 113) | static int verbose_findHighestFreeFd(int startFd=-1){
function ShellRequest (line 125) | static ShellRequest readCheckShellUpdateRequest(){
function verboseCloseShournalSocket (line 160) | static void verboseCloseShournalSocket(){
function verboseCloseRootDirFd (line 171) | static void verboseCloseRootDirFd(){
function updateShellPID (line 182) | static bool updateShellPID(){
function handleDisableRequest (line 213) | static bool handleDisableRequest(){
function handleCleanupCmd (line 230) | static bool handleCleanupCmd(){
function handleEnableRequest (line 278) | static bool handleEnableRequest(){
function ShellRequest (line 497) | ShellRequest shell_request_handler::checkForTriggerAndHandle(bool *succe...
FILE: src/shell-integration-fanotify/shell_request_handler.h
function namespace (line 4) | namespace shell_request_handler {
FILE: src/shournal-run-fanotify/fanotify_controller.cpp
function QString (line 48) | QString fanotifyEventMaskToStr(uint64_t m){
function fanotifyMarkWrapOnInit (line 69) | bool fanotifyMarkWrapOnInit(int fanFd, uint64_t mask, const std::string&...
function addPathsAndSubMountPaths (line 93) | void addPathsAndSubMountPaths(const std::shared_ptr<PathTree>& parentPaths,
type fanotify_event_metadata (line 233) | struct fanotify_event_metadata
type fanotify_event_metadata (line 234) | struct fanotify_event_metadata
type fanotify_event_metadata (line 311) | struct fanotify_event_metadata
function uint (line 408) | uint FanotifyController::getOverflowCount() const
FILE: src/shournal-run-fanotify/fanotify_controller.h
type fanotify_event_metadata (line 9) | struct fanotify_event_metadata
function class (line 11) | class FanotifyController
FILE: src/shournal-run-fanotify/filewatcher_fan.cpp
function unshareOrDie (line 61) | static void unshareOrDie(){
function gid_t (line 79) | static gid_t findMsenterGidOrDie(){
function E_SocketMsg (line 375) | E_SocketMsg FileWatcher::processSocketEvent( CommandInfo& cmdInfo ){
function E_SocketMsg (line 448) | E_SocketMsg FileWatcher::fan_pollUntilStopped(CommandInfo& cmdInfo,
FILE: src/shournal-run-fanotify/filewatcher_fan.h
type CommandInfo (line 10) | struct CommandInfo
function class (line 12) | class FileWatcher {
FILE: src/shournal-run-fanotify/mount_controller.cpp
type mntent (line 42) | struct mntent
FILE: src/shournal-run-fanotify/mount_controller.h
function class (line 11) | class ExcMountCtrl : public QExcCommon
function namespace (line 18) | namespace mountController {
FILE: src/shournal-run-fanotify/msenter.cpp
type stat (line 49) | struct stat
FILE: src/shournal-run-fanotify/msenter.h
function namespace (line 5) | namespace msenter {
FILE: src/shournal-run-fanotify/orig_mountspace_process.cpp
function QString (line 32) | QString userPidPath(){
function setupIfNotExistAsChild (line 41) | [[noreturn]]
function execAsRealsUser (line 96) | [[noreturn]]
FILE: src/shournal-run-fanotify/orig_mountspace_process.h
function namespace (line 4) | namespace orig_mountspace_process {
FILE: src/shournal-run-fanotify/shournal-run-fanotify.cpp
function onterminate (line 44) | void onterminate() {
function callFilewatcherSafe (line 57) | [[noreturn]]
function shournal_run_main (line 78) | int shournal_run_main(int argc, char *argv[])
function main (line 353) | int main(int argc, char *argv[])
FILE: src/shournal-run/fifocom.h
function class (line 8) | class FifoCom
FILE: src/shournal-run/filewatcher_shournalk.cpp
function handleFifoEvent (line 54) | static void handleFifoEvent(shared_ptr<FifoCom>& fifoCom,
function do_polling (line 93) | static int do_polling(ShournalK_ptr& shournalk,
function QByteArray (line 170) | QByteArray Filewatcher_shournalk::fifopathForPid(pid_t pid)
function CommandInfo (line 231) | CommandInfo Filewatcher_shournalk::runExec(ShournalK_ptr &shournalk,
function CommandInfo (line 285) | CommandInfo Filewatcher_shournalk::runMarkPid(ShournalK_ptr &shournalk, ...
type shournalk_run_result (line 342) | struct shournalk_run_result
FILE: src/shournal-run/filewatcher_shournalk.h
type shournalk_group (line 11) | struct shournalk_group
function m_commandArgc (line 45) | int m_commandArgc{}
function m_forkIntoBackground (line 48) | bool m_forkIntoBackground{}
function m_storeToDatabase (line 51) | bool m_storeToDatabase{true};
FILE: src/shournal-run/mark_helper.cpp
function shounalk_settings (line 28) | static shounalk_settings buildKSettings(){
function FILE (line 178) | FILE *ShournalkControl::tmpFileTarget() const
function shournalk_group (line 183) | shournalk_group *ShournalkControl::kgrp() const
FILE: src/shournal-run/mark_helper.h
type shournalk_group (line 9) | struct shournalk_group
function class (line 11) | class ExcShournalk : public QExcCommon
function class (line 18) | class ShournalkControl {
FILE: src/shournal-run/shournal-run.cpp
function onterminate (line 60) | static void onterminate() {
function closeFds (line 73) | static void closeFds(){
function shournal_run_main (line 85) | static int shournal_run_main(int argc, char *argv[])
function main (line 338) | int main(int argc, char *argv[])
FILE: src/shournal-run/shournalk_ctrl.c
function __file_exists (line 30) | static bool __file_exists(const char* filename){
function __open_sysfs_mark (line 35) | static int __open_sysfs_mark(void){
function __shournalk_filter_common (line 60) | static int __shournalk_filter_common(struct shournalk_group* grp, unsign...
function shournalk_module_is_loaded (line 75) | bool shournalk_module_is_loaded(void){
type shournalk_group (line 86) | struct shournalk_group
type shournalk_group (line 88) | struct shournalk_group
type shournalk_group (line 103) | struct shournalk_group
type shournalk_group (line 103) | struct shournalk_group
function shournalk_release (line 116) | void shournalk_release(struct shournalk_group* grp){
function shournalk_set_target_fd (line 131) | void shournalk_set_target_fd(struct shournalk_group* grp, int fd){
function shournalk_set_settings (line 136) | void shournalk_set_settings(struct shournalk_group* grp,
function shournalk_filter_pid (line 143) | int shournalk_filter_pid(struct shournalk_group* grp, unsigned int flags...
function shournalk_filter_string (line 153) | int shournalk_filter_string(struct shournalk_group* grp, unsigned int fl...
function shournalk_commit (line 159) | int shournalk_commit(struct shournalk_group* grp){
function shournalk_prepare_poll_ONCE (line 168) | int shournalk_prepare_poll_ONCE(struct shournalk_group* grp){
function shournalk_read_version (line 180) | int shournalk_read_version(struct shournalk_version* ver){
FILE: src/shournal-run/shournalk_ctrl.h
type shournalk_group (line 17) | struct shournalk_group {
type shournalk_version (line 23) | struct shournalk_version {
type shournalk_group (line 31) | struct shournalk_group
type shournalk_group (line 32) | struct shournalk_group
type shournalk_group (line 35) | struct shournalk_group
type shournalk_group (line 36) | struct shournalk_group
type shounalk_settings (line 37) | struct shounalk_settings
type shournalk_group (line 40) | struct shournalk_group
type shournalk_group (line 41) | struct shournalk_group
type shournalk_group (line 43) | struct shournalk_group
type shournalk_group (line 45) | struct shournalk_group
type shournalk_version (line 47) | struct shournalk_version
FILE: src/shournal/argcontrol_dbdelete.h
function namespace (line 4) | namespace argcontrol_dbdelete {
FILE: src/shournal/argcontrol_dbquery.cpp
function queryCmdPrintAndExit (line 32) | [[noreturn]]
function restoreSingleReadFile (line 42) | [[noreturn]]
function addFileQuery (line 70) | static void addFileQuery(SqlQuery &query, const QOptArg& argFile,
FILE: src/shournal/argcontrol_dbquery.h
function namespace (line 6) | namespace argcontol_dbquery {
FILE: src/shournal/cmd_stats.h
function class (line 9) | class CmdStats
type QVector (line 42) | typedef QVector<MostFileModsEntry> MostFileModsEntrys;
type QVector (line 43) | typedef QVector<SessionMostCmdsEntry> SessionMostCmds;
type QVector (line 44) | typedef QVector<CwdCmdCount> CwdCmdCounts;
type QVector (line 45) | typedef QVector<DirIoCount> DirIoCounts;
type cmpSessionMostCmdEntry (line 72) | struct cmpSessionMostCmdEntry {
type cmpCwdCmdCount (line 78) | struct cmpCwdCmdCount {
type cmpDirIoCount (line 84) | struct cmpDirIoCount {
FILE: src/shournal/command_printer.cpp
function QString (line 23) | static QString buildRestorePath(){
function CmdStats (line 99) | CmdStats &CommandPrinter::cmdStats()
function QFileThrow (line 120) | QFileThrow &CommandPrinter::outputFile()
FILE: src/shournal/command_printer.h
function m_countOfRestoredFiles (line 49) | int m_countOfRestoredFiles {0}
function m_maxCountWfiles (line 53) | int m_maxCountWfiles{0}
function m_maxCountRfiles (line 54) | int m_maxCountRfiles{0}
function m_reportFileStatus (line 57) | bool m_reportFileStatus{false};
FILE: src/shournal/command_printer_html.h
function class (line 15) | class CommandPrinterHtml : public CommandPrinter
FILE: src/shournal/command_printer_human.cpp
type winsize (line 38) | struct winsize
FILE: src/shournal/command_printer_human.h
function QString (line 33) | const QString m_indentlvl3 {" "};
FILE: src/shournal/command_printer_json.h
function class (line 5) | class CommandPrinterJson : public CommandPrinter
FILE: src/shournal/shournal.cpp
function onterminate (line 40) | void onterminate() {
function shournal_main (line 59) | int shournal_main(int argc, char *argv[])
function execShournalRun (line 283) | void execShournalRun(const QByteArray& backendFilename,
function main (line 366) | int main(int argc, char *argv[])
FILE: test/autotest.h
function class (line 22) | class ShournalTestGlobals {
function ShournalTestGlobals (line 33) | inline ShournalTestGlobals& globals(){
type QList (line 39) | typedef QList<QObject*> TestList;
function TestList (line 41) | inline TestList& testList()
function findObject (line 47) | inline bool findObject(QObject* object)
function addTest (line 64) | inline void addTest(QObject* object)
function child (line 182) | Test(const QString& name) : child(new T)
FILE: test/helper_for_test.cpp
function QString (line 99) | QString testhelper::readStringFromFile(const QString &fpath)
function foreach (line 120) | foreach (const QString &fileName, fileNames) {
FILE: test/helper_for_test.h
function namespace (line 6) | namespace testhelper {
FILE: test/integration_test_shell.cpp
function writeLine (line 23) | void writeLine(int fd, const std::string& line){
function prepareHighFdNumberPipe (line 27) | os::Pipes_t prepareHighFdNumberPipe(){
function callWithRedirectedStdin (line 46) | int callWithRedirectedStdin(Subprocess& proc){
class IntegrationTestShell (line 64) | class IntegrationTestShell : public QObject {
method Q_OBJECT (line 65) | Q_OBJECT
method writeScriptSettingToCfg (line 75) | void writeScriptSettingToCfg(const QString& includePath,
method executeCmdInbservedShell (line 87) | void executeCmdInbservedShell(const std::string& cmd, const std::strin...
method executeCmdInbservedShell (line 133) | void executeCmdInbservedShell(const QString& cmd, const std::string& s...
method cmdWrittenFileCheck (line 139) | void cmdWrittenFileCheck(const std::string& cmd, const std::string& fp...
method initTestCase (line 153) | void initTestCase(){
method init (line 158) | void init(){
method cleanup (line 166) | void cleanup(){
method testWrite (line 172) | void testWrite() {
method testRead (line 230) | void testRead(){
method testReadScript (line 303) | void testReadScript(){
FILE: test/test_cfg.cpp
class CfgTest (line 15) | class CfgTest : public QObject {
method verifyStdCfg (line 50) | void verifyStdCfg(Cfg& cfg){
method writeToTmpConfigFile (line 74) | std::unique_ptr<QTemporaryFile> writeToTmpConfigFile(const QString& txt){
method initTestCase (line 86) | void initTestCase(){
method tgeneral (line 90) | void tgeneral() {
method tRenameSection (line 104) | void tRenameSection(){
method tRenameKey (line 126) | void tRenameKey(){
FILE: test/test_cxxhash.cpp
class CXXHashTest (line 10) | class CXXHashTest : public QObject {
method Q_OBJECT (line 11) | Q_OBJECT
method initTestCase (line 35) | void initTestCase(){
method testDigestFile (line 40) | void testDigestFile() {
FILE: test/test_db_controller.cpp
class FileReadEventForTest (line 44) | class FileReadEventForTest {
method FileReadEventForTest (line 46) | FileReadEventForTest(const QByteArray& bytes) :
method QTemporaryFile (line 56) | const QTemporaryFile& file(){ return m_file; }
method QByteArray (line 57) | const QByteArray& bytes(){ return m_bytes; }
function CommandInfo (line 67) | CommandInfo generateCmdInfo(){
function push_back_writeEvent (line 84) | void push_back_writeEvent(FileEvents& fEvents, const FileEvent& e){
function push_back_readEvent (line 92) | void push_back_readEvent(FileEvents& fEvents, const FileReadEventForTest...
function sortFileWriteInfos (line 99) | void sortFileWriteInfos(FileWriteInfos & fInos){
function sortFileReadInfos (line 106) | void sortFileReadInfos(FileReadInfos & fInos){
function countStoredFiles (line 112) | int countStoredFiles(){
function deleteCommandInDb (line 116) | int deleteCommandInDb(qint64 id)
function db_addFileEventsWrapper (line 123) | void db_addFileEventsWrapper(const CommandInfo &cmd, FileEvents &fileEve...
class DbCtrlTest (line 128) | class DbCtrlTest : public QObject {
method fileWriteEventToWriteInfo (line 131) | fileWriteEventToWriteInfo(const FileEvent& e){
method FileReadInfo (line 144) | FileReadInfo fileReadEventToReadInfo(const FileReadEventForTest_ptr& e){
method FileEvent (line 159) | FileEvent generateFileWriteEvent(){
method FileReadEventForTest_ptr (line 181) | FileReadEventForTest_ptr
method initTestCase (line 207) | void initTestCase(){
method init (line 211) | void init(){
method cleanup (line 215) | void cleanup(){
method tWriteOnly (line 220) | void tWriteOnly() {
method tRead (line 266) | void tRead(){
method tDuplicates (line 310) | void tDuplicates(){
method tDeleteCommand (line 352) | void tDeleteCommand(){
method tSchemeUpdates (line 470) | void tSchemeUpdates(){
FILE: test/test_fdcommunication.cpp
type kcmp_type (line 7) | enum kcmp_type { KCMP_FILE}
function makeSockets (line 27) | static QPair<SocketCommunication, SocketCommunication> makeSockets(){
class FCommunicationTest (line 39) | class FCommunicationTest : public QObject {
method Q_OBJECT (line 40) | Q_OBJECT
method initTestCase (line 52) | void initTestCase(){
method tNormal (line 56) | void tNormal() {
method tFd (line 87) | void tFd() {
FILE: test/test_fileeventhandler.cpp
function writeCompareBuf (line 26) | void writeCompareBuf(const std::string & buf,
class FileEventHandlerTest (line 50) | class FileEventHandlerTest : public QObject {
method Q_OBJECT (line 51) | Q_OBJECT
method init (line 57) | void init(){
method cleanup (line 61) | void cleanup(){
method tWrite (line 65) | void tWrite() {
method tRead (line 109) | void tRead(){
FILE: test/test_osutil.cpp
class OsutilTest (line 12) | class OsutilTest : public QObject {
method Q_OBJECT (line 13) | Q_OBJECT
method testReadWholeFile (line 19) | void testReadWholeFile() {
FILE: test/test_pathtree.cpp
class PathTreeTest (line 13) | class PathTreeTest : public QObject {
method Q_OBJECT (line 14) | Q_OBJECT
method checkAllExist (line 27) | void checkAllExist(PathTree& tree,
method erasePathTreeFromIt (line 38) | void erasePathTreeFromIt(PathTree& tree, PathTree::iterator it){
method initTestCase (line 47) | void initTestCase(){
method testContains (line 51) | void testContains(){
method testParent (line 69) | void testParent() {
method testSub (line 100) | void testSub() {
method testFindSub (line 133) | void testFindSub(){
method testClear (line 163) | void testClear(){
method testIter (line 172) | void testIter(){
method testErase (line 190) | void testErase(){
FILE: test/test_qformattedstream.cpp
class QFormattedtStreamTest (line 8) | class QFormattedtStreamTest : public QObject {
method Q_OBJECT (line 9) | Q_OBJECT
method testIt (line 15) | void testIt() {
FILE: test/test_qoptargparse.cpp
class QOptArgparseTest (line 15) | class QOptArgparseTest : public QObject {
method Q_OBJECT (line 16) | Q_OBJECT
method testIt (line 22) | void testIt() {
FILE: test/test_util.cpp
class UtilTest (line 12) | class UtilTest : public QObject {
class T (line 15) | class T
method splitAbsPathTest (line 16) | void splitAbsPathTest(const T & p, const T& expectedPath, const T& exp...
method initTestCase (line 25) | void initTestCase(){
method testSplitAbsPath (line 29) | void testSplitAbsPath() {
method testPathJoinFilename (line 44) | void testPathJoinFilename(){
Condensed preview — 332 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,543K chars).
[
{
"path": ".gitignore",
"chars": 148,
"preview": "CMakeLists.txt.user*\n*.geany\n*.autosave\npackage-lock.json\nhtml-export/node_modules\nhtml-export/dist/SAMPLE_DATA.js\nhtml-"
},
{
"path": "CMakeLists.txt",
"chars": 8498,
"preview": "cmake_minimum_required(VERSION 3.6)\n\nif (NOT (CMAKE_VERSION VERSION_LESS \"3.20\"))\n cmake_policy( SET CMP0115 NEW )\nen"
},
{
"path": "LICENSE",
"chars": 35147,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "README-compile.md",
"chars": 4628,
"preview": "\n# Compile and install from source\n\n* Install gcc >= 5.0. Other compilers might work but are untested.\n* Install cmake >"
},
{
"path": "README-shell-integration.md",
"chars": 8153,
"preview": "\n# Shell integration for shournal\n\n\n\n## Basic setup (interactive)\nAfter installation, to start observing your *interacti"
},
{
"path": "README.md",
"chars": 23013,
"preview": "\n\n\n\n## A (file-) journal for your shell\n\n**Log shell-commands and used files. Snaps"
},
{
"path": "cmake/FindShournalUtil.cmake",
"chars": 303,
"preview": "\n# Join a list of strings using seperator sep\n# and store the output in result.\nfunction(JOIN vals sep result)\n string "
},
{
"path": "extern/folly/LICENSE",
"chars": 11350,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "extern/folly/README.md",
"chars": 8132,
"preview": "Folly: Facebook Open-source Library\n-----------------------------------\n\n[ Facebook, Inc. and its affiliates.\n *\n * Licensed under the Apache License, Version 2.0 (the \"Licens"
},
{
"path": "extern/tsl-ordered-map/CMakeLists.txt",
"chars": 203,
"preview": "\nadd_library(lib_orderedmap\n ordered_hash.h\n ordered_map.h\n ordered_set.h\n)\n\nset_target_properties(lib_orderedmap PRO"
},
{
"path": "extern/tsl-ordered-map/LICENSE",
"chars": 1063,
"preview": "MIT License\n\nCopyright (c) 2017 Tessil\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
},
{
"path": "extern/tsl-ordered-map/ordered_hash.h",
"chars": 57840,
"preview": "/**\n * MIT License\n * \n * Copyright (c) 2017 Tessil\n * \n * Permission is hereby granted, free of charge, to any person o"
},
{
"path": "extern/tsl-ordered-map/ordered_map.h",
"chars": 33480,
"preview": "/**\n * MIT License\n * \n * Copyright (c) 2017 Tessil\n * \n * Permission is hereby granted, free of charge, to any person o"
},
{
"path": "extern/tsl-ordered-map/ordered_set.h",
"chars": 28015,
"preview": "/**\n * MIT License\n * \n * Copyright (c) 2017 Tessil\n * \n * Permission is hereby granted, free of charge, to any person o"
},
{
"path": "extern/xxHash/.gitattributes",
"chars": 167,
"preview": "# Set the default behavior\n* text eol=lf\n\n# Explicitly declare source files\n*.c text eol=lf\n*.h text eol=lf\n\n# Denote fi"
},
{
"path": "extern/xxHash/.gitignore",
"chars": 163,
"preview": "# objects\n*.o\n\n# libraries\nlibxxhash.*\n\n# Executables\nxxh32sum\nxxh64sum\nxxhsum\nxxhsum32\nxxhsum_privateXXH\nxxhsum_inlined"
},
{
"path": "extern/xxHash/.travis.yml",
"chars": 266,
"preview": "language: c\ncompiler: gcc\nscript: make -B test-all\nbefore_install:\n - sudo apt-get update -qq\n - sudo apt-get install"
},
{
"path": "extern/xxHash/LICENSE",
"chars": 1314,
"preview": "xxHash Library\nCopyright (c) 2012-2014, Yann Collet\nAll rights reserved.\n\nRedistribution and use in source and binary fo"
},
{
"path": "extern/xxHash/Makefile",
"chars": 10257,
"preview": "# ################################################################\n# xxHash Makefile\n# Copyright (C) Yann Collet 2012-20"
},
{
"path": "extern/xxHash/README.md",
"chars": 7183,
"preview": "xxHash - Extremely fast hash algorithm\n======================================\n\nxxHash is an Extremely fast Hash algorith"
},
{
"path": "extern/xxHash/appveyor.yml",
"chars": 3384,
"preview": "version: 1.0.{build}\nenvironment:\n matrix:\n - COMPILER: \"gcc\"\n PLATFORM: \"mingw64\"\n - COMPILER: \"gcc\"\n PLATFORM"
},
{
"path": "extern/xxHash/cmake_unofficial/.gitignore",
"chars": 172,
"preview": "# cmake artifacts\n\nCMakeCache.txt\nCMakeFiles\nMakefile\ncmake_install.cmake\n\n\n# make compilation results\n\nlibxxhash.0.6.3."
},
{
"path": "extern/xxHash/cmake_unofficial/CMakeLists.txt",
"chars": 4111,
"preview": "# To the extent possible under law, the author(s) have dedicated all\n# copyright and related and neighboring rights to t"
},
{
"path": "extern/xxHash/cmake_unofficial/README.md",
"chars": 205,
"preview": "\n\nThe `cmake` script present in this directory offers the following options :\n\n- `BUILD_XXHSUM` : build the command line"
},
{
"path": "extern/xxHash/doc/xxhash_spec.md",
"chars": 13266,
"preview": "xxHash fast digest algorithm\n======================\n\n### Notices\n\nCopyright (c) Yann Collet\n\nPermission is granted to co"
},
{
"path": "extern/xxHash/xxhash.c",
"chars": 33771,
"preview": "/*\n* xxHash - Fast Hash algorithm\n* Copyright (C) 2012-2016, Yann Collet\n*\n* BSD 2-Clause License (http://www.opensou"
},
{
"path": "extern/xxHash/xxhash.h",
"chars": 13466,
"preview": "/*\n xxHash - Extremely Fast Hash algorithm\n Header File\n Copyright (C) 2012-2016, Yann Collet.\n\n BSD 2-Clause Li"
},
{
"path": "extern/xxHash/xxhsum.1",
"chars": 3678,
"preview": ".\n.TH \"XXHSUM\" \"1\" \"September 2017\" \"xxhsum 0.6.3\" \"User Commands\"\n.\n.SH \"NAME\"\n\\fBxxhsum\\fR \\- print or check xxHash no"
},
{
"path": "extern/xxHash/xxhsum.1.md",
"chars": 3261,
"preview": "xxhsum(1) -- print or check xxHash non-cryptographic checksums\n========================================================="
},
{
"path": "extern/xxHash/xxhsum.c",
"chars": 42463,
"preview": "/*\n* xxhsum - Command line interface for xxhash algorithms\n* Copyright (C) Yann Collet 2012-2016\n*\n* GPL v2 License\n*"
},
{
"path": "html-export/dist/htmlexportres.qrc",
"chars": 119,
"preview": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource>\n <file>index.html</file>\n <file>main.js</file>\n</qresource>\n</RCC>\n"
},
{
"path": "html-export/dist/index.html",
"chars": 5275,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scal"
},
{
"path": "html-export/dist/main.js",
"chars": 63594,
"preview": "/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/**"
},
{
"path": "html-export/dist/main.licenses.txt",
"chars": 1893,
"preview": "async-mutex\nMIT\nThe MIT License (MIT)\n\nCopyright (c) 2016 Christian Speckner <cnspeckn@googlemail.com>\n\nPermission is he"
},
{
"path": "html-export/package.json",
"chars": 525,
"preview": "{\n \"name\": \"shournal-html-stats\",\n \"version\": \"1.0.0\",\n \"description\": \"interactively browse shournal's command histo"
},
{
"path": "html-export/src/annotation_line_render.js",
"chars": 7305,
"preview": "\n\nimport * as util from './util';\nimport {sleep} from './util';\nimport {Mutex} from 'async-mutex';\n\n/**\n * Render Groups"
},
{
"path": "html-export/src/command_list.js",
"chars": 6376,
"preview": "import * as html_util from './html_util';\nimport * as util from './util';\nimport * as globals from './globals';\nimport *"
},
{
"path": "html-export/src/command_manipulation.js",
"chars": 1853,
"preview": "\nimport * as globals from './globals';\n\n/**\n * Parse the command-date into d3's date and assign session colors\n * @param"
},
{
"path": "html-export/src/command_timeline.js",
"chars": 8553,
"preview": "import * as util from './util';\nimport Tooltip from './tooltip';\nimport AnnotationLineRender from './annotation_line_ren"
},
{
"path": "html-export/src/conversions.js",
"chars": 598,
"preview": "\n/**\n * @return {String} human readble byte-size-string\n * @param {int} bytes \n * @param {boolean} si if true: use 1000 "
},
{
"path": "html-export/src/d3js_util.js",
"chars": 2028,
"preview": "\n\n/**\n * Wrap long axis labels to mutliple lines by maximum width, splitting words by \n * the given *delimeter-keeping* "
},
{
"path": "html-export/src/generic_text_dialog.js",
"chars": 219,
"preview": "\n\nexport default class GenericTextDialog {\n constructor() {\n }\n\n show(title, content){\n $(\"#genericModalTitle\").ht"
},
{
"path": "html-export/src/globals.js",
"chars": 563,
"preview": "\n\nimport GenericTextDialog from './generic_text_dialog';\n\nexport let humanDateFormat;\nexport let humanDateFormatOnlyDate"
},
{
"path": "html-export/src/html_util.js",
"chars": 940,
"preview": "\n\nexport function insertAfter(newNode, referenceNode) {\n referenceNode.parentNode.insertBefore(newNode, referenceNode.n"
},
{
"path": "html-export/src/index.js",
"chars": 1896,
"preview": "\nimport * as command_manipulation from './command_manipulation';\nimport CommandList from './command_list';\nimport {asser"
},
{
"path": "html-export/src/limited_queue.js",
"chars": 518,
"preview": "\n\nimport TinyQueue from 'tinyqueue';\n\n/**\n * Allow for a max. length of the queue.\n * Add further convenience functions\n"
},
{
"path": "html-export/src/map_extended.js",
"chars": 568,
"preview": "\n\nexport default class MapExtended extends Map {\n \n /**\n * Like get() but insert and return a default, if the key\n "
},
{
"path": "html-export/src/plot_cmdcount_per_cwd.js",
"chars": 927,
"preview": "\n\nimport PlotSimpleBar from './plot_simple_bar';\n\n/**\n * A bar plot displaying the working directories\n * where the most"
},
{
"path": "html-export/src/plot_cmdcount_per_session.js",
"chars": 2123,
"preview": "\n\nimport PlotSimpleBar from './plot_simple_bar';\nimport * as globals from './globals';\n\n/**\n * A bar plot displaying the"
},
{
"path": "html-export/src/plot_io_per_dir.js",
"chars": 932,
"preview": "\n\nimport PlotSimpleBar from './plot_simple_bar';\n\n/**\n * A bar plot displaying directories\n * with most IO-activity.\n */"
},
{
"path": "html-export/src/plot_most_written_files.js",
"chars": 1702,
"preview": "\nimport PlotSimpleBar from './plot_simple_bar';\n\nimport * as command_manipulation from './command_manipulation';\nimport "
},
{
"path": "html-export/src/plot_simple_bar.js",
"chars": 4654,
"preview": "\n\nimport * as d3js_util from './d3js_util';\nimport {ErrorNotImplemented} from './util';\n\n/**\n * Base class for several b"
},
{
"path": "html-export/src/session_timeline.js",
"chars": 16356,
"preview": "import * as util from './util';\nimport MapExtended from './map_extended';\nimport TimelineGroupFind from './timeline_grou"
},
{
"path": "html-export/src/stats.js",
"chars": 1890,
"preview": "\nimport PlotMostWrittenFiles from './plot_most_written_files';\nimport PlotCmdCountPerCwd from './plot_cmdcount_per_cwd';"
},
{
"path": "html-export/src/timeline_group_find.js",
"chars": 1364,
"preview": "\n\nimport TinyQueue from 'tinyqueue';\n\n/**\n * Find \"groups\" in an ordered timeline, so that parallel \n * events get diffe"
},
{
"path": "html-export/src/tooltip.js",
"chars": 836,
"preview": "\n\nexport default class Tooltip {\n\n constructor(){\n this._tooltipDiv = d3.select('body')\n .append('div')\n .styl"
},
{
"path": "html-export/src/util.js",
"chars": 3065,
"preview": "\nexport class ErrorNotImplemented extends Error { \n constructor() {\n super('Required method not implemented');\n }\n}"
},
{
"path": "html-export/src/zoom_buttons.js",
"chars": 1670,
"preview": "\n\nexport default class ZoomButtons {\n \n /**\n * @param {d3-element} containerDiv The plot/svg is excepted to be in th"
},
{
"path": "html-export/webpack.config.js",
"chars": 261,
"preview": "const LicenseWebpackPlugin = require('license-webpack-plugin').LicenseWebpackPlugin;\n\nmodule.exports = {\n optimization:"
},
{
"path": "install/90-shournaladd.rules.in",
"chars": 198,
"preview": "ACTION==\"add\", KERNEL==\"shournalk_ctrl\", RUN=\"/bin/sh -c 'test -f /etc/shournal.d/kgroup && read -r ___kgrp < /etc/shour"
},
{
"path": "install/CMakeLists.txt",
"chars": 779,
"preview": "\n# The files here are only required for installation and\n# have no direct relation to source-code.\n\nconfigure_file( post"
},
{
"path": "install/postinst-dkms.in",
"chars": 1178,
"preview": "# No shebang, we are appended as needed!\n\n# Copyright (C) 2002-2005 Flavio Stanchina\n# Copyright (C) 2005-2006 Aric Cyr\n"
},
{
"path": "install/postinst.in",
"chars": 209,
"preview": "#!/bin/sh\nset -e\ngetent group ${MSENTER_GROUPNAME} || groupadd ${MSENTER_GROUPNAME}\ngetent group ${GROUPNAME_SHOURNALK} "
},
{
"path": "install/prerm-dkms.in",
"chars": 309,
"preview": "# No shebang, we are appended as needed!\n\nset -e\n\nDKMS_NAME=shournalk\nDKMS_VERSION=\"${shournal_version}\"\n\ncase \"$1\" in\n "
},
{
"path": "install/prerm.in",
"chars": 149,
"preview": "#!/bin/sh\nset -e\n\n# This file is intentionally left blank for consistency with\n# postinst-dkms\n\n# do not call exit, this"
},
{
"path": "install/shournalk-load.conf",
"chars": 10,
"preview": "shournalk\n"
},
{
"path": "kernel/CMakeLists.txt",
"chars": 2388,
"preview": "\n# Find kernel headers\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake\")\nfind_package(KernelHeaders REQ"
},
{
"path": "kernel/Kbuild",
"chars": 1455,
"preview": "\n$(info building kernel module shournalk version @shournal_version@)\n\nobj-m := shournalk.o\n\n# shournal_version filled by"
},
{
"path": "kernel/LICENSE",
"chars": 18092,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 2, June 1991\n\n Copyright (C) 1989, 1991 Fr"
},
{
"path": "kernel/cmake/FindKernelHeaders.cmake",
"chars": 1294,
"preview": "\n# get kernel release\nexecute_process(\n COMMAND uname -r\n OUTPUT_VARIABLE KERNEL_RELEASE\n OUTPUT_ST"
},
{
"path": "kernel/dkms.conf.in",
"chars": 207,
"preview": "PACKAGE_NAME=\"shournalk\"\nPACKAGE_VERSION=\"@shournal_version@\"\nCLEAN=\"make clean\"\nMAKE[0]=\"make all KVER=$kernelver\"\nBUIL"
},
{
"path": "kernel/event_consumer.c",
"chars": 22311,
"preview": "\n#include <linux/compiler.h>\n#include <linux/dcache.h>\n#include <linux/file.h>\n#include <linux/fdtable.h>\n#include <linu"
},
{
"path": "kernel/event_consumer.h",
"chars": 1534,
"preview": "#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/path.h>\n#include <linux/types.h>\n#include <linux/fs.h>\n#inc"
},
{
"path": "kernel/event_consumer_cache.c",
"chars": 3936,
"preview": "\n#include <linux/jiffies.h>\n#include <linux/dcache.h>\n\n#include \"event_consumer_cache.h\"\n#include \"kutil.h\"\n\n// stolen f"
},
{
"path": "kernel/event_consumer_cache.h",
"chars": 1211,
"preview": "/* Cache d_names and settings (in flags) for\n * the given struct path. Note that in rare cases\n * wrong (older) paths ma"
},
{
"path": "kernel/event_handler.c",
"chars": 14313,
"preview": "\n#include <linux/hashtable.h>\n#include <linux/slab.h>\n#include <linux/pid.h>\n#include <linux/file.h>\n#include <linux/fdt"
},
{
"path": "kernel/event_handler.h",
"chars": 703,
"preview": "#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/types.h>\n\nstruct event_target;\nstruct ftrace_ops;\nstruct pt"
},
{
"path": "kernel/event_queue.c",
"chars": 4239,
"preview": "\n#include <linux/circ_buf.h>\n#include <linux/compiler.h>\n#include <linux/slab.h>\n#include <linux/sched.h>\n#include <linu"
},
{
"path": "kernel/event_queue.h",
"chars": 2961,
"preview": "/* File events are stored into a ringbuffer\n * and consumed in a per-event_target-thread.\n */\n\n#pragma once\n\n#include \"s"
},
{
"path": "kernel/event_target.c",
"chars": 13221,
"preview": "\n\n#include <linux/hashtable.h>\n#include <linux/memory.h>\n#include <linux/memcontrol.h>\n#include <linux/slab.h>\n#include "
},
{
"path": "kernel/event_target.h",
"chars": 3453,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n#include \"xxhash_common.h\"\n\n#include <linux/atomic.h>\n#include <linux/limit"
},
{
"path": "kernel/hash_table_str.c",
"chars": 814,
"preview": "\n#include \"hash_table_str.h\"\n\n#include <linux/slab.h>\n#include <linux/mm.h>\n\n\nstatic const int HASH_GFP_FLAGS = SHOURNAL"
},
{
"path": "kernel/hash_table_str.h",
"chars": 2342,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n#include \"kutil.h\"\n\n#include <linux/hashtable.h>\n\n#include \"xxhash_shournal"
},
{
"path": "kernel/kfileextensions.c",
"chars": 2672,
"preview": "\n\n#include \"kfileextensions.h\"\n\n#include \"hash_table_str.h\"\n\n\nvoid file_extensions_init(struct file_extensions* extensio"
},
{
"path": "kernel/kfileextensions.h",
"chars": 730,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/hashtable.h>\n\n#define KFILEEXT_BITS 6\n\nstruct file_extensi"
},
{
"path": "kernel/kpathtree.c",
"chars": 4200,
"preview": "\n#include \"kpathtree.h\"\n\n#include <linux/hashtable.h>\n#include <linux/slab.h>\n#include <linux/mm.h>\n#include <linux/sort"
},
{
"path": "kernel/kpathtree.h",
"chars": 1072,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/hashtable.h>\n#include <linux/mutex.h>\n\n\n#define KPATHTREE_"
},
{
"path": "kernel/kutil.c",
"chars": 8851,
"preview": "\n#include <linux/dcache.h>\n#include <linux/file.h>\n#include <linux/fdtable.h>\n#include <linux/fs.h>\n#include <linux/slab"
},
{
"path": "kernel/kutil.h",
"chars": 7154,
"preview": "#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/cgroup.h>\n#include <linux/dcache.h>\n#include <linux/bug.h>\n"
},
{
"path": "kernel/shournal_kio.c",
"chars": 1949,
"preview": "\n#include \"shournal_kio.h\"\n#include <linux/slab.h>\n#include <linux/mm.h>\n#include <linux/file.h>\n\n#include \"kutil.h\"\n\n\ns"
},
{
"path": "kernel/shournal_kio.h",
"chars": 482,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/types.h>\n\n\nstruct file;\n\nstruct kbuffered_file {\n struc"
},
{
"path": "kernel/shournalk_global.c",
"chars": 339,
"preview": "\n#include \"shournalk_global.h\"\n\n#include \"kpathtree.h\"\n\n\nstruct kpathtree g_dummy_pathtree;\n\nlong shournalk_global_const"
},
{
"path": "kernel/shournalk_global.h",
"chars": 352,
"preview": "\n#pragma once\n// include module name in print_* messages:\n#ifdef pr_fmt\n#undef pr_fmt\n#endif\n#define pr_fmt(fmt) \"shourn"
},
{
"path": "kernel/shournalk_main.c",
"chars": 1426,
"preview": "#include \"shournalk_global.h\"\n\n#include <linux/kernel.h>\n#include <linux/module.h>\n#include <linux/init.h>\n#include <lin"
},
{
"path": "kernel/shournalk_sysfs.c",
"chars": 12366,
"preview": "\n#include <linux/init.h>\n#include <linux/module.h>\n#include <linux/file.h>\n#include <linux/fs.h>\n#include <linux/fdtable"
},
{
"path": "kernel/shournalk_sysfs.h",
"chars": 126,
"preview": "\n#pragma once\n#include \"shournalk_global.h\"\n\n\n\nint shournalk_sysfs_constructor(void);\n\nvoid shournalk_sysfs_destructor(v"
},
{
"path": "kernel/shournalk_test.c",
"chars": 3863,
"preview": "\n\n#include \"shournalk_test.h\"\n\n#include \"kpathtree.h\"\n#include \"hash_table_str.h\"\n\n\n#define TEST_FAIL_ON(condition) ({\t\t"
},
{
"path": "kernel/shournalk_test.h",
"chars": 94,
"preview": "\n#pragma once\n\n#include \"shournalk_global.h\"\n\n#include <linux/types.h>\n\nbool run_tests(void);\n"
},
{
"path": "kernel/shournalk_user.h",
"chars": 3829,
"preview": "/* Common header for kernel and userspace to control\n * shournalk via a sysfs interface\n */\n\n#pragma once\n\n#ifdef __KERN"
},
{
"path": "kernel/tracepoint_helper.c",
"chars": 6907,
"preview": "\n#include <linux/ftrace.h>\n#include <linux/tracepoint.h>\n#include <linux/version.h>\n#include <linux/file.h>\n#include <li"
},
{
"path": "kernel/tracepoint_helper.h",
"chars": 703,
"preview": "#pragma once\n#include \"shournalk_global.h\"\n#include <linux/version.h>\n#include <linux/ftrace.h>\n\nstruct pt_regs;\n\nint tr"
},
{
"path": "kernel/xxhash_shournalk.c",
"chars": 12858,
"preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Copyright (C) 2012-2016, Yann Collet.\n *\n * BSD 2-Clause License (http:/"
},
{
"path": "kernel/xxhash_shournalk.h",
"chars": 8261,
"preview": "/*\n * xxHash - Extremely Fast Hash algorithm\n * Copyright (C) 2012-2016, Yann Collet.\n *\n * BSD 2-Clause License (http:/"
},
{
"path": "shell-integration-scripts/CMakeLists.txt",
"chars": 2147,
"preview": "\nconfigure_file( _source_me_generic.sh _source_me_generic.sh @ONLY)\n\n# Merge script files into _integration_ko.sh\n# Writ"
},
{
"path": "shell-integration-scripts/_source_me_generic.sh",
"chars": 2764,
"preview": "# Select which shell-integration to be sourced based on config\n# and availability.\n# The backend is chosen in the follow"
},
{
"path": "shell-integration-scripts/integration_fan.sh",
"chars": 15298,
"preview": "\n# shell-integration for shournal - fanotify backend.\n\n\n_shournal_run_backend='shournal-run-fanotify'\n\n\n_shournal_enable"
},
{
"path": "shell-integration-scripts/integration_ko.sh",
"chars": 13018,
"preview": "\n# shell-integration for shournal - kernel-module backend.\n\n\n_shournal_run_backend='shournal-run'\n\n_shournal_enable(){\n "
},
{
"path": "shell-integration-scripts/integration_main.sh.in",
"chars": 7627,
"preview": "\n# Shell integration for shournal\n# This file contains all public functions and\n# must be compatible with all supported "
},
{
"path": "shell-integration-scripts/util.sh",
"chars": 7252,
"preview": "\n\n# don't call it directly, but use one of debug, info, warning, error functions\n# $1: loglevel.\n# all other args: is pr"
},
{
"path": "src/CMakeLists.txt",
"chars": 498,
"preview": "\n\ninclude_directories(\n ../extern\n ../kernel\n common/\n common/database\n common/oscpp\n common/oscpp\n "
},
{
"path": "src/common/CMakeLists.txt",
"chars": 1626,
"preview": "\nadd_subdirectory(util)\nadd_subdirectory(oscpp)\nadd_subdirectory(qoptargparse)\nadd_subdirectory(qsimplecfg)\n\nSET(lib_sho"
},
{
"path": "src/common/app.cpp",
"chars": 2696,
"preview": "\n#include <cstdlib>\n\n#include <QString>\n#include <QCoreApplication>\n#include <QStandardPaths>\n\n#include \"qoutstream.h\"\n#"
},
{
"path": "src/common/app.h",
"chars": 545,
"preview": "#pragma once\n\n#include <QVersionNumber>\n#include <unordered_set>\n\nnamespace app {\n\nconst extern char* CURRENT_NAME;\ncons"
},
{
"path": "src/common/cefd.cpp",
"chars": 658,
"preview": "\n#include <sys/eventfd.h>\n\n#include \"cefd.h\"\n#include \"os.h\"\n#include \"excos.h\"\n#include \"osutil.h\"\n\n\nCEfd::CEfd()\n{\n "
},
{
"path": "src/common/cefd.h",
"chars": 333,
"preview": "\n#pragma once\n\n#include <cstdint>\n\n#include \"util.h\"\n\nclass CEfd {\npublic:\n static const uint64_t MSG_OK {7};\n sta"
},
{
"path": "src/common/console_dialog.cpp",
"chars": 2627,
"preview": "\n#include <cstdlib>\n#include <QTextStream>\n#include <QStandardPaths>\n\n\n#include \"compat.h\"\n#include \"console_dialog.h\"\n#"
},
{
"path": "src/common/console_dialog.h",
"chars": 158,
"preview": "#pragma once\n\n#include <QString>\n\nnamespace console_dialog {\n\nbool yesNo(const QString& question);\n\nint openFileInExtern"
},
{
"path": "src/common/cxxhash.cpp",
"chars": 4996,
"preview": "\n#include <cassert>\n\n#include \"cxxhash.h\"\n#include <iostream>\n\n#include \"excos.h\"\n#include \"os.h\"\n\n\nCXXHash::CXXHash() :"
},
{
"path": "src/common/cxxhash.h",
"chars": 1225,
"preview": "#pragma once\n\n\n#include <cstddef>\n#include <unistd.h>\n#include <string>\n#include <limits>\n\n#include \"xxhash.h\"\n#include "
},
{
"path": "src/common/database/command_query_iterator.cpp",
"chars": 2971,
"preview": "\n#include <QDebug>\n#include \"command_query_iterator.h\"\n#include \"util.h\"\n#include \"db_connection.h\"\n#include \"db_convers"
},
{
"path": "src/common/database/command_query_iterator.h",
"chars": 628,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"qsqlquerythrow.h\"\n#include \"commandinfo.h\"\n#include \"db_connection.h\"\n\nclass "
},
{
"path": "src/common/database/commandinfo.cpp",
"chars": 4822,
"preview": "\n#include <QHostInfo>\n#include <QString>\n#include <QJsonArray>\n\n#include \"commandinfo.h\"\n\n#include \"os.h\"\n#include \"sett"
},
{
"path": "src/common/database/commandinfo.h",
"chars": 1949,
"preview": "#pragma once\n\n#include <QString>\n#include <QVector>\n#include <QJsonObject>\n\n#include \"hashmeta.h\"\n#include \"sessioninfo."
},
{
"path": "src/common/database/db_connection.cpp",
"chars": 7179,
"preview": "\n#include <cassert>\n\n#include <QSqlDatabase>\n#include <QSqlQuery>\n#include <QSqlError>\n#include <QStandardPaths>\n#includ"
},
{
"path": "src/common/database/db_connection.h",
"chars": 247,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"qsqlquerythrow.h\"\n\ntypedef std::shared_ptr<QSqlQueryThrow> QueryPtr;\n\nnamespa"
},
{
"path": "src/common/database/db_controller.cpp",
"chars": 17632,
"preview": "\n#include <fcntl.h>\n#include <csignal>\n#include <QSqlDatabase>\n#include <QSqlRecord>\n#include <QSql>\n#include <QSqlDrive"
},
{
"path": "src/common/database/db_controller.h",
"chars": 899,
"preview": "#pragma once\n\n#include <QByteArray>\n#include <QVector>\n#include <memory>\n\n#include \"fileevents.h\"\n#include \"commandinfo."
},
{
"path": "src/common/database/db_conversions.cpp",
"chars": 646,
"preview": "\n#include <QDateTime>\n#include \"db_conversions.h\"\n#include \"util.h\"\n\nQVariant db_conversions::fromMtime(time_t mtime)\n{\n"
},
{
"path": "src/common/database/db_conversions.h",
"chars": 313,
"preview": "#pragma once\n\n#include <QVariant>\n#include <ctime>\n\n#include \"nullable_value.h\"\n\nnamespace db_conversions {\n QVariant"
},
{
"path": "src/common/database/db_globals.cpp",
"chars": 95,
"preview": "#include \"db_globals.h\"\n\n// SQLITE begins int-ids at one.\nconst qint64 db::INVALID_INT_ID = 0;\n"
},
{
"path": "src/common/database/db_globals.h",
"chars": 90,
"preview": "#pragma once\n\n#include <QtGlobal>\n\nnamespace db {\n\nextern const qint64 INVALID_INT_ID;\n\n}\n"
},
{
"path": "src/common/database/file_query_helper.cpp",
"chars": 9969,
"preview": "\n#include <QDateTime>\n#include <QDebug>\n#include <vector>\n\n#include \"db_controller.h\"\n#include \"db_conversions.h\"\n#inclu"
},
{
"path": "src/common/database/file_query_helper.h",
"chars": 359,
"preview": "#pragma once\n\n#include <QFile>\n\n#include \"sqlquery.h\"\n#include \"nullable_value.h\"\n#include \"fileinfos.h\"\n\nnamespace file"
},
{
"path": "src/common/database/fileinfos.cpp",
"chars": 2766,
"preview": "#include \"fileinfos.h\"\n\n#include \"db_conversions.h\"\n#include \"commandinfo.h\"\n#include \"hashcontrol.h\"\n#include \"logger.h"
},
{
"path": "src/common/database/fileinfos.h",
"chars": 948,
"preview": "#pragma once\n\n#include <QString>\n#include <QDateTime>\n#include <QJsonObject>\n\n#include \"nullable_value.h\"\n#include \"db_g"
},
{
"path": "src/common/database/insertifnotexist.cpp",
"chars": 2663,
"preview": "\n\n#include \"insertifnotexist.h\"\n\n#include \"qsqlquerythrow.h\"\n\ndb_controller::InsertIfNotExist::InsertIfNotExist(QSqlQuer"
},
{
"path": "src/common/database/insertifnotexist.h",
"chars": 917,
"preview": "\n#pragma once\n\n#include <QVariant>\n#include <QVector>\n\n\nclass QSqlQueryThrow;\n\nnamespace db_controller {\n\n/// Insert val"
},
{
"path": "src/common/database/qexcdatabase.cpp",
"chars": 391,
"preview": "\n#include \"qexcdatabase.h\"\n\n\n\n\nQExcDatabase::QExcDatabase(const QString &preamble, const QSqlError &err) :\n QExcCommo"
},
{
"path": "src/common/database/qexcdatabase.h",
"chars": 231,
"preview": "\n#include <QSqlError>\n\n#include \"exccommon.h\"\n\n\nclass QExcDatabase : public QExcCommon\n{\npublic:\n QExcDatabase(const"
},
{
"path": "src/common/database/qsqlquerythrow.cpp",
"chars": 5288,
"preview": "#include <QMap>\n#include <QVariant>\n#include <QHash>\n#include <cassert>\n\n#include \"logger.h\"\n#include \"osutil.h\"\n#includ"
},
{
"path": "src/common/database/qsqlquerythrow.h",
"chars": 1142,
"preview": "#pragma once\n\n#include <QSqlQuery>\n#include <QVariant>\n#include <QVector>\n\nclass QSqlQueryThrow : public QSqlQuery\n{\npub"
},
{
"path": "src/common/database/query_columns.h",
"chars": 1590,
"preview": "#pragma once\n\n#include <QString>\n#include \"util.h\"\n\nnamespace db_controller {\n\nclass QueryColumns {\npublic:\n static Q"
},
{
"path": "src/common/database/sessioninfo.cpp",
"chars": 158,
"preview": "#include \"sessioninfo.h\"\n\n\n\nbool SessionInfo::operator==(const SessionInfo &rhs) const\n{\n return uuid == rhs.uuid &&\n"
},
{
"path": "src/common/database/sessioninfo.h",
"chars": 156,
"preview": "#pragma once\n\n#include <QString>\n\nstruct SessionInfo\n{\n QByteArray uuid;\n QString comment;\n\n bool operator=="
},
{
"path": "src/common/database/sqlite_database_scheme.cpp",
"chars": 2631,
"preview": "#include \"sqlite_database_scheme.h\"\n\n\n// Note: this is the initial scheme, please don't change it.\n// To add new stuff ("
},
{
"path": "src/common/database/sqlite_database_scheme.h",
"chars": 58,
"preview": "#pragma once\n\n\nextern const char* SQLITE_DATABASE_SCHEME;\n"
},
{
"path": "src/common/database/sqlite_database_scheme_updates.cpp",
"chars": 8056,
"preview": "#include \"sqlite_database_scheme_updates.h\"\n\n\nvoid sqlite_database_scheme_updates::v0_9(QSqlQueryThrow &query)\n{\n // "
},
{
"path": "src/common/database/sqlite_database_scheme_updates.h",
"chars": 350,
"preview": "#pragma once\n\n#include \"qsqlquerythrow.h\"\n\nnamespace sqlite_database_scheme_updates {\n void v0_9(QSqlQueryThrow& quer"
},
{
"path": "src/common/database/sqlquery.cpp",
"chars": 8157,
"preview": "\n#include <QDebug>\n#include \"sqlquery.h\"\n#include \"exccommon.h\"\n#include \"util.h\"\n\n\nconst QString &SqlQuery::query() con"
},
{
"path": "src/common/database/sqlquery.h",
"chars": 2272,
"preview": "#pragma once\n\n#include <type_traits>\n#include <QVector>\n#include <QVariant>\n#include <unordered_set>\n\n#include \"compareo"
},
{
"path": "src/common/database/storedfiles.cpp",
"chars": 2547,
"preview": "#include <cassert>\n\n#include \"storedfiles.h\"\n#include \"db_connection.h\"\n#include \"util.h\"\n#include \"qfilethrow.h\"\n#inclu"
},
{
"path": "src/common/database/storedfiles.h",
"chars": 682,
"preview": "#pragma once\n\n#include <QDir>\n\n#include \"fileinfos.h\"\n\nclass StoredFiles\n{\npublic:\n\n static const QString &getReadFil"
},
{
"path": "src/common/fdcommunication.cpp",
"chars": 5086,
"preview": "\n#include <cassert>\n#include <sys/socket.h>\n\n\n\n#include \"fdcommunication.h\"\n#include \"os.h\"\n#include \"cleanupresource.h\""
},
{
"path": "src/common/fdcommunication.h",
"chars": 1306,
"preview": "#pragma once\n\n#include <QVector>\n\n#include \"exccommon.h\"\n\n\nnamespace fdcommunication {\n\n\nclass ExcFdComm : public QExcCo"
},
{
"path": "src/common/fileeventhandler.cpp",
"chars": 12651,
"preview": "\n#include <cassert>\n#include <string>\n#include <sys/fanotify.h>\n#include <cstring>\n#include <unistd.h>\n#include <fstream"
},
{
"path": "src/common/fileeventhandler.h",
"chars": 2465,
"preview": "#pragma once\n\n#include <sys/stat.h>\n#include <string>\n#include <unordered_set>\n#include <QHash>\n#include <QPair>\n#includ"
},
{
"path": "src/common/fileevents.cpp",
"chars": 7752,
"preview": "#include \"fileevents.h\"\n\n#include <sys/stat.h>\n#include <cassert>\n\n#include \"stdiocpp.h\"\n#include \"strlight.h\"\n#include "
},
{
"path": "src/common/fileevents.h",
"chars": 1906,
"preview": "#pragma once\n\n#include <linux/limits.h>\n\n#include \"shournalk_user.h\"\n#include \"nullable_value.h\"\n#include \"strlight.h\"\n\n"
},
{
"path": "src/common/generic_container.h",
"chars": 1217,
"preview": "#pragma once\n\n#include <type_traits>\n\n\ntemplate <class ContainerT>\nclass TypeHas_push_back\n{\n template <class T>\n "
},
{
"path": "src/common/groupcontrol.cpp",
"chars": 1681,
"preview": "\n#include <algorithm>\n#include <QDebug>\n\n#include \"groupcontrol.h\"\n#include \"os.h\"\n\n\n/// @return all 'real' groups, the "
},
{
"path": "src/common/groupcontrol.h",
"chars": 264,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"idmapentry.h\"\n#include \"os.h\"\n\nnamespace groupcontrol {\ntypedef std::vector<S"
},
{
"path": "src/common/hashcontrol.cpp",
"chars": 898,
"preview": "\n#include \"hashcontrol.h\"\n\n/// xxhash parts of a file (or the whole file in case of a small one) according to the\n/// sp"
},
{
"path": "src/common/hashcontrol.h",
"chars": 323,
"preview": "#pragma once\n\n#include \"nullable_value.h\"\n#include \"cxxhash.h\"\n#include \"hashmeta.h\"\n#include \"os.h\"\n\nclass HashControl\n"
},
{
"path": "src/common/hashmeta.cpp",
"chars": 383,
"preview": "#include \"hashmeta.h\"\n\n\nHashMeta::HashMeta(size_type chunks, size_type maxCountOfR)\n : chunkSize(chunks),\n maxCo"
},
{
"path": "src/common/hashmeta.h",
"chars": 398,
"preview": "#pragma once\n\n#include <qglobal.h>\n#include <cstddef>\n\n#include \"database/db_globals.h\"\n\nstruct HashMeta\n{\n typedef i"
},
{
"path": "src/common/idmapentry.h",
"chars": 835,
"preview": "#pragma once\n\n#include <sys/types.h>\n#include <string>\n\ntemplate <typename T>\nclass S_IdMapEntry\n{\npublic:\n T idInNs;"
},
{
"path": "src/common/interrupt_handler.cpp",
"chars": 2745,
"preview": "#include <cassert>\n#include <unordered_map>\n\n#include \"logger.h\"\n#include \"interrupt_handler.h\"\n#include \"os.h\"\n#include"
},
{
"path": "src/common/interrupt_handler.h",
"chars": 719,
"preview": "#pragma once\n\n#include <csignal>\n#include <qglobal.h>\n#include <vector>\n\n#include \"util.h\"\n\n/// Defer processing of sign"
},
{
"path": "src/common/limited_priority_queue.h",
"chars": 1102,
"preview": "#pragma once\n\n#include <cstddef>\n#include <limits>\n#include <queue>\n\n\ntemplate<typename T, typename container, typename "
},
{
"path": "src/common/logger.cpp",
"chars": 5998,
"preview": "#include <cassert>\n#include <QDateTime>\n#include <QtGlobal>\n#include <QStandardPaths>\n#include <QTextStream>\n#include <Q"
},
{
"path": "src/common/logger.h",
"chars": 1363,
"preview": "#pragma once\n\n#include <QtGlobal>\n#include <QDebug>\n#include <QFile>\n#include <QTextStream>\n\n#define logDebug qDebug()\n\n"
},
{
"path": "src/common/oscpp/CMakeLists.txt",
"chars": 206,
"preview": "\n\nadd_library(oscpp_lib\n cflock.cpp\n excos.cpp\n fdentries.cpp\n os.cpp\n osutil.cpp\n oscaps.cpp\n )\n\ntarget_link_l"
},
{
"path": "src/common/oscpp/cflock.cpp",
"chars": 2190,
"preview": "#include <sys/file.h>\n#include <iostream>\n\n#include \"cflock.h\"\n#include \"os.h\"\n#include \"osutil.h\"\n\n#ifndef NDEBUG\n\nstat"
},
{
"path": "src/common/oscpp/cflock.h",
"chars": 726,
"preview": "#pragma once\n\n\n/// Wrapper class for flock.\n/// Due to NFS emulating flock as fcntl(2) byte-range locks\n/// the fd open "
},
{
"path": "src/common/oscpp/excos.cpp",
"chars": 1789,
"preview": "\n#include <unistd.h>\n#include <cstring>\n#include <iostream>\n#include <utility>\n\n\n#include \"excos.h\"\n#include \"translatio"
},
{
"path": "src/common/oscpp/excos.h",
"chars": 1118,
"preview": "#pragma once\n\n#include <string>\n#include <exception>\n\nnamespace os {\n\nclass ExcOsCommon : public std::exception\n{\npublic"
},
{
"path": "src/common/oscpp/fdentries.cpp",
"chars": 1619,
"preview": "\n#include <string>\n#include <iostream>\n\n#include \"fdentries.h\"\n#include \"os.h\"\n\n\nosutil::FdEntries::Iterator::Iterator(D"
},
{
"path": "src/common/oscpp/fdentries.h",
"chars": 756,
"preview": "#pragma once\n\n#include <dirent.h>\n\n#include \"util.h\"\n\nnamespace osutil {\n\n\n/// Allow iterating for entries in /proc/self"
},
{
"path": "src/common/oscpp/os.cpp",
"chars": 20387,
"preview": "\n\n\n#include <sys/mount.h>\n#include <sys/utsname.h>\n#include <pwd.h>\n#include <fcntl.h>\n#include <climits>\n#include <dire"
},
{
"path": "src/common/oscpp/os.h",
"chars": 10162,
"preview": "#pragma once\n\n\n#include <sys/stat.h>\n#include <grp.h>\n\n#include <pwd.h>\n#include <unistd.h>\n#include <linux/limits.h>\n#i"
},
{
"path": "src/common/oscpp/oscaps.cpp",
"chars": 1904,
"preview": "#include <sys/prctl.h>\n#include <sys/capability.h>\n#include <iostream>\n\n#include \"oscaps.h\"\n#include \"excos.h\"\n\n\n\nstatic"
},
{
"path": "src/common/oscpp/oscaps.h",
"chars": 851,
"preview": "#pragma once\n\n#include <sys/capability.h>\n#include <memory>\n#include <vector>\n\n#include \"util.h\"\n\nnamespace os {\n\n\n/// S"
},
{
"path": "src/common/oscpp/osutil.cpp",
"chars": 10858,
"preview": "\n\n\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n#include <fcntl.h>\n#include <unistd.h>\n#include <cerrno>\n#inc"
},
{
"path": "src/common/oscpp/osutil.h",
"chars": 1875,
"preview": "#pragma once\n\n#include <QDebug>\n#include <sys/resource.h>\n#include <string>\n#include <vector>\n#include <fcntl.h>\n#includ"
},
{
"path": "src/common/pathtree.cpp",
"chars": 13930,
"preview": "#include <cassert>\n#include <iostream>\n#include \"pathtree.h\"\n#include \"util.h\"\n#include \"logger.h\"\n\n/// Write the next a"
},
{
"path": "src/common/pathtree.h",
"chars": 3590,
"preview": "#pragma once\n\n#include <vector>\n#include <memory>\n#include <unordered_set>\n#include <QHash>\n\n\n#include \"strlight.h\"\n\n\n//"
},
{
"path": "src/common/pidcontrol.cpp",
"chars": 1877,
"preview": "\n#include <unistd.h>\n#include <fstream>\n#include <memory.h>\n\n#include <iostream>\n#include <fstream>\n#include <string>\n#i"
},
{
"path": "src/common/pidcontrol.h",
"chars": 219,
"preview": "#pragma once\n\n#include \"nullable_value.h\"\n\n#include <string>\n\nnamespace pidcontrol {\n\n std::string parseCmdlineOfPID("
},
{
"path": "src/common/qfddummydevice.cpp",
"chars": 698,
"preview": "#include <iostream>\n\n#include \"qfddummydevice.h\"\n\n#include \"os.h\"\n\n/// @param becomeOwner: if true, close the fd in dest"
},
{
"path": "src/common/qfddummydevice.h",
"chars": 540,
"preview": "#pragma once\n\n#include <QIODevice>\n\n\n/// Dummy wrapper because QFile::open(int fd,...) cannot handle an already\n/// open"
},
{
"path": "src/common/qfilethrow.cpp",
"chars": 2433,
"preview": "#include \"qfilethrow.h\"\n\n#include \"util.h\"\n\n/// @throws QExcIo\nvoid QFileThrow::flush()\n{\n if(! QFile::flush()){\n "
},
{
"path": "src/common/qfilethrow.h",
"chars": 562,
"preview": "#pragma once\n\n#include <QFile>\n\nclass QFileThrow : public QFile\n{\npublic:\n using QFile::QFile;\n\n void flush();\n\n "
},
{
"path": "src/common/qoptargparse/CMakeLists.txt",
"chars": 233,
"preview": "\nadd_library(lib_qoptargparse\n excoptargparse.cpp\n qoptargparse.cpp\n qoptarg.cpp\n qoptsqlarg.cpp\n qoptvar"
},
{
"path": "src/common/qoptargparse/excoptargparse.cpp",
"chars": 118,
"preview": "#include \"excoptargparse.h\"\n\n\n\nExcOptArgParse::ExcOptArgParse(const QString &text)\n : QExcCommon(text, false)\n{\n\n}\n"
},
{
"path": "src/common/qoptargparse/excoptargparse.h",
"chars": 137,
"preview": "#pragma once\n\n#include \"exccommon.h\"\n\nclass ExcOptArgParse : public QExcCommon\n{\npublic:\n ExcOptArgParse(const QStrin"
},
{
"path": "src/common/qoptargparse/qoptarg.cpp",
"chars": 8001,
"preview": "\n#include <cassert>\n\n#include <utility>\n\n#include \"qoptarg.h\"\n#include \"compat.h\"\n#include \"exccommon.h\"\n#include \"excop"
},
{
"path": "src/common/qoptargparse/qoptarg.h",
"chars": 6698,
"preview": "#pragma once\n\n#include <QString>\n#include <QVector>\n#include <unordered_set>\n\n#include \"compat.h\"\n#include \"util.h\"\n#inc"
},
{
"path": "src/common/qoptargparse/qoptargparse.cpp",
"chars": 8678,
"preview": "\n#include <QDebug>\n#include <cassert>\n#include <unistd.h>\n#include <sys/ioctl.h>\n\n\n#include \"qoptargparse.h\"\n#include \"q"
},
{
"path": "src/common/qoptargparse/qoptargparse.h",
"chars": 578,
"preview": "#pragma once\n\n#include <QString>\n#include <QHash>\n\n#include \"qoptarg.h\"\n#include \"ordered_map.h\"\n\n/// Currently no suppo"
}
]
// ... and 132 more files (download for full content)
About this extraction
This page contains the full source code of the tycho-kirchner/shournal GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 332 files (1.4 MB), approximately 371.6k tokens, and a symbol index with 1497 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.