view ini.h @ 142:e3cf5ac9a5aa

[p]array_insert now returns -1 or index of added element
author David Demelier <markand@malikania.fr>
date Tue, 08 May 2012 15:02:17 +0200
parents 07800b7af208
children 0cf53c588a83
line wrap: on
line source

/*
 * ini.h -- parse .ini like files
 *
 * Copyright (c) 2011, 2012, David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or 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 _INI_H_
#define _INI_H_

#ifdef __cplusplus
extern "C" {
#endif

#define	INI_VERBOSE	(1 << 0)	/* be verbose */
#define	INI_NOREDEFINE	(1 << 1)	/* do not allow redefinitions */
#define INI_FAILERROR	(1 << 2)	/* abort parsing on first error */

typedef struct ini_config	INI_Config;
typedef struct ini_section	INI_Section;
typedef struct ini_option	INI_Option;
typedef struct ini_handler	INI_Handler;

typedef void (*INI_ConvertFunc)(void *, const char *, void *);

#if !defined(LIST_ENTRY)
#define LIST_ENTRY(type)						\
struct {								\
	struct type *le_next;						\
	struct type **le_prev;						\
}
#endif

#if !define(LIST_HEAD)
#define LIST_HEAD(name, type)						\
struct name {								\
	struct type *lh_first;
}

/* --------------------------------------------------------
 * Structure definitions
 * -------------------------------------------------------- */

struct ini_config {
	/*
	 * General settings
	 */
	const char	*path;		/* (ro) file path */
	int		flags;		/* (ro) optional flags */

	/*
	 * Sections that have been parsed
	 */
	INI_Section	*sections;	/* (ro) linked-list of sections */

	/* Private fields */
	INI_Section	*ic_current;	/* current working section */
	char		*ic_line;	/* line buffer */
	int		ic_lineno;	/* number of current line */
	int		ic_linesize;	/* initial line size */
	int		ic_ignore;	/* must ignore (no redefine) */
};

struct ini_option {
	char		*key;		/* (rw) option name */
	char		*value;		/* (rw) option value */

	LIST_ENTRY(ini_option) link;	/* (rw) link entry */
};

struct ini_section {
	char		*key;		/* (rw) section key */	
	INI_Option	*options;	/* (ro) linked-list of options */
	INI_Section	*next;		/* (ro) linked-list of sections */
};

struct ini_handler {
	char		*key;		/* (rw) option to check */
	void		*dst;		/* (rw) where to store */
	INI_ConvertFunc	handler;	/* (rw) conversion function */
	void		*userdata;	/* (rw) optional user data */
};

/* --------------------------------------------------------
 * Main functions
 * -------------------------------------------------------- */

INI_Config *
ini_load(const char *, int);

INI_Section *
ini_select_section(const INI_Config *, const char *);

INI_Option *
ini_select_option(const INI_Section *, const char *);

INI_Option *
ini_find(const INI_Config *, const char *, const char *);

char *
ini_get_error(void);

void
ini_free(INI_Config *, int, int);

/* --------------------------------------------------------
 * Convenient api to query and convert data
 * -------------------------------------------------------- */

/*
 * For the config, read all available values and store them in
 * the array ini_handler.
 */

void
ini_dispatch(INI_Section *, INI_Handler *, int);

/*
 * Convert to bool. dst must be (char *).
 * It converts "yes" "true" "1" or opposites. Only lower
 * case is supported right now.
 */

void
ini_convert_bool(void *, const char *, void *);

/*
 * Convert to an int. dst must be (int *).
 */

void
ini_convert_int(void *, const char *, void *);

/*
 * Convert to a short. dst must be (short *).
 */

void
ini_convert_short(void *, const char *, void *);

/*
 * Convert to a char *. dst must be (char **). This
 * function uses strdup(). You need to free the dst
 * pointer.
 */

void
ini_convert_string(void *, const char *, void *);

#ifdef __cplusplus
}
#endif

#endif /* _INI_H_ */