34 Free(section->section_name);
49 char** split_result = NULL;
55 int fd = open(filename, O_RDONLY);
68 n_log(
LOG_ERR,
"fdopen failed for %s (fd=%d): %s",
_str(filename), fd, strerror(errno));
82 if (!cfg_file->sections) {
88 cfg_file->filename = strdup(filename);
89 if (!cfg_file->filename) {
100 if (!default_section) {
109 default_section->section_name = strdup(
"__DEFAULT__");
110 if (!default_section->section_name) {
111 n_log(
LOG_ERR,
"couldn't allocate default_section name");
114 Free(default_section);
121 if (!default_section->entries) {
124 Free(default_section->section_name);
125 Free(default_section);
133 size_t line_number = 0;
137 char* bufptr = (
char*)&buffer;
141 if (strlen(bufptr) == 0) {
154 if (
skipu(bufptr,
']', &end, 1) != TRUE) {
155 n_log(
LOG_ERR,
"coulnd't find end of section at line %zu of %s (string:%s)", line_number, filename, buffer);
161 bufptr[end - 1] =
'\0';
163 if (strlen(bufptr) == 0) {
164 n_log(
LOG_ERR,
"section without name at line %zu", line_number);
172 section->section_name = strdup(bufptr);
173 if (!section->section_name) {
180 if (!section->entries) {
191 section = default_section;
192 n_log(
LOG_DEBUG,
"No section, setting __DEFAULT__ starting line %zu of %s (string:%s)", line_number, filename, bufptr);
196 Malloc(split_result,
char*, 3);
198 split_result[2] = NULL;
200 split_result[1] = strdup(npcre->
match_list[2]);
206 n_log(
LOG_ERR,
"couldn't find entry separator '=' at line %zu of %s (string:%s)", line_number, filename, bufptr);
211 n_log(
LOG_ERR,
"Invalid split count at line %zu of %s (string:%s, count:%d)", line_number, filename, bufptr,
split_count(split_result));
218 n_log(
LOG_ERR,
"couldn't find entry name at line %zu of %s (string:%s)", line_number, filename, buffer[start]);
226 int closing_delimiter_found = 0;
227 int opening_delimiter_found = 0;
229 char delimiter =
'\0';
234 Free(split_result[1]);
240 size_t it = strlen(valptr);
245 if (split_result[1][it] ==
';' || split_result[1][it] ==
'#') {
246 split_result[1][it] =
'\0';
249 if (split_result[1][it] ==
'"' || split_result[1][it] ==
'\'') {
250 delimiter = split_result[1][it];
251 split_result[1][it] =
'\0';
252 closing_delimiter_found = 1;
263 Free(split_result[1]);
270 while (split_result[1][it] !=
'\0') {
271 if (split_result[1][it] ==
';' || split_result[1][it] ==
'#') {
272 split_result[1][it] =
'\0';
274 if (delimiter !=
'\0' && split_result[1][it] == delimiter) {
275 opening_delimiter_found = 1;
277 valptr = split_result[1] + it;
284 Free(split_result[1]);
289 if (delimiter !=
'\0' && ((opening_delimiter_found && !closing_delimiter_found) || (!opening_delimiter_found && closing_delimiter_found))) {
291 n_log(
LOG_ERR,
"Only one delimiter found at line %zu of %s (string:%s)", line_number, filename, buffer);
297 N_STR* entry_key = NULL;
298 size_t nb_entry_in_sections = 0;
301 if (
ht_get_ptr(section->entries,
_nstr(entry_key), (
void**)&result) == FALSE) {
304 nb_entry_in_sections++;
309 strptr = strdup(valptr);
338 int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600);
341 n_log(
LOG_ERR,
"Unable to open '%s' for writing (0600): %s",
_str(filename), strerror(error));
346 out = fdopen(fd,
"w");
349 n_log(
LOG_ERR,
"fdopen failed for '%s' (fd=%d): %s",
_str(filename), fd, strerror(error));
354 char* last_section = NULL;
355 char *section = NULL, *key = NULL, *val = NULL;
359 if (!last_section || strcmp(last_section, section) != 0) {
360 fprintf(out,
"[%s]\n", section);
362 last_section = strdup(section);
364 fprintf(out,
"%s=%s\n", key, val);
383 size_t nb_sections = 0;
387 if (!strcmp(section->section_name, section_name)) {
411 size_t nb_sections = 0;
412 size_t nb_entry_in_sections = 0;
415 if (!strcmp(section->section_name, section_name)) {
416 if (nb_sections == section_position) {
418 N_STR* entry_key = NULL;
420 nstrprintf(entry_key,
"%s%zu", entry, nb_entry_in_sections);
421 if (
ht_get_ptr(section->entries,
_nstr(entry_key), (
void**)&result) == FALSE) {
425 nb_entry_in_sections++;
433 return nb_entry_in_sections;
451 if (section_position >= cfg_file->sections->
nb_items) {
452 n_log(
LOG_DEBUG,
"section_position (%d) is higher than the number of item in list (%d)", section_position, cfg_file->sections->
nb_items);
456 size_t section_position_it = 0;
460 if (!strcmp(section->section_name, section_name)) {
461 if (section_position_it == section_position) {
462 entries = section->entries;
465 section_position_it++;
470 N_STR* entry_key = NULL;
471 nstrprintf(entry_key,
"%s%zu", entry, entry_position);
488 __n_assert(cfg_file && (*cfg_file),
return FALSE);
490 Free((*cfg_file)->filename);
492 if ((*cfg_file)->sections) {
#define FreeNoLog(__ptr)
Free Handler without log.
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define _str(__PTR)
define true
#define Free(__ptr)
Free Handler to get errors.
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
CONFIG_FILE * load_config_file(char *filename, int *errors)
load a config file
int write_config_file(CONFIG_FILE *cfg_file, char *filename)
write a config file
size_t get_nb_config_file_sections_entries(CONFIG_FILE *cfg_file, char *section_name, size_t section_position, char *entry)
Get the number of config file with section_name.
#define config_endfor
Foreach elements of CONFIG_FILE macro END.
#define CONFIG_SECTION_HASH_TABLE_LEN
size of the hash table of config sections entries
int destroy_config_file(CONFIG_FILE **cfg_file)
Destroy a loaded config file.
#define MAX_CONFIG_LINE_LEN
maximum length of a single config line
char * get_config_section_value(CONFIG_FILE *cfg_file, char *section_name, size_t section_position, char *entry, size_t entry_position)
Function to parse sections and get entries values.
#define config_foreach(__config, __section_name, __key, __val)
Foreach elements of CONFIG_FILE macro, i.e config_foreach( config , section , key ,...
size_t get_nb_config_file_sections(CONFIG_FILE *cfg_file, char *section_name)
Get the number of config file with section_name.
Structure of a config file.
Structure of a config section.
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get pointer at 'key' from 'table'
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr))
put a pointer to the string value with given key in the targeted hash table
structure of a hash table
size_t nb_items
number of item currently in the list
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper.
int list_destroy(LIST **list)
Empty and Free a list container.
#define MAX_LIST_ITEMS
flag to pass to new_generic_list for the maximum possible number of item in a list
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
char * trim_nocopy(char *s)
trim and zero end the string, WARNING: keep and original pointer to delete the string correctly
size_t NSTRBYTE
N_STR base unit.
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
int split_count(char **split_result)
Count split elements.
char * str_replace(const char *string, const char *substr, const char *replacement)
Replace "substr" by "replacement" inside string taken from http://coding.debuntu.org/c-implementing-s...
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
int free_split_result(char ***tab)
Free a split result allocated array.
int skipu(char *string, char toskip, NSTRBYTE *iterator, int inc)
skip until 'toskip' occurence is found from 'iterator' to the next 'toskip' value.
A box including a string and his lenght.
const char ** match_list
populated match list if nPcreCapMatch is called
N_PCRE * npcre_new(char *str, int max_cap, int flags)
From pcre doc, the flag bits are: PCRE_ANCHORED Force pattern anchoring PCRE_AUTO_CALLOUT Compile aut...
int npcre_match(char *str, N_PCRE *pcre)
Return TRUE if str matches regexp, and make captures up to max_cap.
int npcre_delete(N_PCRE **pcre)
Free a N_PCRE pointer.
Common headers and low-level functions & define.
void free_no_null(void *ptr)
local free for config entries
void destroy_config_file_section(void *ptr)
Destroy a config file section.
Config file reading and writing.
PCRE helpers for regex matching.