diff --git a/parse_ini b/parse_ini index d2fa395..65d342f 100755 --- a/parse_ini +++ b/parse_ini @@ -1,45 +1,5 @@ #!/bin/bash -# http://en.wikipedia.org/wiki/INI_file: -# * Provides a good explanation of the ini format - use this for docs * -# * INI's have 'sections' and 'properties'. Properties have key = value format * -# -# Case insensitivity: Case is not changed, unless option used to covert to lower/upper case. -# Comments: Allow ; and # for comments. Must be on their own line. -# Blank lines: Blank lines are ignored. -# Escape chars: \ at the end of a line will continue it onto next (leading whitespace is removed per normal) -# Ordering: GLOBAL section must be at the top, sections continue until next section or EOF. - -# Duplicate names: Duplicate property values overwrite previous values. -# Provide an option to abort/error is duplicate is found? -# Add option to merge duplicates separated by octal byte (\036 ??) -# Duplicate sections are merged. Option to error if dup. -# Global properties: Support. Add to a GLOBAL section? -# Hierarchy: No hierarchy support. Each section is own section. -# Name/value delim: Use = by default. Allow : via option? -# Quoted values: Allow values to be within " and ' to keep literal formatting. -# Whitespace: Whitespace around section labels and []s is removed. -# Whitespace within section labels is kept / translated. -# Whitespace around property names is removed. -# Whitespace within property names is kept as is (spaces squashed - option to override). -# Property values have whitespace between = and data removed. -# Property values are kept as is (no squashing) - -# http://www.regular-expressions.info/posixbrackets.html -# http://ajdiaz.wordpress.com/2008/02/09/bash-ini-parser/ -# https://github.com/rudimeier/bash_ini_parser/blob/ff9d46a5503bf41b3344af85447e28cbaf95350e/read_ini.sh -# http://tldp.org/LDP/abs/html/ -# Specs: -# [section] Can be upper/lower/mixed case (set by options) -# Can only include: '-+_. [:alnum:]' -# # Any single or consecutive occurance of '-+_. ' are converted to a *single* _ -# # eg: [foo -+_. bar] becomes [foo_bar] ?? -# Any leading/trailing spaces/tabs between the []s and name will be removed. - - -# Notes: -# * To make env vars available to subsequent programs, use -x|--export. - parser_getopts() { local DELIM_SET=0 @@ -76,9 +36,44 @@ parser_getopts() { fi shift ;; - -h|-help|--help) + -e|-export|--export) + shift + DECLARE_SCOPE="-x" + ;; + -global-name|--global-name) + shift + if [[ -z "$1" ]]; then + echo "${0##*/}: global name (--global-name) cannot be an empty value" >&2 + return 1 + elif [[ "${1:0:1}" =~ [[:digit:]] ]]; then + echo "${0##*/}: global name (--global-name) cannot begin with a number" >&2 + return 1 + elif [[ "$1" =~ [^[:alnum:]_] ]]; then + echo "${0##*/}: only alphanumerics and _ allowed for global name (--global-name)" >&2 + else + CURRENT_SECTION="$1" + fi + shift + ;; + -h|-\?|-help|--help) parser_help - return 0 + return 2 + ;; + -l|-local|--local) + shift + DECLARE_SCOPE="-l" + ;; + -lowercase|--lowercase) + shift + CONVERT_CASE="-1" + ;; + -no-booleans|--no-booleans) + shift + USE_BOOLEANS="0" + ;; + -no-squash|--no-squash) + shift + SQUASH_SPACES=0 ;; -p|-prefix|--prefix) shift @@ -96,16 +91,24 @@ parser_getopts() { echo "${0##*/}: prefix (-p) cannot begin with a number" >&2 return 1 elif [[ "$1" =~ [^[:alnum:]_] ]]; then - echo "${0##*/}: invalid characters in prefix (-p) - alphanumerics and _ only" >&2 + echo "${0##*/}: only alphanumerics and _ allowed for prefix (-p)" >&2 return 1 else VARIABLE_PREFIX="$1" fi shift ;; + -textual-booleans|--textual-booleans) + shift + TEXTUAL_BOOLEANS="1" + ;; + -uppercase|--uppercase) + shift + CONVERT_CASE="1" + ;; -v|-version|--version) parser_version - return 0 + return 2 ;; --) # Stop option processing. @@ -137,93 +140,64 @@ parser_help() { Usage: ${0##*/} [options] Parse an INI-style file into array assignments which can be 'eval'ed into Bash. - Options: + Commonly used options: -b , --bound The bound character which delimits the key from the value in a property line of the INI file. The default is "=". This must be a single character and cannot be empty value. -d , --delim - The character(s) to use as a delimiter between the prefix and section name - when defining the arrays. The default is "_", except where prefix is set - to an empty value, in which case the default is also empty. Only - alphanumerics and _ may be used with this option, and it may not begin - with a number if prefix is empty. To use no delimintaor, use '-d ""'. + The character(s) (which may be an empty value) to use as a delimiter + between the prefix and section name when defining the arrays. The + default is "_", except where prefix is set to an empty value, in which + case the default is also empty. Only alphanumerics and _ may be used with + this option, and it may not begin with a number if prefix is empty. The + delimiter may be converted to upper or lower case depending upon the use + of '--uppercase' or '--lowercase'. + -e, --export + When declaring the arrays, export them to the environment. + -h, -?, --help + Show (this) help. + -l, --local + Declare the arrays as being local in scope, instead of the default of + global scope. -p , --prefix The prefix of all the variables set when defining the arrays. The default is "INI". An empty prefix (denoted by "") implies '-d ""', but this can be overridden by explicitly specifying a delimiter with '-d'. Only alphanumerics and _ may be used with this option, and it may not be empty - when delim ('-d) begins with a number. + when delim ('-d') begins with a number. + -v, --version + Show version and copyright information. - -i, --implied-boolean - Options usually require a value (after the =) in order to be set. - With this option, any key without a value contained in the ini file - if assumed to be a boolean 'true' and set accordingly. Likewise, any key - preceeded with 'no_' (eg: no_foo) will set the value of 'foo' to boolean 'false'. - Cannot be used with --no-boolean. - -c, --case-sensitive - Be case sensitive with section names and properties. - Section names and property names will be used as is - no translation. --d, --delim -The delimiter between the key and value. Must be a single character. Default = - -g, --global-name - INI files can contain an optional implied "global" section - where there - are property names/values before any [section] header. This option - specified what section name the implied "global" section should be given - in the environment variables which are set. The default is 'global'. - - -l, --lowercase - Usually, environment variables are converted to all uppercase before being set. - This option forces all environment variables to be converted to lowercase instead. - Note: This only effects the environment variable set with -e, and the section names - read from the ini file. Options are ?????????????????????????????????????? - -x, --export - Export environment variables. - - --no-boolean - Don't parse 'yes', 'true', 'on', 'no', 'false', 'off' into the corresponding boolean - values, and set the options strictly as is. Incompatible with -i. - --no-squash - Do not squash multiple consecutive occurances of punctuation characters - into a single _ when parsing section names and options. With this option - 'foo.-_bar' would become 'foo___bar' rather than 'foo_bar'. - --no-duplicates - If a duplicate section name or option name is found, report error and stop. - Usually sections with the same name will have their options merged, and - duplicate option values will overwrite previous ones. - -# -c, --check-only Only validate the ini file, don't parse it into the environment - --check - Check/validate the INI file by running it through the parser. Testing the - ini file will report any problems or syntax errors in the file, but will - not set up the environment variables as would happen in normal parsing. - Any parse errors are reported to stderr. When combined with the --debug - option, every detail of the parsing process is reported to stderr. - --debug - Show full details of the ini file parsing process. Detail is written to - stderr. Unless --test is used with this option, the parser will still - set up the environment as would happen normally, - -h, --help - Show (this) help. - -v, --version - Show version and copyright information. - # -b, --booleans Allow 'yes', 'true', 'on', 'no', 'false', 'off' to be used as values - # and interpited as boolean values. 'yes', 'true', 'on' set option value to "1". - # 'no', 'false', 'off' set option value to "0". - # -?, --???? Interprite the presense of an option name without any value as a boolean - # 'true', and no_