Move config spec into a README.md file for the config package.

This commit is contained in:
Sasha Koshka 2024-08-23 01:50:30 -04:00
parent 0ebf3ff4cc
commit 1e92134a38
2 changed files with 80 additions and 41 deletions

78
config/README.md Normal file
View File

@ -0,0 +1,78 @@
# config
Package config provides a configuration system for applications.
## Config File Location
Config files are stored in standard operating system locations. Each application
has exactly one user-level config directory within the user-level config
location, and a system-level subdirectory in each of the system-level config
locations (if applicable). Each subdirectory bears the application's well-known
name as specified in ApplicationDescription. Each subdirectory contains a file
called config.conf, which is where the actual config data is stored.
The user-level configuration file takes precendence over system configuration
files, and system configuration files take precedence over eachother depending
on what order they are specified in. How they are specified depends on the
operating system.
### Linux, Most Unixes
In terms of the XDG Base Directory Specification, an application with the
well-known name com.example.Example would have its config files stored at
`$XDG_CONFIG_DIRS/com.example.Example/config.conf`. On most systems where this
specification is applicable, this will result in a file at
`/etc/xdg/com.example.Example/config.conf` and another at
`$HOME/.config/com.example.Example/config.conf`. The location for config files
on systems that do not make use of this specification is yet to be determined.
## Config File Format
The general format of the file is as follows:
- Encoded in UTF-8
- Consists of lines, separated by \n, or \r\n
- Lines can be any of these:
- Blank line: has only whitespace
- Comment: begins with a '#'
- Entry: a key/value pair separated by an '=' sign
### Entries
For entries, all whitespace on either side of the '=' sign, the key, or the
value is ignored. The key may contain any letter or digit, as well as '-' and
'.'. The value is always identified by its first rune (after the preliminary
whitespace of course) and can be one of:
- String
- Number
- Bool
#### String
A string can be either double-quoted, or any string of runes not identifiable
as any other kind of value. Quoted strings are always unquoted when they are
read. Either way, these escape sequences are supported, and resolved when they
are read:
- '\\\\': a literal backslash
- '\a': alert, bell
- '\b': backspace
- '\t': horizontal tab
- '\n': line feed
- '\v': vertical tab
- '\f': form feed
- '\r': carriage return
- '\\"': double quote
Be aware that some unquoted strings, within reason, are subject to being read
as some other value in the future. For example, if there were suddenly a
third boolean value called glorble, the unquoted string glorble would be read
as a boolean value instead of a string.
#### Number
A number is a floating point value. It can be of the form:
- Inf: positive infinity
- -Inf: negative infinity
- NaN: "not a number"
- [0-9]+: a whole number
- [0-9]+\.[0-9]*: a fractional number
#### Bool
A bool is a boolean value. It can be one of:
- true
- false

View File

@ -31,47 +31,8 @@ func NewFile () *File {
// Parse parses a config file from a reader. This function operates on a // Parse parses a config file from a reader. This function operates on a
// best-effort basis: A file will always be returned, and any errors encountered // best-effort basis: A file will always be returned, and any errors encountered
// will be joined together. // will be joined together. For a description of the format, see the README.md
// // of this package.
// The general format of the file is as follows:
// - Encoded in UTF-8
// - Consists of lines, separated by \n, or \r\n
// - Lines can be any of these:
// - Blank line: has only whitespace
// - Comment: begins with a '#'
// - Entry: a key/value pair separated by an '=' sign
//
// For entries, all whitespace on either side of the '=' sign, the key, or the
// value is ignored. The key may contain any letter or digit, as well as '-'
// and '.'. The value is always identified by its first rune (after the
// preliminary whitespace of course) and can be one of:
// - String: either a double-quoted string, or any string of runes not
// identifiable as any other kind of value. The quoted string is always
// unquoted when it is read. Either way, these escape sequences are
// supported, and resolved when they are read:
// - '\\': a literal backslash
// - '\a': alert, bell
// - '\b': backspace
// - '\t': horizontal tab
// - '\n': line feed
// - '\v': vertical tab
// - '\f': form feed
// - '\r': carriage return
// - '\"': double quote
// - Number: a floating point value. It can be of the form:
// - Inf
// - -Inf
// - NaN
// - [0-9]+
// - [0-9]+\.[0-9]*
// - Bool: a boolean value. It can be one of:
// - true
// - false
//
// Be aware that some unquoted strings, within reason, are subject to being read
// as some other value in the future. For example, if there were suddenly a
// third boolean value called glorble, the unquoted string glorble would be read
// as a boolean value instead of a string.
func Parse (reader io.Reader) (*File, error) { func Parse (reader io.Reader) (*File, error) {
file := &File { file := &File {
keys: make(map[string] int), keys: make(map[string] int),