From b10fdbc98441deeea9ced4e9b9d143ff91c4923f Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal@redhat.com>
Date: Mon, 17 May 2010 13:21:56 -0400
Subject: [PATCH] [INI] Adding support for explicit 32/64 types (attempt 2).

This is a reworked patch to add support for explicit
32 and 64 bit values in the config files.
---
 common/ini/ini.d/real.conf |    4 +
 common/ini/ini_config.h    |  180 ++++++++++++++++++++++++++++++++++++++++++++
 common/ini/ini_config_ut.c |  145 +++++++++++++++++++++++++++++++++++
 common/ini/ini_get_value.c |   74 +++++++++++++++++-
 common/ini/ini_parse.c     |    2 +-
 5 files changed, 400 insertions(+), 5 deletions(-)

diff --git a/common/ini/ini.d/real.conf b/common/ini/ini.d/real.conf
index e3348e338e8690b48fadd95de880fe222317bdf1..c426ec56f32b61d5d63d7523247e332b1c5d9bd7 100644
--- a/common/ini/ini.d/real.conf
+++ b/common/ini/ini.d/real.conf
@@ -50,3 +50,7 @@ long_array = 1  2; 4' ;8p .16/ 32?
 double_array = 1.1  2.222222; .4' . ;8p .16/ -32?
 empty_value =
 space_value = " "
