diff --git a/.gitattributes b/.gitattributes
index 12020148..9a9970c0 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,3 @@
-VERSION export-subst
+VERSION_RAILCONTROL export-subst
VERSION_GIT_HASH export-subst
VERSION_GIT_TIMESTAMP export-subst
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ced349f..3335209a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -310,6 +310,8 @@ Utils/Integer.h
Utils/Network.cpp
Utils/Network.h
Utils/ThreadSafeQueue.h
+Utils/Path.cpp
+Utils/Path.h
Utils/Utils.cpp
Utils/Utils.h
${CMAKE_CURRENT_BINARY_DIR}/Version.cpp
@@ -366,7 +368,7 @@ else()
endif()
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS_DEBUG "-O0")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
@@ -381,353 +383,21 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})
configure_file(Version.cpp.in Version.cpp @ONLY)
-set(CMAKE_INSTALL_BINDIR ".")
-set(DATADIR ".")
+option(USE_GNU_INSTALL "Install according to GNU coding standards" OFF)
+if(USE_GNU_INSTALL)
+ include(GNUInstallDirs)
+ set(DATADIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}")
+ target_compile_definitions(${PROJECT_NAME} PRIVATE RAILCONTROL_DATADIR="${DATADIR}")
+else()
+ set(CMAKE_INSTALL_BINDIR ".")
+ set(CMAKE_INSTALL_DOCDIR "doc")
+ set(DATADIR ".")
+endif()
install(TARGETS ${PROJECT_NAME})
install(FILES railcontrol.conf.dist DESTINATION ${DATADIR})
install(DIRECTORY html DESTINATION ${DATADIR})
-include(CPack)
-
-# Documentation
-find_program(PANDOC_EXECUTABLE pandoc)
-if(NOT PANDOC_EXECUTABLE)
- message(WARNING "pandoc not found!")
-endif()
-
-set(DOC_DE
- Documentation/de/index.md
- Documentation/de/startup-arguments.md
- Documentation/de/general-settings.md
- Documentation/de/config-controls.md
- Documentation/de/config-intellibox.md
- Documentation/de/config-mastercontrol2.md
- Documentation/de/config-mastercontrol.md
- Documentation/de/config-redbox.md
- Documentation/de/config-twincenter.md
- Documentation/de/control-6051.md
- Documentation/de/control-cc-schnitte.md
- Documentation/de/control-cs2-tcp.md
- Documentation/de/control-cs2-udp.md
- Documentation/de/control-hsi88.md
- Documentation/de/control-opendcc-z1.md
- Documentation/de/control-z21.md
- Documentation/de/config-rs232-usb.md
- Documentation/de/config-locomotives.md
- Documentation/de/config-multipleunits.md
- Documentation/de/config-layers.md
- Documentation/de/config-tracks.md
- Documentation/de/config-groups.md
- Documentation/de/config-switches.md
- Documentation/de/config-signals.md
- Documentation/de/config-accessories.md
- Documentation/de/config-routes.md
- Documentation/de/config-feedbacks.md
- Documentation/de/config-texts.md
- Documentation/de/config-counter.md
- Documentation/de/automatic.md
-)
-
-set(DOC_EN
- Documentation/en/index.md
- Documentation/en/startup-arguments.md
- Documentation/en/general-settings.md
- Documentation/en/config-controls.md
- Documentation/en/config-intellibox.md
- Documentation/en/config-mastercontrol2.md
- Documentation/en/config-mastercontrol.md
- Documentation/en/config-redbox.md
- Documentation/en/config-twincenter.md
- Documentation/en/control-6051.md
- Documentation/en/control-cc-schnitte.md
- Documentation/en/control-cs2-tcp.md
- Documentation/en/control-cs2-udp.md
- Documentation/en/control-hsi88.md
- Documentation/en/control-opendcc-z1.md
- Documentation/en/control-z21.md
- Documentation/en/config-rs232-usb.md
- Documentation/en/config-locomotives.md
- Documentation/en/config-multipleunits.md
- Documentation/en/config-layers.md
- Documentation/en/config-tracks.md
- Documentation/en/config-groups.md
- Documentation/en/config-switches.md
- Documentation/en/config-signals.md
- Documentation/en/config-accessories.md
- Documentation/en/config-routes.md
- Documentation/en/config-feedbacks.md
- Documentation/en/config-texts.md
- Documentation/en/config-counter.md
- Documentation/en/automatic.md
-)
-
-set(DOC_ES
- Documentation/es/index.md
- Documentation/es/startup-arguments.md
- Documentation/es/general-settings.md
- Documentation/es/config-controls.md
- Documentation/es/config-intellibox.md
- Documentation/es/config-mastercontrol2.md
- Documentation/es/config-mastercontrol.md
- Documentation/es/config-redbox.md
- Documentation/es/config-twincenter.md
- Documentation/es/control-6051.md
- Documentation/es/control-cc-schnitte.md
- Documentation/es/control-cs2-tcp.md
- Documentation/es/control-cs2-udp.md
- Documentation/es/control-hsi88.md
- Documentation/es/control-opendcc-z1.md
- Documentation/es/control-z21.md
- Documentation/es/config-rs232-usb.md
- Documentation/es/config-locomotives.md
- Documentation/es/config-multipleunits.md
- Documentation/es/config-layers.md
- Documentation/es/config-tracks.md
- Documentation/es/config-groups.md
- Documentation/es/config-switches.md
- Documentation/es/config-signals.md
- Documentation/es/config-accessories.md
- Documentation/es/config-routes.md
- Documentation/es/config-feedbacks.md
- Documentation/es/config-texts.md
- Documentation/es/config-counter.md
- Documentation/es/automatic.md
-)
-
-set(OUTPUT_HTML_DE ${CMAKE_BINARY_DIR}/doc/de/index.html)
-set(OUTPUT_HTML_EN ${CMAKE_BINARY_DIR}/doc/en/index.html)
-set(OUTPUT_HTML_ES ${CMAKE_BINARY_DIR}/doc/es/index.html)
-
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/doc/de)
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/doc/en)
-file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/doc/es)
-
-add_custom_command(
- OUTPUT ${OUTPUT_HTML_DE}
- COMMAND pandoc --toc --toc-depth=2 --standalone --css=../style.css
- --template=Documentation/template.html
- --metadata-file=Documentation/de/metadata.yaml ${DOC_DE}
- --output=${OUTPUT_HTML_DE}
- DEPENDS ${DOC_DE}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMENT "Generating German HTML documentation"
- VERBATIM
-)
-
-add_custom_command(
- OUTPUT ${OUTPUT_HTML_EN}
- COMMAND pandoc --toc --toc-depth=2 --standalone --css=../style.css
- --template=Documentation/template.html
- --metadata-file=Documentation/en/metadata.yaml ${DOC_EN}
- --output=${OUTPUT_HTML_EN}
- DEPENDS ${DOC_EN}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMENT "Generating English HTML documentation"
- VERBATIM
-)
-
-add_custom_command(
- OUTPUT ${OUTPUT_HTML_ES}
- COMMAND pandoc --toc --toc-depth=2 --standalone --css=../style.css
- --template=Documentation/template.html
- --metadata-file=Documentation/es/metadata.yaml ${DOC_ES}
- --output=${OUTPUT_HTML_ES}
- DEPENDS ${DOC_ES}
- WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMENT "Generating Spanish HTML documentation"
- VERBATIM
-)
+add_subdirectory(Documentation)
-set(DOCDATA
- ${PROJECT_SOURCE_DIR}/Documentation/menu_accessory.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_booster.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_control.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_counter.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_feedback.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_fullscreen.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_group.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_layer.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_loco.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_menu.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_multipleunit.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_program.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_quit.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_route.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_settings.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_signalgreen.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_signal.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_signalred.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_stop.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_street.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_switch.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_text.png
- ${PROJECT_SOURCE_DIR}/Documentation/menu_track.png
- ${PROJECT_SOURCE_DIR}/Documentation/style.css
-)
-
-set(DOCDATA_DE
- ${PROJECT_SOURCE_DIR}/Documentation/de/config_layers_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/control_list_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/counter_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/counter_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/cs2_config_can_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/cs2_config_ip_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/cs2_tcp_config_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/cs2_udp_config_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/feedback_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/feedback_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/groups_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/groups_tracks_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/locomotives_automode_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/locomotives_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/locomotives_functions_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/multipleunits_automode_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/multipleunits_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/multipleunits_functions_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/multipleunits_multipleunits_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/routes_atlock_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/routes_atunlock_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/routes_automode_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/routes_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/routes_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/settings_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/signals_addresses_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/signals_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/signals_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/switches_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/switches_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/texts_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/texts_position_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/tracks_automode_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/tracks_basics_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/tracks_feedbacks_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/track_signals_de.png
- ${PROJECT_SOURCE_DIR}/Documentation/de/tracks_position_de.png
-)
-
-set(DOCDATA_EN
- ${PROJECT_SOURCE_DIR}/Documentation/en/config_layers_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/control_list_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/counter_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/counter_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/cs2_tcp_config_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/cs2_udp_config_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/feedback_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/feedback_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/groups_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/groups_tracks_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/locomotives_automode_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/locomotives_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/locomotives_functions_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/multipleunits_automode_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/multipleunits_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/multipleunits_functions_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/multipleunits_multipleunits_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/routes_atlock_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/routes_atunlock_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/routes_automode_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/routes_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/routes_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/settings_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/signals_addresses_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/signals_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/signals_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/switches_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/switches_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/texts_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/texts_position_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/tracks_automode_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/tracks_basics_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/tracks_feedbacks_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/track_signals_en.png
- ${PROJECT_SOURCE_DIR}/Documentation/en/tracks_position_en.png
-)
-
-set(DOCDATA_ES
- ${PROJECT_SOURCE_DIR}/Documentation/es/config_layers_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/control_list_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/cs2_tcp_config_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/cs2_udp_config_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/feedback_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/feedback_position_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/groups_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/groups_tracks_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/locomotives_automode_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/locomotives_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/locomotives_functions_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/multipleunits_automode_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/multipleunits_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/multipleunits_functions_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/multipleunits_multipleunits_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/routes_atlock_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/routes_atunlock_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/routes_automode_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/routes_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/routes_position_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/settings_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/signals_addresses_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/signals_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/signals_position_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/switches_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/switches_position_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/texts_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/texts_position_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/tracks_automode_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/tracks_basics_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/tracks_feedbacks_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/track_signals_es.png
- ${PROJECT_SOURCE_DIR}/Documentation/es/tracks_position_es.png
-)
-
-add_custom_target(doc
- DEPENDS ${OUTPUT_HTML_DE} ${OUTPUT_HTML_EN} ${OUTPUT_HTML_ES}
-)
-
-foreach(DOCDATA ${DOCDATA})
- add_custom_command(TARGET doc POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${DOCDATA}
- ${PROJECT_BINARY_DIR}/doc
- )
-endforeach()
-
-foreach(DOCDATA_DE ${DOCDATA_DE})
- add_custom_command(TARGET doc POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${DOCDATA_DE}
- ${PROJECT_BINARY_DIR}/doc/de
- )
-endforeach()
-
-foreach(DOCDATA_EN ${DOCDATA_EN})
- add_custom_command(TARGET doc POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${DOCDATA_EN}
- ${PROJECT_BINARY_DIR}/doc/en
- )
-endforeach()
-
-foreach(DOCDATA_ES ${DOCDATA_ES})
- add_custom_command(TARGET doc POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy
- ${DOCDATA_ES}
- ${PROJECT_BINARY_DIR}/doc/es
- )
-endforeach()
-
-add_custom_target(doc-for-web
- DEPENDS doc
-)
-
-add_custom_command(TARGET doc-for-web POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${PROJECT_SOURCE_DIR}/Documentation/de/documentation-de
- ${PROJECT_BINARY_DIR}/doc/de/documentation-de
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${PROJECT_SOURCE_DIR}/Documentation/en/documentation-en
- ${PROJECT_BINARY_DIR}/doc/en/documentation-en
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${PROJECT_SOURCE_DIR}/Documentation/es/documentation-es
- ${PROJECT_BINARY_DIR}/doc/es/documentation-es
-)
+include(CPack)
diff --git a/Documentation/CMakeLists.txt b/Documentation/CMakeLists.txt
new file mode 100644
index 00000000..dd025da8
--- /dev/null
+++ b/Documentation/CMakeLists.txt
@@ -0,0 +1,96 @@
+cmake_minimum_required(VERSION 3.10)
+
+find_program(PANDOC_EXECUTABLE pandoc)
+if(NOT PANDOC_EXECUTABLE)
+ message(WARNING "pandoc not found!")
+endif()
+
+set(OUTPUT_HTML ${CMAKE_CURRENT_BINARY_DIR}/doc)
+install(DIRECTORY ${OUTPUT_HTML}/ DESTINATION ${CMAKE_INSTALL_DOCDIR})
+
+# common
+file(GLOB DOCDATA menu_*.png style.css)
+file(COPY ${DOCDATA} DESTINATION ${OUTPUT_HTML})
+
+# DE
+set(OUTPUT_HTML_DE ${OUTPUT_HTML}/de)
+set(OUTPUT_HTML_DE_INDEX ${OUTPUT_HTML_DE}/index.html)
+
+file(GLOB DOCDATA_DE de/*.png)
+file(COPY ${DOCDATA_DE} DESTINATION ${OUTPUT_HTML_DE})
+
+file(GLOB DOC_DE de/*.md)
+file(MAKE_DIRECTORY ${OUTPUT_HTML_DE})
+add_custom_command(
+ OUTPUT ${OUTPUT_HTML_DE_INDEX}
+ COMMAND ${PANDOC_EXECUTABLE} --toc --toc-depth=2 --standalone --css=../style.css
+ --template=template.html
+ --metadata-file=de/metadata.yaml ${DOC_DE}
+ --output=${OUTPUT_HTML_DE_INDEX}
+ DEPENDS ${DOC_DE} ${OUTPUT_HTML_DE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Generating German HTML documentation"
+ VERBATIM
+)
+
+# EN
+set(OUTPUT_HTML_EN ${OUTPUT_HTML}/en)
+set(OUTPUT_HTML_EN_INDEX ${OUTPUT_HTML_EN}/index.html)
+
+file(GLOB DOCDATA_EN en/*.png)
+file(COPY ${DOCDATA_EN} DESTINATION ${OUTPUT_HTML_EN})
+
+file(GLOB DOC_EN en/*.md)
+file(MAKE_DIRECTORY ${OUTPUT_HTML_EN})
+add_custom_command(
+ OUTPUT ${OUTPUT_HTML_EN_INDEX}
+ COMMAND ${PANDOC_EXECUTABLE} --toc --toc-depth=2 --standalone --css=../style.css
+ --template=template.html
+ --metadata-file=en/metadata.yaml ${DOC_EN}
+ --output=${OUTPUT_HTML_EN_INDEX}
+ DEPENDS ${DOC_EN} ${OUTPUT_HTML_EN}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Generating English HTML documentation"
+ VERBATIM
+)
+
+# ES
+set(OUTPUT_HTML_ES ${OUTPUT_HTML}/es)
+set(OUTPUT_HTML_ES_INDEX ${OUTPUT_HTML_ES}/index.html)
+
+file(GLOB DOCDATA_ES es/*.png)
+file(COPY ${DOCDATA_ES} DESTINATION ${OUTPUT_HTML_ES})
+
+file(GLOB DOC_ES es/*.md)
+file(MAKE_DIRECTORY ${OUTPUT_HTML_ES})
+add_custom_command(
+ OUTPUT ${OUTPUT_HTML_ES_INDEX}
+ COMMAND ${PANDOC_EXECUTABLE} --toc --toc-depth=2 --standalone --css=../style.css
+ --template=template.html
+ --metadata-file=es/metadata.yaml ${DOC_ES}
+ --output=${OUTPUT_HTML_ES_INDEX}
+ DEPENDS ${DOC_ES} ${OUTPUT_HTML_ES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Generating Spanish HTML documentation"
+ VERBATIM
+)
+
+add_custom_target(doc ALL
+ DEPENDS ${OUTPUT_HTML_DE_INDEX} ${OUTPUT_HTML_EN_INDEX} ${OUTPUT_HTML_ES_INDEX}
+)
+
+add_custom_target(doc-for-web
+ DEPENDS doc
+)
+
+add_custom_command(TARGET doc-for-web POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${PROJECT_SOURCE_DIR}/de/documentation-de
+ ${PROJECT_BINARY_DIR}/de/documentation-de
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${PROJECT_SOURCE_DIR}/en/documentation-en
+ ${PROJECT_BINARY_DIR}/en/documentation-en
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${PROJECT_SOURCE_DIR}/es/documentation-es
+ ${PROJECT_BINARY_DIR}/es/documentation-es
+)
diff --git a/Makefile b/Makefile
index c102fe12..b03ccd90 100644
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,8 @@ endif
CFLAGSSQLITE=-g -O2 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_RTREE -DHAVE_USLEEP
CFLAGSZLIB=-g -O2 -Wno-implicit-function-declaration
-CXXFLAGS=-I. -g -O2 -Wall -Wextra -pedantic -Werror -Wno-missing-braces -std=c++11 -D_GNU_SOURCE
-CXXFLAGSAMALGAMATION=-I. -g -O2 -Wall -Wextra -pedantic -Werror -Wno-missing-braces -std=c++11
+CXXFLAGS=-I. -g -O2 -Wall -Wextra -pedantic -Werror -Wno-missing-braces -std=c++17 -D_GNU_SOURCE
+CXXFLAGSAMALGAMATION=-I. -g -O2 -Wall -Wextra -pedantic -Werror -Wno-missing-braces -std=c++17
LDFLAGS=-g
LIBS=-lpthread -ldl
LIBSAMALGAMATION=-lpthread -ldl
diff --git a/RailControl.cpp b/RailControl.cpp
index 916bdcbb..2092a244 100644
--- a/RailControl.cpp
+++ b/RailControl.cpp
@@ -39,6 +39,7 @@ along with RailControl; see the file LICENCE. If not see
#include "Network/Select.h"
#include "RailControl.h"
#include "Version.h"
+#include "Utils/Path.h"
#include "Utils/Utils.h"
using std::vector;
@@ -46,7 +47,8 @@ using std::string;
void killRailControlIfNeeded(Logger::Logger* logger)
{
- if (++stopSignalCounter < MaxStopSignalCounter)
+ stopSignalCounter = stopSignalCounter + 1;
+ if (stopSignalCounter < MaxStopSignalCounter)
{
return;
}
@@ -189,7 +191,7 @@ int main (int argc, char* argv[])
logger->Info(Languages::TextStartArgument, argv[0]);
- const string configFileDefaultName("railcontrol.conf");
+ const string configFileDefaultName = Utils::Path::getConfDir() / "railcontrol.conf";
string configFileName = argumentHandler.GetArgumentString('c', configFileDefaultName);
if (configFileName.compare("") == 0)
{
@@ -204,7 +206,8 @@ int main (int argc, char* argv[])
if ((configFileName.compare(configFileDefaultName) == 0) && (!Utils::Utils::FileExists(configFileDefaultName)))
{
- Utils::Utils::CopyFile(logger, "railcontrol.conf.dist", configFileDefaultName);
+ const std::filesystem::path defaultConfDistPath = Utils::Path::getDataDir() / "railcontrol.conf.dist";
+ Utils::Utils::CopyFile(logger, defaultConfDistPath, configFileDefaultName);
}
Config config(configFileName);
diff --git a/Server/Web/WebClient.cpp b/Server/Web/WebClient.cpp
index 46262728..786fb33d 100644
--- a/Server/Web/WebClient.cpp
+++ b/Server/Web/WebClient.cpp
@@ -70,6 +70,7 @@ along with RailControl; see the file LICENCE. If not see
#include "Server/Web/WebClientStatic.h"
#include "Server/Web/WebServer.h"
#include "Utils/Integer.h"
+#include "Utils/Path.h"
using namespace DataModel;
using LayoutPosition = DataModel::LayoutItem::LayoutPosition;
@@ -780,14 +781,8 @@ namespace Server { namespace Web
void WebClient::DeliverFile(const string& virtualFile)
{
- std::stringstream ss;
- char workingDir[128];
- if (getcwd(workingDir, sizeof(workingDir)))
- {
- ss << workingDir << "/html" << virtualFile;
- }
- string sFile = ss.str();
- const char* realFile = sFile.c_str();
+ const std::filesystem::path virtualFilePath = Utils::Path::getDataDir() / "html" / virtualFile;
+ const char* realFile = virtualFilePath.c_str();
FILE* f = fopen(realFile, "r");
if (f == nullptr)
{
diff --git a/Utils/Path.cpp b/Utils/Path.cpp
new file mode 100644
index 00000000..df7f3aef
--- /dev/null
+++ b/Utils/Path.cpp
@@ -0,0 +1,71 @@
+/*
+RailControl - Model Railway Control Software
+
+Copyright (c) 2017-2025 by Teddy / Dominik Mahrer - www.railcontrol.org
+
+RailControl 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, or (at your option) any
+later version.
+
+RailControl 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 RailControl; see the file LICENCE. If not see
+.
+*/
+
+#include
+#include
+
+#include "Utils/Path.h"
+
+namespace Utils::Path
+{
+ std::filesystem::path getConfDir()
+ {
+ const std::filesystem::path dir;
+ // systemd may set this if ConfigurationDirectory= is set for a service
+ const char* env_p = std::getenv("CONFIGURATION_DIRECTORY");
+ if (env_p)
+ {
+ std::filesystem::path dir(env_p);
+ }
+ else
+ {
+ std::filesystem::path dir(".");
+ }
+
+ return dir;
+ }
+
+ std::filesystem::path getDataDir()
+ {
+#ifdef RAILCONTROL_DATADIR
+ const std::filesystem::path dir(RAILCONTROL_DATADIR);
+#else
+ const std::filesystem::path dir(".");
+#endif
+ return dir;
+ }
+
+ std::filesystem::path getStateDir()
+ {
+ const std::filesystem::path dir;
+ // systemd may set this if StateDirectory= is set for a service
+ const char* env_p = std::getenv("STATE_DIRECTORY");
+ if (env_p)
+ {
+ std::filesystem::path dir(env_p);
+ }
+ else
+ {
+ std::filesystem::path dir(".");
+ }
+
+ return dir;
+ }
+}
diff --git a/Utils/Path.h b/Utils/Path.h
new file mode 100644
index 00000000..663a271c
--- /dev/null
+++ b/Utils/Path.h
@@ -0,0 +1,46 @@
+/*
+RailControl - Model Railway Control Software
+
+Copyright (c) 2017-2025 by Teddy / Dominik Mahrer - www.railcontrol.org
+
+RailControl 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, or (at your option) any
+later version.
+
+RailControl 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 RailControl; see the file LICENCE. If not see
+.
+*/
+
+#include
+#include
+
+namespace Utils::Path
+{
+ /**
+ * Get the path to configuration directory
+ *
+ * @return path to the configuration directory
+ */
+ std::filesystem::path getConfDir();
+
+ /**
+ * Get the path to read-only architecture independent data.
+ *
+ * @return path to read-only architecture independent data.
+ */
+ std::filesystem::path getDataDir();
+
+ /**
+ * Get the directory holding the persistent state
+ *
+ * @return path to the persistent state directory
+ */
+ std::filesystem::path getStateDir();
+}