Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for binary integer values #236

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
346 changes: 199 additions & 147 deletions lib/grammar.c

Large diffs are not rendered by default.

84 changes: 41 additions & 43 deletions lib/grammar.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 3.8. */
/* A Bison parser, made by GNU Bison 3.8.2. */

/* Bison interface for Yacc-like parsers in C

Expand Down Expand Up @@ -39,7 +39,7 @@
# define YY_LIBCONFIG_YY_GRAMMAR_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
# define YYDEBUG 1
#endif
#if YYDEBUG
extern int libconfig_yydebug;
Expand All @@ -57,23 +57,25 @@ extern int libconfig_yydebug;
TOK_BOOLEAN = 258, /* TOK_BOOLEAN */
TOK_INTEGER = 259, /* TOK_INTEGER */
TOK_HEX = 260, /* TOK_HEX */
TOK_INTEGER64 = 261, /* TOK_INTEGER64 */
TOK_HEX64 = 262, /* TOK_HEX64 */
TOK_FLOAT = 263, /* TOK_FLOAT */
TOK_STRING = 264, /* TOK_STRING */
TOK_NAME = 265, /* TOK_NAME */
TOK_EQUALS = 266, /* TOK_EQUALS */
TOK_NEWLINE = 267, /* TOK_NEWLINE */
TOK_ARRAY_START = 268, /* TOK_ARRAY_START */
TOK_ARRAY_END = 269, /* TOK_ARRAY_END */
TOK_LIST_START = 270, /* TOK_LIST_START */
TOK_LIST_END = 271, /* TOK_LIST_END */
TOK_COMMA = 272, /* TOK_COMMA */
TOK_GROUP_START = 273, /* TOK_GROUP_START */
TOK_GROUP_END = 274, /* TOK_GROUP_END */
TOK_SEMICOLON = 275, /* TOK_SEMICOLON */
TOK_GARBAGE = 276, /* TOK_GARBAGE */
TOK_ERROR = 277 /* TOK_ERROR */
TOK_BIN = 261, /* TOK_BIN */
TOK_INTEGER64 = 262, /* TOK_INTEGER64 */
TOK_HEX64 = 263, /* TOK_HEX64 */
TOK_BIN64 = 264, /* TOK_BIN64 */
TOK_FLOAT = 265, /* TOK_FLOAT */
TOK_STRING = 266, /* TOK_STRING */
TOK_NAME = 267, /* TOK_NAME */
TOK_EQUALS = 268, /* TOK_EQUALS */
TOK_NEWLINE = 269, /* TOK_NEWLINE */
TOK_ARRAY_START = 270, /* TOK_ARRAY_START */
TOK_ARRAY_END = 271, /* TOK_ARRAY_END */
TOK_LIST_START = 272, /* TOK_LIST_START */
TOK_LIST_END = 273, /* TOK_LIST_END */
TOK_COMMA = 274, /* TOK_COMMA */
TOK_GROUP_START = 275, /* TOK_GROUP_START */
TOK_GROUP_END = 276, /* TOK_GROUP_END */
TOK_SEMICOLON = 277, /* TOK_SEMICOLON */
TOK_GARBAGE = 278, /* TOK_GARBAGE */
TOK_ERROR = 279 /* TOK_ERROR */
};
typedef enum yytokentype yytoken_kind_t;
#endif
Expand All @@ -85,23 +87,25 @@ extern int libconfig_yydebug;
#define TOK_BOOLEAN 258
#define TOK_INTEGER 259
#define TOK_HEX 260
#define TOK_INTEGER64 261
#define TOK_HEX64 262
#define TOK_FLOAT 263
#define TOK_STRING 264
#define TOK_NAME 265
#define TOK_EQUALS 266
#define TOK_NEWLINE 267
#define TOK_ARRAY_START 268
#define TOK_ARRAY_END 269
#define TOK_LIST_START 270
#define TOK_LIST_END 271
#define TOK_COMMA 272
#define TOK_GROUP_START 273
#define TOK_GROUP_END 274
#define TOK_SEMICOLON 275
#define TOK_GARBAGE 276
#define TOK_ERROR 277
#define TOK_BIN 261
#define TOK_INTEGER64 262
#define TOK_HEX64 263
#define TOK_BIN64 264
#define TOK_FLOAT 265
#define TOK_STRING 266
#define TOK_NAME 267
#define TOK_EQUALS 268
#define TOK_NEWLINE 269
#define TOK_ARRAY_START 270
#define TOK_ARRAY_END 271
#define TOK_LIST_START 272
#define TOK_LIST_END 273
#define TOK_COMMA 274
#define TOK_GROUP_START 275
#define TOK_GROUP_END 276
#define TOK_SEMICOLON 277
#define TOK_GARBAGE 278
#define TOK_ERROR 279

/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
Expand All @@ -114,7 +118,7 @@ union YYSTYPE
double fval;
char *sval;

#line 118 "grammar.h"
#line 122 "grammar.h"

};
typedef union YYSTYPE YYSTYPE;
Expand All @@ -124,12 +128,6 @@ typedef union YYSTYPE YYSTYPE;



#if !defined libconfig_yyerror && !defined YYERROR_IS_DECLARED
void libconfig_yyerror (void *scanner, struct parse_context *ctx, struct scan_context *scan_ctx, const char *msg);
#endif
#if !defined libconfig_yylex && !defined YYLEX_IS_DECLARED
int libconfig_yylex (YYSTYPE *yylvalp, void *scanner);
#endif

