diff --git a/src/iniparser.c b/src/iniparser.c index 73db476e7bcd230f69e374255bd1983659aed8f8..63f54f417547247d633cac17b9497508d14f90c9 100644 --- a/src/iniparser.c +++ b/src/iniparser.c @@ -426,11 +426,11 @@ const char * iniparser_getstring(const dictionary * d, const char * key, const c /*-------------------------------------------------------------------------*/ /** - @brief Get the string associated to a key, convert to an int + @brief Get the string associated to a key, convert to an long int @param d Dictionary to search @param key Key string to look for @param notfound Value to return in case of error - @return integer + @return long integer This function queries a dictionary for a key. A key as read from an ini file is given as "section:key". If the key cannot be found, @@ -451,13 +451,46 @@ const char * iniparser_getstring(const dictionary * d, const char * key, const c Credits: Thanks to A. Becker for suggesting strtol() */ /*--------------------------------------------------------------------------*/ -int iniparser_getint(const dictionary * d, const char * key, int notfound) +long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound) { const char * str ; str = iniparser_getstring(d, key, INI_INVALID_KEY); if (str==INI_INVALID_KEY) return notfound ; - return (int)strtol(str, NULL, 0); + return strtol(str, NULL, 0); +} + + +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + "42" -> 42 + "042" -> 34 (octal -> decimal) + "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + + Credits: Thanks to A. Becker for suggesting strtol() + */ +/*--------------------------------------------------------------------------*/ +int iniparser_getint(const dictionary * d, const char * key, int notfound) +{ + return (int)iniparser_getlongint(d, key, notfound); } /*-------------------------------------------------------------------------*/ @@ -692,6 +725,7 @@ dictionary * iniparser_load(const char * ininame) int len ; int lineno=0 ; int errs=0; + int mem_err=0; dictionary * dict ; @@ -750,12 +784,12 @@ dictionary * iniparser_load(const char * ininame) break ; case LINE_SECTION: - errs = dictionary_set(dict, section, NULL); + mem_err = dictionary_set(dict, section, NULL); break ; case LINE_VALUE: sprintf(tmp, "%s:%s", section, key); - errs = dictionary_set(dict, tmp, val) ; + mem_err = dictionary_set(dict, tmp, val); break ; case LINE_ERROR: @@ -772,7 +806,7 @@ dictionary * iniparser_load(const char * ininame) } memset(line, 0, ASCIILINESZ); last=0; - if (errs<0) { + if (mem_err<0) { iniparser_error_callback("iniparser: memory allocation failure\n"); break ; } diff --git a/src/iniparser.h b/src/iniparser.h index 8cc4e9c392d9eacfee27452078a15ccb777f36aa..37ff7b71b209db797539f94bc1b968678c0c83f0 100644 --- a/src/iniparser.h +++ b/src/iniparser.h @@ -202,6 +202,34 @@ const char * iniparser_getstring(const dictionary * d, const char * key, const c /*--------------------------------------------------------------------------*/ int iniparser_getint(const dictionary * d, const char * key, int notfound); +/*-------------------------------------------------------------------------*/ +/** + @brief Get the string associated to a key, convert to an long int + @param d Dictionary to search + @param key Key string to look for + @param notfound Value to return in case of error + @return integer + + This function queries a dictionary for a key. A key as read from an + ini file is given as "section:key". If the key cannot be found, + the notfound value is returned. + + Supported values for integers include the usual C notation + so decimal, octal (starting with 0) and hexadecimal (starting with 0x) + are supported. Examples: + + - "42" -> 42 + - "042" -> 34 (octal -> decimal) + - "0x42" -> 66 (hexa -> decimal) + + Warning: the conversion may overflow in various ways. Conversion is + totally outsourced to strtol(), see the associated man page for overflow + handling. + */ +/*--------------------------------------------------------------------------*/ +long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound); + + /*-------------------------------------------------------------------------*/ /** @brief Get the string associated to a key, convert to a double diff --git a/test/CuTest.c b/test/CuTest.c index 144f8c30613b88b303d28b57434ff403be67d44e..463f1708fe401af18b8f2590ed3d88a7d339d27d 100644 --- a/test/CuTest.c +++ b/test/CuTest.c @@ -211,6 +211,15 @@ void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const cha CuFail_Line(tc, file, line, message, buf); } +void CuAssertLongIntEquals_LineMsg(CuTest *tc, const char *file, int line, const char *message, + long int expected, long int actual) +{ + char buf[STRING_MAX]; + if (expected == actual) return; + sprintf(buf, "expected <%ld> but was <%ld>", expected, actual); + CuFail_Line(tc, file, line, message, buf); +} + void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta) { diff --git a/test/CuTest.h b/test/CuTest.h index 2f7ef5422b1aa0ea3b0c5f69e0e726f1d6a14525..0f5859214b6f5ac5ef98e421f5613c31ff15e2f5 100644 --- a/test/CuTest.h +++ b/test/CuTest.h @@ -64,6 +64,9 @@ void CuAssertStrEquals_LineMsg(CuTest* tc, void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, int expected, int actual); +void CuAssertLongIntEquals_LineMsg(CuTest *tc, + const char *file, int line, const char *message, + long int expected, long int actual); void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, double expected, double actual, double delta); @@ -81,6 +84,8 @@ void CuAssertPtrEquals_LineMsg(CuTest* tc, #define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) #define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) +#define CuAssertLongIntEquals(tc,ex,ac) CuAssertLongIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) +#define CuAssertLongIntEquals_Msg(tc,ms,ex,ac) CuAssertLongIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) #define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) diff --git a/test/ressources/bad_ini/ends_well.ini b/test/ressources/bad_ini/ends_well.ini new file mode 100644 index 0000000000000000000000000000000000000000..3f920c78216a2b202dfb1084f374cf026bafde1b --- /dev/null +++ b/test/ressources/bad_ini/ends_well.ini @@ -0,0 +1,6 @@ +# +# This dict contains an error but ends up with a correct entry +# +[section] +error is here +a = b diff --git a/test/test_iniparser.c b/test/test_iniparser.c index ea81572dd0f6aceb9de19a77e9e1b3b26c87e34c..c76529cd75d67fe4502873b6d468bd544047daa8 100644 --- a/test/test_iniparser.c +++ b/test/test_iniparser.c @@ -338,6 +338,69 @@ void Test_iniparser_getint(CuTest *tc) dictionary_del(dic); } +void Test_iniparser_getlongint(CuTest *tc) +{ + unsigned i; + char key_name[64]; + dictionary *dic; + const struct { long int num; const char *value; } good_val[] = { + { 0, "0" }, + { 1, "1" }, + { -1, "-1" }, + { 1000, "1000" }, + { 077, "077" }, + { -01000, "-01000" }, + { 0x7FFFFFFFFFFFFFFF, "0x7FFFFFFFFFFFFFFF" }, + { -0x7FFFFFFFFFFFFFFF, "-0x7FFFFFFFFFFFFFFF" }, + { 0x4242, "0x4242" }, + { 0, NULL} /* must be last */ + }; + const char *bad_val[] = { + "", + "notanumber", + "0x", + "k2000", + " ", + "0xG1" + }; + /* NULL test */ + CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, NULL, -42)); + CuAssertLongIntEquals(tc, -42, iniparser_getlongint(NULL, "dummy", -42)); + + /* Check the def return element */ + dic = dictionary_new(10); + CuAssertLongIntEquals(tc, 42, iniparser_getlongint(dic, "dummy", 42)); + CuAssertLongIntEquals(tc, 0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, NULL, 0x7FFFFFFFFFFFFFFF)); + CuAssertLongIntEquals(tc, -0x7FFFFFFFFFFFFFFF, iniparser_getlongint(dic, "dummy", -0x7FFFFFFFFFFFFFFF)); + dictionary_del(dic); + + /* Generic dictionary */ + dic = dictionary_new(10); + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + dictionary_set(dic, key_name, good_val[i].value); + } + for (i = 0; good_val[i].value != NULL; ++i) { + sprintf(key_name, "longint:value%d", i); + CuAssertLongIntEquals(tc, good_val[i].num, + iniparser_getlongint(dic, key_name, 0)); + } + dictionary_del(dic); + + /* Test bad names */ + dic = dictionary_new(10); + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + dictionary_set(dic, key_name, bad_val[i]); + } + for (i = 0; i < sizeof (bad_val) / sizeof (char *); ++i) { + sprintf(key_name, "longint:bad%d", i); + CuAssertLongIntEquals(tc, 0, + iniparser_getlongint(dic, key_name, 0)); + } + dictionary_del(dic); +} + void Test_iniparser_getdouble(CuTest *tc) { dictionary *dic;