#!/usr/bin/gawk -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 cli_error (rc) { print "CLI error: " rc exit 1 } function help (rc) { line = appname "\nversion " version "\n\n\033[4mOPTIONS:\033[0m" while (getline < appname) { if (/^#help:BEGIN/) help_started = 1 if (/^#help:END/) help_started = 0 if (help_started) { if (/^[[:blank:]]*case \/\^(.+)\$\/[[:blank:]]*:[[:blank:]]*$/) { option = gensub(/^[[:blank:]]*case \/\^(.+)\$\/[[:blank:]]*:[[:blank:]]*$/, "\\1", "1") line = line "\n\n\033[1m" option "\033[0m" } else if (/^#help:/ && option != "") { split($0, helpinfo, ":") line = line "\n" helpinfo[2] } } } print line | "pager -R" exit 0 } BEGIN { # initialisation appname = ENVIRON["_"] version = "1.0.0" 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 = "" first_element_index = 0 for (arg = 1; arg < ARGC; arg++) switch (ARGV[arg]) { #help:BEGIN case /^--conf=["']?.+["']?$/: #help:file containing the configuration to read filename = gensub(/^--conf=["']?(.+)["']?$/, "\\1", "1", ARGV[arg]) break case /^--conf$/: #help:file containing the configuration to read filename = gensub(/^["']?(.+)["']?$/, "\\1", "1", ARGV[++arg]) break case "--sections-list": #help:list all sections found in given config file returnsectionlist = 1 break case /^--section=["']?.+["']?$/: #help:retrieve information for section
s = gensub(/^--section=["']?(.+)["']?$/, "\\1", "1", ARGV[arg]) onlysections[s] = true break # case /^-s$/: ##help:retrieve information for section
# s = gensub(/^["']?(.+)["']?$/, "\\1", "1", ARGV[++arg]) # onlysections[s] = true # break case /^--clean$/: #help:output commands to clean all variables listed in configuration clean = true break case /^--unset$/: #help:output commands to unset variables listed in configuration file unset = true break case /^--compact$/: #help:output everything on a single line, elements seperated by semi-colon eol = ";" break case /^--array=["']?.+["']?$/: #help:learns the script this entry is intented to be treated as an array, can be used multiple times for multiples array names arrayname=gensub(/^--array=["']?(.+)["']?$/, "\\1", "1", ARGV[arg]) conf_arrays = conf_arrays "|" arrayname key_array[arrayname]++ break case /^--first-element-array=[01]$/: #help:tells the script the array index begins at 0 or 1, defaults to 0 first_element_index = gensub(/^--first-element-array=([01])$/, "\\1", "1", ARGV[arg]) break case /^--var-delim-begin=["']?.{3,}["']?$/: #help:tells the script what is the starting chars sequence to delimitate a variable, defaults to {{{, can be -+= (for example) var_delimiters_begin = gensub(/^--var-delim-begin=["']?(.{3,})["']?$/, "\\1", "1", ARGV[arg]) break case /^--var-delim-end=["']?.{3,}["']?$/: #help:tells the script what is the ending chars sequence to delimitate a variable, defaults to }}}, can be =+- (for example) var_delimiters_end = gensub(/^--var-delim-end=["']?(.{3,})["']?$/, "\\1", "1", ARGV[arg]) break case /^--case-sensitive$/: #help:tells the script if it has to be case-sensitive, defaults to insensitive case_sensitive = true break case /^--case-insensitive(|=lower|=UPPER)$/: #help:tells the script how to behave in insensitive mode (default) #help: lower = variables output in lowercase (default) #help: UPPER = variables output in UPPERCASE case_sensitive = false default_case = gensub(/^--case-insensitive[=]?(.*)$/, "\\1", "1", ARGV[arg]) if (default_case == "") default_case = "lower" break case /^--key-value-delimiter=["']?.["']?$/: #help:tells the script which char is used to separate the key from its assorciated value in the configuration file, defaults to blank-char key_value_delimiter = gensub(/^--key-value-delimiter=["']?(.)["']?$/, "\\1", "1", ARGV[arg]) break case /^--in-var-space-replacement=["']?.["']?$/: #help:tells the script which char to use to replace a space found in a key, defaults to empty in_var_space_remplacement = gensub(/^--in-var-space-replacement=["']?(.)["']?$/, "\\1", "1", ARGV[arg]) break case /^help$/: #help:show this help help() break case /^version$/: #help:show the version of the script print_version() exit #help:END default: cli_error(ARGV[arg]) } if (filename == "" || (getline < filename) < 0 ) exit 1 close(filename) if (conf_arrays != "") { conf_arrays = gensub("^|", "", "1", 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] = first_element_index 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:]]*", "", "1") } 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=first_element_index; i