scripts / readconf /
Sébastien MARQUE commit initial
addf1bd 8 years ago
1 contributor
189 lines | 6.141kb
#!/usr/bin/awk -f

function evaluate (str) {
    for (j = 1; j <= length(str); j++) {
        if (substr(str, j, l_delimiters_begin) == var_delimiters_begin) {
            replacement = true
            k = ""
            j += l_delimiters_begin - 1
            continue
        }
        if (substr(str, j, l_delimiters_end) == var_delimiters_end) {
            replacement = false
            str = gensub(var_delimiters_begin k var_delimiters_end, conf[name][apply_case_sensivity(k)], "g", str)
            j -= l_delimiters_end k
            continue
        }
        if (replacement)
            k = k substr(str, j, 1)
    }
    return dq gensub(dq, "\\\\" dq, "g", str) dq
}

function apply_case_sensivity (str) {
    if (case_sensitive)
        return str
    else {
        if (default_case == "lower")
            return tolower(str)
        else
            return toupper(str)
    }
}

function print_version () {
    printf("%s version %s\n", appname, version)
}

function help (rc) {
    print_version()
    if (rc != "") {
        print "CLI error: " rc
        exit 1
    }
    exit 0
}

BEGIN {
# initialisation
    appname     = ENVIRON["_"]
    version     = "0.9"
    conf_arrays = ""
    filename    = ""
    sections    = ""
    dq          = "\""
    eol         = ORS
    true        = 1
    false       = 0
    clean       = false
    unset       = false
    sectionlist = false
    case_sensitive = false
    default_case = "lower"
    var_delimiters_begin = "{{{"
    var_delimiters_end   = "}}}"
    key_value_delimiter  = ""
    in_var_space_remplacement = ""

    for (arg = 1; arg < ARGC; arg++)
        switch (ARGV[arg]) {
            case /^--conf=["']?.+["']?$/:
                filename = gensub(/^--conf=["']?(.+)["']?$/, "\\1", "", ARGV[arg])
                break
            case "--sections-list":
                returnsectionlist = 1
                break
            case /^--section=["']?.+["']?$/:
                s = gensub(/^--section=["']?(.+)["']?$/, "\\1", "", ARGV[arg])
                onlysections[s] = true
                break
            case /^-s$/:
                s = gensub(/^["']?(.+)["']?$/, "\\1", "", ARGV[++arg])
                onlysections[s] = true
                break
            case /^--clean$/:
                clean = true
                break
            case /^--unset$/:
                unset = true
                break
            case /^--compact$/:
                eol = ";"
                break
            case /^--array=["']?.+["']?$/:
                conf_arrays = conf_arrays "|" gensub(/^--array=["']?(.+)["']?$/, "\\1", "", ARGV[arg])
                break
            case /^--var-delim-begin=["']?.{3,}["']?$/:
                var_delimiters_begin = gensub(/^--var-delim-begin=["']?(.{3,})["']?$/, "\\1", "", ARGV[arg])
                break
            case /^--var-delim-end=["']?.{3,}["']?$/:
                var_delimiters_end = gensub(/^--var-delim-end=["']?(.{3,})["']?$/, "\\1", "", ARGV[arg])
                break
            case /^--case-sensitive$/:
                 case_sensitive = true
                 break
            case /^--case-insensitive(|=lower|=UPPER)$/:
                 case_sensitive = false
                 default_case = gensub(/^--case-insensitive[=]?(.*)$/, "\\1", "", ARGV[arg])
                 if (default_case == "")
                     default_case = "lower"
                 break
            case /^--key-value-delimiter=["']?.["']?$/:
                 key_value_delimiter = gensub(/^--key-value-delimiter=["']?(.)["']?$/, "\\1", "", ARGV[arg])
                 break
            case /^--in-var-space-replacement=["']?.["']?$/:
                in_var_space_remplacement = gensub(/^--in-var-space-replacement=["']?(.)["']?$/, "\\1", "", ARGV[arg])
                break
            case /^help$/:
                 help()
                 break
            case /^version$/:
                 print_version()
                 exit
            default:
                help(ARGV[arg])
        }

    if (filename == "" || (getline < filename) < 0 ) exit 1
    close(filename)

    if (conf_arrays != "") {
        conf_arrays = gensub("^|", "", "", conf_arrays)
        if (key_value_delimiter != "")
            conf_arrays = gensub(/\s/, in_var_space_remplacement, "g", conf_arrays)
        conf_arrays = apply_case_sensivity(conf_arrays)
    }

    l_delimiters_begin = length(var_delimiters_begin)
    l_delimiters_end   = length(var_delimiters_end)

    while ((getline < filename) == 1) {
        if (/^\s*(|#.*)$/)
            continue

        # section
        if (/^\s*\[.+\]\s*$/) {
            name=gensub(/^\s*\[(.+)\]\s*$/, "\\1", "g")
            for (key in key_array)
                ptr[name][key_array[key]] = 0
            continue
        }

        # key (delimiter) value
        else if (name != "") {
            if (key_value_delimiter != "") {
                split($0, keyvalue, "[[:blank:]]*" key_value_delimiter "[[:blank:]]*")
                key   = gensub(/\s/, in_var_space_remplacement, "g", keyvalue[1])
                value = clean ? "" : keyvalue[2] #TODO: "join" toutes les valeurs
            }
            else {
                key = $1
                value = clean ? "" : gensub("^[[:blank:]]*" $1 "[[:blank:]]*", "", "")
            }
            key = apply_case_sensivity(key)
            if (key ~ "^(" conf_arrays ")$" && ! unset) 
                conf[name][key][++ptr[name][key]] = value
            else
                conf[name][key] = value
        }
    }

    if (returnsectionlist)
        for (name in conf)
            print name

    else for (name in onlysections)
        for (key in conf[name]) {
            if (key ~ "^(" conf_arrays ")$" && ! unset)
                for (i=1; i<=ptr[name][key]; i++) 
                    printf("%s[%i]=%s", key, i, evaluate(conf[name][key][i]) eol)
            
            else {
                if (unset)
                    printf("unset %s", key, evaluate(conf[name][key]) eol)
                else
                    printf("%s=%s", key, evaluate(conf[name][key]) eol)
            }
        }
}