xref: /freebsd/lib/libfigpar/figpar.3 (revision ff0ba87247820afbdfdc1b307c803f7923d0e4d3)
1.\" Copyright (c) 2013-2014 Devin Teske <dteske@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd Oct 24, 2014
28.Dt FIGPAR 3
29.Os
30.Sh NAME
31.Nm figpar ,
32.Nm parse_config ,
33.Nm get_config_option
34.Nd configuration file parsing library
35.Sh LIBRARY
36.Lb libfigpar
37.Sh SYNOPSIS
38.In figpar.h
39.Ft int
40.Fo parse_config
41.Fa "struct fp_config options[], const char *path"
42.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct fp_config *option, uint32_t line"
43.Fa "char *directive, char *value\*[rp], uint8_t processing_options"
44.Fc
45.Ft "struct fp_config *"
46.Fo get_config_option
47.Fa "struct fp_config options[], const char *directive"
48.Fc
49.In string_m.h
50.Ft int
51.Fo replaceall
52.Fa "char *source, const char *find, const char *replace"
53.Fc
54.Ft unsigned int
55.Fo strcount
56.Fa "const char *source, const char *find"
57.Fc
58.Ft void
59.Fo strexpand
60.Fa "char *source"
61.Fc
62.Ft void
63.Fo strexpandnl
64.Fa "char *source"
65.Fc
66.Ft void
67.Fo strtolower
68.Fa "char *source"
69.Fc
70.Sh DESCRIPTION
71The
72.Nm
73library provides a light-weight, portable framework for parsing configuration
74files.
75The library uses
76.Xr open 2 ,
77.Xr read 2 ,
78and
79.Xr lseek 2
80within the file pointed to by
81.Fa path
82to find directives and values which are then made available to the application.
83.Pp
84Due to the fact that configuration files may have basic syntax differences,
85the library does not attempt to impose any structure on the data but instead
86provides raw data to a set of callback functions.
87These callback functions can in-turn initiate abort through their return value,
88allowing custom syntax validation during parsing.
89.Pp
90Configuration directives, types, and callback functions are provided through
91data structures defined in
92.In figpar.h :
93.Bd -literal -offset indent
94struct fp_config {
95    enum fp_cfgtype	type;		/* value type */
96    const char		*directive;	/* keyword */
97    union fp_cfgvalue	value;		/* value */
98
99    /* Pointer to function used when directive is found */
100    int (*action)(struct fp_config *option, uint32_t line,
101        char *directive, char *value);
102};
103
104enum fp_cfgtype {
105    FP_TYPE_NONE      = 0x0000, /* for directives with no value */
106    FP_TYPE_BOOL      = 0x0001, /* boolean */
107    FP_TYPE_INT       = 0x0002, /* signed 32 bit integer */
108    FP_TYPE_UINT      = 0x0004, /* unsigned 32 bit integer */
109    FP_TYPE_STR       = 0x0008, /* string pointer */
110    FP_TYPE_STRARRAY  = 0x0010, /* string array pointer */
111    FP_TYPE_DATA1     = 0x0020, /* void data type-1 (whatever) */
112    FP_TYPE_DATA2     = 0x0040, /* void data type-2 (whatever) */
113    FP_TYPE_DATA3     = 0x0080, /* void data type-3 (whatever) */
114    FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */
115    FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */
116    FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */
117};
118
119union fp_cfgvalue {
120    void	*data;      /* Pointer to NUL-terminated string */
121    char	*str;       /* Pointer to NUL-terminated string */
122    char	**strarray; /* Pointer to an array of strings */
123    int32_t	num;        /* Signed 32-bit integer value */
124    uint32_t	u_num;      /* Unsigned 32-bit integer value */
125    uint32_t	boolean:1;  /* Boolean integer value (0 or 1) */
126};
127.Ed
128.Pp
129The
130.Fa processing_options
131argument to
132.Fn parse_config
133is a mask of bit fields which indicate various
134processing options.
135The possible flags are as follows:
136.Bl -tag -width FP_BREAK_ON_SEMICOLON
137.It Dv FP_BREAK_ON_EQUALS
138An equals sign
139.Pq Ql Li =
140is normally considered part of the directive.
141This flag enables terminating the directive at the equals sign.
142Also makes equals sign optional and transient.
143.It Dv FP_BREAK_ON_SEMICOLON
144A semicolon
145.Pq Ql Li \;
146is normally considered part of the value.
147This flag enables terminating the value at the semicolon.
148Also allows multiple statements on a single line separated by semicolon.
149.It Dv FP_CASE_SENSITIVE
150Normally directives are matched case insensitively using
151.Xr fnmatch 3 .
152This flag enables directive matching to be case sensitive.
153.It Dv FP_REQUIRE_EQUALS
154If a directive is not followed by an equals, processing is aborted.
155.It Dv FP_STRICT_EQUALS
156Equals must be part of the directive to be considered a delimiter between
157directive and value.
158.El
159.Pp
160The
161.Fa options
162struct array pointer can be NULL and every directive will invoke the
163.Fn unknown
164function argument.
165.Pp
166The directive for each fp_config item in the
167.Fn parse_config
168options argument is matched against each parsed directive using
169.Xr fnmatch 3
170until a match is found.
171If a match is found, the
172.Fn action
173function for that fp_config directive is invoked with the line number,
174directive, and value.
175Otherwise if no match, the
176.Fn unknown
177function is invoked
178.Pq with the same arguments .
179.Pp
180If either
181.Fa action
182or
183.Fa unknown
184return non-zero,
185.Fn parse_config
186aborts reading the file and returns the error value to its caller.
187.Pp
188.Fn get_config_option
189traverses the options-array and returns the option that matches via
190.Xr strcmp 3 ,
191or if no match a pointer to a static dummy struct is returned
192.Pq whose values are all zero or NULL .
193.Pp
194The use of
195.Fa "struct fp_config"
196is entirely optional as-is the use of
197.Fa "enum fp_cfgtype"
198or
199.Fa "union fp_cfgvalue" .
200For example, you could choose to pass a NULL pointer to
201.Fn parse_config
202for the first argument and then provide a simple
203.Fa unknown
204function based on
205.Xr queue 3
206that populates a singly-linked list of your own struct containing the
207.Fa directive
208and
209.Fa value .
210.Pp
211In addition, the following miscellaneous string manipulation routines are
212provided by
213.In string_m.h :
214.Bl -tag -width strexpandnl()
215.It Fn replaceall
216Replace all occurrences of
217.Fa find
218in
219.Fa source
220with
221.Fa replace .
222.It Fn strcount
223Count the number of occurrences of one string that appear in the
224.Fa source
225string.
226Return value is the total count.
227An example use would be if you need to know how large a block of memory needs
228to be for a
229.Fn replaceall
230series.
231.It Fn strexpand
232Expand escape sequences in a buffer pointed to by
233.Fa source .
234.It Fn strexpandnl
235Expand only the escaped newlines in a buffer pointed to by
236.Fa source .
237.It Fn strtolower
238Convert a string to lower case.
239.El
240.Sh SEE ALSO
241.Xr queue 3
242.Sh HISTORY
243The
244.Nm
245library first appeared in
246.Fx 11.0 .
247.Sh AUTHORS
248.An Devin Teske Aq dteske@FreeBSD.org
249.Sh BUGS
250This is the first implementation of the library,
251and the interface may be subject to refinement.
252