-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit awc_bash_ini_parser-0.3.tgz
- Loading branch information
0 parents
commit bce351a
Showing
25 changed files
with
734 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
|
||
COPYRIGHT | ||
========= | ||
|
||
Copyright (c) 2009 Kevin Porter / Advanced Web Construction Ltd | ||
(http://coding.tinternet.info / http://webutils.co.uk) | ||
|
||
|
||
USAGE | ||
===== | ||
|
||
You must source the bash file into your script: | ||
|
||
> . read_ini.sh | ||
|
||
and then use the read_ini function, defined as: | ||
|
||
> read_ini INI_FILE [SECTION] [[--prefix|-p] PREFIX] [[--booleans|b] [0|1]] | ||
|
||
If SECTION is supplied, then only the specified section of the file will | ||
be processed. | ||
|
||
After running the read_ini function, variables corresponding to the ini | ||
file entries will be available to you. Naming convention for variable | ||
names is: | ||
|
||
PREFIX__SECTION__VARNAME | ||
|
||
PREFIX is 'INI' by default (but can be changed with the --prefix option), | ||
SECTION and VARNAME are the section name and variable name respectively. | ||
For example, to read and output the variables of this ini file: | ||
|
||
-- START test1.ini file | ||
|
||
var1="VAR 1" | ||
var2 = VAR 2 | ||
|
||
[section1] | ||
var1="section1 VAR 1" | ||
var2= section1 VAR 2 | ||
|
||
|
||
-- END test1.ini file | ||
|
||
you could do this: | ||
|
||
-- START bash script | ||
|
||
. read_ini.sh | ||
|
||
read_ini test1.ini | ||
|
||
echo "var1 = ${INI__var1}" | ||
echo "var2 = ${INI__var2}" | ||
echo "section1 var1 = ${INI__section1__var1}" | ||
echo "section1 var2 = ${INI__section1__var2}" | ||
|
||
-- END bash script | ||
|
||
|
||
OPTIONS | ||
======= | ||
|
||
[--prefix | -p] PREFIX | ||
String to prepend to generated variable names (automatically followed by '__'). | ||
Default: INI | ||
|
||
[--booleans | -b] [0|1] | ||
Whether to interpret special unquoted string values 'yes', 'no', 'true', | ||
'false', 'on', 'off' as booleans. | ||
Default: 1 | ||
|
||
|
||
INI FILE FORMAT | ||
=============== | ||
|
||
- Variables are stored as name/value pairs, eg: | ||
var=value | ||
|
||
- Leading and trailing whitespace of the name and the value is discarded. | ||
|
||
- Use double or single quotes to get whitespace in the values | ||
|
||
- Section names in square brackets, eg: | ||
[section1] | ||
var1 = value | ||
|
||
- Variable names can be re-used between sections (or out of section), eg: | ||
var1=value | ||
[section1] | ||
var1=value | ||
[section3] | ||
var1=value | ||
|
||
- Dots are converted to underscores in all variable names. | ||
|
||
- Special boolean values: unquoted strings 'yes', 'true' and 'on' are interpreted | ||
as 1; 'no', 'false' and 'off' are interpreted as 0 | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
|
||
- Tabs/newlines to be preserved | ||
|
||
- [] notation for arrays (like PHP's parse_ini_file()) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
# | ||
# Copyright (c) 2009 Kevin Porter / Advanced Web Construction Ltd | ||
# (http://coding.tinternet.info, http://webutils.co.uk) | ||
# | ||
# Simple INI file parser. | ||
# | ||
# See README for usage. | ||
# | ||
# | ||
|
||
|
||
function read_ini() | ||
{ | ||
|
||
local INI_FILE="" | ||
local INI_SECTION="" | ||
|
||
# {{{ START Deal with command line args | ||
|
||
# Set defaults | ||
local BOOLEANS=1 | ||
local VARNAME_PREFIX=INI | ||
|
||
# {{{ START Options | ||
|
||
# Available options: | ||
# --boolean Whether to recognise special boolean values: ie for 'yes', 'true' | ||
# and 'on' return 1; for 'no', 'false' and 'off' return 0. Quoted | ||
# values will be left as strings | ||
# Default: on | ||
# | ||
# --prefix=STRING String to begin all returned variables with (followed by '__'). | ||
# Default: INI | ||
# | ||
# First non-option arg is filename, second is section name | ||
|
||
while [ $# -gt 0 ] | ||
do | ||
|
||
case $1 in | ||
|
||
--booleans | -b ) | ||
shift | ||
BOOLEANS=$1 | ||
;; | ||
|
||
--prefix | -p ) | ||
shift | ||
VARNAME_PREFIX=$1 | ||
;; | ||
|
||
* ) | ||
if [ -z "$INI_FILE" ] | ||
then | ||
INI_FILE=$1 | ||
else | ||
if [ -z "$INI_SECTION" ] | ||
then | ||
INI_SECTION=$1 | ||
fi | ||
fi | ||
;; | ||
|
||
esac | ||
|
||
shift | ||
done | ||
|
||
if [ -z "$INI_FILE" ] | ||
then | ||
echo "Usage: read_ini FILE [SECTION]" >&2 | ||
return 1 | ||
fi | ||
|
||
if [ ! -f "$INI_FILE" ] | ||
then | ||
echo "Error: ini file '${INI_FILE}' doesn't exist" >&2 | ||
return 1 | ||
fi | ||
|
||
# Be strict with the prefix, since it's going to be run through eval | ||
local PREFIX_BANNED_CHARS=$(echo "$VARNAME_PREFIX" | sed 's/[a-z0-9_]//ig') | ||
|
||
if [ -n "$PREFIX_BANNED_CHARS" ] | ||
then | ||
echo "Invalid characters ('${PREFIX_BANNED_CHARS}') in variable name prefix ('${VARNAME_PREFIX}')" >&2 | ||
return 1 | ||
fi | ||
|
||
# Prefix can't start with a number | ||
local FIRSTCHAR=${VARNAME_PREFIX:0:1} | ||
local BEGINS_WITH_NUMBER="" | ||
case $FIRSTCHAR in | ||
0|1|2|3|4|5|6|7|8|9) | ||
echo "Invalid variable name prefix - must not begin with a number" >&2 | ||
return 1 | ||
;; | ||
esac | ||
|
||
# Sanitise BOOLEANS - interpret "0" as 0, anything else as 1 | ||
if [ "$BOOLEANS" != "0" ] | ||
then | ||
BOOLEANS=1 | ||
fi | ||
|
||
|
||
# }}} END Options | ||
|
||
# }}} END Deal with command line args | ||
|
||
local LINE_NUM=0 | ||
local SECTION="" | ||
while read line | ||
do | ||
|
||
#echo line = "$line" | ||
|
||
((LINE_NUM++)) | ||
|
||
# Skip blank lines and comments | ||
if [ -z "$line" -o "${line:0:1}" = ";" -o "${line:0:1}" = "#" ] | ||
then | ||
continue | ||
fi | ||
|
||
# Section marker? | ||
local line_rev=$(echo "$line" | rev) | ||
if [ "${line:0:1}" = "[" ] && [ "${line_rev:0:1}" = "]" ] | ||
then | ||
|
||
# Set SECTION var to name of section (strip [ and ] from section marker) | ||
SECTION="${line#[}" | ||
SECTION="${SECTION%]}" | ||
|
||
continue | ||
fi | ||
|
||
# Are we getting only a specific section? And are we currently in it? | ||
if [ ! -z "$INI_SECTION" ] | ||
then | ||
if [ "$SECTION" != "$INI_SECTION" ] | ||
then | ||
continue | ||
fi | ||
fi | ||
|
||
# Valid var/value line? (check for variable name and then '=') | ||
local VAR_VAL=$(echo "$line" | awk 'BEGIN { FS="=" } /^[a-zA-Z0-9._-]+[[:space:]]*=/ { print $1,"__INI__PARSER__DELIMITER__",$2; }') | ||
#echo "VAR_VAL = *$VAR_VAL*" | ||
|
||
if [ -z "$VAR_VAL" ] | ||
then | ||
echo "Error: Invalid line:" >&2 | ||
echo " ${LINE_NUM}: $line" >&2 | ||
return 1 | ||
fi | ||
|
||
local VAR=$(echo "$VAR_VAL" | awk -F__INI__PARSER__DELIMITER__ '{print $1}') | ||
local VAL=$(echo "$VAR_VAL" | awk -F__INI__PARSER__DELIMITER__ '{sub(/^[[:space:]]+/,"",$2); print $2;}') | ||
VAR=$(echo $VAR) | ||
#echo VAL = $VAL | ||
|
||
|
||
# Construct variable name: | ||
# ${VARNAME_PREFIX}__$SECTION__$VAR | ||
# Or if not in a section: | ||
# ${VARNAME_PREFIX}__$VAR | ||
# In both cases, full stops ('.') are replaced with underscores ('_') | ||
if [ -z "$SECTION" ] | ||
then | ||
VARNAME=${VARNAME_PREFIX}__${VAR//./_} | ||
else | ||
VARNAME=${VARNAME_PREFIX}__${SECTION}__${VAR//./_} | ||
fi | ||
|
||
# Surround VAL with quotes if it isn't already | ||
local FIRSTCHAR=${VAL:0:1} | ||
local LASTCHAR=${VAL:$LEN-1:1} | ||
local DOUBLEQUOTES="" | ||
local SINGLEQUOTES="" | ||
|
||
if [ "$FIRSTCHAR" = '"' -a "$LASTCHAR" = '"' ] | ||
then | ||
DOUBLEQUOTES=1 | ||
fi | ||
|
||
if [ "$FIRSTCHAR" = "'" -a "$LASTCHAR" = "'" ] | ||
then | ||
SINGLEQUOTES=1 | ||
fi | ||
|
||
if [ -z "$SINGLEQUOTES" -a -z "$DOUBLEQUOTES" ] | ||
then | ||
# Value is not enclosed in quotes | ||
|
||
# If we have booleans processing switched on, check for special boolean | ||
# values and convert | ||
if [ "$BOOLEANS" == 1 ] | ||
then | ||
|
||
# Check length of string first. Since we're going to use tr command to convert | ||
# the string to lowercase, it'll be more efficient if we check string length | ||
# first. If value is more than 5 chars then it can't possibly be one of the | ||
# special boolean values | ||
if [ "${#VAL}" -le 5 ] | ||
then | ||
|
||
# Convert to lower case | ||
local VAL_LOWER=$(echo "$VAL" | tr '[:upper:]' '[:lower:]') | ||
|
||
case "$VAL_LOWER" in | ||
yes | true | on ) | ||
VAL=1 | ||
;; | ||
no | false | off ) | ||
VAL=0 | ||
;; | ||
esac | ||
fi | ||
|
||
fi | ||
|
||
# We'll enclose the value in double quotes now, so we must escape any | ||
# double quotes that may be in the value first | ||
VAL=$(echo "$VAL" | awk '{sub(/"/,"\\\"",$0); print $0;}') | ||
VAL="\"$VAL\"" | ||
fi | ||
|
||
# Replace $ and ` to prevent code running inside eval | ||
VAL=${VAL//\`/\\\`} | ||
VAL=${VAL//\$/\\\$} | ||
#declare -x $VARNAME="$VAL" | ||
eval "$VARNAME=$VAL" | ||
done < <(cat $INI_FILE) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
|
||
DIR=$(dirname $0) | ||
cd $DIR | ||
|
||
TESTS=$(ls test*.sh | grep -v test.sh | sed 's/\.sh$//') | ||
|
||
for test in $TESTS | ||
do | ||
|
||
bash $test.sh &> $test.out | ||
# bash $test.sh >$test.out 2>$test.err | ||
|
||
# Fail and bail out if test didn't pass | ||
PASSED=$(diff $test.out $test.out.correct 2>&1) | ||
if [ ! -z "$PASSED" ] | ||
then | ||
echo "Test $test failed. Output is in $DIR/$test.out" | ||
exit 1 | ||
else | ||
rm -rf $test.out | ||
fi | ||
|
||
done | ||
|
||
|
||
echo "All tests passed" | ||
|
||
|
Oops, something went wrong.