1.\" Copyright (c) 2013-2018 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.Dd March 13, 2018 26.Dt FIGPAR 3 27.Os 28.Sh NAME 29.Nm figpar , 30.Nm parse_config , 31.Nm get_config_option 32.Nd configuration file parsing library 33.Sh LIBRARY 34.Lb libfigpar 35.Sh SYNOPSIS 36.In figpar.h 37.Ft int 38.Fo parse_config 39.Fa "struct figpar_config options[]" 40.Fa "const char *path" 41.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct figpar_config *option" 42.Fa "uint32_t line" 43.Fa "char *directive" 44.Fa "char *value\*[rp]" 45.Fa "uint8_t processing_options" 46.Fc 47.Ft "struct figpar_config *" 48.Fo get_config_option 49.Fa "struct figpar_config options[]" 50.Fa "const char *directive" 51.Fc 52.In string_m.h 53.Ft int 54.Fo replaceall 55.Fa "char *source" 56.Fa "const char *find" 57.Fa "const char *replace" 58.Fc 59.Ft unsigned int 60.Fo strcount 61.Fa "const char *source" 62.Fa "const char *find" 63.Fc 64.Ft void 65.Fo strexpand 66.Fa "char *source" 67.Fc 68.Ft void 69.Fo strexpandnl 70.Fa "char *source" 71.Fc 72.Ft void 73.Fo strtolower 74.Fa "char *source" 75.Fc 76.Sh DESCRIPTION 77The 78.Nm 79library provides a light-weight, 80portable framework for parsing configuration 81files. 82The library uses 83.Xr open 2 , 84.Xr read 2 , 85and 86.Xr lseek 2 87within the file pointed to by 88.Fa path 89to find directives and values which are then made available to the application. 90.Pp 91Due to the fact that configuration files may have basic syntax differences, 92the library does not attempt to impose any structure on the data but instead 93provides raw data to a set of callback functions. 94These callback functions can in-turn initiate abort through their return value, 95allowing custom syntax validation during parsing. 96.Pp 97Configuration directives, 98types, 99and callback functions are provided through data structures defined in 100.In figpar.h : 101.Bd -literal -offset indent 102struct figpar_config { 103 enum figpar_cfgtype type; /* value type */ 104 const char *directive; /* keyword */ 105 union figpar_cfgvalue value; /* value */ 106 107 /* Pointer to function used when directive is found */ 108 int (*action)(struct figpar_config *option, uint32_t line, 109 char *directive, char *value); 110}; 111 112enum figpar_cfgtype { 113 FIGPAR_TYPE_NONE = 0x0000, /* directives with no value */ 114 FIGPAR_TYPE_BOOL = 0x0001, /* boolean */ 115 FIGPAR_TYPE_INT = 0x0002, /* signed 32 bit integer */ 116 FIGPAR_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ 117 FIGPAR_TYPE_STR = 0x0008, /* string pointer */ 118 FIGPAR_TYPE_STRARRAY = 0x0010, /* string array pointer */ 119 FIGPAR_TYPE_DATA1 = 0x0020, /* void data type-1 (open) */ 120 FIGPAR_TYPE_DATA2 = 0x0040, /* void data type-2 (open) */ 121 FIGPAR_TYPE_DATA3 = 0x0080, /* void data type-3 (open) */ 122 FIGPAR_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 */ 123 FIGPAR_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 */ 124 FIGPAR_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 */ 125}; 126 127union figpar_cfgvalue { 128 void *data; /* Pointer to NUL-terminated string */ 129 char *str; /* Pointer to NUL-terminated string */ 130 char **strarray; /* Pointer to an array of strings */ 131 int32_t num; /* Signed 32-bit integer value */ 132 uint32_t u_num; /* Unsigned 32-bit integer value */ 133 uint32_t boolean:1; /* Boolean integer value (0 or 1) */ 134}; 135.Ed 136.Pp 137The 138.Fa processing_options 139argument to 140.Fn parse_config 141is a mask of bit fields which indicate various 142processing options. 143The possible flags are: 144.Bl -tag -width FIGPAR_BREAK_ON_SEMICOLON 145.It Dv FIGPAR_BREAK_ON_EQUALS 146An equals sign 147.Pq Ql Li = 148is normally considered part of the directive. 149This flag enables terminating the directive at the equals sign. 150Also makes equals sign optional and transient. 151.It Dv FIGPAR_BREAK_ON_SEMICOLON 152A semicolon 153.Pq Ql Li \; 154is normally considered part of the value. 155This flag enables terminating the value at the semicolon. 156Also allows multiple statements on a single line separated by semicolon. 157.It Dv FIGPAR_CASE_SENSITIVE 158Normally directives are matched case insensitively using 159.Xr fnmatch 3 . 160This flag enables directive matching to be case sensitive. 161.It Dv FIGPAR_REQUIRE_EQUALS 162If a directive is not followed by an equals, 163processing is aborted. 164.It Dv FIGPAR_STRICT_EQUALS 165Equals must be part of the directive to be considered a delimiter between 166directive and value. 167.El 168.Pp 169The 170.Fa options 171struct array pointer can be NULL and every directive will run the 172.Fn unknown 173function argument. 174.Pp 175The directive for each figpar_config item in the 176.Fn parse_config 177options argument is matched against each parsed directive using 178.Xr fnmatch 3 179until a match is found. 180If a match is found, 181the 182.Fn action 183function for that figpar_config directive is run with the line number, 184directive, 185and value. 186Otherwise if no match, 187the 188.Fn unknown 189function is run 190.Pq with the same arguments . 191.Pp 192If either 193.Fa action 194or 195.Fa unknown 196return non-zero, 197.Fn parse_config 198aborts reading the file and returns the error value to its caller. 199.Pp 200.Fn get_config_option 201traverses the options-array and returns the option that matches via 202.Xr strcmp 3 , 203or if no match a pointer to a static dummy struct is returned 204.Pq whose values are all zero or NULL . 205.Pp 206The use of 207.Fa "struct figpar_config" 208is entirely optional as-is the use of 209.Fa "enum figpar_cfgtype" 210or 211.Fa "union figpar_cfgvalue" . 212For example, 213a NULL pointer can be passed to 214.Fn parse_config 215for the first argument while providing a simple 216.Fa unknown 217function based on 218.Xr queue 3 219that populates a singly-linked list of a struct containing the 220.Fa directive 221and 222.Fa value . 223.Pp 224In addition, 225miscellaneous string manipulation routines are provided by 226.In string_m.h : 227.Bl -tag -width strexpandnl() 228.It Fn replaceall 229Replace all occurrences of 230.Fa find 231in 232.Fa source 233with 234.Fa replace . 235.It Fn strcount 236Count the number of occurrences of one string that appear in the 237.Fa source 238string. 239Return value is the total count. 240An example use would be to show how large a block of memory needs to be for a 241.Fn replaceall 242series. 243.It Fn strexpand 244Expand escape sequences in a buffer pointed to by 245.Fa source . 246.It Fn strexpandnl 247Expand only the escaped newlines in a buffer pointed to by 248.Fa source . 249.It Fn strtolower 250Convert a string to lower case. 251.El 252.Sh SEE ALSO 253.Xr queue 3 254.Sh HISTORY 255The 256.Nm 257library first appeared in 258.Fx 10.2 . 259.Sh AUTHORS 260.An Devin Teske Aq dteske@FreeBSD.org 261.Sh BUGS 262This is the first implementation of the library, 263and the interface may be subject to refinement. 264