File: dotconf.h

package info (click to toggle)
dotconf 1.3-0.3
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 492 kB
  • sloc: ansic: 2,256; makefile: 187; sh: 39
file content (239 lines) | stat: -rw-r--r-- 9,730 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#ifndef DOTCONF_H
#define DOTCONF_H

#ifdef __cplusplus
extern "C" {
#endif

/* stdio.h should be included by the application - as the manual page says */
#ifndef _STDIO_H
#include <stdio.h>		/* needed for FILE* */
#endif

#ifdef WIN32
# ifndef R_OK
#define R_OK 0
# endif
#endif

/* some buffersize definitions */
#define CFG_BUFSIZE 4096	/* max length of one line */
#define CFG_MAX_OPTION 32	/* max length of any option name */
#define CFG_MAX_VALUE 4064	/* max length of any options value */
#define CFG_MAX_FILENAME 256	/* max length of a filename */
#define CFG_VALUES 16		/* max # of arguments an option takes */

#define CFG_INCLUDEPATH_ENV "DC_INCLUDEPATH"
#define WILDCARDS	"*?"	/* list of supported wild-card characters */

/* constants for type of option */
#define ARG_TOGGLE    0		/* TOGGLE on,off; yes,no; 1, 0; */
#define ARG_INT       1		/* callback wants an integer */
#define ARG_DOUBLE    7		/* callback wants a float / double */
#define ARG_STR       2		/* callback expects a \0 terminated str */
#define ARG_LIST      3		/* wants list of strings */
#define ARG_NAME      4		/* wants option name plus ARG_LIST stuff */
#define ARG_RAW       5		/* wants raw argument data */
#define ARG_NONE      6		/* does not expect ANY args */

#define CTX_ALL       0		/* context: option can be used anywhere */

/* for convenience of terminating the dotconf_options list */
#define LAST_OPTION						{ "", 0, NULL, NULL    }
#define LAST_CONTEXT_OPTION				{ "", 0, NULL, NULL, 0 }

#define DOTCONF_CB(__name)     const char *__name(command_t *cmd,             \
                                                  context_t *ctx)
#define FUNC_ERRORHANDLER(_name) int _name(configfile_t * configfile,		  \
											int type, long dc_errno, const char *msg)

/* some flags that change the runtime behaviour of dotconf */
#define NONE 0
#define CASE_INSENSITIVE 1<<0	/* match option names case insensitive */
#define DONT_SUBSTITUTE 1<<1	/* do not call substitute_env after read_arg */
#define NO_INLINE_COMMENTS 1<<2	/* do not allow inline comments */
#define DUPLICATE_OPTION_NAMES 1<<3	/* allow for duplicate option names */

/* syslog style errors as suggested by Sander Steffann <sander@steffann.nl> */
#ifdef HAVE_SYSLOG
#include <syslog.h>

#define DCLOG_EMERG		LOG_EMERG	/* system is unusable */
#define DCLOG_ALERT		LOG_ALERT	/* action must be taken immediately */
#define DCLOG_CRIT		LOG_CRIT	/* critical conditions */
#define DCLOG_ERR		LOG_ERR	/* error conditions */
#define DCLOG_WARNING	LOG_WARNING	/* warning conditions */
#define DCLOG_NOTICE	LOG_NOTICE	/* normal but significant condition */
#define DCLOG_INFO		LOG_INFO	/* informational */
#define DCLOG_DEBUG		LOG_DEBUG	/* debug-level messages */

#define DCLOG_LEVELMASK	LOG_PRIMASK	/* mask off the level value */

#else				/* HAVE_SYSLOG */

#define DCLOG_EMERG     0	/* system is unusable */
#define DCLOG_ALERT     1	/* action must be taken immediately */
#define DCLOG_CRIT      2	/* critical conditions */
#define DCLOG_ERR       3	/* error conditions */
#define DCLOG_WARNING   4	/* warning conditions */
#define DCLOG_NOTICE    5	/* normal but significant condition */
#define DCLOG_INFO      6	/* informational */
#define DCLOG_DEBUG     7	/* debug-level messages */

#define DCLOG_LEVELMASK 7	/* mask off the level value */

#endif				/* HAVE_SYSLOG */

/* callback types for dotconf_callback */

/* error constants */
#define ERR_NOERROR                0x0000
#define ERR_PARSE_ERROR            0x0001
#define ERR_UNKNOWN_OPTION         0x0002
#define ERR_WRONG_ARG_COUNT        0x0003
#define ERR_INCLUDE_ERROR          0x0004
#define ERR_NOACCESS               0x0005
#define ERR_USER                   0x1000	/* base for userdefined errno's */

