Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish v0.2.1 #13

Merged
merged 11 commits into from
Nov 14, 2024
Merged
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.24)
project(cppIni LANGUAGES CXX VERSION 0.2.0)
project(cppIni LANGUAGES CXX VERSION 0.2.1)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,29 @@ On every write, the file is completely rewritten.

## Usage

### C++:

``` cpp
#include <cppIni/cppIni.hpp>

File ini("test.ini");
const auto intValue = init.get<int>("section", "key");
const auto intValue = ini.get<int>("section", "key");
const auto newValue = 42;
ini.set("section", "key", newValue);
```

### C:

``` c
#include <cppIni/cppIni_c.h>

void* ini = cppIni_open("test.ini");
const int intValue = cppIni_geti(ini, "section", "key");
const int newValue = 42;
cppIni_set(ini, "section", "key", newValue);
cppIni_close(&ini);
```

## License

cppIni is licensed under the MIT license. See [COPYING](https://github.com/Master92/cppIni/COPYING) for more information.
cppIni is licensed under the GPLv3. See [COPYING](https://github.com/Master92/cppIni/blob/master/COPYING) for more information.
15 changes: 14 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# 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 <https://www.gnu.org/licenses/>.

from conan import ConanFile
from conan.tools.build import check_min_cppstd
Expand All @@ -34,7 +47,7 @@

class cppiniRecipe(ConanFile):
name = "cppini"
version = "0.2.0"
version = "0.2.1"
package_type = "library"

# Optional metadata
Expand Down
15 changes: 8 additions & 7 deletions include/cppIni/cppIni_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
extern "C" {
#endif

typedef void* pFile;
/// \file cppIni_c.h
/// \brief The C API for cppIni
///
Expand All @@ -32,12 +31,14 @@ typedef void* pFile;
/// the C++ API. It is intended for use with languages that do not support
/// C++.

CPPINI_EXPORT pFile cppIni_open(const char* filename); ///< Opens a file
CPPINI_EXPORT void cppIni_close(pFile* file); ///< Closes a file
CPPINI_EXPORT void cppIni_set(pFile file, const char* section, const char* key, const char* value); ///< Sets a value
CPPINI_EXPORT const char* cppIni_gets(pFile file, const char* section, const char* key, char* out, size_t outSize); ///< Gets a string
CPPINI_EXPORT int cppIni_geti(pFile file, const char* section, const char* key); ///< Gets an integer
CPPINI_EXPORT float cppIni_getf(pFile file, const char* section, const char* key); ///< Gets a float
CPPINI_EXPORT void* cppIni_open(const char* filename); ///< Opens a file
CPPINI_EXPORT void cppIni_close(void** file); ///< Closes a file

CPPINI_EXPORT void cppIni_set(void* file, const char* section, const char* key, const char* value); ///< Sets a value

CPPINI_EXPORT const char* cppIni_gets(const void* file, const char* section, const char* key, char* out, size_t outSize); ///< Gets a string
CPPINI_EXPORT int cppIni_geti(const void* file, const char* section, const char* key); ///< Gets an integer
CPPINI_EXPORT float cppIni_getf(const void* file, const char* section, const char* key); ///< Gets a float

#ifdef __cplusplus
}
Expand Down
18 changes: 9 additions & 9 deletions src/CInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
///
/// \param[in] filename The name of the file to open
/// \return A pointer to a File object
pFile cppIni_open(const char* filename)
void* cppIni_open(const char* filename)
{
return new File(filename);
}

/// Closes a file that was opened with cppIni_open().
/// \param[in] file A pointer to a File object
void cppIni_close(pFile* file)
void cppIni_close(void** const file)
{
delete static_cast<File*>(*file);
}
Expand All @@ -40,7 +40,7 @@ void cppIni_close(pFile* file)
/// \param[in] section The name of the section to add
/// \param[in] key The name of the key to add
/// \param[in] value The value to add
void cppIni_set(pFile file, const char* section, const char* key, const char* value)
void cppIni_set(void* const file, const char* const section, const char* const key, const char* value)
{
static_cast<File*>(file)->set(section, key, value);
}
Expand All @@ -51,9 +51,9 @@ void cppIni_set(pFile file, const char* section, const char* key, const char* va
/// \param[out] out A buffer to store the value in
/// \param[in] outSize The size of the buffer
/// \return A pointer to the buffer
const char* cppIni_gets(pFile file, const char* section, const char* key, char* out, size_t outSize)
const char* cppIni_gets(const void* const file, const char* const section, const char* const key, char* out, size_t outSize)
{
const auto value = static_cast<File*>(file)->get<std::string>(section, key);
const auto value = static_cast<const File*>(file)->get<std::string>(section, key);

if (value.empty()) {
return out;
Expand All @@ -68,17 +68,17 @@ const char* cppIni_gets(pFile file, const char* section, const char* key, char*
/// \param[in] section The name of the section to get
/// \param[in] key The name of the key to get
/// \return The value of the key
int cppIni_geti(pFile file, const char* section, const char* key)
int cppIni_geti(const void* const file, const char* const section, const char* const key)
{
return static_cast<File*>(file)->get<int>(section, key);
return static_cast<const File*>(file)->get<int>(section, key);
}

/// \see cppIni_gets
/// \param[in] file A pointer to a File object
/// \param[in] section The name of the section to get
/// \param[in] key The name of the key to get
/// \return The value of the key
float cppIni_getf(pFile file, const char* section, const char* key)
float cppIni_getf(const void* const file, const char* const section, const char* const key)
{
return static_cast<File*>(file)->get<float>(section, key);
return static_cast<const File*>(file)->get<float>(section, key);
}
80 changes: 33 additions & 47 deletions tests/CInterfaceTest.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
// cppIni - A C++20 library for reading and writing INI files
// Copyright (C) 2023-2024 Nils Hofmann <[email protected]>
//
// 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 <https://www.gnu.org/licenses/>.
/*
* cppIni - A C++20 library for reading and writing INI files
* Copyright (C) 2023-2024 Nils Hofmann <[email protected]>
*
* 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 <https://www.gnu.org/licenses/>.
*/

#include <array>
#include <filesystem>
#include <format>

#include <cppIni/cppIni_c.h>
#include <doctest/doctest.h>
#include "utils.h"

static const std::string fileName = std::format("{}{}", WORKING_DIR, "/res/test.ini");;

Expand All @@ -33,67 +36,50 @@ TEST_CASE("Construction of File object")
CHECK_NOTHROW(cppIni_close(&file));
}

struct ScopeGuard
{
ScopeGuard(pFile file) : file(file){};
~ScopeGuard(){ cppIni_close(&file); };
pFile file;
};

TEST_CASE("Read a string entry")
{
void* file = cppIni_open(fileName.c_str());
ScopeGuard guard{file};
auto file = utils::ScopeGuard<void*, cppIni_close>(cppIni_open(fileName.c_str()));

std::array<char, 64> buffer{0};
cppIni_gets(file, "Section1", "Entry1", buffer.data(), buffer.size());
cppIni_gets(*file, "Section1", "Entry1", buffer.data(), buffer.size());

CHECK_EQ(std::string_view{buffer.data()}, "Value1");
}

TEST_CASE("Try to read a non-existing entry")
{
void* file = cppIni_open(fileName.c_str());
ScopeGuard guard{file};
auto file = utils::ScopeGuard<void*, cppIni_close>(cppIni_open(fileName.c_str()));

std::array<char, 64> buffer{0};
CHECK_EQ(cppIni_gets(file, "Section1", "NonExistingEntry", buffer.data(), buffer.size()), buffer.data());
CHECK_EQ(cppIni_gets(*file, "Section1", "NonExistingEntry", buffer.data(), buffer.size()), buffer.data());
CHECK_EQ(buffer[0], '\0');
}

TEST_CASE("Change a value")
{
constexpr auto tempFileName = "tmp.ini";
std::filesystem::copy_file(fileName, tempFileName);

{
constexpr auto newValue = 1337;
void* file = cppIni_open(tempFileName);
ScopeGuard guard{file};
constexpr auto newValue = 1337;

const auto previousValue = cppIni_geti(file, "Section1", "IntEntry");
CHECK_NE(previousValue, newValue);
cppIni_set(file, "Section1", "IntEntry", std::to_string(newValue).c_str());
CHECK_EQ(cppIni_geti(file, "Section1", "IntEntry"), newValue);
}
utils::TempFile tmpFile(fileName);
auto file = utils::ScopeGuard<void*, cppIni_close>(cppIni_open(tmpFile.filename().data()));

std::filesystem::remove(tempFileName);
const auto previousValue = cppIni_geti(*file, "Section1", "IntEntry");
CHECK_NE(previousValue, newValue);
cppIni_set(*file, "Section1", "IntEntry", std::to_string(newValue).c_str());
CHECK_EQ(cppIni_geti(*file, "Section1", "IntEntry"), newValue);
}

TEST_CASE("Read an integer entry")
{
void* file = cppIni_open(fileName.c_str());
ScopeGuard guard{file};
auto file = utils::ScopeGuard<void*, cppIni_close>(cppIni_open(fileName.c_str()));

CHECK_EQ(cppIni_geti(file, "Section1", "IntEntry"), 42);
CHECK_EQ(cppIni_geti(*file, "Section1", "IntEntry"), 42);
}

TEST_CASE("Read a floating point value entry")
{
void* file = cppIni_open(fileName.c_str());
ScopeGuard guard{file};
auto file = utils::ScopeGuard<void*, cppIni_close>(cppIni_open(fileName.c_str()));

CHECK_LT(std::abs(cppIni_getf(file, "Section1.Subsection1", "DoubleEntry") - 3.1415), 0.001);
CHECK_LT(std::abs(cppIni_getf(*file, "Section1.Subsection1", "DoubleEntry") - 3.1415), 0.001);
}

TEST_SUITE_END();
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(TEST_SOURCES
FileTest.cpp
SectionTest.cpp
CInterfaceTest.cpp
utils.h
)

add_executable(${PROJECT_NAME}_tests ${TEST_SOURCES})
Expand Down
23 changes: 6 additions & 17 deletions tests/FileTest.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* cppIni - A C++20 library for reading and writing INI files
* Copyright (C) 2023 Nils Hofmann <[email protected]>
* Copyright (C) 2023-2024 Nils Hofmann <[email protected]>
*
* 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
Expand All @@ -21,26 +21,14 @@
#include <doctest/doctest.h>

#include <cppIni/File.h>
#include "utils.h"

using namespace std::literals;

static const std::string fileName = std::format("{}{}", WORKING_DIR, "/res/test.ini");

TEST_SUITE_BEGIN("File");

class FileFixture
{
public:
FileFixture() {
std::filesystem::copy_file(::fileName, fileName);
}
~FileFixture() {
std::filesystem::remove(fileName);
}
protected:
const std::string fileName = std::format("{}{}", WORKING_DIR, "/res/tmp.ini");
};

TEST_CASE("Failing construction of an empty File object")
{
CHECK_THROWS(File{""});
Expand Down Expand Up @@ -145,15 +133,16 @@ TEST_CASE("Equality operator")
CHECK_EQ(f, f2);
}

TEST_CASE_FIXTURE(FileFixture, "Change a value with set")
TEST_CASE("Change a value with set")
{
constexpr auto newValue = "NewValue"sv;

auto f = File{fileName};
utils::TempFile tmpFile(fileName);
auto f = File{tmpFile.filename()};
f.set("Section1", "Entry1", "NewValue");
CHECK_EQ(f.get<std::string_view>("Section1", "Entry1"), newValue);

const auto f2 = File{fileName};
const auto f2 = File{tmpFile.filename()};
CHECK_EQ(f.get<std::string_view>("Section1", "Entry1"), newValue);
}

Expand Down
Loading
Loading