madmurphy / libconfini Goto Github PK
View Code? Open in Web Editor NEWYet another INI parser
Home Page: https://madmurphy.github.io/libconfini/
License: GNU General Public License v3.0
Yet another INI parser
Home Page: https://madmurphy.github.io/libconfini/
License: GNU General Public License v3.0
I was trying to build the library on macOS Sierra 10.12.4 and had to install GNU libtool
and libtoolize
from Homebrew. The thing is the commands are called glibtool
and glibtoolize
in order to avoid conflict with Apple's, which apparently is unrelated to GNU's, so I had to edit autogen.sh
in order to reflect this.
Would you consider testing for this tools also in the script?
Is there, or is it planned somehow, a standalone program to handle ini-files from the shell?
I am looking for something like crudini but without the python overhead.
If this is not available/planned I could volunteer to write such a thing, if there's interest.
~$ cat /etc/debian_version
9.2
~$ uname -r
4.9.0-3-amd64
~$ git clone https://github.com/madmurphy/libconfini.git
.......
~$ cd libconfini
~/libconfini$ ./autogen.sh
.........
~/libconfini$ make
make all-recursive
make[1]: Entering directory '/home/user1/libconfini'
Making all in src
make[2]: Entering directory '/home/user1/libconfini/src'
CC confini.lo
CCLD libconfini.la
ar: `u' modifier ignored since `D' is the default (see `U')
make[2]: Leaving directory '/home/user1/libconfini/src'
Making all in po
make[2]: Entering directory '/home/user1/libconfini/po'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/user1/libconfini/po'
make[2]: Entering directory '/home/user1/libconfini'
make[2]: Leaving directory '/home/user1/libconfini'
make[1]: Leaving directory '/home/user1/libconfini'
Can not find binary libconfini libs. What's wrong?
Hi there,
I liked a lot this library and I was thinking in adding support for writing .ini files. Is this feature been planned for a future release?
Best regards,
F.Borges
Is there a problem in calling load_ini_file() from inside iniDispHandler?.
e.g.
top.ini
[Global]
Include = child.ini
[Something]
else=here
my iniParse() function which processes the keeps its current state in the user_data.. But I seem to be unable to continue to parse the top file once the child.ini is done.
Entirely possible its my code ;-), could you confirm if load_ini_file() is reentrant or I'm barking up the wrong tree?.
Thanks in advance
Second Function:
static int configure_program(IniDispatch *dispatch, void *_program) {
if (dispatch->type == INI_KEY) {
PROGRAM *program = (PROGRAM *) _program;
ini_unquote(dispatch->data, dispatch->format);
ini_string_parse(dispatch->value, dispatch->format);
if (ini_string_match_si("language_folder", dispatch->data, dispatch->format)) {
program->language_directory = dispatch->value;
return 0;
} else if (ini_string_match_si("save_folder", dispatch->data, dispatch->format)) {
if (strcmp("NONE", dispatch->value) == 0) {
program->save_directory = NULL;
} else {
program->save_directory == dispatch->value;
}
return 0;
} else if (ini_string_match_si("multithreading", dispatch->data, dispatch->format)) {
if (strcmp("TRUE", dispatch->value) == 0) {
program->multithreading_enabled = 1;
} else {
program->multithreading_enabled = 0;
}
return 0;
} else {
return 0;
}
}
}
First Function:
int load_settings(PROGRAM *program) {
char program_directory[MAX_PATH];
// returns 0 on failure; don't change
if (!ExpandEnvironmentStrings("%SHIROI_INSTALL%", program_directory, MAX_PATH)) {
puts("Failed to find program's directory. Make sure to define %SHIROI_INSTALL% or relaunch setup.bat");
return 1;
}
strcat(program_directory, "\\shiroi-settings.ini");
printf("Reading %s...\n", program_directory);
FILE *settings_file = fopen(program_directory, "rb");
if (settings_file == NULL) {
puts("Couldn't find settings file");
return 1;
}
if (load_ini_file(settings_file, INI_DEFAULT_FORMAT, NULL, configure_program, &program)) {
puts("Couldn't load settings file. Perhaps invalid?");
return 1;
}
fclose(settings_file);
return 0;
}
Starting ./autoget.sh on an Ubuntu 18.04 machine, I'm getting
./autogen.sh: Syntax error: "(" unexpected
The reason is:
The solution for me was to replace !#/bin/sh
by !#/bin/bash
.
I've compared some ini file parsers now, and libconfini really fits best to my needs: It is easy-to-use, compact and will also run on a very simple embedded system without considerable memory consumption or runtime overhead. Really a nice pice of software!
The only drawback is its license for me: Due to the roles of GPL v3.0, all the code using libconfini also has to be put under GPL v3.0. For open source projects this should be no problem, but for a commercial application like mine this is not possible.
Do you think it would be possible to put libconfini under a less restricted license like MIT, maybe under a dual-license? Thank you!
My embedded program dynamic generate small config data frequently.
these conig data used by another part of the same program.
So use a file to transfer the config data seems strange and too slow.
Could you give a new interface func which get config data from a "const char *"
==> Please choose a number to compile and run (q to exit): 1
-> Compiling "cplusplus/generic.cpp" with gcc
(g++ -Wall -pedantic -lconfini 'cplusplus/generic.cpp'
)...
/usr/bin/ld: /tmp/ccisF92m.o: in function callback(IniDispatch*, void*)': generic.cpp:(.text+0x43): undefined reference to
ini_array_match'
/usr/bin/ld: generic.cpp:(.text+0x65): undefined reference to ini_string_match_ii' /usr/bin/ld: generic.cpp:(.text+0xd9): undefined reference to
ini_array_match'
/usr/bin/ld: generic.cpp:(.text+0xfb): undefined reference to ini_string_match_ii' /usr/bin/ld: /tmp/ccisF92m.o: in function
main':
generic.cpp:(.text+0x19a): undefined reference to `load_ini_path'
collect2: error: ld returned 1 exit status
-> Couldn't compile file "cplusplus/generic.cpp".
it compiles fine with this command
g++ -Wall -pedantic generic.cpp -lconfini
but then fails to run
./a.out: error while loading shared libraries: libconfini.so.0: cannot open shared object file: No such file or directory
but works when i do this
./configure --prefix=/usr
i can reproduce the error with the following...
lxc launch ubuntu:20.04 delme
lxc shell delme
git clone https://github.com/madmurphy/libconfini.git
apt update
apt install -y libtool-bin autoconf automake make gawk g++
cd libconfini/
./bootstrap
make install
/usr/local/share/doc/libconfini/examples/run-example.sh
You are not mentioning that ./autoconf.sh
must be run. The ./configure
file does not exist in the repository!
The installation guide should say to run:
./autogen.sh
make
make install
instead of:
./configure
make
make install
I'm not sure where else to report this, but re: https://github.com/madmurphy/libconfini/wiki/An-INI-critique-of-TOML#18-performance
This is really a tomlc99 issue, not a TOML issue. The problem is that it allocates memory in 1,000 byte chucks, which takes quite a while (see start of toml_parse_file()), and after this it spends most of its time in check_key(), which loops over an array of keys, and is called every time it parses a new key, so ... yeah,
But these are not issues with TOML the file format. Other parsers are much faster; for example:
% ls -lh ~/50M.toml
-rw-r--r-- 1 martin martin 49M Sep 30 20:23 /home/martin/50M.toml
With C++:
% time ./tomlv++ ~/50M.toml
./tomlv++ ~/50M.toml 2.19s user 0.15s system 99% cpu 2.348 total
Go:
% time tomlv-go ~/50M.toml
tomlv-go ~/50M.toml 6.31s user 0.51s system 154% cpu 4.421 total
And Python:
% time ./tomlv.py ~/50M.toml
./tomlv.py ~/50M.toml 11.95s user 0.42s system 99% cpu 12.413 total
None are spectacularly fast as such, but orders of magnitudes faster than tomlc99, which is the outlier here. I also don't know how this compares to the 50M test-file you used (the TOML file lacks comments and is more "dense" in syntax than the big_file.ini that your script generates, so it's probably not a fair comparison).
Most of the other points in that article are more subjective, but I felt this one was clearly wrong.
I was testing libconfini v1.16.1 (latest, current master
branch) with some randomly generated files when I found the following file causes an heap buffer overflow when parsed by the library with INI_MULTILINE_EVERYWHERE
:
#\
# 'x'
The file is 9 bytes, though the trailing newline does not matter, the bug can be reproduced anyway.
Full test program to reproduce the bug (compile libconfini with CFLAGS='-O0 -g -fsanitize=address'
and link statically):
#include <confini.h>
static const IniFormat my_ini_format = {
.delimiter_symbol = INI_ANY_SPACE,
.case_sensitive = false,
.semicolon_marker = INI_IGNORE,
.hash_marker = INI_DISABLED_OR_COMMENT,
.section_paths = INI_ABSOLUTE_AND_RELATIVE,
.multiline_nodes = INI_MULTILINE_EVERYWHERE,
.no_single_quotes = false,
.no_double_quotes = false,
.no_spaces_in_names = false,
.implicit_is_not_empty = false,
.do_not_collapse_values = false,
.preserve_empty_quotes = false,
.disabled_after_space = false,
.disabled_can_be_implicit = false
};
int main(void) {
load_ini_path("test.ini", my_ini_format, NULL, NULL, NULL);
return 0;
}
ASAN backtrace:
==21423==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000001a at pc 0x0000004027e7 bp 0x7ffde47d8fb0 sp 0x7ffde47d8fa8
READ of size 1 at 0x60200000001a thread T0
#0 0x4027e6 in getn_metachar_pos /home/dummy/src/libconfini/src/confini.c:973
#1 0x405dcc in get_type_as_active /home/dummy/src/libconfini/src/confini.c:1839
#2 0x406c40 in further_cuts /home/dummy/src/libconfini/src/confini.c:2059
#3 0x40820a in strip_ini_cache /home/dummy/src/libconfini/src/confini.c:2479
#4 0x40a499 in load_ini_path /home/dummy/src/libconfini/src/confini.c:3136
#5 0x401286 in main /home/dummy/src/main.c:21
#6 0x7f67d8b5a09a in __libc_start_main ../csu/libc-start.c:308
#7 0x4011a9 in _start (/home/dummy/src/test+0x4011a9)
0x60200000001a is located 0 bytes to the right of 10-byte region [0x602000000010,0x60200000001a)
allocated by thread T0 here:
#0 0x7f67d8de0330 in __interceptor_malloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x40a40b in load_ini_path /home/dummy/src/libconfini/src/confini.c:3116
#2 0x401286 in main /home/dummy/src/main.c:21
#3 0x7f67d8b5a09a in __libc_start_main ../csu/libc-start.c:308
I'm not entirely sure about the logical nature of the bug since the source code for the library seems quite... esoteric, but it seems to originate here:
Lines 2044 to 2075 in 409b9ee
The function dqultrim_s()
returns 5
while ltrim_s()
returns 3
, which later causes an unsigned integer overflow when calculating idx - focus_at
at line 2061
, causing get_type_as_active()
to be called with len = 18446744073709551614
, running past the end of the allocated buffer.
I have built libconfini and referenced the generated file libconfini\src\.libs\libconfini-0.dll
in an empty C++ Managed Build project using Eclipse CDT on a Windows 7 host with mingw64 (gcc version 8.2).
Building my project TestIniReader works fine, but when calling my application the output is always:
The file content is:
[users]
have_visited = ronnie, lilly82, robrob
[last_update]
date = 12.03.2017
Sorry, something went wrong :-(
To quit, press 'q' then the 'Enter' key.
The source code (see TestIniReader.zip) is pretty much the same as mentioned in the documentation of libconfini, still the callback
method does not seem to get called. The line "This is a message!" is never printed to console.
How can I find out what the couse for the failed method call to load_ini_path
is?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.