/* i needed this to check an ARG_LIST entry if it's toggled in one of my apps; maybe you do too */
#define CFG_TOGGLED(_val) ( (_val[0] == 'Y'                                \
                             || _val[0] == 'y')                            \
                             || (_val[0] == '1')                           \
                             || ((_val[0] == 'o'                           \
                                 || _val[0] == 'O')                        \
                                && (_val[1] == 'n'                         \
                                    || _val[1] == 'N')))

	enum callback_types {
		ERROR_HANDLER = 1,
		CONTEXT_CHECKER
	};

	typedef enum callback_types callback_types;
	typedef struct configfile_t configfile_t;
	typedef struct configoption_t configoption_t;
	typedef struct configoption_t ConfigOption;
	typedef struct command_t command_t;
	typedef void context_t;
	typedef void info_t;

	typedef const char *(*dotconf_callback_t) (command_t *, context_t *);
	typedef int (*dotconf_errorhandler_t) (configfile_t *, int,
					       unsigned long, const char *);
	typedef const char *(*dotconf_contextchecker_t) (command_t *,
							 unsigned long);

	struct configfile_t {
		/* ------ the fields in configfile_t are provided to the app via command_t's ; READ ONLY! --- */

		FILE *stream;
		char eof;	/* end of file reached ? */
		size_t size;	/* file size; cached on-demand for here-documents */

		context_t *context;

		configoption_t const **config_options;
		int config_option_count;

		/* ------ misc read-only fields ------------------------------------------------------------- */
		char *filename;	/* name of file this option was found in */
		unsigned long line;	/* line number we're currently at */
		unsigned long flags;	/* runtime flags given to dotconf_open */

		char *includepath;

		/* ------ some callbacks for interactivity -------------------------------------------------- */
		dotconf_errorhandler_t errorhandler;
		dotconf_contextchecker_t contextchecker;

		int (*cmp_func) (const char *, const char *, size_t);
	};

	struct configoption_t {
		const char *name;	/* name of configuration option */
		int type;	/* for possible values, see above */
		dotconf_callback_t callback;	/* callback function */
		info_t *info;	/* additional info for multi-option callbacks */
		unsigned long context;	/* context sensitivity flags */
	};

	struct command_t {
		const char *name;	/* name of the command */
		configoption_t *option;	/* the option as given in the app; READ ONLY */

		/* ------ misc context information ---------------------------------------------------------- */
		configfile_t *configfile;
		context_t *context;

		/* ------ argument data filled in for each line / command ----------------------------------- */
		int arg_count;	/* number of arguments (in data.list) */
		struct {
			long value;	/* ARG_INT, ARG_TOGGLE */
			char *str;	/* ARG_STR */
			char **list;	/* ARG_LIST */
			double dvalue;	/* ARG_DOUBLE */
		} data;
	};

/* ------ dotconf_create() - create the configfile_t needed for further dot.conf fun ------------ */
	configfile_t *dotconf_create(char *, const configoption_t *,
				     context_t *, unsigned long);

/* ------ dotconf_cleanup() - tidy up behind dotconf_create and the parser dust ----------------- */
	void dotconf_cleanup(configfile_t * configfile);

/* ------ dotconf_command_loop() - iterate through each line of file and handle the commands ---- */
	int dotconf_command_loop(configfile_t * configfile);

/* ------ dotconf_command_loop_until_error() - like continue_line but return on the first error - */
	const char *dotconf_command_loop_until_error(configfile_t * configfile);

/* ------ dotconf_continue_line() - check if line continuation is to be handled ----------------- */
	int dotconf_continue_line(char *buffer, size_t length);

/* ------ dotconf_get_next_line() - read in the next line of the configfile_t ------------------- */
	int dotconf_get_next_line(char *buffer, size_t bufsize,
				  configfile_t * configfile);

/* ------ dotconf_get_here_document() - read the here document until delimit is found ----------- */
	char *dotconf_get_here_document(configfile_t * configfile,
					const char *delimit);

/* ------ dotconf_invoke_command() - call the callback for command_t ---------------------------- */
	const char *dotconf_invoke_command(configfile_t * configfile,
					   command_t * cmd);

/* ------ dotconf_find_command() - iterate through all registered options trying to match ------- */
	configoption_t *dotconf_find_command(configfile_t * configfile,
					     const char *command);

/* ------ dotconf_read_arg() - read one argument from the line handling quoting and escaping ---- */
/*
	side effects: the char* returned by dotconf_read_arg is malloc() before, hence that pointer
                  will have to be free()ed later.
*/
	char *dotconf_read_arg(configfile_t * configfile, signed char **line);

/* ------ dotconf_handle_command() - parse, substitute, find, invoke the command found in buffer  */
	const char *dotconf_handle_command(configfile_t * configfile,
					   char *buffer);

/* ------ dotconf_register_option() - add a new option table to the list of commands ------------ */
	int dotconf_register_options(configfile_t * configfile,
				     const configoption_t * options);

/* ------ dotconf_warning() - handle the dispatch of error messages of various levels ----------- */
	int dotconf_warning(configfile_t * configfile, int level,
			    unsigned long errnum, const char *, ...);

/* ------ dotconf_callback() - register a special callback -------------------------------------- */
	void dotconf_callback(configfile_t * configfile, callback_types type,
			      dotconf_callback_t);

/* ------ dotconf_substitute_env() - handle the substitution on environment variables ----------- */
	char *dotconf_substitute_env(configfile_t *, char *);

#ifdef __cplusplus
}				/* extern "C" */
#endif
#endif				/* DOTCONF_H */