38 Free( section -> section_name );
56 char **split_result = NULL ;
62 in = fopen( filename,
"r" );
66 n_log(
LOG_ERR,
"Unable to open %s: %s",
_str( filename ), strerror( error ) );
79 if( !cfg_file -> sections )
86 cfg_file -> filename = strdup( filename );
87 if( !cfg_file -> filename )
99 if( !default_section )
109 default_section -> section_name = strdup(
"__DEFAULT__" );
110 if( !default_section -> section_name )
112 n_log(
LOG_ERR,
"couldn't allocate default_section name" );
115 Free( default_section );
122 if( !default_section -> entries )
126 Free( default_section -> section_name );
127 Free( default_section );
135 int line_number = 0 ;
140 char *bufptr = (
char *)&buffer ;
144 if( strlen( bufptr ) == 0 )
149 switch( bufptr[ 0 ] )
159 if(
skipu( bufptr,
']', &end, 1 ) != TRUE )
161 n_log(
LOG_ERR,
"coulnd't find end of section at line %d of %s (string:%s)", line_number, filename, buffer );
167 bufptr[ end - 1 ] =
'\0' ;
169 if( strlen( bufptr ) == 0 )
171 n_log(
LOG_ERR,
"section without name at line %d", line_number );
179 section -> section_name = strdup( bufptr );
180 if( !section -> section_name )
188 if( !section -> entries )
201 section = default_section ;
202 n_log(
LOG_DEBUG,
"No section, setting __DEFAULT__ starting line %d of %s (string:%s)", line_number, filename, bufptr );
207 Malloc( split_result,
char *, 3 );
209 split_result[ 2 ] = NULL ;
210 split_result[ 0 ] =
str_replace( npcre -> match_list[ 1 ],
"=",
" " );
211 split_result[ 1 ] = strdup( npcre -> match_list[ 2 ] );
215 split_result = NULL ;
220 n_log(
LOG_ERR,
"couldn't find entry separator '=' at line %d of %s (string:%s)", line_number, filename, bufptr );
226 n_log(
LOG_ERR,
"Invalid split count at line %d of %s (string:%s, count:%d)", line_number, filename, bufptr,
split_count( split_result ) );
231 if( strlen(
trim_nocopy( split_result[ 0 ] ) ) == 0 )
234 n_log(
LOG_ERR,
"couldn't find entry name at line %d of %s (string:%s)", line_number, filename, buffer[ start ] );
240 char *valptr = NULL ;
242 int closing_delimiter_found = 0 ;
243 int opening_delimiter_found = 0 ;
245 char delimiter =
'\0' ;
249 if( strlen(
trim_nocopy( split_result[ 1 ] ) ) == 0 )
251 Free( split_result[ 1 ] );
258 int it = strlen( valptr );
264 if( split_result[ 1 ][ it ] ==
';' || split_result[ 1 ][ it ] ==
'#' )
266 split_result[ 1 ][ it ] =
'\0' ;
271 if( split_result[ 1 ][ it ] ==
'"' || split_result[ 1 ][ it ] ==
'\'' )
273 delimiter = split_result[ 1 ][ it ] ;
274 split_result[ 1 ][ it ] =
'\0' ;
275 closing_delimiter_found = 1 ;
282 if( strlen(
trim_nocopy( split_result[ 1 ] ) ) == 0 )
284 Free( split_result[ 1 ] );
291 while( split_result[ 1 ][ it ] !=
'\0' )
293 if( split_result[ 1 ][ it ] ==
';' || split_result[ 1 ][ it ] ==
'#' )
295 split_result[ 1 ][ it ] =
'\0' ;
299 if( delimiter !=
'\0' && split_result[ 1 ][ it ] == delimiter )
301 opening_delimiter_found = 1 ;
303 valptr = split_result[ 1 ]+ it ;
309 if( strlen(
trim_nocopy( split_result[ 1 ] ) ) == 0 )
311 Free( split_result[ 1 ] );
316 if( delimiter !=
'\0' && ( ( opening_delimiter_found && !closing_delimiter_found ) || ( !opening_delimiter_found && closing_delimiter_found ) ) )
319 n_log(
LOG_ERR,
"Only one delimiter found at line %d of %s (string:%s)", line_number, filename, buffer );
324 char *result = NULL ;
325 N_STR *entry_key = NULL ;
326 int nb_entry_in_sections = 0 ;
330 if(
ht_get_ptr( section -> entries,
_nstr( entry_key ), (
void **)&result ) == FALSE )
334 nb_entry_in_sections ++ ;
337 char *strptr = NULL ;
340 strptr = strdup( valptr );
374 out = fopen( filename,
"w" );
378 char *last_section = NULL ;
379 char *section = NULL, *key = NULL, *val = NULL ;
384 if( !last_section || strcmp( last_section, section ) != 0 )
386 fprintf( out,
"[%s]\n", section );
388 last_section = strdup( section );
390 fprintf( out,
"%s=%s\n", key, val );
411 __n_assert( cfg_file -> sections,
return -2 );
413 int nb_sections = 0 ;
419 if( !strcmp( section -> section_name, section_name ) )
445 __n_assert( cfg_file -> sections,
return -2 );
449 int nb_sections = 0 ;
450 int nb_entry_in_sections = 0 ;
454 if( !strcmp( section -> section_name, section_name ) )
456 if( nb_sections == section_position )
458 char *result = NULL ;
459 N_STR *entry_key = NULL ;
462 nstrprintf( entry_key,
"%s%d", entry, nb_entry_in_sections );
463 if(
ht_get_ptr( section -> entries,
_nstr( entry_key ), (
void **)&result ) == FALSE )
468 nb_entry_in_sections ++ ;
476 return nb_entry_in_sections ;
493 __n_assert( cfg_file -> sections,
return NULL );
497 if( section_position >= cfg_file -> sections -> nb_items )
499 n_log(
LOG_DEBUG,
"section_position (%d) is higher than the number of item in list (%d)", section_position, cfg_file -> sections -> nb_items );
503 int section_position_it = 0 ;
508 if( !strcmp( section -> section_name, section_name ) )
510 if( section_position_it == section_position )
512 entries = section -> entries ;
515 section_position_it ++ ;
519 char *result = NULL ;
520 N_STR *entry_key = NULL ;
521 nstrprintf( entry_key,
"%s%d", entry, entry_position );
522 if(
ht_get_ptr( entries,
_nstr( entry_key ), (
void **)&result ) == FALSE )
542 __n_assert( cfg_file&&(*cfg_file),
return FALSE );
544 Free( (*cfg_file) -> filename );
546 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
char * get_config_section_value(CONFIG_FILE *cfg_file, char *section_name, int section_position, char *entry, int entry_position)
Function to parse sections and get entries values.
#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
#define config_foreach(__config, __section_name, __key, __val)
Foreach elements of CONFIG_FILE macro, i.e config_foreach( config , section , key ,...
int get_nb_config_file_sections(CONFIG_FILE *cfg_file, char *section_name)
Get the number of config file with section_name.
int get_nb_config_file_sections_entries(CONFIG_FILE *cfg_file, char *section_name, int section_position, char *entry)
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
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.
LIST * new_generic_list(int max_items)
Initialiaze a generic list container to max_items pointers.
#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.
#define nstrprintf(__nstr_var,...)
Macro to quickly allocate and sprintf to N_STR *.
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...
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.
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 hugly 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.