summaryrefslogtreecommitdiff
path: root/src/parseconf.sh
blob: abc6b36721a94d43281bfd86a55ce896174611a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/bin/sh

usage () {
    printf "Usage $0 "
    echo << "EOF"
OPTIONS... [FILTER]

Print the parsed config file filtering by the keys
Arguments:
    -f file         read configuration from a file, uses /dev/sdtin otherwise
    -v              only print values
    -c n            print the last [n]
EOF
}

# parse a single config file line
#
parse_line() {
    [ $# = "0" ] && return

    local line="$@"
    local key=$1
    shift
    local value="$@"

    case $key in 
        "include")
            cat $value | parse
            return
            ;;
        "]")
            IFS=. 
            set -- $list
            list="${*%${!#}}"
            IFS=" " 
            printf "\n"
            return
            ;;
        "}")
            [ "$level" = "${level%.*}" ] &&
                level="" || level=${level%.*}
            return
            ;;
    esac

    case ${value##* } in 
        "{")
            level="${level}${level:+.}${key}"
            ;;
        "[")
            list="${list}${list:+.}${key}"
            printf "$level${level:+.}$key:"
            ;;
        *)

            [ "${#list}" = "0" ] && 
                printf "$level${level:+.}$key:$value\n" ||
                printf "$line "
            ;;
    esac
}

# print the parsed values from the config file in key:value format
#
parse () {
    local file="$1"

    export level=""
    export list=""
    while IFS= read -r line; do
        parse_line $line 
    done < "/dev/stdin" 
}

# Use the env variable if exists
[ -z ${CONF_FILE} ] && CONF_FILE="/dev/stdin"

# initialise options
print_keys=true
count=

while getopts ":f:c:v" opt; do
    case "${opt}" in 
        f)
            [ "${OPTARG}" = "-" ] &&
                CONF_FILE="/dev/stdin" ||
                CONF_FILE="${OPTARG}"
            ;;

        v)
            print_keys=false
            ;;
        c)
            count="${OPTARG}q"
            ;;
        *)
    esac
done

shift $((OPTIND-1))

[ $# = 0 ] &&
    pattern=".*" ||
    pattern=$(echo $@ | sed "s/\*/[^:]*/g")

$print_keys && 
    pattern="s/^($pattern:.+)/\1/p;${count}" ||
    pattern="s/^$pattern:(.+)/\1/p;${count}"

# strip whitespace
sed "s/^#.*$\|\s(\s\+)\|^\s\|\s^\|;*$//g" $CONF_FILE |
    parse $@ | 
    sed -rn $pattern