diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f4f306..9b232ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.12) # Ensure built-in policies from CMake are used, (e.g. improved policies for macOS) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -project(libeconf VERSION 0.6.3 +project(libeconf VERSION 0.7.0 DESCRIPTION "Enhanced config file parser, which merges config files placed in several locations into one." LANGUAGES C ) diff --git a/README.md b/README.md index d80bd61..d21f2b7 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ as the vendor configuration file. Optionally, schemes with only drop-ins and without a ‘main’ configuration file will be supported too. In such schemes many drop-ins are loaded from a common directory in each hierarchy. -For example, /usr/lib/.d/*, /run/.d/* and /etc/.d/c.conf are all loaded and parsed +For example, /usr/lib/_project_.d/*, /run/_project_.d/* and /etc/_project_.d/c.conf are all loaded and parsed in this scheme. **Example 1** @@ -76,5 +76,5 @@ The API is written in plain C. The description can be found here :https://opensu ## Bindings for other languages -- [Python](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/python3/) ([Documentation](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/python3/docs/python-libeconf.3) -- [C#](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/csharp/) ([Documentation](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/csharp/docs/README.md)) +- [Python](https://github.com/openSUSE/libeconf/blob/v0.7.0/bindings/python3/) ([Documentation](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/python3/docs/python-libeconf.3) +- [C#](https://github.com/openSUSE/libeconf/blob/v0.7.0/bindings/csharp/) ([Documentation](https://github.com/openSUSE/libeconf/blob/v0.6.0/bindings/csharp/docs/README.md)) diff --git a/bindings/python3/econf.py b/bindings/python3/econf.py index 815f8f4..8099a3b 100644 --- a/bindings/python3/econf.py +++ b/bindings/python3/econf.py @@ -631,6 +631,15 @@ def write_file(ef: EconfFile, save_to_dir: str, file_name: str) -> None: if err: raise ECONF_EXCEPTION[EconfError(err)](f"write_file failed with error: {err_string(err)}") +def econf_set_opt(option: str) -> None: + """ + Set libeconv environment. + + :param option: defined as a string (format =) + :return: Nothing + """ + c_option = _encode_str(option) + LIBECONF.econf_set_opt(c_option) def get_path(ef: EconfFile) -> str: """ diff --git a/bindings/python3/pyproject.toml b/bindings/python3/pyproject.toml index 41a23af..d027761 100644 --- a/bindings/python3/pyproject.toml +++ b/bindings/python3/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "python-libeconf" -version = "0.6.0" +version = "0.7.0" description = "Python bindings for libeconf" authors = [{name="nkrapp", email="nico.krapp@suse.com"}] diff --git a/doc/man/libeconf.3 b/doc/man/libeconf.3 index ce2e5d3..673f211 100644 --- a/doc/man/libeconf.3 +++ b/doc/man/libeconf.3 @@ -700,7 +700,7 @@ econf_free (key_file); .fi .PP .PP -Default behaviour if entries have the same name in one file: The first hit will be returned\&. Further entries will be ignored\&. This can be changed by setting the environment variable ECONF_JOIN_SAME_ENTRIES\&. In that case entries with the same name will be joined to one single entry\&. +Default behaviour if entries have the same name in one file: The first hit will be returned\&. Further entries will be ignored\&. This can be changed by setting the environment variable JOIN_SAME_ENTRIES (see econf_set_opt)\&. In that case entries with the same name will be joined to one single entry\&. .SS "\fBeconf_err\fP econf_readFileWithCallback (\fBeconf_file\fP ** result, const char * file_name, const char * delim, const char * comment, bool (*callback)(const char *filename, const void *data), const void *callback_data)" @@ -744,7 +744,7 @@ econf_free (key_file); .fi .PP .PP -Default behaviour if entries have the same name in one file: The first hit will be returned\&. Further entries will be ignored\&. This can be changed by setting the environment variable ECONF_JOIN_SAME_ENTRIES\&. In that case entries with the same name will be joined to one single entry\&. +Default behaviour if entries have the same name in one file: The first hit will be returned\&. Further entries will be ignored\&. This can be changed by setting the environment variable JOIN_SAME_ENTRIES (see econf_set_opt)\&. In that case entries with the same name will be joined to one single entry\&. .SS "\fBeconf_err\fP econf_mergeFiles (\fBeconf_file\fP ** merged_file, \fBeconf_file\fP * usr_file, \fBeconf_file\fP * etc_file)" diff --git a/docs/libeconf_8h.html b/docs/libeconf_8h.html index 47be6b5..1cee02c 100644 --- a/docs/libeconf_8h.html +++ b/docs/libeconf_8h.html @@ -516,7 +516,7 @@

Returns
econf_err ECONF_SUCCESS or error code
-

Usage:

econf_file *key_file = NULL;
econf_err error;
error = econf_readFile (&key_file, "/etc/test.conf", "=", "#");
econf_free (key_file);

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name will be joined to one single entry.

+

Usage:

#include "libeconf.h"
econf_file *key_file = NULL;
econf_err error;
error = econf_readFile (&key_file, "/etc/test.conf", "=", "#");
econf_free (key_file);

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with the same name will be joined to one single entry.

@@ -584,7 +584,7 @@

Returns
econf_err ECONF_SUCCESS or error code
-

Usage:

bool checkFile(const char *filename, const void *data) {
- checking code which returns true or false -
return true;
}
econf_file *key_file = NULL;
econf_err error;
error = econf_readFileWithCallback (&key_file, "/etc/test.conf", "=", "#", checkFile, NULL);
econf_free (key_file);

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name will be joined to one single entry.

+

Usage:

#include "libeconf.h"
bool checkFile(const char *filename, const void *data) {
- checking code which returns true or false -
return true;
}
econf_file *key_file = NULL;
econf_err error;
error = econf_readFileWithCallback (&key_file, "/etc/test.conf", "=", "#", checkFile, NULL);
econf_free (key_file);

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with the same name will be joined to one single entry.

@@ -1014,7 +1014,7 @@

Returns
econf_err ECONF_SUCCESS or error code
-

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name will be joined to one single entry.

+

Default behaviour if entries have the same name in one file: The first hit will be returned. Further entries will be ignored. This can be changed by setting the environment variable JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with the same name will be joined to one single entry.

