Skip to content

Instantly share code, notes, and snippets.

@DanielO
Created December 12, 2013 01:10
Show Gist options
  • Save DanielO/7921624 to your computer and use it in GitHub Desktop.
Save DanielO/7921624 to your computer and use it in GitHub Desktop.
#!/bin/sh
. /usr/share/bsdconfig/struct.subr || exit 1
parse_geom_confxml()
{
# NB: Change "echo" to "eval" below to perform the output
echo "$( sysctl -n kern.geom.confxml | awk '
BEGIN {
struct_count["class"] = 0
struct_count["geom"] = 0
struct_count["consumer"] = 0
struct_count["provider"] = 0
}
############################################### FUNCTIONS
function set_value(prop, value)
{
if (!struct_stack[cur_struct]) return failure
printf "%s set %s \"%s\"\n",
struct_stack[cur_struct], prop, value
}
function create(type, id)
{
if (struct = created[type "_" id]) {
print "f_struct_free", struct
print "f_struct_new GEOM_" toupper(type), struct
} else {
struct = struct_stack[cur_struct]
struct = struct ( struct ? "" : "geom" )
struct = struct "_" type "_" ++struct_count[type]
print "f_struct_new GEOM_" toupper(type), struct
}
struct_stack[++cur_struct] = struct
set_value("id", id)
}
function extract_attr(field, attr)
{
if (match(field, attr "=\"0x[[:xdigit:]]+\"")) {
len = length(attr)
return substr($2, len + 3, RLENGTH - len - 3)
}
}
function extract_data(type)
{
data = $0
sub("^[[:space:]]*<" type ">", "", data)
sub("</" type ">.*$", "", data)
return data
}
############################################### OPENING PATTERNS
$1 ~ /^<mesh/ { mesh = 1 }
$1 ~ /^<(class|geom|consumer|provider)$/ && mesh {
if ((ref = extract_attr($2, "ref")) != "")
set_value(substr($1, 2) "_ref", ref)
else if ((id = extract_attr($2, "id")) != "")
create(substr($1, 2), id)
}
############################################### PROPERTIES
$1 ~ /^<[[:alnum:]]+>/ {
prop = $1
sub(/^</, "", prop); sub(/>.*/, "", prop)
set_value(prop, extract_data(prop))
}
############################################### CLOSING PATTERNS
$1 ~ "^</(consumer|provider)>$" {
cur_struct--
}
$1 == "</geom>" {
cur_struct--
set_value("nconsumers", struct_count["consumer"])
set_value("nproviders", struct_count["provider"])
struct_count["consumer"] = 0
struct_count["provider"] = 0
}
$1 == "</class>" {
set_value("ngeoms", struct_count["geom"])
cur_struct--
struct_count["consumer"] = 0
struct_count["provider"] = 0
struct_count["geom"] = 0
}
$1 == "</mesh>" {
printf "NGEOM_CLASSES=%u\n", struct_count["class"]
delete struct_count
mesh = 0
}
' )"
}
parse_geom_confxml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment