195 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .TH CONFIGFILE 3
 | |
| .SH NAME
 | |
| configfile, config_read, config_delete, config_renewed, config_length, config_issub, config_isatom, config_isstring \- generic configuration file functions
 | |
| .SH SYNOPSIS
 | |
| .ft B
 | |
| .nf
 | |
| #include <configfile.h>
 | |
| 
 | |
| config_t *config_read(const char *\fIfile\fP, int \fIflags\fP, config_t *\fIcfg\fP)
 | |
| void config_delete(config_t *\fIcfg\fP)
 | |
| int config_renewed(config_t *\fIcfg\fP)
 | |
| size_t config_length(config_t *\fIcfg\fP)
 | |
| int config_issub(config_t *\fIcfg\fP)
 | |
| int config_isatom(config_t *\fIcfg\fP)
 | |
| int config_isstring(config_t *\fIcfg\fP)
 | |
| .fi
 | |
| .ft P
 | |
| .SH DESCRIPTION
 | |
| The
 | |
| .B configfile
 | |
| routines operate on a generic configuration file that follows the syntax
 | |
| described in
 | |
| .BR configfile (5).
 | |
| .PP
 | |
| The interface presented by the functions above uses the following type and
 | |
| definitions from <configfile.h>:
 | |
| .PP
 | |
| .if n .in +2
 | |
| .if t .RS
 | |
| .nf
 | |
| .ta +\w'type'u +\w'const charmm'u +\w'word[];mm'u
 | |
| typedef const struct config {
 | |
| 	config_t	*next;	/* Next configuration file thing. */
 | |
| 	config_t	*list;	/* For a { sublist }. */
 | |
| 	const char	*file;	/* File and line where this is found. */
 | |
| 	unsigned	line;
 | |
| 	int	flags;	/* Special flags. */
 | |
| 	char	word[];	/* Payload. */
 | |
| } config_t;
 | |
| 
 | |
| .ta +\w'#definem'u +\w'CFG_SUBLISTm'u +\w'0x0000mm'u
 | |
| #define	CFG_CLONG	0x0001	/* strtol(word, &end, 0) is valid. */
 | |
| #define	CFG_OLONG	0x0002	/* strtol(word, &end, 010). */
 | |
| #define	CFG_DLONG	0x0004	/* strtol(word, &end, 10). */
 | |
| #define	CFG_XLONG	0x0008	/* strtol(word, &end, 0x10). */
 | |
| #define	CFG_CULONG	0x0010	/* strtoul(word, &end, 0). */
 | |
| #define	CFG_OULONG	0x0020	/* strtoul(word, &end, 010). */
 | |
| #define	CFG_DULONG	0x0040	/* strtoul(word, &end, 10). */
 | |
| #define	CFG_XULONG	0x0080	/* strtoul(word, &end, 0x10). */
 | |
| #define	CFG_STRING	0x0100	/* The word is enclosed in quotes. */
 | |
| #define	CFG_SUBLIST	0x0200	/* This is a sublist, so no word. */
 | |
| #define	CFG_ESCAPED	0x0400	/* Escapes are still marked with \e. */
 | |
| .fi
 | |
| .if n .in -2
 | |
| .if t .RE
 | |
| .PP
 | |
| In memory a configuration file is represented as a list of
 | |
| .B config_t
 | |
| cells linked together with the
 | |
| .B next
 | |
| field ending with a null pointer.  A sublist between braces is attached to a
 | |
| cell at the
 | |
| .B list
 | |
| field.
 | |
| Words and strings are put in the
 | |
| .B word
 | |
| field, a null terminated string.  The
 | |
| .B flags
 | |
| field records the type and features of a cell.  The
 | |
| .B CFG_*LONG
 | |
| flags are set if a word is a number according to one of the
 | |
| .B strtol
 | |
| or
 | |
| .B strtoul
 | |
| calls.  Purely a number, no quotes or trailing garbage.  The
 | |
| .B CFG_STRING
 | |
| flag is set if the object was enclosed in double quotes.  Lastly
 | |
| .B CFG_SUBLIST
 | |
| tells if the cell is only a pointer to a sublist in braces.
 | |
| .PP
 | |
| Characters in a word or string may have been formed with the
 | |
| .B \e
 | |
| escape character.  They have been parsed and expanded, but the \e is still
 | |
| present if
 | |
| .B CFG_ESCAPED
 | |
| is set.  The
 | |
| .B word
 | |
| array may be changed, as long as it doesn't grow longer, so one may remove
 | |
| the \es like this:
 | |
| .PP
 | |
| .RS
 | |
| .ta +4n +4n
 | |
| .nf
 | |
| if (cfg->flags & CFG_ESCAPED) {
 | |
| 	char *p, *q;
 | |
| 	p= q= cfg->word;
 | |
| 	for (;;) {
 | |
| 		if ((*q = *p) == '\e\e') *q = *++p;
 | |
| 		if (*q == 0) break;
 | |
| 		p++;
 | |
| 		q++;
 | |
| 	}
 | |
| }
 | |
| .fi
 | |
| .RE
 | |
| .PP
 | |
| The low level syntax of a config file is checked when it is read.  If an
 | |
| error is encountered a message is printed and the program exits with exit
 | |
| code 1.  What the data means is not checked, that
 | |
| should be done by the program using the data.  Only the atom
 | |
| .B include
 | |
| at the beginning of a list is special.  It should be followed by a string.
 | |
| The string is seen as the name of a file, that is opened, read, and inserted
 | |
| in place of the
 | |
| .BR include .
 | |
| Unless the name of the file starts with a
 | |
| .BR / ,
 | |
| it is sought relative to the directory the current file is found in.
 | |
| Nonexistent files are treated as being empty.
 | |
| .PP
 | |
| The
 | |
| .B file
 | |
| and
 | |
| .B line
 | |
| fields in each cell tell where the cell was read.
 | |
| .SS Functions
 | |
| A configuration file is read with
 | |
| .BR config_read .
 | |
| The first argument is the file to read.  The second is either
 | |
| .B 0
 | |
| or
 | |
| .B CFG_ESCAPED
 | |
| to tell whether \e escapes should be fully expanded without leaving a trace,
 | |
| or if they should still be marked with a \e so that the caller knows where
 | |
| the excapes are.
 | |
| The third argument,
 | |
| .IR cfg ,
 | |
| should be a null pointer on the first call.  If you want to reread a config
 | |
| file that may have changed then
 | |
| .I cfg
 | |
| should be what you previously read.
 | |
| .PP
 | |
| With
 | |
| .B config_delete
 | |
| one can free up the memory that has been acquired with
 | |
| .BR malloc (3)
 | |
| to hold the contents of the configuration file.
 | |
| .PP
 | |
| To determine if the contents of configuration file has changed when reread
 | |
| one uses
 | |
| .BR config_renewed
 | |
| after
 | |
| .BR config_read .
 | |
| It returns a "changed" flag that is set when the configuration file changed
 | |
| and then clears that flag.  It returns true on the very first call.  For the
 | |
| function to work you need to feed the old data back into
 | |
| .BR config_read ,
 | |
| not delete and reread.
 | |
| .PP
 | |
| The length of a series of config structures is told by
 | |
| .BR config_length .
 | |
| It follows the
 | |
| .B next
 | |
| fields, so a sublist between braces counts as one extra.
 | |
| .PP
 | |
| The
 | |
| .BR config_issub ,
 | |
| .BR config_isatom
 | |
| and
 | |
| .BR config_isstring
 | |
| functions are just pretty macros to test if a cell references a sublist, is
 | |
| a word/string, or is just a string.
 | |
| .B CFG_SUBLIST
 | |
| and
 | |
| .B CFG_STRING
 | |
| tell the same story.
 | |
| .SH FILES
 | |
| .TP \w'*/etc/*.confmmmm'u
 | |
| .B */etc/*.conf
 | |
| Several files in several
 | |
| .B etc
 | |
| directories.
 | |
| .SH "SEE ALSO"
 | |
| .BR configfile (5).
 | |
| .SH NOTES
 | |
| The syntax of a config file puts some constraints on what you find in memory.
 | |
| The top level list consists entirely of sublist cells.  These point to lists
 | |
| that start with at least an atom, followed by a mix of atoms and sublist cells.
 | |
| These sublists in turn point to a list of only sublist cells (recurse now.)
 | |
| .PP
 | |
| The struct config shown above is not exactly proper C to aid
 | |
| readability, read <configfile.h> itself to see why.
 | |
| .SH AUTHOR
 | |
| Kees J. Bot (kjb@cs.vu.nl)
 | 
