autoconfiguration

This commit is contained in:
2020-02-11 20:27:53 -08:00
parent 0d8053dc20
commit 8f5419f2a2
12 changed files with 221 additions and 48 deletions

View File

@@ -1,40 +0,0 @@
BINS := srm
EDS := ke kte
LIBS := libdirutils.a libiniparser.a
LDFLAGS := -L. -L/usr/local/lib
CFLAGS := -pedantic -Wall -Werror -Wextra -O0 -std=c99 -g
CFLAGS += -I../include/ -I/usr/local/include/
.PHONY: all
all: $(BINS) $(EDS) $(LIBS)
.PHONY: clean
clean:
rm -f $(BINS) $(EDS) $(LIBS) *.o *.core
ke kte:
cd ../$@ && make && cp $@ ../src
srm: srm.c
$(CC) $(CFLAGS) -o $@ srm.c
libiniparser.a: iniparser.o
$(AR) -rcs $@ iniparser.o
libdirutils.a: dirlist.o dirutils.o dirwalk.o
$(AR) -rcs $@ dirlist.o dirutils.o dirwalk.o
.PHONY: tests
tests: iniparser-test dirlist-test dirutils-test
iniparser-test: iniparser_test.c libiniparser.a
$(CC) $(CFLAGS) -o $@ iniparser_test.c libiniparser.a
dirlist-test: dirlist_test.c libdirutils.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ dirlist_test.c libdirutils.a -lcunit
dirutils-test: dirutils_test.c libdirutils.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ dirutils_test.c libdirutils.a -lcunit

19
src/Makefile.am Normal file
View File

@@ -0,0 +1,19 @@
CFLAGS := -pedantic -Wall -Werror -Wextra -O2 -std=c99 -g
lib_LIBRARIES := libdirutils.a libiniparser.a
nobase_include_HEADERS := kst/dirutils.h \
kst/iniparser.h \
dist_noinst_HEADERS := kst/dirlist.h
bin_PROGRAMS := srm
## programs
srm_SOURCES = srm.c
## libraries
libdirutils_a_SOURCES = dirutils.c dirlist.c dirwalk.c dirlist.h

View File

@@ -1,212 +0,0 @@
/*
* Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* ---------------------------------------------------------------------
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <dirlist.h>
/*
* helper that, given a list and the expected key, determines whether
* the the popped path matches. Return values use if semantics: success
* is 1, failure is 0. It is up to the caller to ensure that keylen is
* in the acceptable range (FILENAME_MAX) for tests that are to be
* successful.
*/
int
test_pop_helper(struct tq_dirlst *lst, const char *key, size_t keylen)
{
struct dirlst *elm;
int match;
if (keylen > FILENAME_MAX)
return 0;
elm = dirlst_pop(lst);
if (NULL == elm)
return 0;
match = strncmp(elm->path, key, keylen);
free(elm);
return 0 == match;
}
void
test_dirlst_create(void)
{
struct tq_dirlst *lst;
lst = dirlst_create((const char *)"foo", 3);
CU_ASSERT(lst != NULL);
CU_ASSERT(EXIT_SUCCESS == dirlst_destroy(&lst));
}
void
test_dirlst_single(void)
{
struct tq_dirlst *lst;
struct dirlst *elm;
int n_elms, ret;
lst = dirlst_create((const char *)"foo", 3);
ret = dirlst_push(lst, (const char *)"bar", 3);
CU_ASSERT(EXIT_SUCCESS == ret);
n_elms = 0;
TAILQ_FOREACH(elm, lst, dirs)
n_elms++;
CU_ASSERT(2 == n_elms);
CU_ASSERT(test_pop_helper(lst, "bar", 3));
n_elms = 0;
TAILQ_FOREACH(elm, lst, dirs)
n_elms++;
CU_ASSERT(1 == n_elms);
CU_ASSERT(EXIT_SUCCESS == dirlst_destroy(&lst));
}
/*
* ensure an invalid path_len aborts the push
*/
void
test_dirlst_bad(void)
{
struct tq_dirlst *lst;
lst = dirlst_create((const char *)"foo", 3);
CU_ASSERT(EXIT_SUCCESS == dirlst_push(lst, "bar", 3));
CU_ASSERT(EXIT_FAILURE == dirlst_push(lst, "baz", FILENAME_MAX * 2));
CU_ASSERT(test_pop_helper(lst, "bar", 3));
CU_ASSERT(EXIT_SUCCESS == dirlst_destroy(&lst));
}
void
test_dirlst_multi(void)
{
char testkeys[][4] = {"bar", "baz", "quux", ""};
int testkeylen[4];
struct tq_dirlst *lst;
struct dirlst *elm;
int i, n_elms, ret;
lst = dirlst_create((const char *)"foo", 3);
for(i = 0; i < 3; ++i) {
testkeylen[i] = strlen(testkeys[i]);
ret = dirlst_push(lst, testkeys[i], testkeylen[i]);
CU_ASSERT(EXIT_SUCCESS == ret);
}
n_elms = 0;
TAILQ_FOREACH(elm, lst, dirs)
n_elms++;
CU_ASSERT(4 == n_elms);
for (i = 2; i >= 0; i--)
CU_ASSERT(test_pop_helper(lst, testkeys[i], testkeylen[i]));
CU_ASSERT(test_pop_helper(lst, "foo", 3));
CU_ASSERT(EXIT_SUCCESS == dirlst_destroy(&lst));
}
/*
* Stubs required by the test suite, but for which no functionality is
* required in this code. init_test is called each time a test is run,
* and cleanup is run after every test.
*/
int init_test(void)
{
return 0;
}
int cleanup_test(void)
{
return 0;
}
/*
* fireball is the code called when adding test fails: cleanup the test
* registry and exit.
*/
void
fireball(void)
{
CU_cleanup_registry();
exit(CU_get_error());
}
/*
* The main function sets up the test suite, registers the test cases,
* runs through them, and hopefully doesn't explode.
*/
int
main(void)
{
CU_pSuite tsuite = NULL;
unsigned int fails;
printf("\n\n[+] running tests for dirutils\n");
if (!(CUE_SUCCESS == CU_initialize_registry())) {
errx(EX_CONFIG, "failed to initialise test registry");
return EXIT_FAILURE;
}
tsuite = CU_add_suite(TEST_SUITE, init_test, cleanup_test);
if (NULL == tsuite)
fireball();
if (NULL == CU_add_test(tsuite, "dirlst create", test_dirlst_create))
fireball();
if (NULL == CU_add_test(tsuite, "single push/pop", test_dirlst_single))
fireball();
if (NULL == CU_add_test(tsuite, "multi push/pop", test_dirlst_multi))
fireball();
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
fails = CU_get_number_of_tests_failed();
warnx("%u tests failed", fails);
CU_cleanup_registry();
return fails;
}
/*
* This is an empty test provided for reference.
*/
void
empty_test()
{
CU_ASSERT(1 == 0);
}