diff --git a/include/libeconf.h b/include/libeconf.h index 465abaa..ecfe800 100644 --- a/include/libeconf.h +++ b/include/libeconf.h @@ -149,8 +149,8 @@ typedef struct econf_file econf_file; * Default behaviour if entries have the same name in one file: The * first hit will be returned. Further entries will be ignored. * This can be changed by setting the environment variable - * ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name - * will be joined to one single entry. + * JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with + * the same name will be joined to one single entry. */ extern econf_err econf_readFile(econf_file **result, const char *file_name, const char *delim, const char *comment); @@ -191,8 +191,8 @@ extern econf_err econf_readFile(econf_file **result, const char *file_name, * Default behaviour if entries have the same name in one file: The * first hit will be returned. Further entries will be ignored. * This can be changed by setting the environment variable - * ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name - * will be joined to one single entry. + * JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with + * the same name will be joined to one single entry. */ extern econf_err econf_readFileWithCallback(econf_file **result, const char *file_name, const char *delim, const char *comment, @@ -618,8 +618,8 @@ extern econf_err econf_readDirsHistoryWithCallback(econf_file ***key_files, * Default behaviour if entries have the same name in one file: The * first hit will be returned. Further entries will be ignored. * This can be changed by setting the environment variable - * ECONF_JOIN_SAME_ENTRIES. In that case entries with the same name - * will be joined to one single entry. + * JOIN_SAME_ENTRIES (see econf_set_opt). In that case entries with + * the same name will be joined to one single entry. */ extern econf_err econf_newKeyFile(econf_file **result, char delimiter, char comment); @@ -1034,6 +1034,27 @@ extern void econf_freeArray(char **array); */ extern void econf_freeFile(econf_file *key_file); +/** @brief Set libeconv environment. + * + * @param option defined as a string (format "=") + * @return void + * + * Usage: + * @code + * #include "libeconf.h" + * + * econf_set_opt("JOIN_SAME_ENTRIES=1"); + * @endcode + * + * Not known options will be ignored. Following options are supported: + * JOIN_SAME_ENTRIES (default 0) + * Parsed entries with the same name will not be replaces but + * will be joined to one entry. + * PYTHON_STYLE (default 0) + * E.G. Identations will be handled like multiline entries. + */ +extern void econf_set_opt(const char *option); + /** @brief All parsed files require this user permission. * DEPRECATED: Use the callback in econf_readFileWithCallback or * econf_readConfigWithCallback instead. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 62bfa08..8b467aa 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,6 +4,7 @@ set(econf_SRCS libeconf.c getfilecontents.c mergefiles.c helpers.c + options.c keyfile.c econf_error.c get_value_def.c @@ -14,6 +15,7 @@ set(econf_HDRS defines.h getfilecontents.h mergefiles.h helpers.h + options.h keyfile.h readconfig.h ) diff --git a/lib/getfilecontents.c b/lib/getfilecontents.c index 4cd3753..667556e 100644 --- a/lib/getfilecontents.c +++ b/lib/getfilecontents.c @@ -25,6 +25,7 @@ #include "defines.h" #include "getfilecontents.h" #include "helpers.h" +#include "options.h" #include #include @@ -529,7 +530,7 @@ read_file(econf_file *ef, const char *file, if (current_comment_after_value) free(current_comment_after_value); - if(getenv("ECONF_JOIN_SAME_ENTRIES")) + if(option_join_same_entries() == true) { join_same_entries(ef); } diff --git a/lib/libeconf.map b/lib/libeconf.map index 1914c62..7b86e5c 100644 --- a/lib/libeconf.map +++ b/lib/libeconf.map @@ -77,4 +77,8 @@ LIBECONF_0.6 { global: econf_readConfigWithCallback; econf_readConfig; -} LIBECONF_0.5; \ No newline at end of file +} LIBECONF_0.5; +LIBECONF_0.7 { + global: + econf_set_opt; +} LIBECONF_0.6; \ No newline at end of file diff --git a/lib/options.c b/lib/options.c new file mode 100644 index 0000000..7c2db4d --- /dev/null +++ b/lib/options.c @@ -0,0 +1,62 @@ +/* + Copyright (C) 2024 SUSE LLC + + 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. +*/ + +#include "libeconf.h" +#include "options.h" + +#include +#include +#include + +/*General options which can be set with econf_set_opt */ +static bool join_same_entries = false; +static bool python_style = false; + +extern void econf_set_opt(const char *option) +{ + if (strcmp(option, "JOIN_SAME_ENTRIES=1") == 0) { + join_same_entries = true; + return; + } + if (strcmp(option, "JOIN_SAME_ENTRIES=0") == 0) { + join_same_entries = false; + return; + } + if (strcmp(option, "PYTHON_STYLE=1") == 0) { + python_style = true; + return; + } + if (strcmp(option, "PYTHON_STYLE=0") == 1) { + python_style = false; + return; + } +} + +bool option_join_same_entries(void) +{ + return join_same_entries; +} +bool option_python_style(void) +{ + return python_style; +} + diff --git a/lib/options.h b/lib/options.h new file mode 100644 index 0000000..fbcbe8d --- /dev/null +++ b/lib/options.h @@ -0,0 +1,5 @@ + +#pragma once + +bool option_join_same_entries(void); +bool option_python_style(void); diff --git a/meson.build b/meson.build index abc4960..d81ae88 100644 --- a/meson.build +++ b/meson.build @@ -7,7 +7,7 @@ project( 'b_pie=true', 'warning_level=3',], license : 'MIT', - version : '0.6.3', + version : '0.7.0', ) cc = meson.get_compiler('c') @@ -50,6 +50,7 @@ libeconf_src = files( 'lib/libeconf_ext.c', 'lib/readconfig.c', 'lib/mergefiles.c', + 'lib/options.c' ) example_src = ['example/example.c'] econftool_src = ['util/econftool.c'] diff --git a/tests/meson.build b/tests/meson.build index 00f9998..bb8e620 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -79,67 +79,67 @@ tst_getconfdirs8_exe = executable('tst-getconfdirs8', 'tst-getconfdirs8.c', c_ar test('tst-getconfdirs8', tst_getconfdirs8_exe) tst_uapi_1_exe = executable('tst-uapi-1', - sources: ['tst-uapi-1.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-1.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-1-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-1', tst_uapi_1_exe) tst_uapi_2_exe = executable('tst-uapi-2', - sources: ['tst-uapi-2.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-2.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-2-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-2', tst_uapi_2_exe) tst_uapi_3_exe = executable('tst-uapi-3', - sources: ['tst-uapi-3.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-3.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-3-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-3', tst_uapi_3_exe) tst_uapi_4_exe = executable('tst-uapi-4', - sources: ['tst-uapi-4.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-4.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-4-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-4', tst_uapi_4_exe) tst_uapi_5_exe = executable('tst-uapi-5', - sources: ['tst-uapi-5.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-5.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-5-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-5', tst_uapi_5_exe) tst_uapi_6_exe = executable('tst-uapi-6', - sources: ['tst-uapi-6.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-6.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-6-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-6', tst_uapi_6_exe) tst_uapi_7_exe = executable('tst-uapi-7', - sources: ['tst-uapi-7.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-7.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-7-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-7', tst_uapi_7_exe) tst_uapi_8_exe = executable('tst-uapi-8', - sources: ['tst-uapi-8.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-8.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-8-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-8', tst_uapi_8_exe) tst_uapi_9_exe = executable('tst-uapi-9', - sources: ['tst-uapi-9.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-9.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-9-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-9', tst_uapi_9_exe) tst_uapi_10_exe = executable('tst-uapi-10', - sources: ['tst-uapi-10.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-10.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-10-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-10', tst_uapi_10_exe) tst_uapi_11_exe = executable('tst-uapi-11', - sources: ['tst-uapi-11.c', '../lib/helpers.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', + sources: ['tst-uapi-11.c', '../lib/helpers.c', '../lib/options.c', '../lib/readconfig.c', '../lib/libeconf.c', '../lib/getfilecontents.c', '../lib/mergefiles.c', '../lib/econf_error.c', '../lib/keyfile.c'], c_args: ['-DTESTSDIR="' + testdir + 'tst-uapi-11-data' + '"'], dependencies : staticlibeconf_dep) test('tst-uapi-11', tst_uapi_11_exe) diff --git a/tests/tst-string-append.c b/tests/tst-string-append.c index 0a37eab..4ee9dd3 100644 --- a/tests/tst-string-append.c +++ b/tests/tst-string-append.c @@ -9,7 +9,7 @@ /* Test case: * An string array has been defined mutitple times in a file with the - * same ID. If the environment ECONF_JOIN_SAME_ENTRIES is set, these + * same ID. If the environment JOIN_SAME_ENTRIES is set, these * multiple entries are packed into an single one. */ @@ -114,7 +114,7 @@ main(void) }; /* double entries will be joined together */ - setenv("ECONF_JOIN_SAME_ENTRIES", "1", 1); + econf_set_opt("JOIN_SAME_ENTRIES=1"); error = econf_readFile (&key_file, TESTSDIR"tst-append-string/input.conf", "=", "#"); if (error)