int libconfig_yyparse (void *scanner, struct parse_context *ctx, struct scan_context *scan_ctx);

Expand Down
48 changes: 46 additions & 2 deletions lib/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ void libconfig_yyerror(void *scanner, struct parse_context *ctx,
char *sval;
}

%token <ival> TOK_BOOLEAN TOK_INTEGER TOK_HEX
%token <llval> TOK_INTEGER64 TOK_HEX64
%token <ival> TOK_BOOLEAN TOK_INTEGER TOK_HEX TOK_BIN
%token <llval> TOK_INTEGER64 TOK_HEX64 TOK_BIN64
%token <fval> TOK_FLOAT
%token <sval> TOK_STRING TOK_NAME
%token TOK_EQUALS TOK_NEWLINE TOK_ARRAY_START TOK_ARRAY_END TOK_LIST_START TOK_LIST_END TOK_COMMA TOK_GROUP_START TOK_GROUP_END TOK_SEMICOLON TOK_GARBAGE TOK_ERROR
Expand Down Expand Up @@ -298,6 +298,50 @@ simple_value:
config_setting_set_format(ctx->setting, CONFIG_FORMAT_HEX);
}
}
| TOK_BIN
{
if(IN_ARRAY() || IN_LIST())
{
config_setting_t *e = config_setting_set_int_elem(ctx->parent, -1, $1);
if(! e)
{
libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type);
YYABORT;
}
else
{
config_setting_set_format(e, CONFIG_FORMAT_BIN);
CAPTURE_PARSE_POS(e);
}
}
else
{
config_setting_set_int(ctx->setting, $1);
config_setting_set_format(ctx->setting, CONFIG_FORMAT_BIN);
}
}
| TOK_BIN64
{
if(IN_ARRAY() || IN_LIST())
{
config_setting_t *e = config_setting_set_int64_elem(ctx->parent, -1, $1);
if(! e)
{
libconfig_yyerror(scanner, ctx, scan_ctx, err_array_elem_type);
YYABORT;
}
else
{
config_setting_set_format(e, CONFIG_FORMAT_BIN);
CAPTURE_PARSE_POS(e);
}
}
else
{
config_setting_set_int64(ctx->setting, $1);
config_setting_set_format(ctx->setting, CONFIG_FORMAT_BIN);
}
}
| TOK_FLOAT
{
if(IN_ARRAY() || IN_LIST())
Expand Down
23 changes: 18 additions & 5 deletions lib/libconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ 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];
char temp_buf[65]; /* Long enough for 64 binary digits + NULL terminator.
Used to be 64 when just used for floats */

switch(type)
{
Expand All @@ -160,7 +161,13 @@ static void __config_write_value(const config_t *config,
fprintf(stream, "0x%X", value->ival);
break;

case CONFIG_FORMAT_DEFAULT:
case CONFIG_FORMAT_BIN:
/* Once %b/%B become more widely supported, could feature test for them */
libconfig_format_bin(value->ival, temp_buf, sizeof(temp_buf));
fprintf(stream, "0b%s", temp_buf);
break;

case CONFIG_FORMAT_DEFAULT:
default:
fprintf(stream, "%d", value->ival);
break;
Expand All @@ -175,6 +182,12 @@ static void __config_write_value(const config_t *config,
fprintf(stream, "0x" INT64_HEX_FMT "L", value->llval);
break;

case CONFIG_FORMAT_BIN:
/* Once %b/%B become more widely supported, could feature test for them */
libconfig_format_bin(value->llval, temp_buf, sizeof(temp_buf));
fprintf(stream, "0b%sL", temp_buf);
break;

case CONFIG_FORMAT_DEFAULT:
default:
fprintf(stream, INT64_FMT "L", value->llval);
Expand All @@ -188,8 +201,8 @@ static void __config_write_value(const config_t *config,
const int sci_ok = config_get_option(
config, CONFIG_OPTION_ALLOW_SCIENTIFIC_NOTATION);
libconfig_format_double(value->fval, config->float_precision, sci_ok,
fbuf, sizeof(fbuf));
fputs(fbuf, stream);
temp_buf, sizeof(temp_buf));
fputs(temp_buf, stream);
break;
}

Expand Down Expand Up @@ -1181,7 +1194,7 @@ int config_setting_set_format(config_setting_t *setting, unsigned short format)
{
if(((setting->type != CONFIG_TYPE_INT)
&& (setting->type != CONFIG_TYPE_INT64))
|| ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX)))
|| ((format != CONFIG_FORMAT_DEFAULT) && (format != CONFIG_FORMAT_HEX) && (format != CONFIG_FORMAT_BIN)))
return(CONFIG_FALSE);

setting->format = format;
Expand Down
1 change: 1 addition & 0 deletions lib/libconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ extern "C" {

#define CONFIG_FORMAT_DEFAULT 0
#define CONFIG_FORMAT_HEX 1
#define CONFIG_FORMAT_BIN 2
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the C++ wrapper needs to be updated as well to update the corresponding enum there


#define CONFIG_OPTION_AUTOCONVERT 0x01
#define CONFIG_OPTION_SEMICOLON_SEPARATORS 0x02
Expand Down
Loading