Skip to content
Serge Aleynikov edited this page Jun 13, 2020 · 18 revisions

SCON grammar

Simple CONfiguration (SCON) format is defined by the following grammar:

nodes := node
       | node   nodes
       | node , nodes
node  := pair
       | pair { nodes }
pair  := key
       | key   value
       | key = value
key   := string()
       | inc
       | fun
value := string()
       | integer()
       | float()
       | boolean()
inc   := $include string()
       | $include { string() }
       | $include string() { root = string() }
fun   := ${ string() } | $env{ string() }
       | $date{}
       | $path{}
  • Comments in SCON begin with "#".
  • Strings in SCON format can be included in single or double quotes.
  • Dollar sign inside strings must be escaped ($).
  • SCON configuration can contain the following dynamically evaluated functions: ${...}, $date{}, $path{}.
  • SCON grammer allows for the $include{} directive to include other SCON files at "almost" infinite depth.
  • Ignore macros in the form {{...}}. This feature allows to perform macro substitutions in strings at the post-parsing phase using explicit calls to the utxx::path::replace_macros() function.

Functions

  • ${...} or $env{...} - return the given environment variable. A special ${EXEPATH} variable returns the path of the currently running executable.
    config {
        key1 = ${HOME}
        key2 = "${A} $env{B} ${C}"
        key3 = "${EXEPATH}"
    }
  • $date{} - return the date. This function may contain formatting options acceptable by strftime(3). The function may additionally take two options:
    • now="YYYY-mm-dd HH:MM:SS"
    • utc=true | false
    config {
        key3 = $date{'%Y%m%d-%H:%M:%S', utc=true}
        key4 = $date{'%Y%m%d', now="2014-12-01 23:55:13"}
        key5 = "Time is: $date{'%Y%m%d-%H:%M:%S'}"
        key6 = "Home is: ${HOME}. Time is: $date{'%Y%m%d-%H:%M:%S at ${HOME}'}"
    }
  • $path{} - return formatted file path. It takes a path that may begin with "~" and may contain environment variables, date/time formatting options just like the $date{} function:
    • now="YYYY-mm-dd HH:MM:SS"
    • utc=true | false
    config {
        key7  = $path{'/var/log/%Y%m%d-%H%M%S-mqt.log', utc=true}
        key8  = $path{'${HOME}/var/config-%Y%m%d.log', now="2014-12-01 23:55:13"}
        key9  = "$path{'~/tmp/temp%H:%M:%S.log'}"
        key10 = "$path{'${EXEPATH}/tmp/temp%H:%M:%S.log'}"
        key11 = "$path{'~/tmp/{{instance}}.log.%Y%m%d'}"   # {{instance}} will be left verbatim
    }
  • $include{} - include a SCON file at the current location of the configuration tree. The file is searched either relative to the current working directory, or the directory of the file that calls the $include{} macro or is resolved using a special resolver function given to the parser. If a root node is specified in the include setting, then just a subtree portion of the given file will be included belonging to the given root child node.
    config {
        $include "base.config"                       # The whole tree of base.config in included here
        $include "other.config" { root = "logger" }  # The "logger" section of other.config is included here
    }

Examples are shown below:

test {
  key1 = "value1"            # Line comments start with a hash sign
  key2 = true                # Supported value types: str | int | double | bool

  key3   value3              # Equal sign is optional as well as double quotes
                             #   (in the absence of double quotes the data type
                             #    is inferred. Strings with spaces and special
                             #    characters have to be double quoted)

  key3a = "begin here" \     # Multiline strings can be wrapped with a slash
          "end here"
  
  key4 = 4, key5 = 5.0       # Key/value pairs can be separated by ','

  key6 = test1,              # Keys don't have to be unique
  key6 = test2,              # and before end of line keys can be comma-delimited

  key7 {                     # Keys can have unlimited hierarchy of child nodes
    key71 = true
    key72 = value72 {
      key721 = 100,
      key722 = 1.0
    }
  }

  key8{k1=1,k2=2}            # Some
  key9=value9{k1=1,k2=2}     #      more
  key9 value9{k1=1,k2=2}     #           examples

  key10 value10 {            # Child nodes can have values (e.g. "address")
    key101 = true            # Supported value types: str | int | double | bool
    $include "name.conf"     # Supports inclusion of other files at any level
  }

  $include{file=name.conf,
           root=/logger  }   # Include directive may specify that not the
                             # whole file needs to be included, but only the
                             # part matching the path

  # Valid include syntax:

  $include "filename"
  $include="filename"
  $include { "filename" }
  $include "filename" { root = "path.to.root.node" }
}

Using SCON format in C++

#include <utxx/variant_tree.hpp>
#include <utxx/variant_tree_parser.hpp>

utxx::config_tree cfg;
utxx::read_config("/path/to/file.config", cfg);

The example above reads "/path/to/file.config" and parses it into the configuration object cfg. Note that the parser identifies the format of the file by its extension, and can understand the SCON ("*.scon|*.config|*.conf|*.cfg"), XML ("*.xml"), and INI ("*.ini") file formats. utxx::config_tree class is derived from boost::property_tree, so the XML and INI parsing is natively done by that implementation, whereas SCON grammar parsing is implemented by utxx.

You can also construct the tree from a stream:

std::stringstream s; s << "config { key = 'value' }\n";
utxx::config_tree cfg;
utxx::read_config(s, cfg, utxx::FORMAT_SCON);

Clone this wiki locally