summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2009-12-25 18:54:56 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-01-21 15:02:15 -0500
commit526dd14cdc1461859a5dd1cdd83ee9b1268175fe (patch)
treec5822d0dc74c09021d2f13cbd3d8fc0ee7ba87be
parent650261ebb1fc02b1469a3ca38e1bdc17fa5b96ec (diff)
downloadsssd-526dd14cdc1461859a5dd1cdd83ee9b1268175fe.tar.gz
sssd-526dd14cdc1461859a5dd1cdd83ee9b1268175fe.tar.xz
sssd-526dd14cdc1461859a5dd1cdd83ee9b1268175fe.zip
INI: Added method to get string list with empty values
The original implementation was compressing the list, throwing away empty strings. The function that did that was pretty brain damaging. I cleaned it up and adjusted so that it could return list with empty values and without them. The old function was turned into a wrapper and a new high level function was intorduced to provide ability to get both empty and non empty strings.
-rw-r--r--common/ini/ini_config.c104
-rw-r--r--common/ini/ini_config.h32
-rw-r--r--common/ini/ini_config_ut.c35
3 files changed, 117 insertions, 54 deletions
diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c
index 17cb53b10..67af11bfd 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -42,6 +42,9 @@
#define SLASH "/"
+#define EXCLUDE_EMPTY 0
+#define INCLUDE_EMPTY 1
+
/* Name of the special collection used to store parsing errors */
#define FILE_ERROR_SET "ini_file_error_set"
@@ -1569,13 +1572,16 @@ void free_bin_config_value(char *value)
if (value) free(value);
}
-/* Arrays of stings and integers */
-char **get_string_config_array(struct collection_item *item,
- const char *sep, int *size, int *error)
+/* Arrays of stings */
+static char **get_str_cfg_array(struct collection_item *item,
+ int include,
+ const char *sep,
+ int *size,
+ int *error)
{
- const char *defsep = ",";
char *copy = NULL;
char *dest = NULL;
+ char locsep[4];
int lensep;
char *buff;
int count = 0;
@@ -1583,11 +1589,10 @@ char **get_string_config_array(struct collection_item *item,
int resume_len;
char **array;
char *start;
- int i, j, k;
- int growlen = 0;
+ int i, j;
int dlen;
- TRACE_FLOW_STRING("get_string_config_array", "Entry");
+ TRACE_FLOW_STRING("get_str_cfg_array", "Entry");
/* Do we have the item ? */
if ((item == NULL) ||
@@ -1598,8 +1603,16 @@ char **get_string_config_array(struct collection_item *item,
}
/* Handle the separators */
- if (sep == NULL) sep = defsep;
- lensep = strnlen(sep, 3);
+ if (sep == NULL) {
+ locsep[0] = ',';
+ locsep[1] = '\0';
+ lensep = 2;
+ }
+ else {
+ strncpy(locsep, sep, 3);
+ locsep[4] = '\0';
+ lensep = strlen(locsep) + 1;
+ }
/* Allocate memory for the copy of the string */
copy = malloc(col_get_item_length(item));
@@ -1613,17 +1626,18 @@ char **get_string_config_array(struct collection_item *item,
dest = copy;
buff = col_get_item_data(item);
start = buff;
- dlen = col_get_item_length(item) - 1;
+ dlen = col_get_item_length(item);
for(i = 0; i < dlen; i++) {
- growlen = 1;
for(j = 0; j < lensep; j++) {
- if(buff[i] == sep[j]) {
+ if(buff[i] == locsep[j]) {
/* If we found one of the separators trim spaces around */
resume_len = len;
while (len > 0) {
if (isspace(start[len - 1])) len--;
else break;
}
+ TRACE_INFO_STRING("Current:", start);
+ TRACE_INFO_NUMBER("Length:", len);
if (len > 0) {
/* Save block aside */
memcpy(dest, start, len);
@@ -1631,52 +1645,29 @@ char **get_string_config_array(struct collection_item *item,
dest += len;
*dest = '\0';
dest++;
- len = 0;
}
+ else if(include) {
+ count++;
+ *dest = '\0';
+ dest++;
+ }
+ if (locsep[j] == '\0') break; /* We are done */
+
/* Move forward and trim spaces if any */
start += resume_len + 1;
i++;
TRACE_INFO_STRING("Other pointer :", buff + i);
- k = 0;
- while(1) {
- TRACE_INFO_STRING("Remaining buffer :", start);
- while (((i + k) < dlen) && (isspace(*start))) {
- k++;
- start++;
- }
- /* May be we have another separator */
- TRACE_INFO_STRING("Remaining before sep check :", start);
- if(*start && strchr(sep, *start)) {
- TRACE_INFO_NUMBER("Found separator:", *start);
- start++;
- k++;
- }
- else {
- break;
- }
+ while ((i < dlen) && (isspace(*start))) {
+ i++;
+ start++;
}
-
+ len = -1; /* Len will be increased in the loop */
+ i--; /* i will be increas so we need to step back */
TRACE_INFO_STRING("Remaining buffer after triming spaces:", start);
-
- if (k) i += k - 1;
- /* Next iteration of the loop will add 1 */
- /* Break out of the inner loop */
- growlen = 0;
break;
}
}
- if (growlen) len++;
- }
-
- TRACE_INFO_STRING("Last part :", start);
- TRACE_INFO_NUMBER("Length :", len);
- if(len) {
- /* Copy the remaining piece */
- memcpy(dest, start, len);
- count++;
- dest += len;
- *dest = '\0';
- dest++;
+ len++;
}
/* Now we know how many items are there in the list */
@@ -1702,10 +1693,25 @@ char **get_string_config_array(struct collection_item *item,
if (error) *error = EOK;
if (size) *size = count;
- TRACE_FLOW_STRING("get_string_config_array", "Exit");
+ TRACE_FLOW_STRING("get_str_cfg_array", "Exit");
return array;
}
+/* Get array of strings from item eliminating empty tokens */
+char **get_string_config_array(struct collection_item *item,
+ const char *sep, int *size, int *error)
+{
+ TRACE_FLOW_STRING("get_string_config_array", "Called.");
+ return get_str_cfg_array(item, EXCLUDE_EMPTY, sep, size, error);
+}
+/* Get array of strings from item preserving empty tokens */
+char **get_raw_string_config_array(struct collection_item *item,
+ const char *sep, int *size, int *error)
+{
+ TRACE_FLOW_STRING("get_raw_string_config_array", "Called.");
+ return get_str_cfg_array(item, INCLUDE_EMPTY, sep, size, error);
+}
+
/* Special function to free string config array */
void free_string_config_array(char **str_config)
{
diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h
index 12d4a8092..2c906e476 100644
--- a/common/ini/ini_config.h
+++ b/common/ini/ini_config.h
@@ -226,15 +226,37 @@ const char *get_const_string_config_value(struct collection_item *item, int *err
char *get_bin_config_value(struct collection_item *item, int *length, int *error);
void free_bin_config_value(char *);
-/* Array of stings */
-/* Separator string includes up to three different separators. If NULL comma is assumed. */
-/* The spaces are trimmed automatically around separators in the string. */
-char **get_string_config_array(struct collection_item *item, const char *sep, int *size, int *error);
+/* Array of stings.
+ * Separator string includes up to three different separators. If NULL comma is assumed.
+ * The spaces are trimmed automatically around separators in the string.
+ * The function drops empty tokens from the list.
+ * This means that the string like this: "apple, ,banana, ,orange ,"
+ * will be translated into the list of three items: "apple","banana" and "orange".
+ *
+ * The length of the allocated array is returned in "size".
+ * Size and error parameters can be NULL.
+ * Use free_string_config_array() to free the array after use.
+ */
+char **get_string_config_array(struct collection_item *item,
+ const char *sep, int *size, int *error);
+
+/* This function is same as above but does not omit empty tokens.
+ * This means that the string like this: "apple, ,banana, ,orange ,"
+ * will be translated into the items: "apple", "", "banana", "", "orange", "".
+ * This function is useful when the configuration parameter
+ * holds a positionally sensitive list.
+ * Use free_string_config_array() to free the array after use.
+ */
+char **get_raw_string_config_array(struct collection_item *item,
+ const char *sep, int *size, int *error);
+
/* Array of long values - separators are detected automatically. */
-/* The length of the allocated array is returned in "size" */
+/* The length of the allocated array is returned in "size". */
+/* Size and error parameters can be NULL. */
long *get_long_config_array(struct collection_item *item, int *size, int *error);
/* Array of double values - separators are detected automatically. */
/* The length of the allocated array is returned in "size" */
+/* Size and error parameters can be NULL. */
double *get_double_config_array(struct collection_item *item, int *size, int *error);
/* Special function to free string config array */
diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c
index 52e89cb15..fabc08818 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -755,6 +755,25 @@ int get_test(void)
free_string_config_array(strarray);
+ printf("Get raw str array without size.\n");
+
+ error = 0;
+ strarray = get_raw_string_config_array(item, ",", NULL, &error);
+ if (error) {
+ printf("Expect success got error %d.\n", error);
+ free_ini_config(ini_config);
+ return error;
+ }
+
+ /* Can be used with this cycle */
+ strptr = strarray;
+ while (*strptr != NULL) {
+ printf("[%s]\n",*strptr);
+ strptr++;
+ }
+
+ free_string_config_array(strarray);
+
printf("Get str array with size.\n");
error = 0;
@@ -771,6 +790,22 @@ int get_test(void)
free_string_config_array(strarray);
+ printf("Get raw str array with size.\n");
+
+ error = 0;
+ size = 0;
+ strarray = get_raw_string_config_array(item, ",", &size, &error);
+ if (error) {
+ printf("Expect success got error %d.\n", error);
+ free_ini_config(ini_config);
+ return error;
+ }
+
+ /* Can be used with this cycle */
+ for (i=0;i<size;i++) printf("[%s]\n",*(strarray + i));
+
+ free_string_config_array(strarray);
+
printf("Get long array item\n");
item = NULL;