Browse code

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

Jenkins authored on 2014/10/17 07:51:25
Showing 3 changed files
... ...
@@ -119,6 +119,33 @@ function ini_has_option {
119 119
     [ -n "$line" ]
120 120
 }
121 121
 
122
+# Add another config line for a multi-line option.
123
+# It's normally called after iniset of the same option and assumes
124
+# that the section already exists.
125
+#
126
+# Note that iniset_multiline requires all the 'lines' to be supplied
127
+# in the argument list. Doing that will cause incorrect configuration
128
+# if spaces are used in the config values.
129
+#
130
+# iniadd_literal config-file section option value
131
+function iniadd_literal {
132
+    local xtrace=$(set +o | grep xtrace)
133
+    set +o xtrace
134
+    local file=$1
135
+    local section=$2
136
+    local option=$3
137
+    local value=$4
138
+
139
+    [[ -z $section || -z $option ]] && return
140
+
141
+    # Add it
142
+    sed -i -e "/^\[$section\]/ a\\
143
+$option = $value
144
+" "$file"
145
+
146
+    $xtrace
147
+}
148
+
122 149
 # Set an option in an INI file
123 150
 # iniset config-file section option value
124 151
 function iniset {
... ...
@@ -86,7 +86,11 @@ function merge_config_file {
86 86
     # having to do nasty quoting games
87 87
     get_meta_section $file $matchgroup $configfile | \
88 88
     $CONFIG_AWK_CMD -v configfile=$configfile '
89
-        BEGIN { section = "" }
89
+        BEGIN {
90
+            section = ""
91
+            last_section = ""
92
+            section_count = 0
93
+        }
90 94
         /^\[.+\]/ {
91 95
             gsub("[][]", "", $1);
92 96
             section=$1
... ...
@@ -106,10 +110,48 @@ function merge_config_file {
106 106
             # need to strip leading & trailing whitespace from value
107 107
             sub(/^[ \t]*/, "", value)
108 108
             sub(/[ \t]*$/, "", value)
109
-            print "iniset " configfile " " section " " attr " \x27" value "\x27"
109
+
110
+            # cfg_attr_count: number of config lines per [section, attr]
111
+            # cfg_attr: three dimensional array to keep all the config lines per [section, attr]
112
+            # cfg_section: keep the section names in the same order as they appear in local.conf
113
+            # cfg_sec_attr_name: keep the attr names in the same order as they appear in local.conf
114
+            if (! (section, attr) in cfg_attr_count) {
115
+                if (section != last_section) {
116
+                    cfg_section[section_count++] = section
117
+                    last_section = section
118
+                }
119
+                attr_count = cfg_sec_attr_count[section_count - 1]++
120
+                cfg_sec_attr_name[section_count - 1, attr_count] = attr
121
+
122
+                cfg_attr[section, attr, 0] = value
123
+                cfg_attr_count[section, attr] = 1
124
+            } else {
125
+                lno = cfg_attr_count[section, attr]++
126
+                cfg_attr[section, attr, lno] = value
127
+            }
128
+        }
129
+        END {
130
+            # Process each section in order
131
+            for (sno = 0; sno < section_count; sno++) {
132
+                section = cfg_section[sno]
133
+                # The ini routines simply append a config item immediately
134
+                # after the section header. To keep the same order as defined
135
+                # in local.conf, invoke the ini routines in the reverse order
136
+                for (attr_no = cfg_sec_attr_count[sno] - 1; attr_no >=0; attr_no--) {
137
+                    attr = cfg_sec_attr_name[sno, attr_no]
138
+                    if (cfg_attr_count[section, attr] == 1)
139
+                        print "iniset " configfile " " section " " attr " \x27" cfg_attr[section, attr, 0] "\x27"
140
+                    else {
141
+                        # For multiline, invoke the ini routines in the reverse order
142
+                        count = cfg_attr_count[section, attr]
143
+                        print "iniset " configfile " " section " " attr " \x27" cfg_attr[section, attr, count - 1] "\x27"
144
+                        for (l = count -2; l >= 0; l--)
145
+                            print "iniadd_literal " configfile " " section " " attr " \x27" cfg_attr[section, attr, l] "\x27"
146
+                    }
147
+                }
148
+            }
110 149
         }
111 150
     ' | while read a; do eval "$a"; done
112
-
113 151
 }
114 152
 
115 153
 
... ...
@@ -108,6 +108,27 @@ attr = strip_trailing_space
108 108
 [[test7|test-colon.conf]]
109 109
 [DEFAULT]
110 110
 servers=10.11.12.13:80
111
+
112
+[[test-multi-sections|test-multi-sections.conf]]
113
+[sec-1]
114
+cfg_item1 = abcd
115
+cfg_item2 = efgh
116
+
117
+[sec-2]
118
+cfg_item1 = abcd
119
+cfg_item3 = /1/2/3/4:5
120
+cfg_item4 = end
121
+
122
+[sec-3]
123
+cfg_item5 = 5555
124
+cfg_item6 = 6666
125
+cfg_item5 = 5555another
126
+
127
+[[test-multiline|test-multiline.conf]]
128
+[multi]
129
+cfg_item1 = "ab":"cd", "ef":   "gh"
130
+cfg_item1 = abcd
131
+cfg_item2 = efgh
111 132
 EOF
112 133
 
113 134
 echo -n "get_meta_section_files: test0 doesn't exist: "
... ...
@@ -189,8 +210,39 @@ VAL=$(cat test2a.conf)
189 189
 # iniset adds a blank line if it creates the file...
190 190
 EXPECT_VAL="
191 191
 [ddd]
192
-additional = true
193
-type = new"
192
+type = new
193
+additional = true"
194
+check_result "$VAL" "$EXPECT_VAL"
195
+
196
+echo -n "merge_config_file test-multi-sections: "
197
+rm -f test-multi-sections.conf
198
+merge_config_file test.conf test-multi-sections test-multi-sections.conf
199
+VAL=$(cat test-multi-sections.conf)
200
+EXPECT_VAL='
201
+[sec-1]
202
+cfg_item1 = abcd
203
+cfg_item2 = efgh
204
+
205
+[sec-2]
206
+cfg_item1 = abcd
207
+cfg_item3 = /1/2/3/4:5
208
+cfg_item4 = end
209
+
210
+[sec-3]
211
+cfg_item5 = 5555
212
+cfg_item5 = 5555another
213
+cfg_item6 = 6666'
214
+check_result "$VAL" "$EXPECT_VAL"
215
+
216
+echo -n "merge_config_file test-multiline: "
217
+rm -f test-multiline.conf
218
+merge_config_file test.conf test-multiline test-multiline.conf
219
+VAL=$(cat test-multiline.conf)
220
+EXPECT_VAL='
221
+[multi]
222
+cfg_item1 = "ab":"cd", "ef":   "gh"
223
+cfg_item1 = abcd
224
+cfg_item2 = efgh'
194 225
 check_result "$VAL" "$EXPECT_VAL"
195 226
 
196 227
 echo -n "merge_config_group test2: "
... ...
@@ -200,8 +252,8 @@ VAL=$(cat test2a.conf)
200 200
 # iniset adds a blank line if it creates the file...
201 201
 EXPECT_VAL="
202 202
 [ddd]
203
-additional = true
204
-type = new"
203
+type = new
204
+additional = true"
205 205
 check_result "$VAL" "$EXPECT_VAL"
206 206
 
207 207
 echo -n "merge_config_group test2 no conf file: "
... ...
@@ -281,4 +333,5 @@ servers = 10.11.12.13:80"
281 281
 check_result "$VAL" "$EXPECT_VAL"
282 282
 
283 283
 rm -f test.conf test1c.conf test2a.conf test-quote.conf test-space.conf test-equals.conf test-strip.conf test-colon.conf
284
+rm -f test-multiline.conf test-multi-sections.conf
284 285
 rm -rf test-etc