+int32_t = -1000000000
+uint32_t = 3000000000
+int64_t = -1000000000123
+uint64_t = 3000000000123
diff --git a/common/ini/ini_config.h b/common/ini/ini_config.h
index 3b58a1161793ea155a07480ffa0ffe094b96784a..28e1af8dfb519f7a8a38f22eef8604ecba858a38 100644
--- a/common/ini/ini_config.h
+++ b/common/ini/ini_config.h
@@ -1172,6 +1172,186 @@ unsigned long get_ulong_config_value(struct collection_item *item,
                                      int *error);
 
 /**
+ * @brief Convert item value to integer number.
+ *
+ * This is a conversion function.
+ * It converts the value read from the INI file
+ * and stored in the configuration item
+ * into an int32_t number. Any of the conversion
+ * functions can be used to try to convert the value
+ * stored as a string inside the item.
+ * The results can be different depending upon
+ * how the caller tries to interpret the value.
+ * If "strict" parameter is non zero the function will fail
+ * if there are more characters after the last digit.
+ * The value range is from INT_MIN to INT_MAX.
+ *
+ * @param[in]  item             Item to interpret.
+ *                              It must be retrieved using
+ *                              \ref get_config_item().
+ * @param[in]  strict           Fail the function if
+ *                              the symbol after last digit
+ *                              is not valid.
+ * @param[in]  def              Default value to use if
+ *                              conversion failed.
+ * @param[out] error            Variable will get the value
+ *                              of the error code if
+ *                              error happened.
+ *                              Can be NULL. In this case
+ *                              function does not set
+ *                              the code.
+ *                              Codes:
+ *                              - 0 - Success.
+ *                              - EINVAL - Argument is invalid.
+ *                              - EIO - Conversion failed due
+ *                                invalid characters.
+ *                              - ERANGE - Value is out of range.
+ *
+ * @return Converted value.
+ * In case of failure the function returns default value and
+ * sets error code into the provided variable.
+ */
+int32_t get_int32_config_value(struct collection_item *item,
+                               int strict,
+                               int32_t def,
+                               int *error);
+
+/**
+ * @brief Convert item value to integer number.
+ *
+ * This is a conversion function.
+ * It converts the value read from the INI file
+ * and stored in the configuration item
+ * into an uint32_t number. Any of the conversion
+ * functions can be used to try to convert the value
+ * stored as a string inside the item.
+ * The results can be different depending upon
+ * how the caller tries to interpret the value.
+ * If "strict" parameter is non zero the function will fail
+ * if there are more characters after the last digit.
+ * The value range is from 0 to ULONG_MAX.
+ *
+ * @param[in]  item             Item to interpret.
+ *                              It must be retrieved using
+ *                              \ref get_config_item().
+ * @param[in]  strict           Fail the function if
+ *                              the symbol after last digit
+ *                              is not valid.
+ * @param[in]  def              Default value to use if
+ *                              conversion failed.
+ * @param[out] error            Variable will get the value
+ *                              of the error code if
+ *                              error happened.
+ *                              Can be NULL. In this case
+ *                              function does not set
+ *                              the code.
+ *                              Codes:
+ *                              - 0 - Success.
+ *                              - EINVAL - Argument is invalid.
+ *                              - EIO - Conversion failed due
+ *                                invalid characters.
+ *                              - ERANGE - Value is out of range.
+ *
+ * @return Converted value.
+ * In case of failure the function returns default value and
+ * sets error code into the provided variable.
+ */
+uint32_t get_uint32_config_value(struct collection_item *item,
+                                 int strict,
+                                 uint32_t def,
+                                 int *error);
+
+/**
+ * @brief Convert item value to integer number.
+ *
+ * This is a conversion function.
+ * It converts the value read from the INI file
+ * and stored in the configuration item
+ * into an int64_t number. Any of the conversion
+ * functions can be used to try to convert the value
+ * stored as a string inside the item.
+ * The results can be different depending upon
+ * how the caller tries to interpret the value.
+ * If "strict" parameter is non zero the function will fail
+ * if there are more characters after the last digit.
+ * The value range is from LLONG_MIN to LLONG_MAX.
+ *
+ * @param[in]  item             Item to interpret.
+ *                              It must be retrieved using
+ *                              \ref get_config_item().
+ * @param[in]  strict           Fail the function if
+ *                              the symbol after last digit
+ *                              is not valid.
+ * @param[in]  def              Default value to use if
+ *                              conversion failed.
+ * @param[out] error            Variable will get the value
+ *                              of the error code if
+ *                              error happened.
+ *                              Can be NULL. In this case
+ *                              function does not set
+ *                              the code.
+ *                              Codes:
+ *                              - 0 - Success.
+ *                              - EINVAL - Argument is invalid.
+ *                              - EIO - Conversion failed due
+ *                                invalid characters.
+ *                              - ERANGE - Value is out of range.
+ *
+ * @return Converted value.
+ * In case of failure the function returns default value and
+ * sets error code into the provided variable.
+ */
+int64_t get_int64_config_value(struct collection_item *item,
+                               int strict,
+                               int64_t def,
+                               int *error);
+
+/**
+ * @brief Convert item value to integer number.
+ *
+ * This is a conversion function.
+ * It converts the value read from the INI file
+ * and stored in the configuration item
+ * into an uint64_t number. Any of the conversion
+ * functions can be used to try to convert the value
+ * stored as a string inside the item.
+ * The results can be different depending upon
+ * how the caller tries to interpret the value.
+ * If "strict" parameter is non zero the function will fail
+ * if there are more characters after the last digit.
+ * The value range is from 0 to ULLONG_MAX.
+ *
+ * @param[in]  item             Item to interpret.
+ *                              It must be retrieved using
+ *                              \ref get_config_item().
+ * @param[in]  strict           Fail the function if
+ *                              the symbol after last digit
+ *                              is not valid.
+ * @param[in]  def              Default value to use if
+ *                              conversion failed.
+ * @param[out] error            Variable will get the value
+ *                              of the error code if
+ *                              error happened.
+ *                              Can be NULL. In this case
+ *                              function does not set
+ *                              the code.
+ *                              Codes:
+ *                              - 0 - Success.
+ *                              - EINVAL - Argument is invalid.
+ *                              - EIO - Conversion failed due
+ *                                invalid characters.
+ *                              - ERANGE - Value is out of range.
+ *
+ * @return Converted value.
+ * In case of failure the function returns default value and
+ * sets error code into the provided variable.
+ */
+uint64_t get_uint64_config_value(struct collection_item *item,
+                                 int strict,
+                                 uint64_t def,
+                                 int *error);
+
+/**
  * @brief Convert item value to floating point number.
  *
  * This is a conversion function.
diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c
index c9b13fd574cac752911a9046efb2d18c533830ba..b88b769a3b678fe9904b6219aa00808ceb35fd82 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -480,6 +480,11 @@ int get_test(void)
     long *array;
     double *darray;
     char **prop_array;
+    int32_t val_int32;
+    uint32_t val_uint32;
+    int64_t val_int64;
+    uint64_t val_uint64;
+
 
     COLOUT(printf("\n\n===== GET TEST START ======\n"));
     COLOUT(printf("Reading collection\n"));
@@ -1060,6 +1065,146 @@ int get_test(void)
     COLOUT(for (i=0;i<size;i++) printf("Attribute: [%s]\n", prop_array[i]));
     free_attribute_list(prop_array);
 
+
+    /***************************************/
+    /* Test special types                  */
+    /***************************************/
+    COLOUT(printf("Test int32_t\n"));
+
+    item = NULL;
+    error = get_config_item("domains/EXAMPLE.COM",
+                            "int32_t",
+                            ini_config,
+                            &item);
+    if (error) {
+        printf("Expected success but got error! %d\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    /* Item should be found */
+    if (item == NULL) {
+        printf("Expected success but got NULL.\n");
+        free_ini_config(ini_config);
+        return -1;
+    }
+
+    COLOUT(col_debug_item(item));
+
+    error = 0;
+    val_int32 = get_int32_config_value(item, 1, 0, &error);
+    if (error) {
+        printf("Expect success got error %d.\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    COLOUT(printf("Value: %d\n", val_int32));
+
+    /***************************************/
+
+    COLOUT(printf("Test uint32_t\n"));
+
+    item = NULL;
+    error = get_config_item("domains/EXAMPLE.COM",
+                            "uint32_t",
+                            ini_config,
+                            &item);
+    if (error) {
+        printf("Expected success but got error! %d\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    /* Item should be found */
+    if (item == NULL) {
+        printf("Expected success but got NULL.\n");
+        free_ini_config(ini_config);
+        return -1;
+    }
+
+    COLOUT(col_debug_item(item));
+
+    error = 0;
+    val_uint32 = get_uint32_config_value(item, 1, 0, &error);
+    if (error) {
+        printf("Expect success got error %d.\n", error);
+        free_ini_config(ini_config);
+        return error;
+   }
+
+    COLOUT(printf("Value: %u\n", val_uint32));
+
+    /***************************************/
+
+    COLOUT(printf("Test int64_t\n"));
+
+    item = NULL;
+    error = get_config_item("domains/EXAMPLE.COM",
+                            "int64_t",
+                            ini_config,
+                            &item);
+    if (error) {
+        printf("Expected success but got error! %d\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    /* Item should be found */
+    if (item == NULL) {
+        printf("Expected success but got NULL.\n");
+        free_ini_config(ini_config);
+        return -1;
+    }
+
+    COLOUT(col_debug_item(item));
+
+    error = 0;
+    val_int64 = get_int64_config_value(item, 1, 0, &error);
+    if (error) {
+        printf("Expect success got error %d.\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    COLOUT(printf("Value: %lld\n", (long long)val_int64));
+
+    /***************************************/
+
+    COLOUT(printf("Test uint32_t\n"));
+
+    item = NULL;
+    error = get_config_item("domains/EXAMPLE.COM",
+                            "uint64_t",
+                            ini_config,
+                            &item);
+    if (error) {
+        printf("Expected success but got error! %d\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    /* Item should be found */
+    if (item == NULL) {
+        printf("Expected success but got NULL.\n");
+        free_ini_config(ini_config);
+        return -1;
+    }
+
+    COLOUT(col_debug_item(item));
+
+    error = 0;
+    val_uint64 = get_uint64_config_value(item, 1, 0, &error);
+    if (error) {
+        printf("Expect success got error %d.\n", error);
+        free_ini_config(ini_config);
+        return error;
+    }
+
+    COLOUT(printf("Value: %llu\n", (unsigned long long)val_uint64));
+
+    /***************************************/
+
     free_ini_config(ini_config);
     COLOUT(printf("Done with get test!\n"));
     return EOK;
diff --git a/common/ini/ini_get_value.c b/common/ini/ini_get_value.c
index 70d940fa1e33ef9b829255cd377f9e8c7f3302f5..f31077f119f04d32bbc923f483f21e3d897c3b45 100644
--- a/common/ini/ini_get_value.c
+++ b/common/ini/ini_get_value.c
@@ -104,7 +104,7 @@ static long long get_llong_config_value(struct collection_item *item,
     char *endptr;
     long long val = 0;
 
-    TRACE_FLOW_STRING("get_long_config_value", "Entry");
+    TRACE_FLOW_STRING("get_llong_config_value", "Entry");
 
     /* Do we have the item ? */
     if ((item == NULL) ||
@@ -136,7 +136,7 @@ static long long get_llong_config_value(struct collection_item *item,
         return def;
     }
 
-    TRACE_FLOW_NUMBER("get_long_config_value returning", (long)val);
+    TRACE_FLOW_NUMBER("get_llong_config_value returning", (long)val);
     return val;
 }
 
@@ -183,7 +183,7 @@ static unsigned long long get_ullong_config_value(struct collection_item *item,
         return def;
     }
 
-    TRACE_FLOW_NUMBER("get_ullong_config_value returning", (long)val);
+    TRACE_FLOW_NUMBER("get_ullong_config_value returning", val);
     return val;
 }
 
@@ -291,6 +291,72 @@ unsigned long get_ulong_config_value(struct collection_item *item,
     return (unsigned long)val;
 }
 
+/* Get int32_t value from config item */
+int32_t get_int32_config_value(struct collection_item *item,
+                               int strict,
+                               int32_t def,
+                               int *error)
+{
+    int val = 0;
+
+    TRACE_FLOW_STRING("get_int32_config_value", "Entry");
+
+    val = get_int_config_value(item, strict, (int)def, error);
+
+    TRACE_FLOW_SNUMBER("get_int32_config_value returning", (int32_t)val);
+    return (int32_t)val;
+}
+
+/* Get uint32_t value from config item */
+uint32_t get_uint32_config_value(struct collection_item *item,
+                                 int strict,
+                                 uint32_t def,
+                                 int *error)
+{
+    unsigned val = 0;
+
+    TRACE_FLOW_STRING("get_uint32_config_value", "Entry");
+
+    val = get_unsigned_config_value(item, strict, (unsigned)def, error);
+
+    TRACE_FLOW_NUMBER("get_uint32_config_value returning", (uint32_t)val);
+    return (uint32_t)val;
+}
+
+/* Get int64_t value from config item */
+int64_t get_int64_config_value(struct collection_item *item,
+                               int strict,
+                               int64_t def,
+                               int *error)
+{
+    long long val = 0;
+
+    TRACE_FLOW_STRING("get_int64_config_value", "Entry");
+
+    val = get_llong_config_value(item, strict, (long long)def, error);
+
+    TRACE_FLOW_SLNUMBER("get_int64_config_value returning", (int64_t)val);
+    return (int64_t)val;
+}
+
+/* Get uint64_t value from config item */
+uint64_t get_uint64_config_value(struct collection_item *item,
+                                 int strict,
+                                 uint64_t def,
+                                 int *error)
+{
+    unsigned long long val = 0;
+
+    TRACE_FLOW_STRING("get_uint64_config_value", "Entry");
+
+    val = get_ullong_config_value(item,
+                                  strict,
+                                  (unsigned long long)def,
+                                  error);
+
+    TRACE_FLOW_LNUMBER("get_uint64_config_value returning", (uint64_t)val);
+    return (uint64_t)val;
+}
 
 /* Get double value */
 double get_double_config_value(struct collection_item *item,
@@ -332,7 +398,7 @@ double get_double_config_value(struct collection_item *item,
         val = def;
     }
 
-    TRACE_FLOW_NUMBER("get_double_config_value returning", val);
+    TRACE_FLOW_DOUBLE("get_double_config_value returning", val);
     return val;
 }
 
diff --git a/common/ini/ini_parse.c b/common/ini/ini_parse.c
index be733d611a5e3d04a7f2d1c0cf096fc67d97954a..7b3785c34d0fc487a2828085df50f93d3fa6e20c 100644
--- a/common/ini/ini_parse.c
+++ b/common/ini/ini_parse.c
@@ -163,7 +163,7 @@ int read_line(FILE *file,
 
     /* Copy key into provided buffer */
     if(i >= MAX_KEY) {
-        TRACE_ERROR_STRING("Section name is too long", buf);
+        TRACE_ERROR_STRING("Key name is too long", buf);
         *ext_error = ERR_LONGKEY;
         return RET_INVALID;
     }
-- 
1.5.5.6

