diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c2ebb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +*.o \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 498e61b..537750d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "compare": "cpp", "type_traits": "cpp", "iostream": "cpp", - "iosfwd": "cpp" + "iosfwd": "cpp", + "fstream": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f388765 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,66 @@ +cmake_minimum_required(VERSION 3.15) +project(config LANGUAGES CXX) + +# Postavi standard za C++ +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Dodaj glavnu biblioteku +add_library(config STATIC + src/config.cpp +) + +# Uključi zaglavlja +target_include_directories(config + PUBLIC + $ + $ +) + + +# # Generiši export fajl za lokalnu upotrebu +# export(TARGETS config +# FILE ${CMAKE_CURRENT_BINARY_DIR}/configTargets.cmake +# NAMESPACE config:: +# ) + +# Generiši configConfig.cmake +# include(CMakePackageConfigHelpers) + +# configure_package_config_file( +# ${CMAKE_CURRENT_SOURCE_DIR}/cmake/configConfig.cmake.in +# ${CMAKE_CURRENT_BINARY_DIR}/configConfig.cmake +# INSTALL_DESTINATION lib/cmake/config +# ) + +# write_basic_package_version_file( +# ${CMAKE_CURRENT_BINARY_DIR}/configConfigVersion.cmake +# VERSION 1.0.0 +# COMPATIBILITY SameMajorVersion +# ) + +# Instalacija za lokalnu upotrebu +install(TARGETS config + EXPORT configTargets + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin +) + +install(EXPORT configTargets + FILE configTargets.cmake + NAMESPACE config:: + DESTINATION lib/cmake/config +) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/configConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configConfigVersion.cmake + DESTINATION lib/cmake/config +) + +# Opcionalno dodaj testove +# enable_testing() +# add_subdirectory(test) + +add_subdirectory(test) \ No newline at end of file diff --git a/example/config.cfg b/example/config.cfg index 7a98b7f..60f0602 100644 --- a/example/config.cfg +++ b/example/config.cfg @@ -10,4 +10,3 @@ DinioServer1Port=5000; DinioServer2Port=4048; DinioGetIPURL=http://lab-it.ddns.net/getip/index.php; #ovo ide na više A recorda i više servera pod istim domenom # DinioGetIPURL2=http://ns-hl.ddns.net/getip/index.php; - diff --git a/lib/config.hpp b/lib/config.hpp index 22329f7..3216ff1 100644 --- a/lib/config.hpp +++ b/lib/config.hpp @@ -14,26 +14,27 @@ namespace marcelb { /** * Clears white fields from a string */ -void clearWhiteSpaces(string &a); +static void clearWhiteSpaces(string &a); /** * Removes comments from a string * Returns false if the entire line is a comment, * false if it is not */ -bool clearComments(string &a); +static bool clearComments(string &a); /** * It parses the line of the configuration file, * receives the string line and returns the key, * value pair via reference */ -void parseConfigLine(const string a, string &b, string &c); +static void parseConfigLine(const string a, string &b, string &c); /** * Configuration class - at the level of a single file */ class config { + const string configFilePath; vector necessary; map element; @@ -45,7 +46,12 @@ class config { /** * Internal method for initialization */ - bool init(const string _configFilePath); + bool init(const string _configFilePath); + + /** + * Update config file + */ + void update_file(const string& key); public: @@ -60,6 +66,11 @@ class config { */ string operator[] (const string& key); + /** + * Update config entry + */ + void update(const string& key, const string& value); + /** * Method to print all configuration key value pairs */ diff --git a/src/config.cpp b/src/config.cpp index 0692970..e464be5 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,8 +1,9 @@ #include "../lib/config.hpp" -marcelb::config::config(const string _configFilePath, const vector _necessary) { - necessary = _necessary; +marcelb::config::config(const string _configFilePath, const vector _necessary): + configFilePath(_configFilePath), necessary(_necessary) { + if(!init(_configFilePath)) { throw string("[ERROR] Init config file "); } @@ -16,6 +17,10 @@ string marcelb::config::operator[](const string& key) { return element[key]; } +void marcelb::config::update(const string& key, const string& value) { + element[key] = value; + update_file(key); +} bool marcelb::config::init(const string _configFilePath) { @@ -63,6 +68,48 @@ bool marcelb::config::isHaveNecessary() { } +void marcelb::config::update_file(const string& key) { + ifstream configFile(configFilePath); + if (!configFile.is_open()) { + throw invalid_argument("[ERROR] Cant open config file for update!"); + } + + vector lines; + string line; + bool update = false; + while (getline(configFile, line)) { + + size_t pos = line.find(key + "="); + if (pos != string::npos) { + + size_t eqPos = line.find("=", pos); + size_t semicolonPos = line.find(";", eqPos); + if (eqPos != string::npos && semicolonPos != string::npos) { + line = key + "=" + element[key] + ";"; + update = true; + } + } + lines.push_back(line); + } + if (!update) { + line = key + "=" + element[key] + ";"; + lines.push_back(line); + } + configFile.close(); + + ofstream configFileOut(configFilePath); + if (!configFileOut.is_open()) { + throw invalid_argument("[ERROR] Cant update config file!"); + } + + for (const string& updatedLine : lines) { + configFileOut << updatedLine << endl; + } + + configFileOut.close(); +} + + void marcelb::clearWhiteSpaces(string &a) { const char whitespaces[] = {' ', '\t'}; for (int i=0; i