t/package.m4: Delete generated file.
[runlisp] / lib.h
CommitLineData
7b8ff279
MW
1/* -*-c-*-
2 *
3 * Common definitions for `runlisp'
4 *
5 * (c) 2020 Mark Wooding
6 */
7
8/*----- Licensing notice --------------------------------------------------*
9 *
10 * This file is part of Runlisp, a tool for invoking Common Lisp scripts.
11 *
12 * Runlisp is free software: you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 3 of the License, or (at your
15 * option) any later version.
16 *
17 * Runlisp is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with Runlisp. If not, see <https://www.gnu.org/licenses/>.
24 */
25
26#ifndef LIB_H
27#define LIB_H
28
29#ifdef __cplusplus
30 extern "C" {
31#endif
32
33/*----- Header files ------------------------------------------------------*/
34
35#include <limits.h>
36#include <stdarg.h>
37#include <stddef.h>
38#include <stdio.h>
39
40/*----- Handy macros ------------------------------------------------------*/
41
42#define N(v) (sizeof(v)/sizeof((v)[0]))
8996f767 43 /* The number of elements in the array V. */
7b8ff279 44
8996f767 45/* Figure out the compiler version to see whether fancy tricks will work. */
7b8ff279
MW
46#if defined(__GNUC__)
47# define GCC_VERSION_P(maj, min) \
48 (__GNUC__ > (maj) || (__GNUC__ == (maj) && __GNUC_MINOR__ >= (min)))
49#else
50# define GCC_VERSION_P(maj, min) 0
51#endif
52
53#ifdef __clang__
54# define CLANG_VERSION_P(maj, min) \
55 (__clang_major__ > (maj) || (__clang_major__ == (maj) && \
56 __clang_minor__ >= (min)))
57#else
58# define CLANG_VERSION_P(maj, min) 0
59#endif
60
61#if GCC_VERSION_P(2, 5) || CLANG_VERSION_P(3, 3)
8996f767 62
7b8ff279 63# define NORETURN __attribute__((__noreturn__))
8996f767
MW
64 /* Mark a function as not returning. */
65
7b8ff279 66# define PRINTF_LIKE(fix, aix) __attribute__((__format__(printf, fix, aix)))
8996f767
MW
67 /* Mark a function as accepting a printf(3)-like format string as
68 * argument FIX, with arguments to be substituted starting at AIX.
69 */
7b8ff279
MW
70#endif
71
72#if GCC_VERSION_P(4, 0) || CLANG_VERSION_P(3, 3)
8996f767 73
7b8ff279 74# define EXECL_LIKE(ntrail) __attribute__((__sentinel__(ntrail)))
8996f767
MW
75 /* Mark a function as expecting a variable number of arguments
76 * terminated by a null pointer, followed by NTRAIL further
77 * arguments.
78 */
79
80#endif
81
82/* Couldn't detect fancy compiler features. We'll have to make do
83 * without.
84 */
85#ifndef NORETURN
86# define NORETURN
87#endif
88#ifndef PRINTF_LIKE
89# define PRINTF_LIKE(fix, aix)
90#endif
91#ifndef EXECL_LIKE
92# define EXECL_LIKE(ntrail)
7b8ff279
MW
93#endif
94
8996f767
MW
95#define DISCARD(x) do if (x); while (0)
96 /* Discard the result of evaluating expression X, without upsetting
97 * the compiler.
98 */
99
100#define END ((const char *)0)
101 /* A null pointer to terminate the argument tail to an `EXECL_LIKE'
102 * function. (Note that `NULL' is /not/ adequate for this purpose,
103 * since it might expand simply to `0', which is an integer, not a
104 * pointer, and might well be the wrong size and/or value.)
105 */
106
107/* Wrap up <ctype.h> macros with explicit conversions to `unsigned char'. */
7b8ff279
MW
108#define CTYPE_HACK(func, ch) (func((unsigned char)(ch)))
109#define ISSPACE(ch) CTYPE_HACK(isspace, ch)
110#define ISALNUM(ch) CTYPE_HACK(isalnum, ch)
6c39ec6d 111#define ISXDIGIT(ch) CTYPE_HACK(isxdigit, ch)
8996f767
MW
112#define TOLOWER(ch) CTYPE_HACK(tolower, ch)
113#define TOUPPER(ch) CTYPE_HACK(toupper, ch)
7b8ff279 114
8996f767
MW
115/* Wrap up comparison functions to take an ordering relation as part of their
116 * syntax. This makes it much harder to screw up.
117 */
7b8ff279
MW
118#define MEMCMP(x, op, y, n) (memcmp((x), (y), (n)) op 0)
119#define STRCMP(x, op, y) (strcmp((x), (y)) op 0)
120#define STRNCMP(x, op, y, n) (strncmp((x), (y), (n)) op 0)
121
7b8ff279
MW
122#ifndef SIZE_MAX
123# define SIZE_MAX (-(size_t)1)
124#endif
8996f767
MW
125 /* The largest value that can be stored in an object of type
126 * `size_t'. A proper <limits.h> setting would be a preprocessor-
127 * time constant, but we don't actually need that.
128 */
7b8ff279
MW
129
130/*----- Diagnostic utilities ----------------------------------------------*/
131
132extern const char *progname;
8996f767 133 /* Our program name, for use in error messages. */
7b8ff279
MW
134
135extern void set_progname(const char */*prog*/);
8996f767
MW
136 /* Set `progname' from the pathname in PROG (typically from
137 * `argv[0]').
138 */
139
7b8ff279 140extern void vmoan(const char */*msg*/, va_list /*ap*/);
8996f767
MW
141 /* Report an error or warning in Unix style, given a captured
142 * argument cursor.
143 */
144
7b8ff279 145extern PRINTF_LIKE(1, 2) void moan(const char */*msg*/, ...);
8996f767
MW
146 /* Issue a warning message. */
147
7b8ff279 148extern NORETURN PRINTF_LIKE(1, 2) void lose(const char */*msg*/, ...);
8996f767 149 /* Issue a fatal error message and exit unsuccessfully. */
7b8ff279
MW
150
151/*----- Memory allocation -------------------------------------------------*/
152
153extern void *xmalloc(size_t /*n*/);
8996f767
MW
154 /* Allocate and return a pointer to N bytes, or report a fatal error.
155 *
156 * Release the pointer using `free' as usual. If N is zero, returns
157 * null (but you are not expected to check for this).
158 */
159
7b8ff279 160extern void *xrealloc(void */*p*/, size_t /*n*/);
8996f767
MW
161 /* Resize the block at P (from `malloc' or `xmalloc') to be N bytes
162 * long.
163 *
164 * The block might (and probably will) move, so it returns the new
165 * address. If N is zero, then the block is freed (if necessary) and
166 * a null pointer returned; otherwise, if P is null then a fresh
167 * block is allocated. If allocation fails, then a fatal error is
168 * reported.
169 */
170
7b8ff279 171extern char *xstrndup(const char */*p*/, size_t /*n*/);
8996f767
MW
172 /* Allocate and return a copy of the N-byte string starting at P.
173 *
174 * The new string is null-terminated, though P need not be. If
175 * allocation fails, then a fatal error is reported.
176 */
177
7b8ff279 178extern char *xstrdup(const char */*p*/);
8996f767
MW
179 /* Allocate and return a copy of the null-terminated string starting
180 * at P.
181 *
182 * If allocation fails, then a fatal error is reported.
183 */
7b8ff279
MW
184
185/*----- Dynamic strings ---------------------------------------------------*/
186
8996f767
MW
187/* A dynamic string.
188 *
189 * Note that the string might not be null-terminated.
190 */
7b8ff279 191struct dstr {
8996f767
MW
192 char *p; /* string base address */
193 size_t len; /* current string length */
194 size_t sz; /* allocated size of buffer */
7b8ff279
MW
195};
196#define DSTR_INIT { 0, 0, 0 }
197
198extern void dstr_init(struct dstr */*d*/);
8996f767
MW
199 /* Initialize the string D.
200 *
201 * Usually you'd use the static initializer `DSTR_INIT'.
202 */
203
7b8ff279 204extern void dstr_reset(struct dstr */*d*/);
8996f767
MW
205 /* Reset string D so it's empty again. */
206
7b8ff279 207extern void dstr_ensure(struct dstr */*d*/, size_t /*n*/);
8996f767
MW
208 /* Ensure that D has at least N unused bytes available. */
209
7b8ff279 210extern void dstr_release(struct dstr */*d*/);
8996f767
MW
211 /* Release the memory held by D.
212 *
213 * It must be reinitialized (e.g., by `dstr_init') before it can be
214 * used again.
215 */
216
7b8ff279 217extern void dstr_putm(struct dstr */*d*/, const void */*p*/, size_t /*n*/);
8996f767
MW
218 /* Append the N-byte string at P to D.
219 *
220 * P need not be null-terminated. D will not be null-terminated
221 * afterwards.
222 */
223
7b8ff279 224extern void dstr_puts(struct dstr */*d*/, const char */*p*/);
8996f767
MW
225 /* Append the null-terminated string P to D.
226 *
227 * D /is/ guaranteed to be null-terminated after this.
228 */
229
7b8ff279 230extern void dstr_putc(struct dstr */*d*/, int /*ch*/);
8996f767
MW
231 /* Append the single character CH to D.
232 *
233 * D will not be null-terminated afterwards.
234 */
235
236extern void dstr_putcn(struct dstr */*d*/, int /*ch*/, size_t /*n*/);
237 /* Append N copies of the character CH to D.
238 *
239 * D will not be null-terminated afterwards.
240 */
241
7b8ff279 242extern void dstr_putz(struct dstr */*d*/);
8996f767
MW
243 /* Null-terminate the string D.
244 *
245 * This doesn't change the length of D. If further stuff is appended
246 * then the null terminator will be overwritten.
247 */
248
7b8ff279
MW
249extern void dstr_vputf(struct dstr */*d*/,
250 const char */*p*/, va_list /*ap*/);
8996f767
MW
251 /* Append stuff to D, determined by printf(3) format string P and
252 * argument tail AP.
253 *
254 * D will not be null-terminated afterwards.
255 */
256
7b8ff279
MW
257extern PRINTF_LIKE(2, 3)
258 void dstr_putf(struct dstr */*d*/, const char */*p*/, ...);
8996f767
MW
259 /* Append stuff to D, determined by printf(3) format string P and
260 * arguments.
261 *
262 * D will not be null-terminated afterwards.
263 */
264
7b8ff279 265extern int dstr_readline(struct dstr */*d*/, FILE */*fp*/);
8996f767
MW
266 /* Append the next input line from FP to D.
267 *
268 * Return 0 on success, or -1 if reading immediately fails or
269 * encounters end-of-file (call ferror(3) to distinguish). Any
270 * trailing newline is discarded: it is not possible to determine
271 * whether the last line was ended with a newline. D is guaranteed
272 * to be null-terminated afterwards.
273 */
7b8ff279
MW
274
275/*----- Dynamic vectors of strings ----------------------------------------*/
276
8996f767
MW
277/* A dynamic vector of strings.
278 *
279 * This machinery only actually tracks character pointers. It assumes that
280 * the caller will manage the underlying storage for the strings.
281 *
282 * Note that `v' always points to the first element in the vector. The
283 * underlying storage starts `o' slots before this.
284*/
7b8ff279 285struct argv {
8996f767
MW
286 char **v; /* pointer the first element */
287 size_t n; /* length of the vector */
288 size_t o; /* number of spare slots at start */
289 size_t sz; /* allocated size (in slots) */
7b8ff279
MW
290};
291#define ARGV_INIT { 0, 0, 0, 0 }
292
293extern void argv_init(struct argv */*a*/v);
8996f767
MW
294 /* Initialize the vector AV.
295 *
296 * Usually you'd use the static initializer `ARGV_INIT'.
297 */
298
7b8ff279 299extern void argv_reset(struct argv */*av*/);
8996f767
MW
300 /* Reset the vector AV so that it's empty again. */
301
7b8ff279 302extern void argv_ensure(struct argv */*av*/, size_t /*n*/);
8996f767
MW
303 /* Ensure that AV has at least N unused slots at the end. */
304
7b8ff279 305extern void argv_ensure_offset(struct argv */*av*/, size_t /*n*/);
8996f767
MW
306 /* Ensure that AV has at least N unused slots at the /start/. */
307
7b8ff279 308extern void argv_release(struct argv */*av*/);
8996f767
MW
309 /* Release the memory held by AV.
310 *
311 * It must be reinitialized (e.g., by `argv_init') before it can be
312 * used again.
313 */
314
315extern void argv_append(struct argv */*av*/, char */*p*/);
316 /* Append the pointer P to AV. */
317
7b8ff279 318extern void argv_appendz(struct argv */*av*/);
8996f767
MW
319 /* Append a null pointer to AV, without extending the vactor length.
320 *
321 * The null pointer will be overwritten when the next string is
322 * appended.
323 */
324
7b8ff279 325extern void argv_appendn(struct argv */*av*/,
8996f767
MW
326 char *const */*v*/, size_t /*n*/);
327 /* Append a N-element vector V of pointers to AV. */
328
7b8ff279 329extern void argv_appendav(struct argv */*av*/, const struct argv */*bv*/);
8996f767
MW
330 /* Append the variable-length vector BV to AV. */
331
7b8ff279 332extern void argv_appendv(struct argv */*av*/, va_list /*ap*/);
8996f767
MW
333 /* Append the pointers from a variable-length argument list AP to AV.
334 *
335 * The list is terminated by a null pointer.
336 */
337
7b8ff279 338extern EXECL_LIKE(0) void argv_appendl(struct argv */*av*/, ...);
8996f767
MW
339 /* Append the argument pointers, terminated by a null pointer, to
340 * AV.
341 */
342
343extern void argv_prepend(struct argv */*av*/, char */*p*/);
344 /* Prepend the pointer P to AV. */
345
7b8ff279 346extern void argv_prependn(struct argv */*av*/,
8996f767
MW
347 char *const */*v*/, size_t /*n*/);
348 /* Prepend a N-element vector V of pointers to AV. */
349
7b8ff279 350extern void argv_prependav(struct argv */*av*/, const struct argv */*bv*/);
8996f767
MW
351 /* Prepend the variable-length vector BV to AV. */
352
7b8ff279 353extern void argv_prependv(struct argv */*av*/, va_list /*ap*/);
8996f767
MW
354 /* Prepend the pointers from a variable-length argument list AP to
355 * AV.
356 *
357 * The list is terminated by a null pointer.
358 */
359
7b8ff279 360extern EXECL_LIKE(0) void argv_prependl(struct argv */*av*/, ...);
8996f767
MW
361 /* Prepend the argument pointers, terminated by a null pointer, to
362 * AV.
363 */
7b8ff279
MW
364
365/*----- Treaps ------------------------------------------------------------*/
366
8996f767
MW
367/* A `treap' is a data structure for associating values with keys. This
368 * implementation assumes that keys are simply text strings.
369 */
7b8ff279
MW
370struct treap {
371 struct treap_node *root;
372};
373#define TREAP_INIT { 0 }
374
8996f767
MW
375/* A treap is a combination of a binary search tree and a binary heap. The
376 * nodes are ordered according to the search keys, in the usual way, so that
377 * all the keys in a node's left subtree precede that node's key, and all of
378 * the keys in its right subtree follow the node's key. The trick is that
379 * the tree must /also/ satisfy the heap condition regarding randomly
380 * assigned `weights' attached to each node: so a node's weight must not be
381 * less than their weight of either of its children.
382 *
383 * This combination uniquely determines the structure of the tree, except for
384 * nodes whose weights exactly match one (or both) of their children. (The
385 * root must be the heaviest node in the tree. The root's key splits the
386 * remaining nodes into left and right subtrees, whose structure is then
387 * uniquely determined by induction.)
388 *
389 * This is an /intrusive/ data structure. A caller is expected to include a
390 * `struct treap_node' as (probably) the initial part of a larger structure.
391 */
7b8ff279 392struct treap_node {
8996f767
MW
393 unsigned wt; /* weight (randomly assigned) */
394 struct treap_node *left, *right; /* left and right subtrees */
395 char *k; size_t kn; /* key pointer and length */
7b8ff279
MW
396};
397#define TREAP_NODE_KEY(n) (((const struct treap_node *)(n))->k + 0)
398#define TREAP_NODE_KEYLEN(n) (((const struct treap_node *)(n))->kn + 0)
399
8996f767
MW
400/* We can't allocate nodes ourselves, because only the caller knows how.
401 * Instead, insertion is split into two operations: `treap_probe' looks to
402 * see whether a matching node is already in the treap, and returns it if so;
403 * otherwise, it flls in this `treap_path' structure, which is passed back to
404 * `treap_insert' to help it add the fresh node into the treap. (See the
405 * commentary in `treap_probe' and `treap_insert' for the details.)
406 */
7b8ff279
MW
407#define TREAP_PATHMAX 64
408struct treap_path {
409 struct treap_node **path[TREAP_PATHMAX];
410 unsigned nsteps;
411};
412
8996f767
MW
413/* An external iterator for a treap. (See the commentary for
414 * `treap_start_iter' and `treap_next' for the details.)
415 */
7b8ff279
MW
416struct treap_iter {
417 struct treap_node *stack[TREAP_PATHMAX];
418 unsigned sp;
419};
420
421extern void treap_init(struct treap */*t*/);
8996f767
MW
422 /* Initialize the treap T.
423 *
424 * Usually you'd use the static initializer `TREAP_INIT'.
425 */
426
7b8ff279
MW
427extern void *treap_lookup(const struct treap */*t*/,
428 const char */*k*/, size_t /*kn*/);
8996f767
MW
429 /* Look up the KN-byte key K in the treap T.
430 *
431 * Return a pointer to the matching node if one was found, or null
432 * otherwise.
433 */
434
7b8ff279
MW
435extern void *treap_probe(struct treap */*t*/,
436 const char */*k*/, size_t /*kn*/,
437 struct treap_path */*p*/);
8996f767
MW
438 /* Look up the KN-byte K in the treap T, recording a path in P.
439 *
440 * This is similar to `treap_lookup', in that it returns the
441 * requested node if it already exists, or null otherwise, but it
442 * also records in P information to be used by `treap_insert' to
10427eb2 443 * insert a new node with the given key if it's not there already.
8996f767
MW
444 */
445
7b8ff279
MW
446extern void treap_insert(struct treap */*t*/, const struct treap_path */*p*/,
447 struct treap_node */*n*/,
448 const char */*k*/, size_t /*kn*/);
8996f767
MW
449 /* Insert a new node N into T, associating it with the KN-byte key K.
450 *
451 * Use the path data P, from `treap_probe', to help with insertion.
452 */
453
7b8ff279
MW
454extern void *treap_remove(struct treap */*t*/,
455 const char */*k*/, size_t /*kn*/);
8996f767
MW
456 /* Remove the node with the KN-byte K from T.
457 *
458 * Return the address of the node we removed, or null if it couldn't
459 * be found.
460 */
461
7b8ff279 462extern void treap_start_iter(struct treap */*t*/, struct treap_iter */*i*/);
8996f767
MW
463 /* Initialize an iterator I over T's nodes. */
464
7b8ff279 465extern void *treap_next(struct treap_iter */*i*/);
8996f767
MW
466 /* Return the next node from I, in ascending order by key.
467 *
468 * If there are no more nodes, then return null.
469 */
470
7b8ff279 471extern void treap_check(struct treap */*t*/);
8996f767
MW
472 /* Check the treap structure rules for T. */
473
7b8ff279 474extern void treap_dump(struct treap */*t*/);
8996f767 475 /* Dump the treap T to standard output, for debugging purposes. */
7b8ff279
MW
476
477/*----- Configuration file parsing ----------------------------------------*/
478
8996f767 479/* A configuration file. */
7b8ff279 480struct config {
8996f767
MW
481 struct treap sections; /* treap of sections */
482 struct config_section *head, **tail; /* section list, in creation order */
483 struct config_section *fallback; /* default parent section */
7b8ff279
MW
484};
485#define CONFIG_INIT { TREAP_INIT, 0, 0 }
486
8996f767 487/* A configuration section. */
7b8ff279 488struct config_section {
8996f767
MW
489 struct treap_node _node; /* treap intrustion */
490 struct config_section *next; /* next section in creation order */
491 struct config_section **parents; size_t nparents; /* vector of parents */
492 struct treap vars; /* treap of variables */
493 struct treap cache; /* inheritance cache */
7b8ff279
MW
494};
495#define CONFIG_SECTION_NAME(sect) TREAP_NODE_KEY(sect)
496#define CONFIG_SECTION_NAMELEN(sect) TREAP_NODE_KEYLEN(sect)
497
8996f767
MW
498/* An entry in a section's inheritance cache: see `search_recursive' for
499 * details.
500 */
7b8ff279 501struct config_cache_entry {
8996f767
MW
502 struct treap_node _node; /* treap intrusion */
503 unsigned f; /* flags */
504#define CF_OPEN 1u /* traps inheritance cycles */
505 struct config_var *var; /* pointer to inherited variable */
7b8ff279
MW
506};
507
8996f767 508/* A configuration variable. */
7b8ff279 509struct config_var {
8996f767
MW
510 struct treap_node _node; /* treap intrusion */
511 char *file; unsigned line; /* source location, or null/0 */
512 char *val; size_t n; /* value pointer and length */
513 unsigned f; /* flags */
514#define CF_LITERAL 1u /* value should not be expanded */
515#define CF_EXPAND 2u /* traps expansion cycles */
516#define CF_OVERRIDE 4u /* override settings from files */
7b8ff279
MW
517};
518#define CONFIG_VAR_NAME(var) TREAP_NODE_KEY(var)
519#define CONFIG_VAR_NAMELEN(var) TREAP_NODE_KEYLEN(var)
7b8ff279 520
8996f767
MW
521/* A section iterator.
522 *
523 * (Sections are visited in the order in which they were created.)
524 */
7b8ff279 525struct config_section_iter {
8996f767 526 struct config_section *sect; /* next section to return */
7b8ff279
MW
527};
528
8996f767
MW
529/* A variable iterator.
530 *
531 * (Variables are visited in lexicographical order.)
532 */
7b8ff279
MW
533struct config_var_iter {
534 struct treap_iter i;
535};
536
8996f767
MW
537/* Common flags. */
538#define CF_CREAT 1u /* create section or variable */
539#define CF_INHERIT 2u /* look up variable in parents */
540
7b8ff279 541extern void config_init(struct config */*conf*/);
8996f767
MW
542 /* Initialize the configuration state CONF.
543 *
544 * Usually you'd use the static initializer `CONFIG_INIT'.
545 */
7b8ff279
MW
546
547extern struct config_section *config_find_section(struct config */*conf*/,
548 unsigned /*f*/,
549 const char */*name*/);
8996f767
MW
550 /* Find and return the section with null-terminated NAME in CONF.
551 *
552 * If no section is found, the behaviour depends on whether
553 * `CF_CREAT' is set in F: if so, an empty section is created and
554 * returned; otherwise, a null pointer is returned.
555 */
556
7b8ff279
MW
557extern struct config_section *config_find_section_n(struct config */*conf*/,
558 unsigned /*f*/,
559 const char */*name*/,
560 size_t /*sz*/);
8996f767
MW
561 /* Find and return the section with the given SZ-byte NAME in CONF.
562 *
563 * This works like `config_find_section', but with an explicit length
564 * for the NAME rather than null-termination.
565 */
7b8ff279
MW
566
567extern void config_set_fallback(struct config */*conf*/,
568 struct config_section */*sect*/);
8996f767
MW
569 /* Set the fallback section for CONF to be SECT.
570 *
571 * That is, if a section has no explicit parents, then by default it
572 * will have a single parent which is SECT. If SECT is null then
573 * there is no fallback section, and sections which don't have
574 * explicitly specified parents have no parents at all. (This is the
575 * default situation.)
576 */
577
7b8ff279
MW
578extern void config_set_parent(struct config_section */*sect*/,
579 struct config_section */*parent*/);
8996f767
MW
580 /* Arrange that SECT has PARENT as its single parent section.
581 *
582 * If PARENT is null, then arrange that SECT has no parents at all.
583 * In either case, any `@parents' setting will be ignored.
584 */
7b8ff279
MW
585
586extern void config_start_section_iter(struct config */*conf*/,
587 struct config_section_iter */*i*/);
8996f767
MW
588 /* Initialize I to iterate over the sections defined in CONF. */
589
7b8ff279
MW
590extern struct config_section *config_next_section
591 (struct config_section_iter */*i*/);
8996f767
MW
592 /* Return the next section from I, in order of creation.
593 *
594 * If there are no more sections, then return null.
595 */
7b8ff279
MW
596
597extern struct config_var *config_find_var(struct config */*conf*/,
598 struct config_section */*sect*/,
599 unsigned /*f*/,
600 const char */*name*/);
8996f767
MW
601 /* Find and return the variable with null-terminated NAME in SECT.
602 *
603 * If `CF_INHERIT' is set in F, then the function searches the
604 * section's parents recursively; otherwise, it only checks to see
605 * whether the variable is set directly in SECT.
606 *
607 * If no variable is found, the behaviour depends on whether
608 * `CF_CREAT' is set in F: if so, an empty variable is created and
609 * returned; otherwise, a null pointer is returned.
610 *
611 * Setting both `CF_INHERIT' and `CF_CREAT' is not useful.
612 */
613
7b8ff279
MW
614extern struct config_var *config_find_var_n(struct config */*conf*/,
615 struct config_section */*sect*/,
616 unsigned /*f*/,
617 const char */*name*/,
618 size_t /*sz*/);
8996f767
MW
619 /* Find and return the variable with the given SZ-byte NAME in SECT.
620 *
621 * This works like `config_find_var', but with an explicit length for
622 * the NAME rather than null-termination.
623 */
7b8ff279 624
6c39ec6d
MW
625extern struct config_var *config_set_var(struct config */*conf*/,
626 struct config_section */*sect*/,
627 unsigned /*f*/,
628 const char */*name*/,
629 const char */*value*/);
8996f767
MW
630 /* Set variable NAME to VALUE in SECT, with associated flags F.
631 *
632 * The names are null-terminated. The flags are variable flags: see
6c39ec6d 633 * `struct config_var' for details. Returns the variable.
8996f767
MW
634 *
635 * If the variable is already set and has the `CF_OVERRIDE' flag,
636 * then this function does nothing unless `CF_OVERRIDE' is /also/ set
637 * in F.
638 */
639
6c39ec6d
MW
640extern struct config_var *config_set_var_n(struct config */*conf*/,
641 struct config_section */*sect*/,
642 unsigned /*f*/,
643 const char */*name*/,
644 size_t /*namelen*/,
645 const char */*value*/,
646 size_t /*valuelen*/);
8996f767
MW
647 /* As `config_set_var', except that the variable NAME and VALUE have
648 * explicit lengths (NAMELEN and VALUELEN, respectively) rather than
649 * being null- terminated.
650 */
651
652extern void config_start_var_iter(struct config */*conf*/,
653 struct config_section */*sect*/,
7b8ff279 654 struct config_var_iter */*i*/);
8996f767
MW
655 /* Initialize I to iterate over the variables directly defined in
656 * SECT.
657 */
658
7b8ff279 659extern struct config_var *config_next_var(struct config_var_iter */*i*/);
8996f767
MW
660 /* Return next variable from I, in ascending lexicographical order.
661 *
662 * If there are no more variables, then return null.
663 */
7b8ff279
MW
664
665extern int config_read_file(struct config */*conf*/, const char */*file*/,
666 unsigned /*f*/);
8996f767
MW
667#define CF_NOENTOK 1u
668 /* Read and parse configuration FILE, applying its settings to CONF.
669 *
670 * If all goes well, the function returns 0. If the file is not
671 * found, then the behaviour depends on whether `CF_NOENTOK' is set
672 * in F: if so, then the function simply returns -1. Otherwise, a
673 * fatal error is reported. Note that this /only/ applies if the
674 * file does not exist (specifically, opening it fails with `ENOENT')
675 * -- any other problems are reported as fatal errors regardless of
676 * the flag setting.
677 */
678
7b8ff279
MW
679extern void config_read_env(struct config */*conf*/,
680 struct config_section */*sect*/);
8996f767
MW
681 /* Populate SECT with environment variables.
682 *
683 * Environment variables are always set with `CF_LITERAL'.
684 */
7b8ff279
MW
685
686extern void config_subst_string(struct config */*config*/,
687 struct config_section */*home*/,
688 const char */*what*/,
689 const char */*p*/, struct dstr */*d*/);
8996f767
MW
690 /* Expand substitutions in a string.
691 *
692 * Expand the null-terminated string P relative to the HOME section,
693 * using configuration CONFIG, and appending the result to dynamic
694 * string D. Blame WHAT in any error messages.
695 */
696
7b8ff279
MW
697extern char *config_subst_string_alloc(struct config */*config*/,
698 struct config_section */*home*/,
699 const char */*what*/,
700 const char */*p*/);
8996f767
MW
701 /* Expand substitutions in a string.
702 *
703 * Expand the null-terminated string P relative to the HOME section,
704 * using configuration CONFIG, returning the result as a freshly
705 * malloc(3)ed string. Blame WHAT in any error messages.
706 */
707
7b8ff279
MW
708extern void config_subst_var(struct config */*config*/,
709 struct config_section */*home*/,
710 struct config_var */*var*/,
711 struct dstr */*d*/);
8996f767
MW
712 /* Expand substitutions in a variable.
713 *
714 * Expand the value of the variable VAR relative to the HOME section,
715 * using configuration CONFIG, appending the result to dynamic string
716 * D.
717 */
718
7b8ff279
MW
719extern char *config_subst_var_alloc(struct config */*config*/,
720 struct config_section */*home*/,
721 struct config_var */*var*/);
8996f767
MW
722 /* Expand substitutions in a variable.
723 *
724 * Expand the value of the variable VAR relative to the HOME section,
725 * using configuration CONFIG, returning the result as a freshly
726 * malloc(3)ed string.
727 */
728
7b8ff279
MW
729extern void config_subst_split_var(struct config */*config*/,
730 struct config_section */*home*/,
731 struct config_var */*var*/,
732 struct argv */*av*/);
8996f767
MW
733 /* Expand substitutions in a variable and split into words.
734 *
735 * Expand and word-split the value of the variable VAR relative to
736 * the HOME section, using configuration CONFIG, appending the
737 * resulting words into the vector AV.
738 */
7b8ff279
MW
739
740/*----- That's all, folks -------------------------------------------------*/
741
742#ifdef __cplusplus
743 }
744#endif
745
746#endif