chiark / gitweb /
lib.c (subst): Make the big table a bit more comprehensible.
[runlisp] / lib.h
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]))
43         /* The number of elements in the array V. */
44
45 /* Figure out the compiler version to see whether fancy tricks will work. */
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)
62
63 #  define NORETURN __attribute__((__noreturn__))
64         /* Mark a function as not returning. */
65
66 #  define PRINTF_LIKE(fix, aix) __attribute__((__format__(printf, fix, aix)))
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          */
70 #endif
71
72 #if GCC_VERSION_P(4, 0) || CLANG_VERSION_P(3, 3)
73
74 #  define EXECL_LIKE(ntrail) __attribute__((__sentinel__(ntrail)))
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)
93 #endif
94
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'. */
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)
111 #define ISXDIGIT(ch) CTYPE_HACK(isxdigit, ch)
112 #define TOLOWER(ch) CTYPE_HACK(tolower, ch)
113 #define TOUPPER(ch) CTYPE_HACK(toupper, ch)
114
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  */
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
122 #ifndef SIZE_MAX
123 #  define SIZE_MAX (-(size_t)1)
124 #endif
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          */
129
130 /*----- Diagnostic utilities ----------------------------------------------*/
131
132 extern const char *progname;
133         /* Our program name, for use in error messages. */
134
135 extern void set_progname(const char */*prog*/);
136         /* Set `progname' from the pathname in PROG (typically from
137          * `argv[0]').
138          */
139
140 extern void vmoan(const char */*msg*/, va_list /*ap*/);
141         /* Report an error or warning in Unix style, given a captured
142          * argument cursor.
143          */
144
145 extern PRINTF_LIKE(1, 2) void moan(const char */*msg*/, ...);
146         /* Issue a warning message. */
147
148 extern NORETURN PRINTF_LIKE(1, 2) void lose(const char */*msg*/, ...);
149         /* Issue a fatal error message and exit unsuccessfully. */
150
151 /*----- Memory allocation -------------------------------------------------*/
152
153 extern void *xmalloc(size_t /*n*/);
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
160 extern void *xrealloc(void */*p*/, size_t /*n*/);
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
171 extern char *xstrndup(const char */*p*/, size_t /*n*/);
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
178 extern char *xstrdup(const char */*p*/);
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          */
184
185 /*----- Dynamic strings ---------------------------------------------------*/
186
187 /* A dynamic string.
188  *
189  * Note that the string might not be null-terminated.
190  */
191 struct dstr {
192   char *p;                              /* string base address */
193   size_t len;                           /* current string length */
194   size_t sz;                            /* allocated size of buffer */
195 };
196 #define DSTR_INIT { 0, 0, 0 }
197
198 extern void dstr_init(struct dstr */*d*/);
199         /* Initialize the string D.
200          *
201          * Usually you'd use the static initializer `DSTR_INIT'.
202          */
203
204 extern void dstr_reset(struct dstr */*d*/);
205         /* Reset string D so it's empty again. */
206
207 extern void dstr_ensure(struct dstr */*d*/, size_t /*n*/);
208         /* Ensure that D has at least N unused bytes available. */
209
210 extern void dstr_release(struct dstr */*d*/);
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
217 extern void dstr_putm(struct dstr */*d*/, const void */*p*/, size_t /*n*/);
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
224 extern void dstr_puts(struct dstr */*d*/, const char */*p*/);
225         /* Append the null-terminated string P to D.
226          *
227          * D /is/ guaranteed to be null-terminated after this.
228          */
229
230 extern void dstr_putc(struct dstr */*d*/, int /*ch*/);
231         /* Append the single character CH to D.
232          *
233          * D will not be null-terminated afterwards.
234          */
235
236 extern 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
242 extern void dstr_putz(struct dstr */*d*/);
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
249 extern void dstr_vputf(struct dstr */*d*/,
250                        const char */*p*/, va_list /*ap*/);
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
257 extern PRINTF_LIKE(2, 3)
258   void dstr_putf(struct dstr */*d*/, const char */*p*/, ...);
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
265 extern int dstr_readline(struct dstr */*d*/, FILE */*fp*/);
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          */
274
275 /*----- Dynamic vectors of strings ----------------------------------------*/
276
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 */
285 struct argv {
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) */
290 };
291 #define ARGV_INIT { 0, 0, 0, 0 }
292
293 extern void argv_init(struct argv */*a*/v);
294         /* Initialize the vector AV.
295          *
296          * Usually you'd use the static initializer `ARGV_INIT'.
297          */
298
299 extern void argv_reset(struct argv */*av*/);
300         /* Reset the vector AV so that it's empty again. */
301
302 extern void argv_ensure(struct argv */*av*/, size_t /*n*/);
303         /* Ensure that AV has at least N unused slots at the end. */
304
305 extern void argv_ensure_offset(struct argv */*av*/, size_t /*n*/);
306         /* Ensure that AV has at least N unused slots at the /start/. */
307
308 extern void argv_release(struct argv */*av*/);
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
315 extern void argv_append(struct argv */*av*/, char */*p*/);
316         /* Append the pointer P to AV. */
317
318 extern void argv_appendz(struct argv */*av*/);
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
325 extern void argv_appendn(struct argv */*av*/,
326                          char *const */*v*/, size_t /*n*/);
327         /* Append a N-element vector V of pointers to AV. */
328
329 extern void argv_appendav(struct argv */*av*/, const struct argv */*bv*/);
330         /* Append the variable-length vector BV to AV. */
331
332 extern void argv_appendv(struct argv */*av*/, va_list /*ap*/);
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
338 extern EXECL_LIKE(0) void argv_appendl(struct argv */*av*/, ...);
339         /* Append the argument pointers, terminated by a null pointer, to
340          * AV.
341          */
342
343 extern void argv_prepend(struct argv */*av*/, char */*p*/);
344         /* Prepend the pointer P to AV. */
345
346 extern void argv_prependn(struct argv */*av*/,
347                           char *const */*v*/, size_t /*n*/);
348         /* Prepend a N-element vector V of pointers to AV. */
349
350 extern void argv_prependav(struct argv */*av*/, const struct argv */*bv*/);
351         /* Prepend the variable-length vector BV to AV. */
352
353 extern void argv_prependv(struct argv */*av*/, va_list /*ap*/);
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
360 extern EXECL_LIKE(0) void argv_prependl(struct argv */*av*/, ...);
361         /* Prepend the argument pointers, terminated by a null pointer, to
362          * AV.
363          */
364
365 /*----- Treaps ------------------------------------------------------------*/
366
367 /* A `treap' is a data structure for associating values with keys.  This
368  * implementation assumes that keys are simply text strings.
369  */
370 struct treap {
371   struct treap_node *root;
372 };
373 #define TREAP_INIT { 0 }
374
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  */
392 struct treap_node {
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 */
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
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  */
407 #define TREAP_PATHMAX 64
408 struct treap_path {
409   struct treap_node **path[TREAP_PATHMAX];
410   unsigned nsteps;
411 };
412
413 /* An external iterator for a treap.  (See the commentary for
414  * `treap_start_iter' and `treap_next' for the details.)
415  */
416 struct treap_iter {
417   struct treap_node *stack[TREAP_PATHMAX];
418   unsigned sp;
419 };
420
421 extern void treap_init(struct treap */*t*/);
422         /* Initialize the treap T.
423          *
424          * Usually you'd use the static initializer `TREAP_INIT'.
425          */
426
427 extern void *treap_lookup(const struct treap */*t*/,
428                           const char */*k*/, size_t /*kn*/);
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
435 extern void *treap_probe(struct treap */*t*/,
436                          const char */*k*/, size_t /*kn*/,
437                          struct treap_path */*p*/);
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
443          * insert a new node with the given key if it's not there already.
444          */
445
446 extern void treap_insert(struct treap */*t*/, const struct treap_path */*p*/,
447                          struct treap_node */*n*/,
448                          const char */*k*/, size_t /*kn*/);
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
454 extern void *treap_remove(struct treap */*t*/,
455                           const char */*k*/, size_t /*kn*/);
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
462 extern void treap_start_iter(struct treap */*t*/, struct treap_iter */*i*/);
463         /* Initialize an iterator I over T's nodes. */
464
465 extern void *treap_next(struct treap_iter */*i*/);
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
471 extern void treap_check(struct treap */*t*/);
472         /* Check the treap structure rules for T. */
473
474 extern void treap_dump(struct treap */*t*/);
475         /* Dump the treap T to standard output, for debugging purposes. */
476
477 /*----- Configuration file parsing ----------------------------------------*/
478
479 /* A configuration file. */
480 struct config {
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 */
484 };
485 #define CONFIG_INIT { TREAP_INIT, 0, 0 }
486
487 /* A configuration section. */
488 struct config_section {
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 */
494 };
495 #define CONFIG_SECTION_NAME(sect) TREAP_NODE_KEY(sect)
496 #define CONFIG_SECTION_NAMELEN(sect) TREAP_NODE_KEYLEN(sect)
497
498 /* An entry in a section's inheritance cache: see `search_recursive' for
499  * details.
500  */
501 struct config_cache_entry {
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 */
506 };
507
508 /* A configuration variable. */
509 struct config_var {
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 */
517 };
518 #define CONFIG_VAR_NAME(var) TREAP_NODE_KEY(var)
519 #define CONFIG_VAR_NAMELEN(var) TREAP_NODE_KEYLEN(var)
520
521 /* A section iterator.
522  *
523  * (Sections are visited in the order in which they were created.)
524  */
525 struct config_section_iter {
526   struct config_section *sect;          /* next section to return */
527 };
528
529 /* A variable iterator.
530  *
531  * (Variables are visited in lexicographical order.)
532  */
533 struct config_var_iter {
534   struct treap_iter i;
535 };
536
537 /* Common flags. */
538 #define CF_CREAT 1u                     /* create section or variable */
539 #define CF_INHERIT 2u                   /* look up variable in parents */
540
541 extern void config_init(struct config */*conf*/);
542         /* Initialize the configuration state CONF.
543          *
544          * Usually you'd use the static initializer `CONFIG_INIT'.
545          */
546
547 extern struct config_section *config_find_section(struct config */*conf*/,
548                                                   unsigned /*f*/,
549                                                   const char */*name*/);
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
557 extern struct config_section *config_find_section_n(struct config */*conf*/,
558                                                     unsigned /*f*/,
559                                                     const char */*name*/,
560                                                     size_t /*sz*/);
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          */
566
567 extern void config_set_fallback(struct config */*conf*/,
568                                 struct config_section */*sect*/);
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
578 extern void config_set_parent(struct config_section */*sect*/,
579                               struct config_section */*parent*/);
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          */
585
586 extern void config_start_section_iter(struct config */*conf*/,
587                                       struct config_section_iter */*i*/);
588         /* Initialize I to iterate over the sections defined in CONF. */
589
590 extern struct config_section *config_next_section
591   (struct config_section_iter */*i*/);
592         /* Return the next section from I, in order of creation.
593          *
594          * If there are no more sections, then return null.
595          */
596
597 extern struct config_var *config_find_var(struct config */*conf*/,
598                                           struct config_section */*sect*/,
599                                           unsigned /*f*/,
600                                           const char */*name*/);
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
614 extern 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*/);
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          */
624
625 extern 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*/);
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
633          * `struct config_var' for details.  Returns the variable.
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
640 extern 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*/);
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
652 extern void config_start_var_iter(struct config */*conf*/,
653                                   struct config_section */*sect*/,
654                                   struct config_var_iter */*i*/);
655         /* Initialize I to iterate over the variables directly defined in
656          * SECT.
657          */
658
659 extern struct config_var *config_next_var(struct config_var_iter */*i*/);
660         /* Return next variable from I, in ascending lexicographical order.
661          *
662          * If there are no more variables, then return null.
663          */
664
665 extern int config_read_file(struct config */*conf*/, const char */*file*/,
666                             unsigned /*f*/);
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
679 extern void config_read_env(struct config */*conf*/,
680                             struct config_section */*sect*/);
681         /* Populate SECT with environment variables.
682          *
683          * Environment variables are always set with `CF_LITERAL'.
684          */
685
686 extern void config_subst_string(struct config */*config*/,
687                                 struct config_section */*home*/,
688                                 const char */*what*/,
689                                 const char */*p*/, struct dstr */*d*/);
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
697 extern char *config_subst_string_alloc(struct config */*config*/,
698                                        struct config_section */*home*/,
699                                        const char */*what*/,
700                                        const char */*p*/);
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
708 extern void config_subst_var(struct config */*config*/,
709                              struct config_section */*home*/,
710                              struct config_var */*var*/,
711                              struct dstr */*d*/);
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
719 extern char *config_subst_var_alloc(struct config */*config*/,
720                                     struct config_section */*home*/,
721                                     struct config_var */*var*/);
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
729 extern void config_subst_split_var(struct config */*config*/,
730                                    struct config_section */*home*/,
731                                    struct config_var */*var*/,
732                                    struct argv */*av*/);
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          */
739
740 /*----- That's all, folks -------------------------------------------------*/
741
742 #ifdef __cplusplus
743   }
744 #endif
745
746 #endif