From ca866ca47835aa72f7e60f31cbdeb0b62ac0a258 Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal@redhat.com>
Date: Sat, 10 Apr 2010 13:45:50 -0400
Subject: [PATCH] [INI] Adding support for explicit 32/64 types.

---
 common/ini/ini.d/real.conf |    4 +
 common/ini/ini_config.c    |   78 ++++++++++++++++++-
 common/ini/ini_config.h    |  181 ++++++++++++++++++++++++++++++++++++++++++++
 common/ini/ini_config_ut.c |  145 +++++++++++++++++++++++++++++++++++
 4 files changed, 403 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.c b/common/ini/ini_config.c
index 1c8e4aef37d330ab29805eeaae22e43cbf72f210..b7e7273c52a24c29d7a6e21213b33f31ed3cbbc6 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -1171,7 +1171,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;
     }
@@ -1488,7 +1488,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) ||
@@ -1520,7 +1520,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_SLNUMBER("get_llong_config_value returning", val);
     return val;
 }
 
@@ -1567,7 +1567,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_LNUMBER("get_ullong_config_value returning", val);
     return val;
 }
 
@@ -1623,6 +1623,74 @@ unsigned get_unsigned_config_value(struct collection_item *item,
     return (unsigned)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 long value from config item */
 long get_long_config_value(struct collection_item *item,
                            int strict,
@@ -1716,7 +1784,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_config.h b/common/ini/ini_config.h
index a5fd4a932f856b716b4654d9f2488677511af24e..5af69f91b6699e6dfdb76c88878ca74c6603509f 100644
--- a/common/ini/ini_config.h
+++ b/common/ini/ini_config.h
@@ -1169,6 +1169,187 @@ 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 44d633fcb1f12eb2063fad42e95908179d584981..b229dae45049f1024e7f7e7b21e7648a3d3e5709 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -479,6 +479,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"));
@@ -1059,6 +1064,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;
-- 
1.5.5.6

