1 | .TH CONFIGFILE 3
|
---|
2 | .SH NAME
|
---|
3 | configfile, config_read, config_delete, config_renewed, config_length, config_issub, config_isatom, config_isstring \- generic configuration file functions
|
---|
4 | .SH SYNOPSIS
|
---|
5 | .ft B
|
---|
6 | .nf
|
---|
7 | #include <configfile.h>
|
---|
8 |
|
---|
9 | config_t *config_read(const char *\fIfile\fP, int \fIflags\fP, config_t *\fIcfg\fP)
|
---|
10 | void config_delete(config_t *\fIcfg\fP)
|
---|
11 | int config_renewed(config_t *\fIcfg\fP)
|
---|
12 | size_t config_length(config_t *\fIcfg\fP)
|
---|
13 | int config_issub(config_t *\fIcfg\fP)
|
---|
14 | int config_isatom(config_t *\fIcfg\fP)
|
---|
15 | int config_isstring(config_t *\fIcfg\fP)
|
---|
16 | .fi
|
---|
17 | .ft P
|
---|
18 | .SH DESCRIPTION
|
---|
19 | The
|
---|
20 | .B configfile
|
---|
21 | routines operate on a generic configuration file that follows the syntax
|
---|
22 | described in
|
---|
23 | .BR configfile (5).
|
---|
24 | .PP
|
---|
25 | The interface presented by the functions above uses the following type and
|
---|
26 | definitions from <configfile.h>:
|
---|
27 | .PP
|
---|
28 | .if n .in +2
|
---|
29 | .if t .RS
|
---|
30 | .nf
|
---|
31 | .ta +\w'type'u +\w'const charmm'u +\w'word[];mm'u
|
---|
32 | typedef const struct config {
|
---|
33 | config_t *next; /* Next configuration file thing. */
|
---|
34 | config_t *list; /* For a { sublist }. */
|
---|
35 | const char *file; /* File and line where this is found. */
|
---|
36 | unsigned line;
|
---|
37 | int flags; /* Special flags. */
|
---|
38 | char word[]; /* Payload. */
|
---|
39 | } config_t;
|
---|
40 |
|
---|
41 | .ta +\w'#definem'u +\w'CFG_SUBLISTm'u +\w'0x0000mm'u
|
---|
42 | #define CFG_CLONG 0x0001 /* strtol(word, &end, 0) is valid. */
|
---|
43 | #define CFG_OLONG 0x0002 /* strtol(word, &end, 010). */
|
---|
44 | #define CFG_DLONG 0x0004 /* strtol(word, &end, 10). */
|
---|
45 | #define CFG_XLONG 0x0008 /* strtol(word, &end, 0x10). */
|
---|
46 | #define CFG_CULONG 0x0010 /* strtoul(word, &end, 0). */
|
---|
47 | #define CFG_OULONG 0x0020 /* strtoul(word, &end, 010). */
|
---|
48 | #define CFG_DULONG 0x0040 /* strtoul(word, &end, 10). */
|
---|
49 | #define CFG_XULONG 0x0080 /* strtoul(word, &end, 0x10). */
|
---|
50 | #define CFG_STRING 0x0100 /* The word is enclosed in quotes. */
|
---|
51 | #define CFG_SUBLIST 0x0200 /* This is a sublist, so no word. */
|
---|
52 | #define CFG_ESCAPED 0x0400 /* Escapes are still marked with \e. */
|
---|
53 | .fi
|
---|
54 | .if n .in -2
|
---|
55 | .if t .RE
|
---|
56 | .PP
|
---|
57 | In memory a configuration file is represented as a list of
|
---|
58 | .B config_t
|
---|
59 | cells linked together with the
|
---|
60 | .B next
|
---|
61 | field ending with a null pointer. A sublist between braces is attached to a
|
---|
62 | cell at the
|
---|
63 | .B list
|
---|
64 | field.
|
---|
65 | Words and strings are put in the
|
---|
66 | .B word
|
---|
67 | field, a null terminated string. The
|
---|
68 | .B flags
|
---|
69 | field records the type and features of a cell. The
|
---|
70 | .B CFG_*LONG
|
---|
71 | flags are set if a word is a number according to one of the
|
---|
72 | .B strtol
|
---|
73 | or
|
---|
74 | .B strtoul
|
---|
75 | calls. Purely a number, no quotes or trailing garbage. The
|
---|
76 | .B CFG_STRING
|
---|
77 | flag is set if the object was enclosed in double quotes. Lastly
|
---|
78 | .B CFG_SUBLIST
|
---|
79 | tells if the cell is only a pointer to a sublist in braces.
|
---|
80 | .PP
|
---|
81 | Characters in a word or string may have been formed with the
|
---|
82 | .B \e
|
---|
83 | escape character. They have been parsed and expanded, but the \e is still
|
---|
84 | present if
|
---|
85 | .B CFG_ESCAPED
|
---|
86 | is set. The
|
---|
87 | .B word
|
---|
88 | array may be changed, as long as it doesn't grow longer, so one may remove
|
---|
89 | the \es like this:
|
---|
90 | .PP
|
---|
91 | .RS
|
---|
92 | .ta +4n +4n
|
---|
93 | .nf
|
---|
94 | if (cfg->flags & CFG_ESCAPED) {
|
---|
95 | char *p, *q;
|
---|
96 | p= q= cfg->word;
|
---|
97 | for (;;) {
|
---|
98 | if ((*q = *p) == '\e\e') *q = *++p;
|
---|
99 | if (*q == 0) break;
|
---|
100 | p++;
|
---|
101 | q++;
|
---|
102 | }
|
---|
103 | }
|
---|
104 | .fi
|
---|
105 | .RE
|
---|
106 | .PP
|
---|
107 | The low level syntax of a config file is checked when it is read. If an
|
---|
108 | error is encountered a message is printed and the program exits with exit
|
---|
109 | code 1. What the data means is not checked, that
|
---|
110 | should be done by the program using the data. Only the atom
|
---|
111 | .B include
|
---|
112 | at the beginning of a list is special. It should be followed by a string.
|
---|
113 | The string is seen as the name of a file, that is opened, read, and inserted
|
---|
114 | in place of the
|
---|
115 | .BR include .
|
---|
116 | Unless the name of the file starts with a
|
---|
117 | .BR / ,
|
---|
118 | it is sought relative to the directory the current file is found in.
|
---|
119 | Nonexistent files are treated as being empty.
|
---|
120 | .PP
|
---|
121 | The
|
---|
122 | .B file
|
---|
123 | and
|
---|
124 | .B line
|
---|
125 | fields in each cell tell where the cell was read.
|
---|
126 | .SS Functions
|
---|
127 | A configuration file is read with
|
---|
128 | .BR config_read .
|
---|
129 | The first argument is the file to read. The second is either
|
---|
130 | .B 0
|
---|
131 | or
|
---|
132 | .B CFG_ESCAPED
|
---|
133 | to tell whether \e escapes should be fully expanded without leaving a trace,
|
---|
134 | or if they should still be marked with a \e so that the caller knows where
|
---|
135 | the excapes are.
|
---|
136 | The third argument,
|
---|
137 | .IR cfg ,
|
---|
138 | should be a null pointer on the first call. If you want to reread a config
|
---|
139 | file that may have changed then
|
---|
140 | .I cfg
|
---|
141 | should be what you previously read.
|
---|
142 | .PP
|
---|
143 | With
|
---|
144 | .B config_delete
|
---|
145 | one can free up the memory that has been acquired with
|
---|
146 | .BR malloc (3)
|
---|
147 | to hold the contents of the configuration file.
|
---|
148 | .PP
|
---|
149 | To determine if the contents of configuration file has changed when reread
|
---|
150 | one uses
|
---|
151 | .BR config_renewed
|
---|
152 | after
|
---|
153 | .BR config_read .
|
---|
154 | It returns a "changed" flag that is set when the configuration file changed
|
---|
155 | and then clears that flag. It returns true on the very first call. For the
|
---|
156 | function to work you need to feed the old data back into
|
---|
157 | .BR config_read ,
|
---|
158 | not delete and reread.
|
---|
159 | .PP
|
---|
160 | The length of a series of config structures is told by
|
---|
161 | .BR config_length .
|
---|
162 | It follows the
|
---|
163 | .B next
|
---|
164 | fields, so a sublist between braces counts as one extra.
|
---|
165 | .PP
|
---|
166 | The
|
---|
167 | .BR config_issub ,
|
---|
168 | .BR config_isatom
|
---|
169 | and
|
---|
170 | .BR config_isstring
|
---|
171 | functions are just pretty macros to test if a cell references a sublist, is
|
---|
172 | a word/string, or is just a string.
|
---|
173 | .B CFG_SUBLIST
|
---|
174 | and
|
---|
175 | .B CFG_STRING
|
---|
176 | tell the same story.
|
---|
177 | .SH FILES
|
---|
178 | .TP \w'*/etc/*.confmmmm'u
|
---|
179 | .B */etc/*.conf
|
---|
180 | Several files in several
|
---|
181 | .B etc
|
---|
182 | directories.
|
---|
183 | .SH "SEE ALSO"
|
---|
184 | .BR configfile (5).
|
---|
185 | .SH NOTES
|
---|
186 | The syntax of a config file puts some constraints on what you find in memory.
|
---|
187 | The top level list consists entirely of sublist cells. These point to lists
|
---|
188 | that start with at least an atom, followed by a mix of atoms and sublist cells.
|
---|
189 | These sublists in turn point to a list of only sublist cells (recurse now.)
|
---|
190 | .PP
|
---|
191 | The struct config shown above is not exactly proper C to aid
|
---|
192 | readability, read <configfile.h> itself to see why.
|
---|
193 | .SH AUTHOR
|
---|
194 | Kees J. Bot (kjb@cs.vu.nl)
|
---|