Allow multi-line config items in meta-section of local.conf

It would behave such as the contents from each meta-section in
local.conf is copied to the destination files. One exception is the multiline
options not grouped together. In that case, the contents will be grouped
together in its destination config file.

Check tests/test_config.sh for examples.

Change-Id: I8c046b558eeb98ed221f6f1a59182d4179956ced
Partial-Bug: #1374118
This commit is contained in:
Robert Li 2014-10-10 12:43:05 -04:00
parent cc87c2871d
commit 6ff21acf4c
3 changed files with 129 additions and 7 deletions

View File

@ -119,6 +119,33 @@ function ini_has_option {
[ -n "$line" ] [ -n "$line" ]
} }
# Add another config line for a multi-line option.
# It's normally called after iniset of the same option and assumes
# that the section already exists.
#
# Note that iniset_multiline requires all the 'lines' to be supplied
# in the argument list. Doing that will cause incorrect configuration
# if spaces are used in the config values.
#
# iniadd_literal config-file section option value
function iniadd_literal {
local xtrace=$(set +o | grep xtrace)
set +o xtrace
local file=$1
local section=$2
local option=$3
local value=$4
[[ -z $section || -z $option ]] && return
# Add it
sed -i -e "/^\[$section\]/ a\\
$option = $value
" "$file"
$xtrace
}
# Set an option in an INI file # Set an option in an INI file
# iniset config-file section option value # iniset config-file section option value
function iniset { function iniset {

View File

@ -86,7 +86,11 @@ function merge_config_file {
# having to do nasty quoting games # having to do nasty quoting games
get_meta_section $file $matchgroup $configfile | \ get_meta_section $file $matchgroup $configfile | \
$CONFIG_AWK_CMD -v configfile=$configfile ' $CONFIG_AWK_CMD -v configfile=$configfile '
BEGIN { section = "" } BEGIN {
section = ""
last_section = ""
section_count = 0
}
/^\[.+\]/ { /^\[.+\]/ {
gsub("[][]", "", $1); gsub("[][]", "", $1);
section=$1 section=$1
@ -106,10 +110,48 @@ function merge_config_file {
# need to strip leading & trailing whitespace from value # need to strip leading & trailing whitespace from value
sub(/^[ \t]*/, "", value) sub(/^[ \t]*/, "", value)
sub(/[ \t]*$/, "", value) sub(/[ \t]*$/, "", value)
print "iniset " configfile " " section " " attr " \x27" value "\x27"
# cfg_attr_count: number of config lines per [section, attr]
# cfg_attr: two dimensional array to keep all the config lines per [section, attr]
# cfg_section: keep the section names in the same order as they appear in local.conf
# cfg_sec_attr_name: keep the attr names in the same order as they appear in local.conf
if (! (section, attr) in cfg_attr_count) {
if (section != last_section) {
cfg_section[section_count++] = section
last_section = section
}
attr_count = cfg_sec_attr_count[section_count - 1]++
cfg_sec_attr_name[section_count - 1][attr_count] = attr
cfg_attr[section, attr][0] = value
cfg_attr_count[section, attr] = 1
} else {
lno = cfg_attr_count[section, attr]++
cfg_attr[section, attr][lno] = value
}
}
END {
# Process each section in order
for (sno = 0; sno < section_count; sno++) {
section = cfg_section[sno]
# The ini routines simply append a config item immediately
# after the section header. To keep the same order as defined
# in local.conf, invoke the ini routines in the reverse order
for (attr_no = cfg_sec_attr_count[sno] - 1; attr_no >=0; attr_no--) {
attr = cfg_sec_attr_name[sno][attr_no]
if (cfg_attr_count[section, attr] == 1)
print "iniset " configfile " " section " " attr " \x27" cfg_attr[section, attr][0] "\x27"
else {
# For multiline, invoke the ini routines in the reverse order
count = cfg_attr_count[section, attr]
print "iniset " configfile " " section " " attr " \x27" cfg_attr[section, attr][count - 1] "\x27"
for (l = count -2; l >= 0; l--)
print "iniadd_literal " configfile " " section " " attr " \x27" cfg_attr[section, attr][l] "\x27"
}
}
}
} }
' | while read a; do eval "$a"; done ' | while read a; do eval "$a"; done
} }

View File

@ -104,6 +104,27 @@ drivers = driver=python.import.path.Driver
[DEFAULT] [DEFAULT]
# next line has trailing space # next line has trailing space
attr = strip_trailing_space attr = strip_trailing_space
[[test-multi-sections|test-multi-sections.conf]]
[sec-1]
cfg_item1 = abcd
cfg_item2 = efgh
[sec-2]
cfg_item1 = abcd
cfg_item3 = /1/2/3/4:5
cfg_item4 = end
[sec-3]
cfg_item5 = 5555
cfg_item6 = 6666
cfg_item5 = 5555another
[[test-multiline|test-multiline.conf]]
[multi]
cfg_item1 = "ab":"cd", "ef": "gh"
cfg_item1 = abcd
cfg_item2 = efgh
EOF EOF
echo -n "get_meta_section_files: test0 doesn't exist: " echo -n "get_meta_section_files: test0 doesn't exist: "
@ -185,8 +206,39 @@ VAL=$(cat test2a.conf)
# iniset adds a blank line if it creates the file... # iniset adds a blank line if it creates the file...
EXPECT_VAL=" EXPECT_VAL="
[ddd] [ddd]
additional = true type = new
type = new" additional = true"
check_result "$VAL" "$EXPECT_VAL"
echo -n "merge_config_file test-multi-sections: "
rm -f test-multi-sections.conf
merge_config_file test.conf test-multi-sections test-multi-sections.conf
VAL=$(cat test-multi-sections.conf)
EXPECT_VAL='
[sec-1]
cfg_item1 = abcd
cfg_item2 = efgh
[sec-2]
cfg_item1 = abcd
cfg_item3 = /1/2/3/4:5
cfg_item4 = end
[sec-3]
cfg_item5 = 5555
cfg_item5 = 5555another
cfg_item6 = 6666'
check_result "$VAL" "$EXPECT_VAL"
echo -n "merge_config_file test-multiline: "
rm -f test-multiline.conf
merge_config_file test.conf test-multiline test-multiline.conf
VAL=$(cat test-multiline.conf)
EXPECT_VAL='
[multi]
cfg_item1 = "ab":"cd", "ef": "gh"
cfg_item1 = abcd
cfg_item2 = efgh'
check_result "$VAL" "$EXPECT_VAL" check_result "$VAL" "$EXPECT_VAL"
echo -n "merge_config_group test2: " echo -n "merge_config_group test2: "
@ -196,8 +248,8 @@ VAL=$(cat test2a.conf)
# iniset adds a blank line if it creates the file... # iniset adds a blank line if it creates the file...
EXPECT_VAL=" EXPECT_VAL="
[ddd] [ddd]
additional = true type = new
type = new" additional = true"
check_result "$VAL" "$EXPECT_VAL" check_result "$VAL" "$EXPECT_VAL"
echo -n "merge_config_group test2 no conf file: " echo -n "merge_config_group test2 no conf file: "
@ -268,4 +320,5 @@ attr = strip_trailing_space"
check_result "$VAL" "$EXPECT_VAL" check_result "$VAL" "$EXPECT_VAL"
rm -f test.conf test1c.conf test2a.conf test-quote.conf test-space.conf test-equals.conf test-strip.conf rm -f test.conf test1c.conf test2a.conf test-quote.conf test-space.conf test-equals.conf test-strip.conf
rm -f test-multiline.conf test-multi-sections.conf
rm -rf test-etc rm -rf test-etc