-
----- version 1.5 ------
+2014-09-19 Mark Lindner <markl@neuromancer>
+
+ * lib/libconfig.c, lib/wincompat.h - check if file being opened is a
+ directory
+ * lib/libconfig.c, lib/libconfig.h, lib/libconfig.h++,
+ doc/libconfig.texi - added config_set_options(),
+ config_get_options(), setOptions(), getOptions().
+
2014-05-25 Mark Lindner <markl@neuromancer>
* lib/libconfig.c++, lib/libconfig.h++ - added patches from Matt
@settitle libconfig
@set edition 1.5
-@set update-date 26 May 2014
+@set update-date 21 Sep 2014
@set subtitle-text A Library For Processing Structured Configuration Files
@set author-text Mark A.@: Lindner
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 2005-2012 Mark A Lindner
+Copyright @copyright{} 2005-2014 Mark A Lindner
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@end deftypefun
-@deftypefun void config_set_auto_convert (@w{config_t *@var{config}}, @w{int @var{flag}})
-@deftypefunx int config_get_auto_convert (@w{const config_t *@var{config}})
+@deftypefun void config_set_options (@w{config_t *@var{config}}, @w{int @var{options}})
+@deftypefunx int config_get_options (@w{config_t *@var{config}})
+
+These functions set and get the options for the configuration
+@var{config}. The options affect how configurations are read and
+written. The following options are defined:
+
+@table @code
-@code{config_set_auto_convert()} enables number auto-conversion for
-the configuration @var{config} if @var{flag} is non-zero, and disables
-it otherwise. When this feature is enabled, an attempt to retrieve a
+@item CONFIG_OPTION_AUTOCONVERT
+Turning this option on enables number auto-conversion for
+the configuration. When this feature is enabled, an attempt to retrieve a
floating point setting's value into an integer (or vice versa), or
store an integer to a floating point setting's value (or vice versa)
will cause the library to silently perform the necessary conversion
(possibly leading to loss of data), rather than reporting failure. By
-default this feature is disabled.
+default this option is turned off.
+
+@item CONFIG_OPTION_SEMICOLON_SEPARATORS
+This option controls whether a semicolon (`;') is output after each setting
+when the configuration is written to a file or stream. (The semicolon
+separators are optional in the configuration syntax.) By default this
+option is turned on.
+
+@item CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS
+This option controls whether a colon (`:') is output between each
+group setting's name and its value when the configuration is written to
+a file or stream. If the option is turned off, an equals sign (`=') is
+output instead. (These tokens are interchangeable in the configuration
+syntax.) By default this option is turned on.
+
+@item CONFIG_OPTION_COLON_ASSIGNMENT_FOR_NON_GROUPS
+This option controls whether a colon (`:') is output between each
+non-group setting's name and its value when the configuration is written
+to a file or stream. If the option is turned off, an equals sign (`=')
+is output instead. (These tokens are interchangeable in the configuration
+syntax.) By default this option is turned off.
+
+@item CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE
+This option controls whether an open brace (`@{') will be written on its own
+line when the configuration is written to a file or stream. If the option is
+turned off, the brace will be written at the end of the previous line.
+By default this option is turned on.
-@code{config_get_auto_convert()} returns @code{CONFIG_TRUE} if number
-auto-conversion is currently enabled for @var{config}; otherwise it
-returns @code{CONFIG_FALSE}.
+@end table
+
+@end deftypefun
+
+@deftypefun void config_set_auto_convert (@w{config_t *@var{config}}, @w{int @var{flag}})
+@deftypefunx int config_get_auto_convert (@w{const config_t *@var{config}})
+
+These functions get and set the @code{CONFIG_OPTION_AUTO_CONVERT}
+option. They are obsoleted by the @code{config_set_options()} and
+@code{config_get_options()} functions described above.
@end deftypefun
@end deftypemethod
+@deftypemethod Config void setOptions (int @var{options})
+@deftypemethodx Config int getOptions ()
+
+These methods set and get the options for the configuration. The
+options affect how configurations are read and written. The following
+options are defined:
+
+@table @code
+
+@item OptionAutoConvert
+Turning this option on enables number auto-conversion for
+the configuration. When this feature is enabled, an attempt to retrieve a
+floating point setting's value into an integer (or vice versa), or
+store an integer to a floating point setting's value (or vice versa)
+will cause the library to silently perform the necessary conversion
+(possibly leading to loss of data), rather than reporting failure. By
+default this option is turned off.
+
+@item OptionSemicolonSeparators
+This option controls whether a semicolon (`;') is output after each setting
+when the configuration is written to a file or stream. (The semicolon
+separators are optional in the configuration syntax.) By default this
+option is turned on.
+
+@item OptionColonAssignmentForGroups
+This option controls whether a colon (`:') is output between each
+group setting's name and its value when the configuration is written to
+a file or stream. If the option is turned off, an equals sign (`=') is
+output instead. (These tokens are interchangeable in the configuration
+syntax.) By default this option is turned on.
+
+@item OptionColonAssignmentForNonGroups
+This option controls whether a colon (`:') is output between each
+non-group setting's name and its value when the configuration is written
+to a file or stream. If the option is turned off, an equals sign (`=')
+is output instead. (These tokens are interchangeable in the configuration
+syntax.) By default this option is turned off.
+
+@item OptionOpenBraceOnSeparateLine
+This option controls whether an open brace (`@{') will be written on its own
+line when the configuration is written to a file or stream. If the option is
+turned off, the brace will be written at the end of the previous line.
+By default this option is turned on.
+
+@end table
+
+@end deftypemethod
+
@deftypemethod Config void setAutoConvert (bool @var{flag})
@deftypemethodx Config bool getAutoConvert ()
-@code{setAutoConvert()} enables number auto-conversion for the
-configuration if @var{flag} is @code{true}, and disables it
-otherwise. When this feature is enabled, an attempt to assign a
-floating point setting to an integer (or vice versa), or
-assign an integer to a floating point setting (or vice versa) will
-cause the library to silently perform the necessary conversion
-(possibly leading to loss of data), rather than throwing a
-@code{SettingTypeException}. By default this feature is disabled.
-
-@code{getAutoConvert()} returns @code{true} if number auto-conversion
-is currently enabled for the configuration; otherwise it returns
-@code{false}.
+These methods get and set the @code{OptionAutoConvert} option. They
+are obsoleted by the @code{setOptions()} and @code{getOptions()}
+methods described above.
@end deftypemethod
@code{false} otherwise. These methods do not throw exceptions.
@end deftypemethod
-
+@page
@deftypemethod Setting iterator begin ()
@deftypemethodx Setting iterator end ()
@deftypemethodx Setting const_iterator begin ()
setting = config_setting_add(movie, "qty", CONFIG_TYPE_INT);
config_setting_set_float(setting, 20);
+ config_set_options(&cfg, 0);
+
/* Write out the updated configuration. */
if(! config_write_file(&cfg, output_file))
{
static const char *__io_error = "file I/O error";
static void __config_list_destroy(config_list_t *list);
-static void __config_write_setting(const config_setting_t *setting,
- FILE *stream, int depth,
- unsigned short tab_width);
+static void __config_write_setting(const config_t *config,
+ const config_setting_t *setting,
+ FILE *stream, int depth);
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
+#define __config_has_option(C, O) \
+ (((C)->options & (O)) != 0)
+
+/* ------------------------------------------------------------------------- */
+
static void __config_locale_restore(void)
{
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
/* ------------------------------------------------------------------------- */
-static void __config_write_value(const config_value_t *value, int type,
- int format, int depth,
- unsigned short tab_width, FILE *stream)
+static void __config_write_value(const config_t *config,
+ const config_value_t *value, int type,
+ int format, int depth, FILE *stream)
{
char fbuf[64];
for(s = list->elements; len--; s++)
{
- __config_write_value(&((*s)->value), (*s)->type,
- config_setting_get_format(*s),
- depth + 1, tab_width, stream);
+ __config_write_value(config, &((*s)->value), (*s)->type,
+ config_setting_get_format(*s), depth + 1,
+ stream);
if(len)
fputc(',', stream);
for(s = list->elements; len--; s++)
{
- __config_write_value(&((*s)->value), (*s)->type,
- config_setting_get_format(*s),
- depth + 1, tab_width, stream);
+ __config_write_value(config, &((*s)->value), (*s)->type,
+ config_setting_get_format(*s), depth + 1,
+ stream);
if(len)
fputc(',', stream);
if(depth > 0)
{
-#ifdef K_AND_R_STYLE /* Horrendous, but many people like it. */
- fputc(' ', stream);
-#else
- fputc('\n', stream);
+ if((config->options & CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE) != 0)
+ {
+ fputc('\n', stream);
+
+ if(depth > 1)
+ __config_indent(stream, depth, config->tab_width);
+ }
- if(depth > 1)
- __config_indent(stream, depth, tab_width);
-#endif
fprintf(stream, "{\n");
}
config_setting_t **s;
for(s = list->elements; len--; s++)
- __config_write_setting(*s, stream, depth + 1, tab_width);
+ __config_write_setting(config, *s, stream, depth + 1);
}
if(depth > 1)
- __config_indent(stream, depth, tab_width);
+ __config_indent(stream, depth, config->tab_width);
if(depth > 0)
fputc('}', stream);
void (*destructor)(void *) = config->destructor;
const char *include_dir = config->include_dir;
unsigned short tab_width = config->tab_width;
- unsigned short flags = config->flags;
+ int options = config->options;
config->include_dir = NULL;
config_destroy(config);
config->destructor = destructor;
config->include_dir = include_dir;
config->tab_width = tab_width;
- config->flags = flags;
+ config->options = options;
parsectx_init(&parse_ctx);
parse_ctx.config = config;
/* ------------------------------------------------------------------------- */
-static void __config_write_setting(const config_setting_t *setting,
- FILE *stream, int depth,
- unsigned short tab_width)
+static void __config_write_setting(const config_t *config,
+ const config_setting_t *setting,
+ FILE *stream, int depth)
{
+ char group_assign_char = ((config->options
+ & CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS) != 0)
+ ? ':' : '=';
+
+ char nongroup_assign_char
+ = ((config->options & CONFIG_OPTION_COLON_ASSIGNMENT_FOR_NON_GROUPS) != 0)
+ ? ':' : '=';
+
if(depth > 1)
- __config_indent(stream, depth, tab_width);
+ __config_indent(stream, depth, config->tab_width);
+
if(setting->name)
{
fputs(setting->name, stream);
- fprintf(stream, " %c ", (setting->type == CONFIG_TYPE_GROUP ? ':' : '='));
+ fprintf(stream, " %c ", ((setting->type == CONFIG_TYPE_GROUP)
+ ? group_assign_char
+ : nongroup_assign_char));
}
- __config_write_value(&(setting->value), setting->type,
- config_setting_get_format(setting),
- depth, tab_width, stream);
+ __config_write_value(config, &(setting->value), setting->type,
+ config_setting_get_format(setting), depth, stream);
if(depth > 0)
{
- fputc(';', stream);
+ if((config->options & CONFIG_OPTION_SEMICOLON_SEPARATORS) != 0)
+ fputc(';', stream);
+
fputc('\n', stream);
}
}
{
__config_locale_override();
- __config_write_setting(config->root, stream, 0, config->tab_width);
+ __config_write_setting(config, config->root, stream, 0);
__config_locale_restore();
}
config->root = _new(config_setting_t);
config->root->type = CONFIG_TYPE_GROUP;
config->root->config = config;
+ config->options = (CONFIG_OPTION_SEMICOLON_SEPARATORS
+ | CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS
+ | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE);
config->tab_width = 2;
}
void config_set_auto_convert(config_t *config, int flag)
{
if(flag)
- config->flags |= CONFIG_OPTION_AUTOCONVERT;
+ config->options |= CONFIG_OPTION_AUTOCONVERT;
else
- config->flags &= ~CONFIG_OPTION_AUTOCONVERT;
+ config->options &= ~CONFIG_OPTION_AUTOCONVERT;
}
/* ------------------------------------------------------------------------- */
int config_get_auto_convert(const config_t *config)
{
- return((config->flags & CONFIG_OPTION_AUTOCONVERT) != 0);
+ return((config->options & CONFIG_OPTION_AUTOCONVERT) != 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void config_set_options(config_t *config, int options)
+{
+ config->options = options;
+}
+
+/* ------------------------------------------------------------------------- */
+
+int config_get_options(const config_t *config)
+{
+ return(config->options);
}
/* ------------------------------------------------------------------------- */
return(CONFIG_TRUE);
case CONFIG_TYPE_FLOAT:
- if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ if((setting->config->options & CONFIG_OPTION_AUTOCONVERT) != 0)
{
*value = (int)(setting->value.fval);
return(CONFIG_TRUE);
return(CONFIG_TRUE);
case CONFIG_TYPE_FLOAT:
- if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ if((setting->config->options & CONFIG_OPTION_AUTOCONVERT) != 0)
{
*value = (long long)(setting->value.fval);
return(CONFIG_TRUE);
return(CONFIG_TRUE);
case CONFIG_TYPE_INT:
- if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ if((setting->config->options & CONFIG_OPTION_AUTOCONVERT) != 0)
{
setting->value.ival = (int)value;
return(CONFIG_TRUE);
return(CONFIG_FALSE);
case CONFIG_TYPE_INT64:
- if((setting->config->flags & CONFIG_OPTION_AUTOCONVERT) != 0)
+ if((setting->config->options & CONFIG_OPTION_AUTOCONVERT) != 0)
{
setting->value.llval = (long long)value;
return(CONFIG_TRUE);
#define CONFIG_FORMAT_DEFAULT 0
#define CONFIG_FORMAT_HEX 1
-#define CONFIG_OPTION_AUTOCONVERT 0x01
+#define CONFIG_OPTION_AUTOCONVERT 0x01
+#define CONFIG_OPTION_SEMICOLON_SEPARATORS 0x02
+#define CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS 0x04
+#define CONFIG_OPTION_COLON_ASSIGNMENT_FOR_NON_GROUPS 0x08
+#define CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE 0x10
#define CONFIG_TRUE (1)
#define CONFIG_FALSE (0)
{
config_setting_t *root;
void (*destructor)(void *);
- unsigned short flags;
+ int options;
unsigned short tab_width;
short default_format;
const char *include_dir;
extern LIBCONFIG_API void config_set_default_format(config_t *config,
short format);
+extern LIBCONFIG_API void config_set_options(config_t *config, int options);
+extern LIBCONFIG_API int config_get_options(const config_t *config);
+
extern LIBCONFIG_API void config_set_auto_convert(config_t *config, int flag);
extern LIBCONFIG_API int config_get_auto_convert(const config_t *config);
FormatHex = 1
};
+ enum Option
+ {
+ OptionNone = 0,
+ OptionAutoConvert = 0x01,
+ OptionSemicolonSeparators = 0x02,
+ OptionColonAssignmentForGroups = 0x04,
+ OptionColonAssignmentForNonGroups = 0x08,
+ OptionOpenBraceOnSeparateLine = 0x10
+ };
+
typedef SettingIterator iterator;
typedef SettingConstIterator const_iterator;
Config();
virtual ~Config();
+ void setOptions(int options);
+ int getOptions() const;
+
void setAutoConvert(bool flag);
bool getAutoConvert() const;
// ---------------------------------------------------------------------------
+void Config::setOptions(int options)
+{
+ config_set_options(_config, options);
+}
+
+// ---------------------------------------------------------------------------
+
+int Config::getOptions() const
+{
+ return(config_get_options(_config));
+}
+
+// ---------------------------------------------------------------------------
+
bool Config::getAutoConvert() const
{
return(config_get_auto_convert(_config) != CONFIG_FALSE);