Commit 170131f9 authored by Mark Lindner's avatar Mark Lindner

Fix int<->int64 conversions.

parent 95a985a5
......@@ -439,7 +439,7 @@ characters, dashes (@samp{-}), underscores (@samp{_}), and asterisks
characters are allowed.
In C and C++, integer, 64-bit integer, floating point, and string
values are mapped to the types @code{int}, @code{long long},
values are mapped to the native types @code{int}, @code{long long},
@code{double}, and @code{const char *}, respectively. The boolean type
is mapped to @code{int} in C and @code{bool} in C++.
......@@ -524,6 +524,16 @@ of version 1.5 of the library, the trailing `L' is optional; if the
integer value exceeds the range of a 32-bit integer, it will
automatically be interpreted as a 64-bit integer.
The @i{integer} and @i{64-bit integer} setting types are interchangeable to the
extent that a conversion between the corresponding native types would not
result in an overflow or underflow. For example, a @i{long long} value can be
written to a setting that has an @i{integer} type, if that value is within the
range of an @i{int}. This rule applies to every API function or method that
reads a value from or writes a value to a setting: if the type conversion would
not result in an overflow or underflow, then the call will succeed, and
otherwise it will fail. This behavior was not well-defined prior to version 1.7
of the library.
@node Floating Point Values, Boolean Values, 64-bit Integer Values, Configuration Files
@comment node-name, next, previous, up
@section Floating Point Values
......@@ -2082,8 +2092,8 @@ applies to settings of type @code{TypeInt} and @code{TypeInt64}. If
@end deftypemethod
@deftypemethod Setting bool exists (@w{const std::string &@var{name}})
@deftypemethodx Setting bool exists (@w{const char *@var{name}})
@deftypemethod Setting bool exists (@w{const std::string &@var{name}}) const
@deftypemethodx Setting bool exists (@w{const char *@var{name}}) const
These methods test if the setting has a child setting with the given
@var{name}. They return @code{true} if the setting exists, and
......@@ -2182,6 +2192,10 @@ An example C program that constructs a new configuration in memory and writes it
@item examples/c++/example3.cpp
The C++ equivalent of @file{example3.c}
@item examples/c/example4.c
An example C program that uses a custom include function for processing
wildcard includes. Note that this code will not compile on Windows.
@end table
@node Configuration File Grammar, License, Example Programs, Top
......
......@@ -842,12 +842,14 @@ static int __config_setting_get_int(const config_setting_t *setting,
return(CONFIG_TRUE);
case CONFIG_TYPE_INT64:
if((setting->value.llval > INT32_MAX)
|| (setting->value.llval < INT32_MIN))
*value = 0;
else
if((setting->value.llval >= INT_MIN)
&& (setting->value.llval <= INT_MAX))
{
*value = (int)(setting->value.llval);
return(CONFIG_TRUE);
return(CONFIG_TRUE);
}
else
return(CONFIG_FALSE);
case CONFIG_TYPE_FLOAT:
if(config_get_option(setting->config, CONFIG_OPTION_AUTOCONVERT))
......@@ -856,7 +858,7 @@ static int __config_setting_get_int(const config_setting_t *setting,
return(CONFIG_TRUE);
}
else
{ /* fall through */ }
return(CONFIG_FALSE);
default:
return(CONFIG_FALSE);
......@@ -894,7 +896,7 @@ static int __config_setting_get_int64(const config_setting_t *setting,
return(CONFIG_TRUE);
}
else
{ /* fall through */ }
return(CONFIG_FALSE);
default:
return(CONFIG_FALSE);
......@@ -961,7 +963,7 @@ static int __config_setting_get_float(const config_setting_t *setting,
return(CONFIG_TRUE);
}
else
{ /* fall through */ }
return(CONFIG_FALSE);
default:
return(CONFIG_FALSE);
......@@ -1064,11 +1066,13 @@ int config_setting_set_int64(config_setting_t *setting, long long value)
return(CONFIG_TRUE);
case CONFIG_TYPE_INT:
if((value > INT32_MAX) || (value < INT32_MIN))
setting->value.ival = 0;
else
if((value >= INT_MIN) && (value <= INT_MAX))
{
setting->value.ival = (int)value;
return(CONFIG_TRUE);
return(CONFIG_TRUE);
}
else
return(CONFIG_FALSE);
case CONFIG_TYPE_FLOAT:
if(config_get_auto_convert(setting->config))
......
......@@ -23,6 +23,8 @@
#ifndef __wincompat_h
#define __wincompat_h
#include <limits.h>
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#ifdef _MSC_VER
......@@ -74,17 +76,17 @@
#define INT64_CONST(I) (I ## i64)
#define UINT64_CONST(I) (I ## Ui64)
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#ifndef INT_MAX
#define INT_MAX (2147483647)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#ifndef INT_MIN
#define INT_MIN (-2147483647-1)
#endif
#include <Shlwapi.h>
#define IS_RELATIVE_PATH(P) \
(PathIsRelative(P))
(PathIsRelativeA(P))
#else /* defined(WIN32) && ! defined(__MINGW32__) */
......
/* ----------------------------------------------------------------------------
libconfig - A library for processing structured configuration files
Copyright (C) 2005-2015 Mark A Lindner
Copyright (C) 2005-2018 Mark A Lindner
This file is part of libconfig.
......@@ -58,6 +58,8 @@ static void parse_and_compare(const char *input_file, const char *output_file)
config_destroy(&cfg);
}
/* ------------------------------------------------------------------------- */
static void parse_file_and_compare_error(const char *input_file,
const char *parse_error)
{
......@@ -80,6 +82,8 @@ static void parse_file_and_compare_error(const char *input_file,
TT_ASSERT_STR_EQ(actual_error, expected_error);
}
/* ------------------------------------------------------------------------- */
static void parse_string_and_compare_error(const char *input_text,
const char *parse_error)
{
......@@ -101,6 +105,8 @@ static void parse_string_and_compare_error(const char *input_text,
TT_ASSERT_STR_EQ(actual_error, expected_error);
}
/* ------------------------------------------------------------------------- */
static const char *read_file_to_string(const char *file)
{
struct stat stbuf;
......@@ -215,7 +221,6 @@ TT_TEST(BigInt1)
int ival;
long long llval;
/* int = 5 */
buf = "someint=5;";
config_init(&cfg);
......@@ -240,21 +245,19 @@ TT_TEST(BigInt2)
char *buf;
config_t cfg;
int rc;
int ival;
int ival = 123;
long long llval;
/* int = 2^33 */
buf = "someint=8589934592;";
buf = "someint=8589934592;"; /* 2^33 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
TT_ASSERT_TRUE(rc);
/* Should fail because value was parsed as an int64. */
rc = config_lookup_int(&cfg, "someint", &ival);
TT_ASSERT_TRUE(rc);
/* This looks very wrong. config_lookup_int should fail
* instead. */
TT_ASSERT_INT_EQ(ival, 0);
TT_ASSERT_FALSE(rc);
TT_ASSERT_INT_EQ(ival, 123);
rc = config_lookup_int64(&cfg, "someint", &llval);
TT_ASSERT_TRUE(rc);
......@@ -270,21 +273,19 @@ TT_TEST(BigInt3)
char *buf;
config_t cfg;
int rc;
int ival;
int ival = 123;
long long llval;
/* int = -2^33 */
buf = "someint=-8589934592;";
buf = "someint=-8589934592;"; /* -2^33 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
TT_ASSERT_TRUE(rc);
/* Should fail because value was parsed as an int64. */
rc = config_lookup_int(&cfg, "someint", &ival);
TT_ASSERT_TRUE(rc);
/* This looks very wrong. config_lookup_int should fail
* instead. */
TT_ASSERT_INT_EQ(ival, 0);
TT_ASSERT_FALSE(rc);
TT_ASSERT_INT_EQ(ival, 123);
rc = config_lookup_int64(&cfg, "someint", &llval);
TT_ASSERT_TRUE(rc);
......@@ -300,11 +301,10 @@ TT_TEST(BigInt4)
char *buf;
config_t cfg;
int rc;
int ival;
int ival = 123;
long long llval;
/* int = 2^31-1 */
buf = "someint=2147483647;";
buf = "someint=2147483647;"; /* 2^31-1 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
......@@ -328,21 +328,19 @@ TT_TEST(BigInt5)
char *buf;
config_t cfg;
int rc;
int ival;
int ival = 123;
long long llval;
/* int = 2^31 */
buf = "someint=2147483648;";
buf = "someint=2147483648;"; /* 2^31 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
TT_ASSERT_TRUE(rc);
/* Should fail because value was parsed as an int64. */
rc = config_lookup_int(&cfg, "someint", &ival);
TT_ASSERT_TRUE(rc);
/* This looks very wrong. config_lookup_int should fail
* instead. */
TT_ASSERT_INT_EQ(ival, 0);
TT_ASSERT_FALSE(rc);
TT_ASSERT_INT_EQ(ival, 123);
rc = config_lookup_int64(&cfg, "someint", &llval);
TT_ASSERT_TRUE(rc);
......@@ -361,8 +359,7 @@ TT_TEST(BigInt6)
int ival;
long long llval;
/* int = -2^31 */
buf = "someint=-2147483648;";
buf = "someint=-2147483648;"; /* -2^31 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
......@@ -386,21 +383,19 @@ TT_TEST(BigInt7)
char *buf;
config_t cfg;
int rc;
int ival;
int ival = 123;
long long llval;
/* int = -2^31-1 */
buf = "someint=-2147483649;";
buf = "someint=-2147483649;"; /* -2^31-1 */
config_init(&cfg);
rc = config_read_string(&cfg, buf);
TT_ASSERT_TRUE(rc);
/* Should fail because value was parsed as an int64. */
rc = config_lookup_int(&cfg, "someint", &ival);
TT_ASSERT_TRUE(rc);
/* This looks very wrong. config_lookup_int should fail
* instead. */
TT_ASSERT_INT_EQ(ival, 0);
TT_ASSERT_FALSE(rc);
TT_ASSERT_INT_EQ(ival, 123);
rc = config_lookup_int64(&cfg, "someint", &llval);
TT_ASSERT_TRUE(rc);
......@@ -428,7 +423,7 @@ TT_TEST(RemoveSetting)
rc = config_setting_remove(rootSetting, "a.c");
TT_ASSERT_TRUE(rc);
// a and a.b are found
/* a and a.b are found */
rootSetting = config_lookup(&cfg, "a");
TT_EXPECT_PTR_NOTNULL(rootSetting);
rootSetting = config_lookup(&cfg, "a.b");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment