let daemon = let host = [ label "host" . Util.del_str "@" . store Rx.word ] in [ label "process" . store Rx.word . host? ]
A list of daemons
let daemon_list = Build.opt_list daemon comma
let database = let database_kw = "aliases" | "automount" | "bootparams" | "ethers" | "group" | "hosts" | "netgroup" | "netmasks" | "networks" | "passwd" | "protocols" | "publickey" | "rpc" | "sendmailvars" | "services" | "shadow" | "sudoers" in [ label "database" . store database_kw . sep_colon . (Build.opt_list (service|reaction) Sep.space) . Util.eol ]
TODO: support for quoted strings
let database = comma_sep_list "database"
let dayofmonth = [ label "dayofmonth" . store num ]
let dayofweek = [ label "dayofweek" . store alphanum ]
A debian-specific section, made of debian_entry lines
let debian = [ label "debian" . del debian_header debian_header . (debian_comment|empty|debian_entry)* . del debian_footer debian_footer ]
A comment entry inside a debian-specific section
let debian_comment = [ Util.indent . label "#comment" . del /##[ \t]*/ "## " . store debian_comment_re . eol ]
let debian_comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/ - "## End Default Options ##"
let debian_entry = [ Util.del_str "#" . Util.indent . key debian_setting_re . del /[ \t]*=/ "=" . value_to_eol? . eol ]
Footer for a debian-specific section
let debian_footer = "## ## End Default Options ##\n"
Header for a debian-specific section
let debian_header = "## ## Start Default Options ##\n"
let debian_setting_re = "kopt" | "groot" | "alternative" | "lockalternative" | "defoptions" | "lockold" | "xenhopt" | "xenkopt" | "altoptions" | "howmany" | "memtest86" | "updatedefaultentry" | "savedefault" | "indomU"
A decimal value (using ‘,’ or ‘.’
let decimal = /[0-9]+([.,][0-9]+)?/
!ELEMENT declaration tags are mapped in “!ELEMENT” nodes.
test Xml.decl_def_item get "<!ELEMENT greeting (#PCDATA)>" = { "!ELEMENT" = "greeting" { "#decl" = "(#PCDATA)" } }
A full configuration
let default_approx = "# The following are the defaults, so there is no need # to uncomment them unless you want a different value. # See approx.conf(5) for details. $interface any $port 9999 $interval 720 $max_wait 10 $max_rate unlimited $debug false # Here are some examples of remote repository mappings. # See http://www.debian.org/mirror/list for mirror sites. debian http://ftp.nl.debian.org/debian debian-volatile http://ftp.nl.debian.org/debian-volatile security http://security.debian.org "
let default_depth = entry_int "DefaultDepth" /[dD]efault[dD]epth/
Type definition for defaults
let default_type = let value = store /[@:!>][^ \t\n\\]+/ in [ label "type" . value ]
A defaults section
let defaults = IniFile.record defaults_title ((Util.indent . (defaults_entry|common_entry)) | comment)
A Defaults entry
let defaults = [ indent . key "Defaults" . default_type? . sep_cont . parameter_list . comment_or_eol ]
Possible entries under the defaults section
let defaults_entry = entry_sto "force_undo" ("true"|"false") | entry_sto "fs_type" Rx.word | entry_sto "undo_dir" Rx.fspath
Title for the defaults section
let defaults_title = IniFile.title "defaults"
Delete an even number of ‘!’
let del_negate = del /(!!)*/ ""
Delete optional whitespace
let del_opt_ws = del /[ \t]*/
Delete a string and default to it
let del_str (s:string) = del s s
let del_to_eol = del /[^ \t\n]*/ ""
Delete mandatory whitespace
let del_ws = del /[ \t]+/
Delete mandatory whitespace, default to single space
let del_ws_spc = del_ws " "
Delete mandatory whitespace, default to single tab
let del_ws_tab = del_ws "\t"
let dels (s:string) = Util.del_str s
Descriptions are special entries, which can have an optional lang parameter
let description = let lang = [ Util.del_str "[" . label "lang" . store IniFile.entry_re . Util.del_str "]" ] in [ key "description" . lang? . sep . IniFile.sto_to_comment? . (comment|IniFile.eol) ]
Can be either a word (no spaces included) or a command with spaces
let destination = ( word | command )
let device = [ label "device" . store Rx.fspath ]
This is a shell-only directive in upstream grub; the grub versions in at least Fedora/RHEL use this to find devices for UEFI boot
let device = [ command "device" "" . Sep.space . store /\([A-Za-z0-9_.-]+\)/ . spc . [ label "file" . value_to_eol ] . Util.eol ]
let device = entry_str "Device" /[dD]evice/
A Linux device name like eth0 or i2c-0.
let device_name = /[a-zA-Z0-9_?.+:!-]+/
let disk = [ label "disk" . store /[^., \t\n]+/ . partition? ]
let disk_config = let other_label = Rx.fspath - "lvm" - "raid" - "end" - /disk[0-9]+/ - "cryptsetup" - "tmpfs" in disk_config_entry "lvm" lvmoption volume_lvm | disk_config_entry "raid" raidoption volume_raid | disk_config_entry "tmpfs" option volume_tmpfs | disk_config_entry "end" option volume (* there shouldn't be an option here *) | disk_config_entry /disk[0-9]+/ option volume | disk_config_entry "cryptsetup" cryptoption volume_cryptsetup | disk_config_entry other_label option volume
Test FAI_DiskConfig.disk_config
test FAI_DiskConfig.disk_config get "disk_config hda preserve_always:6,7 disklabel:msdos bootable:3\n" = { "disk_config" = "hda" { "preserve_always" { "1" = "6" } { "2" = "7" } } { "disklabel" = "msdos" } { "bootable" = "3" } }
let disk_config_entry (kw:regexp) (opt:lens) (vol:lens) = [ key "disk_config" . space . store kw . (space . opt)* . eol . (volume_or_comment vol)? ]
A list of disk_with_opts
let disk_list = Build.opt_list disk_with_opt Sep.comma
A disk with a spare/missing option for raids
let disk_with_opt = [ label "disk" . store /[^:., \t\n]+/ . partition? . spare_missing* ]
let display = [ indent . del "SubSection" "SubSection" . sep_spc . sep_dquote . key "Display" . sep_dquote . eol . display_entry* . indent . del "EndSubSection" "EndSubSection" . eol ]
Known values for entries in the Display subsection
let display_entry = entry_int "Depth" /[dD]epth/ | entry_int "FbBpp" /[fF]b[bB]pp/ | entry_rgb "Weight" /[wW]eight/ | entry_xy "Virtual" /[vV]irtual/ | entry_xy "ViewPort" /[vV]iew[pP]ort/ | display_modes | entry_str "Visual" /[vV]isual/ | entry_rgb "Black" /[bB]lack/ | entry_rgb "White" /[wW]hite/ | entry_str "Options" /[oO]ptions/ | empty | comment
let display_modes = [ indent . del /[mM]odes/ "Modes" . label "Modes" . [ label "mode" . sep_spc . quoted_string_val ]+ . eol ]
Test input1 with Xml.doc
test Xml.doc get input1 = { "#declaration" { "#attribute" { "version" = "1.0" } { "encoding" = "UTF-8" } } } { "html" { "#text" = "\n " } { "head" { "#text" = "\n " } { "title" { "#text" = "Wiki" } } { "#text" = " " } } { "#text" = " " } { "body" { "#text" = " " } { "h1" { "#text" = "Augeas" } } { "#text" = " " } { "p" { "#attribute" { "class" = "main" } } { "#text" = "Augeas is now able to parse XML files!" } } { "#text" = " " } { "ul" { "#text" = "\n " } { "li" { "#text" = "Translate from XML to a tree syntax" } } { "#text" = " " } { "li" { "#text" = "Translate from the tree back to XML" } } { "#text" = " " } { "#comment" = " this is some comment " } { "#text" = " " } { "li" { "#text" = "this" } } { "#text" = " " } } { "#text" = " " } } }
!DOCTYPE tags are mapped in “!DOCTYPE” nodes.
test Xml.doctype get "<!DOCTYPE greeting SYSTEM \"hello.dtd\">" = { "!DOCTYPE" = "greeting" { "SYSTEM" = "hello.dtd" } }
let domain = Build.key_value_line_comment "domain" Sep.space (store Rx.word) comment_eol
Deletes a dot and default to it
let dot = Util.del_str "."
let driver = entry_str "Driver" /[dD]river/