ding-libs/INI-Extend-INI_MS_DETECT-to-be-non-exclusive.patch
Robbie Harwood 5f77bc5cc3 Backport INI merge detection support
Also, migrate to autosetup
2017-08-09 17:58:16 +00:00

314 lines
12 KiB
Diff

From b9ce9b7ecd1db5afbfc1a51def601ec03e657f32 Mon Sep 17 00:00:00 2001
From: Alexander Scheel <ascheel@redhat.com>
Date: Wed, 12 Jul 2017 15:14:52 -0400
Subject: [PATCH] INI: Extend INI_MS_DETECT to be non-exclusive
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This updates the INI_MS_DETECT flag such that it can be
used in combination with INI_MS_MERGE, INI_MS_OVERWRITE,
and INI_MS_PRESERVE. With the previous behavior, to detect
that duplicate sections exist in a config directory, two
separate calls to ini_augment would need to be made:
one with a copy baes_obj and INI_MS_DETECT, and one with
INI_MS_PRESERVE.
Resolves:
https://pagure.io/SSSD/ding-libs/issue/3167
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
Merges: https://pagure.io/SSSD/ding-libs/issue/3167
(cherry picked from commit 3163a969bbcd10c4d9e48e191f978c6991ac01cd)
---
ini/ini_augment.c | 4 +--
ini/ini_configobj.c | 71 ++++++++++++++++++++++++++++++++---------------------
ini/ini_configobj.h | 3 ++-
ini/ini_defines.h | 5 ++++
ini/ini_parse.c | 32 +++++++++++-------------
5 files changed, 67 insertions(+), 48 deletions(-)
diff --git a/ini/ini_augment.c b/ini/ini_augment.c
index 0855381..e4ac94b 100644
--- a/ini/ini_augment.c
+++ b/ini/ini_augment.c
@@ -808,9 +808,9 @@ static int ini_aug_apply(struct ini_cfgobj *cfg,
}
else if
((error == EEXIST) &&
- ((((merge_flags & INI_MS_MASK) == INI_MS_DETECT) &&
+ ((ini_flags_have(INI_MS_DETECT, merge_flags) &&
((merge_flags & INI_MV2S_MASK) != INI_MV2S_ERROR)) ||
- (((merge_flags & INI_MS_MASK) != INI_MS_ERROR) &&
+ ((!ini_flags_have(INI_MS_ERROR, merge_flags)) &&
((merge_flags & INI_MV2S_MASK) == INI_MV2S_DETECT)))) {
TRACE_ERROR_NUMBER("Got error in detect mode", error);
/* Fall through! */
diff --git a/ini/ini_configobj.c b/ini/ini_configobj.c
index 04e81ba..09bedc4 100644
--- a/ini/ini_configobj.c
+++ b/ini/ini_configobj.c
@@ -270,6 +270,23 @@ static int ini_copy_cb(struct collection_item *item,
return error;
}
+/* Check flags for flag */
+int ini_flags_have(uint32_t flag, uint32_t flags)
+{
+ switch (flag) {
+ case INI_MS_MERGE:
+ case INI_MS_ERROR:
+ case INI_MS_OVERWRITE:
+ case INI_MS_PRESERVE:
+ return flag == (flags & INI_MS_MODE_MASK);
+ case INI_MS_DETECT:
+ return flag == (flags & INI_MS_DETECT);
+ default:
+ TRACE_ERROR_NUMBER("Unsupported flag", flag);
+ }
+ return 0;
+}
+
/* Copy configuration */
int ini_config_copy(struct ini_cfgobj *ini_config,
struct ini_cfgobj **ini_new)
@@ -547,7 +564,12 @@ static int acceptor_handler(const char *property,
donor = passed_data->ci;
acceptor = *((struct collection_item **)(data));
- mergemode = passed_data->flags & INI_MS_MASK;
+ mergemode = passed_data->flags & INI_MS_MODE_MASK;
+
+ if (passed_data->flags & INI_MS_DETECT) {
+ TRACE_INFO_STRING("Detect mode", "");
+ passed_data->error = EEXIST;
+ }
switch (mergemode) {
case INI_MS_ERROR: /* Report error and return */
@@ -582,21 +604,6 @@ static int acceptor_handler(const char *property,
}
break;
- case INI_MS_DETECT: /* Detect mode */
- TRACE_INFO_STRING("Detect mode", "");
- passed_data->error = EEXIST;
- error = merge_two_sections(donor,
- acceptor,
- passed_data->flags);
- if (error) {
- if (error != EEXIST) {
- TRACE_ERROR_NUMBER("Failed to merge "
- "sections", error);
- return error;
- }
- }
- break;
-
case INI_MS_MERGE: /* Merge */
default: TRACE_INFO_STRING("Merge mode", "");
error = merge_two_sections(donor,
@@ -608,14 +615,22 @@ static int acceptor_handler(const char *property,
"sections", error);
return error;
}
- passed_data->error = error;
+
+ if (!(passed_data->flags & INI_MS_DETECT)) {
+ passed_data->error = error;
+ }
+
+ error = EOK;
}
break;
}
- *dummy = 1;
+ if (error == EOK) {
+ *dummy = 1;
+ }
+
TRACE_FLOW_EXIT();
- return EOK;
+ return error;
}
/* Callback to process the donating config */
@@ -671,8 +686,8 @@ static int donor_handler(const char *property,
/* Save error anyway */
passed_data->error = acceptor_data.error;
/* If it is section DETECT or MERGE+DETECT */
- if (((passed_data->flags & INI_MS_MASK) == INI_MS_DETECT) ||
- (((passed_data->flags & INI_MS_MASK) != INI_MS_ERROR) &&
+ if (ini_flags_have(INI_MS_DETECT, passed_data->flags) ||
+ (!ini_flags_have(INI_MS_ERROR, passed_data->flags) &&
((passed_data->flags & INI_MV2S_MASK) ==
INI_MV2S_DETECT))) {
TRACE_INFO_NUMBER("Non-critical error",
@@ -782,7 +797,7 @@ static int merge_configs(struct ini_cfgobj *donor,
/* Check if we got error */
if ((data.error) &&
- (((collision_flags & INI_MS_MASK) == INI_MS_ERROR) ||
+ (ini_flags_have(INI_MS_ERROR, collision_flags) ||
((collision_flags & INI_MV2S_MASK) == INI_MV2S_ERROR))) {
TRACE_ERROR_NUMBER("Got error in error mode", data.error);
return data.error;
@@ -806,7 +821,7 @@ static int merge_configs(struct ini_cfgobj *donor,
/* Check if we got error */
if ((data.error) &&
- (((collision_flags & INI_MS_MASK) == INI_MS_DETECT) ||
+ (ini_flags_have(INI_MS_DETECT, collision_flags) ||
((collision_flags & INI_MV2S_MASK) == INI_MV2S_DETECT))) {
TRACE_ERROR_NUMBER("Got error in error or detect mode", data.error);
error = data.error;
@@ -843,12 +858,12 @@ int valid_collision_flags(uint32_t collision_flags)
return 0;
}
- flag = collision_flags & INI_MS_MASK;
+ /* Any combination of DETECT and a MODE flag is valid. */
+ flag = collision_flags & INI_MS_MODE_MASK;
if ((flag != INI_MS_MERGE) &&
(flag != INI_MS_OVERWRITE) &&
(flag != INI_MS_ERROR) &&
- (flag != INI_MS_PRESERVE) &&
- (flag != INI_MS_DETECT)) {
+ (flag != INI_MS_PRESERVE)) {
TRACE_ERROR_STRING("Invalid section collision flag","");
return 0;
}
@@ -906,9 +921,9 @@ int ini_config_merge(struct ini_cfgobj *first,
if (error) {
TRACE_ERROR_NUMBER("Failed to merge configuration", error);
if ((error == EEXIST) &&
- ((((collision_flags & INI_MS_MASK) == INI_MS_DETECT) &&
+ ((ini_flags_have(INI_MS_DETECT, collision_flags) &&
((collision_flags & INI_MV2S_MASK) != INI_MV2S_ERROR)) ||
- (((collision_flags & INI_MS_MASK) != INI_MS_ERROR) &&
+ (!ini_flags_have(INI_MS_ERROR, collision_flags) &&
((collision_flags & INI_MV2S_MASK) == INI_MV2S_DETECT)))) {
TRACE_ERROR_NUMBER("Got error in detect mode", error);
/* Fall through! */
diff --git a/ini/ini_configobj.h b/ini/ini_configobj.h
index 093916a..ca1e5ff 100644
--- a/ini/ini_configobj.h
+++ b/ini/ini_configobj.h
@@ -344,7 +344,8 @@ enum ERR_PARSE {
#define INI_MS_OVERWRITE 0x0200
/** @brief Second section is discarded */
#define INI_MS_PRESERVE 0x0300
-/** @brief Merge but log errors if duplicate sections are detected */
+/** @brief Log errors if duplicate sections are detected; non-exclusive */
+/** This defaults to MERGE, but can be used with OVERWRITE and PRESERVE **/
#define INI_MS_DETECT 0x0400
/**
diff --git a/ini/ini_defines.h b/ini/ini_defines.h
index bb34510..d79019b 100644
--- a/ini/ini_defines.h
+++ b/ini/ini_defines.h
@@ -22,6 +22,8 @@
#ifndef INI_DEFINES_H
#define INI_DEFINES_H
+#include <stdint.h>
+
#define NAME_OVERHEAD 10
#define SLASH "/"
@@ -115,9 +117,12 @@
#define INI_MV2S_MASK 0x00F0 /* Merge values options mask
* for two sections. */
#define INI_MS_MASK 0x0F00 /* Merge section options mask */
+#define INI_MS_MODE_MASK 0x0300 /* Merge section merge mode mask */
/* Different error string functions can be passed as callbacks */
typedef const char * (*error_fn)(int error);
+int ini_flags_have(uint32_t flag, uint32_t flags);
+
#endif
diff --git a/ini/ini_parse.c b/ini/ini_parse.c
index e5baeca..3050223 100644
--- a/ini/ini_parse.c
+++ b/ini/ini_parse.c
@@ -580,7 +580,7 @@ static int parser_save_section(struct parser_obj *po)
TRACE_INFO_STRING("Merge collision detected", "");
- mergemode = po->collision_flags & INI_MS_MASK;
+ mergemode = po->collision_flags & INI_MS_MODE_MASK;
switch (mergemode) {
case INI_MS_ERROR:
@@ -623,9 +623,15 @@ static int parser_save_section(struct parser_obj *po)
merge = 1;
break;
- case INI_MS_DETECT:
- /* Detect mode */
- TRACE_INFO_STRING("Detect mode", "");
+ case INI_MS_MERGE:
+ /* Merge */
+ default:
+ TRACE_INFO_STRING("Merge mode", "");
+ merge = 1;
+ break;
+ }
+
+ if (po->collision_flags & INI_MS_DETECT) {
po->merge_error = EEXIST;
error = save_error(po->el,
po->seclinenum,
@@ -637,15 +643,6 @@ static int parser_save_section(struct parser_obj *po)
error);
return error;
}
- merge = 1;
- break;
-
- case INI_MS_MERGE:
- /* Merge */
- default:
- TRACE_INFO_STRING("Merge mode", "");
- merge = 1;
- break;
}
if (merge) {
@@ -1599,9 +1596,9 @@ static int parser_error(struct parser_obj *po)
* We check for reverse condition and return error,
* otherwise fall through.
*/
- if (!((((po->collision_flags & INI_MS_MASK) == INI_MS_ERROR) &&
+ if (!(((ini_flags_have(INI_MS_ERROR, po->collision_flags)) &&
(error == EEXIST)) ||
- (((po->collision_flags & INI_MS_MASK) == INI_MS_MERGE) &&
+ (ini_flags_have(INI_MS_ERROR, po->collision_flags) &&
((po->collision_flags & INI_MV2S_MASK) == INI_MV2S_ERROR) &&
(error == EEXIST)))) {
return error;
@@ -1728,11 +1725,12 @@ int ini_config_parse(struct ini_cfgfile *file_ctx,
error = parser_run(po);
if (error) {
- fl1 = collision_flags & INI_MS_MASK;
+ fl1 = collision_flags & INI_MS_MODE_MASK;
fl2 = collision_flags & INI_MV1S_MASK;
fl3 = collision_flags & INI_MV2S_MASK;
if ((error == EEXIST) &&
- (((fl1 == INI_MS_DETECT) &&
+ ((ini_flags_have(INI_MS_DETECT, collision_flags) &&
+ (fl1 != INI_MS_ERROR) &&
(fl2 != INI_MV1S_ERROR) &&
(fl3 != INI_MV2S_ERROR)) ||
((fl2 == INI_MV1S_DETECT) &&
--
2.13.2