summaryrefslogtreecommitdiffstats
path: root/common/ini
diff options
context:
space:
mode:
authorDmitri Pal <dpal@redhat.com>2009-04-08 17:27:44 -0400
committerSimo Sorce <ssorce@redhat.com>2009-04-09 15:52:48 -0400
commit329651039032f044b4e1e13d0fc338e4d174b980 (patch)
tree107ef60b024fd3bc84256898eb7b349ff09bea15 /common/ini
parent0c7bc8d567fa099ebd0d23978176dfb4a2dc9007 (diff)
downloadsssd-329651039032f044b4e1e13d0fc338e4d174b980.tar.gz
sssd-329651039032f044b4e1e13d0fc338e4d174b980.tar.xz
sssd-329651039032f044b4e1e13d0fc338e4d174b980.zip
INI component: Fixed issues introduced by cleanup.
Added a few new functions. Cleaned code that was subject to conditional build. Fixed the floating point conversion. Keep const values as const.
Diffstat (limited to 'common/ini')
-rw-r--r--common/ini/ini.d/real.conf5
-rw-r--r--common/ini/ini_config.c227
-rw-r--r--common/ini/ini_config.h20
-rw-r--r--common/ini/ini_config_ut.c47
4 files changed, 223 insertions, 76 deletions
diff --git a/common/ini/ini.d/real.conf b/common/ini/ini.d/real.conf
index f026bd896..41f91c79e 100644
--- a/common/ini/ini.d/real.conf
+++ b/common/ini/ini.d/real.conf
@@ -31,7 +31,7 @@ description = InfoPipe Configuration
command = ./sbin/sssd_info
[domains]
-domainsOrder = LOCAL, EXAMPLE.COM , SOMEOTHER.COM
+domainsOrder = , LOCAL, , EXAMPLE.COM, , SOMEOTHER.COM , ,
[domains/LOCAL]
description = Reserved domain for local configurations
@@ -46,7 +46,8 @@ server = ipabackupserver.example.com
legacy = FALSE
enumerate = 0
binary_test = '010203'
-long_array = 1, 2; 4' ;8p .16/ 32?
+long_array = 1 2; 4' ;8p .16/ 32?
+double_array = 1.1 2.222222; .4' . ;8p .16/ -32?
diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c
index c3e83fb39..b4b4b25fd 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
+#include <locale.h>
#include "config.h"
/* For error text */
#include <libintl.h>
@@ -61,9 +62,6 @@
#define RET_EOF 5
#define RET_ERROR 6
-/* STATIC INTERNAL FUNCTIONS */
-#ifdef HAVE_PARSE_ERROR
-
/* Function to return parsing error */
inline const char *parsing_error_str(int parsing_error)
@@ -85,16 +83,6 @@ inline const char *parsing_error_str(int parsing_error)
return str_error[parsing_error-1];
}
-#else
-
-
-inline const char *parsing_error_str(int parsing_error)
-{
- const char *placeholder= _("Parsing errors are not compiled.");
- return placeholder;
-}
-
-#endif
int read_line(FILE *file,char **key,char **value, int *length, int *ext_error);
@@ -623,7 +611,7 @@ int read_line(FILE *file, char **key,char **value, int *length, int *ext_error)
if (eq == NULL) {
TRACE_ERROR_STRING("No equal sign", buf);
*ext_error = ERR_NOEQUAL;
- return RET_BEST_EFFORT;
+ return RET_INVALID;
}
len -= eq-buffer;
@@ -634,14 +622,14 @@ int read_line(FILE *file, char **key,char **value, int *length, int *ext_error)
if (i < 0) {
TRACE_ERROR_STRING("No key", buf);
*ext_error = ERR_NOKEY;
- return RET_BEST_EFFORT;
+ return RET_INVALID;
}
/* Copy key into provided buffer */
if(i >= MAX_KEY) {
TRACE_ERROR_STRING("Section name is too long", buf);
*ext_error = ERR_LONGKEY;
- return RET_BEST_EFFORT;
+ return RET_INVALID;
}
*key = buffer;
buffer[i + 1] = '\0';
@@ -865,7 +853,8 @@ int get_config_item(const char *section,
long get_long_config_value(struct collection_item *item,
int strict, long def, int *error)
{
- char *endptr, *str;
+ const char *str;
+ char *endptr;
long val = 0;
TRACE_FLOW_STRING("get_long_config_value", "Entry");
@@ -881,7 +870,7 @@ long get_long_config_value(struct collection_item *item,
if (error) *error = EOK;
/* Try to parse the value */
- str = (char *)get_item_data(item);
+ str = (const char *)get_item_data(item);
errno = 0;
val = strtol(str, &endptr, 10);
@@ -931,7 +920,8 @@ unsigned long get_ulong_config_value(struct collection_item *item,
double get_double_config_value(struct collection_item *item,
int strict, double def, int *error)
{
- char *endptr, *str;
+ const char *str;
+ char *endptr;
double val = 0;
TRACE_FLOW_STRING("get_double_config_value", "Entry");
@@ -947,7 +937,7 @@ double get_double_config_value(struct collection_item *item,
if (error) *error = EOK;
/* Try to parse the value */
- str = (char *)get_item_data(item);
+ str = (const char *)get_item_data(item);
errno = 0;
val = strtod(str, &endptr);
@@ -974,7 +964,7 @@ double get_double_config_value(struct collection_item *item,
unsigned char get_bool_config_value(struct collection_item *item,
unsigned char def, int *error)
{
- char *str;
+ const char *str;
int len;
TRACE_FLOW_STRING("get_bool_config_value", "Entry");
@@ -989,7 +979,7 @@ unsigned char get_bool_config_value(struct collection_item *item,
if (error) *error = EOK;
- str = (char *)get_item_data(item);
+ str = (const char *)get_item_data(item);
len = get_item_length(item);
/* Try to parse the value */
@@ -1011,7 +1001,7 @@ unsigned char get_bool_config_value(struct collection_item *item,
/* Return a string out of the value */
char *get_string_config_value(struct collection_item *item,
- int dup, int *error)
+ int *error)
{
char *str = NULL;
@@ -1025,21 +1015,40 @@ char *get_string_config_value(struct collection_item *item,
return NULL;
}
- /* If we are told to dup the value */
- if (dup) {
- errno = 0;
- str = strdup((char *)get_item_data(item));
- if (str == NULL) {
- TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
- if (error) *error = ENOMEM;
- return NULL;
- }
+ errno = 0;
+ str = strdup((const char *)get_item_data(item));
+ if (str == NULL) {
+ TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
+ if (error) *error = ENOMEM;
+ return NULL;
+ }
+
+ if (error) *error = EOK;
+
+ TRACE_FLOW_STRING("get_string_config_value returning", str);
+ return str;
+}
+
+/* Get string from item */
+const char *get_const_string_config_value(struct collection_item *item, int *error)
+{
+ const char *str;
+
+ TRACE_FLOW_STRING("get_const_string_config_value", "Entry");
+
+ /* Do we have the item ? */
+ if ((item == NULL) ||
+ (get_item_type(item) != COL_TYPE_STRING)) {
+ TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
+ if (error) *error = EINVAL;
+ return NULL;
}
- else str = (char *)get_item_data(item);
+
+ str = (const char *)get_item_data(item);
if (error) *error = EOK;
- TRACE_FLOW_STRING("get_string_config_value", "Exit");
+ TRACE_FLOW_STRING("get_const_string_config_value returning", str);
return str;
}
@@ -1054,11 +1063,11 @@ char *get_bin_config_value(struct collection_item *item,
{
int i;
char *value = NULL;
- char *buff;
+ const char *buff;
int size = 0;
unsigned char hex;
int len;
- char *str;
+ const char *str;
TRACE_FLOW_STRING("get_bin_config_value", "Entry");
@@ -1078,7 +1087,7 @@ char *get_bin_config_value(struct collection_item *item,
return NULL;
}
- str = (char *)get_item_data(item);
+ str = (const char *)get_item_data(item);
/* Is the format correct ? */
if ((*str != '\'') ||
@@ -1154,6 +1163,7 @@ char **get_string_config_array(struct collection_item *item,
char *start;
int i, j, k;
int growlen = 0;
+ int dlen;
TRACE_FLOW_STRING("get_string_config_array", "Entry");
@@ -1181,7 +1191,8 @@ char **get_string_config_array(struct collection_item *item,
dest = copy;
buff = item->data;
start = buff;
- for(i = 0; i < item->length; i++) {
+ dlen = item->length - 1;
+ for(i = 0; i < dlen; i++) {
growlen = 1;
for(j = 0; j < lensep; j++) {
if(buff[i] == sep[j]) {
@@ -1199,20 +1210,34 @@ char **get_string_config_array(struct collection_item *item,
*dest = '\0';
dest++;
len = 0;
- /* Move forward and trim spaces if any */
- start += resume_len + 1;
- i++;
+ }
+ /* 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);
- TRACE_INFO_STRING("Other pointer :", buff + i);
- k = 0;
- while (((i + k) < item->length) && (isspace(*start))) {
+ while (((i + k) < dlen) && (isspace(*start))) {
k++;
start++;
}
- TRACE_INFO_STRING("Remaining buffer after triming spaces:", start);
- if (k) i += k - 1;
- /* Next iteration of the loop will add 1 */
+ /* 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;
+ }
}
+
+ 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;
@@ -1221,12 +1246,16 @@ char **get_string_config_array(struct collection_item *item,
if (growlen) len++;
}
- /* Copy the remaining piece */
- memcpy(dest, start, len);
- count++;
- dest += len;
- dest = '\0';
- dest++;
+ 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++;
+ }
/* Now we know how many items are there in the list */
array = malloc((count + 1) * sizeof(char *));
@@ -1240,8 +1269,11 @@ char **get_string_config_array(struct collection_item *item,
/* Loop again to fill in the pointers */
start = copy;
for (i = 0; i < count; i++) {
+ TRACE_INFO_STRING("Token :", start);
+ TRACE_INFO_NUMBER("Item :", i);
array[i] = start;
- while (start) start++;
+ /* Move to next item */
+ while(*start) start++;
start++;
}
array[count] = NULL;
@@ -1268,7 +1300,8 @@ void free_string_config_array(char **str_config)
/* Get an array of long values */
long *get_long_config_array(struct collection_item *item, int *size, int *error)
{
- char *endptr, *str;
+ const char *str;
+ char *endptr;
long val = 0;
long *array;
int count = 0;
@@ -1293,8 +1326,8 @@ long *get_long_config_array(struct collection_item *item, int *size, int *error)
}
/* Now parse the string */
- str = (char *)get_item_data(item);
- while (str) {
+ str = (const char *)get_item_data(item);
+ while (*str) {
errno = 0;
val = strtol(str, &endptr, 10);
if (((errno == ERANGE) &&
@@ -1314,7 +1347,7 @@ long *get_long_config_array(struct collection_item *item, int *size, int *error)
if (*endptr == 0) break;
/* Advance to the next valid number */
for (str = endptr; *str; str++) {
- if (isdigit(*str) || (*str != '-') || (*str != '+')) break;
+ if (isdigit(*str) || (*str == '-') || (*str == '+')) break;
}
}
@@ -1326,9 +1359,87 @@ long *get_long_config_array(struct collection_item *item, int *size, int *error)
}
+/* Get an array of double values */
+double *get_double_config_array(struct collection_item *item, int *size, int *error)
+{
+ const char *str;
+ char *endptr;
+ double val = 0;
+ double *array;
+ int count = 0;
+ struct lconv *loc;
+
+ TRACE_FLOW_STRING("get_double_config_array", "Entry");
+
+ /* Do we have the item ? */
+ if ((item == NULL) ||
+ (get_item_type(item) != COL_TYPE_STRING) ||
+ (size == NULL)) {
+ TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
+ if (error) *error = EINVAL;
+ return NULL;
+ }
+
+ /* Assume that we have maximum number of different numbers */
+ array = (double *)malloc(sizeof(double) * get_item_length(item)/2);
+ if (array == NULL) {
+ TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
+ if (error) *error = ENOMEM;
+ return NULL;
+ }
+
+ /* Get locale information so that we can check for decimal point character.
+ * Based on the man pages it is unclear if this is an allocated memory or not.
+ * Seems like it is a static thread or process local structure so
+ * I will not try to free it after use.
+ */
+ loc = localeconv();
+
+ /* Now parse the string */
+ str = (const char *)get_item_data(item);
+ while (*str) {
+ errno = 0;
+ TRACE_INFO_STRING("String to convert",str);
+ val = strtod(str, &endptr);
+ if ((errno == ERANGE) ||
+ ((errno != 0) && (val == 0)) ||
+ (endptr == str)) {
+ TRACE_ERROR_NUMBER("Conversion failed", EIO);
+ free(array);
+ if (error) *error = EIO;
+ return NULL;
+ }
+ /* Save value */
+ array[count] = val;
+ count++;
+ /* Are we done? */
+ if (*endptr == 0) break;
+ TRACE_INFO_STRING("End pointer after conversion",endptr);
+ /* Advance to the next valid number */
+ for (str = endptr; *str; str++) {
+ if (isdigit(*str) || (*str == '-') || (*str == '+') ||
+ /* It is ok to do this since the string is null terminated */
+ ((*str == *(loc->decimal_point)) && isdigit(str[1]))) break;
+ }
+ }
+
+ *size = count;
+ if (error) *error = EOK;
+
+ TRACE_FLOW_NUMBER("get_double_config_value returning", val);
+ return array;
+
+}
+
+
/* Special function to free long config array */
inline void free_long_config_array(long *array)
{
if (array != NULL) free(array);
}
+/* Special function to free double config array */
+inline void free_double_config_array(double *array)
+{
+ if (array != NULL) free(array);
+}
diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h
index 21b912b92..2a9aa52a8 100644
--- a/common/ini/ini_config.h
+++ b/common/ini/ini_config.h
@@ -54,11 +54,6 @@
#define ERR_MAXPARSE ERR_LONGKEY
-#ifdef HAVE_INI_BEST_EFFORT /* Ignore bad lines in the INI files */
-#define RET_BEST_EFFORT RET_INVALID
-#else
-#define RET_BEST_EFFORT RET_ERROR
-#endif
/* Internal sizes */
/* FIXME - make them configurable via config.h */
@@ -79,7 +74,7 @@ int config_from_file(const char *application, /* Name of the appli
const char *config_file, /* Name of the config file - if NULL the collection will be empty */
struct collection_item **ini_config, /* If *ini_config is NULL a new ini object will be allocated, */
/* otherwise the one that is pointed to will be updated. */
- int error_level, /* Error level - break for erros, warnings or best effort (don't break) */
+ int error_level, /* Error level - break for errors, warnings or best effort (don't break) */
struct collection_item **error_list); /* List of errors for a file */
@@ -125,10 +120,10 @@ unsigned long get_ulong_config_value(struct collection_item *item, int strict, u
double get_double_config_value(struct collection_item *item, int strict, double def, int *error);
unsigned char get_bool_config_value(struct collection_item *item, unsigned char def, int *error);
-/* Function get_string_config_value returns pointer to the string out of item.
- * If 'dup' is not 0 it makes a copyof the string otherwise it does not.
- */
-char *get_string_config_value(struct collection_item *item, int dup, int *error);
+/* Function get_string_config_value returns a newly allocated pointer to the string out of item.*/
+char *get_string_config_value(struct collection_item *item, int *error);
+/* Function returns the string stored in the item */
+const char *get_const_string_config_value(struct collection_item *item, int *error);
/* A get_bin_value and get_xxx_array functions allocate memory.
* It is the responsibility of the caller to free it after use.
@@ -151,10 +146,15 @@ char **get_string_config_array(struct collection_item *item, char *sep, int *siz
/* Array of long values - separators are detected automatically. */
/* The length of the allocated array is returned in "size" */
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" */
+double *get_double_config_array(struct collection_item *item, int *size, int *error);
/* Special function to free string config array */
void free_string_config_array(char **str_config);
/* Special function to free long config array */
void free_long_config_array(long *array);
+/* Special function to free double config array */
+void free_double_config_array(double *array);
#endif
diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c
index 642f268b3..4968a0ac2 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -217,6 +217,8 @@ int get_test()
unsigned long number_ulong;
unsigned char logical;
char *str;
+ const char *cstr;
+ const char *cstrn;
void *binary;
int length;
int i;
@@ -224,6 +226,7 @@ int get_test()
char **strptr;
int size;
long *array;
+ double *darray;
printf("\n\n===== GET TEST START ======\n");
printf("Reading collection\n");
@@ -298,9 +301,8 @@ int get_test()
/* Get a string without duplicication */
/* Negative test */
- error = 0;
- str = get_string_config_value(NULL, 0, &error);
- if(!error) {
+ cstrn = get_const_string_config_value(NULL, NULL);
+ if(cstrn != NULL) {
printf("Expected error got success.\n");
destroy_collection(ini_config);
return -1;
@@ -310,21 +312,21 @@ int get_test()
/* Now get string from the right item */
error = 0;
- str = get_string_config_value(item, 0, &error);
+ cstr = get_const_string_config_value(item, &error);
if(error) {
printf("Expected success got error %d.\n",error);
destroy_collection(ini_config);
return error;
}
- printf("Value: [%s]\n",str);
+ printf("Value: [%s]\n",cstr);
/* Same thing but create a dup */
printf("Get item as string with duplication from correct item.\n");
error = 0;
- str = get_string_config_value(item, 1, &error);
+ str = get_string_config_value(item, &error);
if(error) {
printf("Expected success got error %d.\n",error);
destroy_collection(ini_config);
@@ -677,6 +679,39 @@ int get_test()
free_long_config_array(array);
+ printf("Get double array item\n");
+
+ item = (struct collection_item *)(NULL);
+ error = get_config_item("domains/EXAMPLE.COM","double_array", ini_config, &item);
+ if(error) {
+ printf("Expected success but got error! %d\n",error);
+ destroy_collection(ini_config);
+ return error;
+ }
+
+ /* Item should be found */
+ if(item == (struct collection_item *)(NULL)) {
+ printf("Expected success but got NULL.\n");
+ destroy_collection(ini_config);
+ return -1;
+ }
+
+ debug_item(item);
+
+ error = 0;
+ size = 0; /* Here size is not optional!!! */
+ darray = get_double_config_array(item, &size, &error);
+ if(error) {
+ printf("Expect success got error %d.\n",error);
+ destroy_collection(ini_config);
+ return error;
+ }
+
+ /* Can be used with this cycle */
+ for(i=0;i<size;i++) printf("%.4f\n",darray[i]);
+
+ free_double_config_array(darray);
+
printf("Done with get test!\n");
return EOK;
}