View File

@@ -1,267 +0,0 @@
/*
* Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* ---------------------------------------------------------------------
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <dirutils.h>
static int test_write_file_helper(const char *, const char *);
static int test_touch_file_helper(const char *);
/*
* test the use of the exists function
*/
void
test_exists(void)
{
char testdir[] = "testdata/testdir";
char testfil[] = "testdata/testfile";
char testnot[] = "testdata/nosuchfile";
EXISTS_STATUS ftype;
ftype = path_exists(testdir);
CU_ASSERT(EXISTS_DIR == ftype);
ftype = path_exists(testfil);
CU_ASSERT(EXISTS_FILE == ftype);
ftype = path_exists(testnot);
CU_ASSERT(EXISTS_NOENT == ftype);
}
void
test_makedirs(void)
{
char testpath[] = "testdata/foo/bar/baz\0";
/*
* use the system to ensure we have a clean slate for this test
*/
if (EXISTS_DIR == path_exists(testpath))
system("rm -fr testdata/foo/");
CU_ASSERT(EXIT_SUCCESS == makedirs(testpath));
CU_ASSERT(EXISTS_DIR == path_exists(testpath));
/*
* we can't guarantee rmdirs yet; this ensures a clean slate.
*/
system("rm -r testdata/foo/");
}
void
test_empty_rmdirs(void)
{
char testpath[20] = "testdata/foo";
char cmd[FILENAME_MAX];
int rv;
memset(cmd, 0x0, FILENAME_MAX);
snprintf(cmd, FILENAME_MAX, "mkdir -p %s/bar/baz", testpath);
system(cmd);
rv = rmdirs(testpath);
if (EXIT_FAILURE == rv) {
printf("\n");
warn("rmdirs");
system("rm -fr testdata/foo/");
}
CU_ASSERT(EXIT_SUCCESS == rv);
CU_ASSERT(EXISTS_NOENT == path_exists(testpath));
/*
* we can't guarantee rmdirs yet; this ensures a clean slate.
*/
}
void
test_rmdirs_simple(void)
{
char testpath[] = "testdata/foo";
char cmd[FILENAME_MAX];
int rv;
memset(cmd, 0x0, FILENAME_MAX);
snprintf(cmd, FILENAME_MAX, "mkdir -p %s/bar/baz", testpath);
system(cmd);
memset(cmd, 0x0, FILENAME_MAX);
snprintf(cmd, FILENAME_MAX, "touch %s/bar/quux", testpath);
system(cmd);
rv = rmdirs(testpath);
if (EXIT_FAILURE == rv) {
printf("\n");
warn("rmdirs");
/*
* we can't guarantee rmdirs yet; this ensures a clean slate.
*/
system("rm -r testdata/foo/ 2>/dev/null");
}
CU_ASSERT(EXIT_SUCCESS == rv);
CU_ASSERT(EXISTS_NOENT == path_exists(testpath));
}
void
test_dirutils(void)
{
char testpath[] = "testdata/dirutils";
char tmp_path[FILENAME_MAX + 1];
char lnk_path[FILENAME_MAX + 1];
/* set up directory structure */
CU_ASSERT(EXISTS_NOENT == path_exists(testpath));
snprintf(tmp_path, FILENAME_MAX, "%s/foo/bar", testpath);
CU_ASSERT(EXIT_SUCCESS == makedirs(tmp_path));
CU_ASSERT(EXISTS_DIR == path_exists(tmp_path));
snprintf(tmp_path, FILENAME_MAX, "%s/foo/baz", testpath);
CU_ASSERT(EXIT_SUCCESS == makedirs(tmp_path));
CU_ASSERT(EXISTS_DIR == path_exists(tmp_path));
/* add a few files */
snprintf(tmp_path, FILENAME_MAX, "%s/foo/quux", testpath);
CU_ASSERT(EXIT_SUCCESS == test_touch_file_helper(tmp_path));
CU_ASSERT(EXISTS_FILE == path_exists(tmp_path));
snprintf(tmp_path, FILENAME_MAX, "%s/foo/bar/xyzzy", testpath);
snprintf(lnk_path, FILENAME_MAX, "%s/foo/baz/xyzzy", testpath);
CU_ASSERT(EXIT_SUCCESS == test_write_file_helper(tmp_path,
"some data should go here"));
CU_ASSERT(EXISTS_FILE == path_exists(tmp_path));
CU_ASSERT(-1 != link(tmp_path, lnk_path));
CU_ASSERT(EXISTS_FILE == path_exists(lnk_path));
snprintf(tmp_path, FILENAME_MAX, "%s/foo/bar/thud", testpath);
snprintf(lnk_path, FILENAME_MAX, "%s/foo/baz/fred", testpath);
CU_ASSERT(EXIT_SUCCESS == test_write_file_helper(tmp_path,
"we want something for the link"));
CU_ASSERT(EXISTS_FILE == path_exists(tmp_path));
CU_ASSERT(-1 != symlink(tmp_path, lnk_path));
CU_ASSERT_FATAL(EXIT_SUCCESS == rmdirs(testpath));
CU_ASSERT_FATAL(EXISTS_NOENT == path_exists(testpath));
}
/*
* utility function to touch a file
*/
static int
test_write_file_helper(const char *path, const char *data)
{
ssize_t wrsz;
size_t data_len;
int fail, fd;
fail = EXIT_SUCCESS;
data_len = strlen(data);
fd = open(path, O_WRONLY|O_CREAT, S_IRUSR| S_IWUSR);
if (-1 == fd)
return EXIT_FAILURE;
wrsz = write(fd, data, data_len);
if (wrsz != data_len)
fail = EXIT_FAILURE;
if (-1 == close(fd))
fail = EXIT_FAILURE;
return fail;
}
static int
test_touch_file_helper(const char *path)
{
return test_write_file_helper(path, "");
}
/*
* Stubs required by the test suite, but for which no functionality is
* required in this code. init_test is called each time a test is run,
* and cleanup is run after every test.
*/
int init_test(void)
{
return 0;
}
int cleanup_test(void)
{
return 0;
}
/*
* fireball is the code called when adding test fails: cleanup the test
* registry and exit.
*/
void
fireball(void)
{
CU_cleanup_registry();
exit(CU_get_error());
}
/*
* The main function sets up the test suite, registers the test cases,
* runs through them, and hopefully doesn't explode.
*/
int
main(void)
{
CU_pSuite tsuite = NULL;
unsigned int fails;
printf("\n\n[+] running tests for dirutils\n");
if (!(CUE_SUCCESS == CU_initialize_registry())) {
errx(EX_CONFIG, "failed to initialise test registry");
return EXIT_FAILURE;
}
tsuite = CU_add_suite(TEST_SUITE, init_test, cleanup_test);
if (NULL == tsuite)
fireball();
if (NULL == CU_add_test(tsuite, "path_exists", test_exists))
fireball();
if (NULL == CU_add_test(tsuite, "makedirs simple", test_makedirs))
fireball();
if (NULL == CU_add_test(tsuite, "empty dir rmdirs", test_empty_rmdirs))
fireball();
if (NULL == CU_add_test(tsuite, "simple rmdirs", test_rmdirs_simple))
fireball();
if (NULL == CU_add_test(tsuite, "full test", test_dirutils))
fireball();
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
fails = CU_get_number_of_tests_failed();
warnx("%u tests failed", fails);
CU_cleanup_registry();
return fails;
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright (c) 2015 Kyle Isom <kyle@tyrfingr.is>
*
* 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "kst/iniparser.h"
int
main(int argc, char *argv[])
{
iniparser_file_s *file = NULL;
iniparser_line_s line;
int i;
int ret;
ret = iniparser_init();
if (0 != ret) {
fprintf(stderr, "init failed: %d\n", ret);
goto exit;
}
argc--;
argv++;
for (i = 0; i < argc; i++) {
printf("Processing %s\n", argv[i]);
ret = iniparser_open(argv[i], &file);
if (0 != ret) {
perror("_open");
fprintf(stderr, "retval: %d\n", ret);
goto exit;
}
iniparser_line_init(&line);
while (1) {
ret = iniparser_readline(file, &line);
/* -1 is returned on error. */
if (-1 == ret) {
perror("_readline");
fprintf(stderr, "retval: %d\n", ret);
goto exit;
}
/* 1 means EOF. */
else if (1 == ret) {
ret = 0;
break;
}
if (line.is_section) {
printf("Now in section '%s'\n", line.name);
}
else {
printf("Read key '%s' with value '%s'\n",
line.name, line.value);
}
iniparser_line_destroy(&line);
}
iniparser_close(file);
free(file);
file = NULL;
iniparser_line_destroy(&line);
}
exit:
iniparser_line_destroy(&line);
if (argc > 0) {
iniparser_destroy();
}
return ret==0;
}

42
src/kst/dirlist.h Normal file
View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* ---------------------------------------------------------------------
*/
#ifndef __DIRUTILS_DIRLIST_H
#define __DIRUTILS_DIRLIST_H
#include <stdio.h>
#include <dirent.h>
#include "queue.h"
struct dirlst {
char path[FILENAME_MAX + 1];
TAILQ_ENTRY(dirlst) dirs;
};
TAILQ_HEAD(tq_dirlst, dirlst);
struct tq_dirlst *dirlst_create(const char *, size_t);
int dirlst_push(struct tq_dirlst *, const char *, size_t);
struct dirlst *dirlst_pop(struct tq_dirlst *);
int dirlst_destroy(struct tq_dirlst **);
#endif

53
src/kst/dirutils.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2012 Kyle Isom <kyle@tyrfingr.is>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* ---------------------------------------------------------------------
*/
#ifndef __DIRUTILS_DIRUTILS_H
#define __DIRUTILS_DIRUTILS_H
#include <sys/queue.h>
#include <dirent.h>
#include <stdio.h>
enum E_EXISTS_STATUS {
EXISTS_ERROR,
EXISTS_NOENT,
EXISTS_NOPERM,
EXISTS_DIR,
EXISTS_FILE,
EXISTS_OTHER
};
typedef enum E_EXISTS_STATUS EXISTS_STATUS;
typedef int (*dirwalk_action)(const char *);
extern const unsigned char FT_ANY;
extern const unsigned char FT_STD;
extern const unsigned char FT_NODESCEND;
int makedirs(const char *);
int rmdirs(const char *);
EXISTS_STATUS path_exists(const char *);
int walkdir(const char *, dirwalk_action, unsigned char);
#endif

51
src/kst/iniparser.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2015 Kyle Isom <kyle@tyrfingr.is>
*
* 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.
*/
#ifndef __LIBINIPARSER_INIPARSER_H
#define __LIBINIPARSER_INIPARSER_H
typedef struct {
FILE *source;
char *lineptr;
size_t linelen;
ssize_t readlen;
} iniparser_file_s;
typedef struct {
uint8_t is_section;
uint8_t is_set;
char *name;
char *value;
} iniparser_line_s;
int iniparser_init(void);
void iniparser_destroy(void);
int iniparser_open(const char *, iniparser_file_s **);
int iniparser_close(iniparser_file_s *);
int iniparser_readline(iniparser_file_s *, iniparser_line_s *);
void iniparser_line_init(iniparser_line_s *);
void iniparser_line_destroy(iniparser_line_s *);
#endif