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 7 commits
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
35 changes: 22 additions & 13 deletions doc/libconfig.texi
Copy link
Owner

Choose a reason for hiding this comment

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

Please also update the C++ section of the documentation; there's a 'format' enum there as well

Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ application:
bigint = 9223372036854775807L;
columns = [ "Last Name", "First Name", "MI" ];
bitmask = 0x1FC3; // hex
bitmask2 = 0b1011; // binary
umask = 0027; // octal. Range limited to that of "int"
@};
@};
Expand Down Expand Up @@ -509,24 +510,26 @@ The last element in a list may be followed by a comma, which will be ignored.
@comment node-name, next, previous, up
@section Integer Values

Integers can be represented in one of two ways: as a series of one or
more decimal digits (@samp{0} - @samp{9}), with an optional leading
sign character (@samp{+} or @samp{-}); or as a hexadecimal value
consisting of the characters @samp{0x} followed by a series of one or
more hexadecimal digits (@samp{0} - @samp{9}, @samp{A} - @samp{F},
@samp{a} - @samp{f}). Additionally, octal notation integers (that is,
those having a leading zero with non-zero value) are also allowed.
Integers can be represented in one of two ways: as a series of one or more
Copy link
Owner

@hyperrealm hyperrealm Apr 25, 2024

Choose a reason for hiding this comment

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

s/one of two/the following/

decimal digits (@samp{0} - @samp{9}), with an optional leading sign character
(@samp{+} or @samp{-}); as a hexadecimal value consisting of the characters
@samp{0x} followed by a series of one or more hexadecimal digits (@samp{0} -
@samp{9}, @samp{A} - @samp{F}, @samp{a} - @samp{f}); or (as of version 1.7.4 of
the library) as a binary value consisting of the characters @samp{0b} followed
by a series of @samp{0}s or @samp{1}s. Additionally, octal notation integers
(that is, those having a leading zero with non-zero value) are also allowed.

@node 64-bit Integer Values, Floating Point Values, Integer Values, Configuration Files
@comment node-name, next, previous, up
@section 64-bit Integer Values

Long long (64-bit) integers are represented identically to integers,
except that an `L' character is appended to indicate a 64-bit
value. For example, @samp{0L} indicates a 64-bit integer value 0. As
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.
Long long (64-bit) integers are represented identically to integers, except
that an `L' character is appended to indicate a 64-bit value. For example,
@samp{0L} indicates a 64-bit integer value 0. As 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.
As of version 1.7.4 of the library this behavior is extended to hexadecimal
(and binary) integers as well.
Copy link
Owner

Choose a reason for hiding this comment

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

no need for parens around 'and binary'


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
Expand Down Expand Up @@ -2464,6 +2467,8 @@ directives are not part of the grammar, so they are not included here.
<boolean>
| <integer>
| <integer64>
| <bin>
| <bin64>
| <hex>
| <hex64>
| <float>
Expand Down Expand Up @@ -2501,6 +2506,10 @@ Terminals are defined below as regular expressions:
@code{[-+]?[0-9]+}
@item @code{<integer64>} @tab
@code{[-+]?[0-9]+L(L)?}
@item @code{<bin>} @tab
@code{0[bB][01]+}
@item @code{<bin64>} @tab
@code{0[bB][01]+L(L)?}
@item @code{<hex>} @tab
@code{0[Xx][0-9A-Fa-f]+}
@item @code{<hex64>} @tab
Expand Down
2 changes: 1 addition & 1 deletion lib/grammar.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
# define YY_LIBCONFIG_YY_GRAMMAR_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 1
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int libconfig_yydebug;
Expand Down
86 changes: 62 additions & 24 deletions lib/scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,7 +1382,7 @@ YY_RULE_SETUP
#line 144 "scanner.l"
{
int ok;
long long llval = libconfig_parse_integer(yytext, &ok);
long long llval = libconfig_parse_integer(yytext, &ok,0);
if(!ok)
return(TOK_ERROR);

Expand All @@ -1401,76 +1401,114 @@ YY_RULE_SETUP
case 38:
YY_RULE_SETUP
#line 161 "scanner.l"
{ yylval->llval = atoll(yytext); return(TOK_INTEGER64); }
{
int ok;
long long llval = libconfig_parse_integer(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);

yylval->llval = llval;
return(TOK_INTEGER64);
}
YY_BREAK
case 39:
YY_RULE_SETUP
#line 162 "scanner.l"
#line 170 "scanner.l"
{
yylval->ival = strtoul(yytext+2, NULL,2);
return(TOK_BIN);
int ok;
unsigned long long llval = libconfig_parse_bin64(yytext,&ok,0);
if (!ok)
return (TOK_ERROR);

if (llval < INT_MAX)
{
yylval->ival = (int) llval;
return TOK_BIN;
}

yylval->llval = llval;
return(TOK_BIN64);
}
YY_BREAK
case 40:
YY_RULE_SETUP
#line 166 "scanner.l"
#line 185 "scanner.l"
{
yylval->llval = libconfig_parse_bin64(yytext);
return(TOK_BIN64);
int ok;
unsigned long long llval = libconfig_parse_bin64(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);
yylval->llval = llval;
return (TOK_BIN64);
}
YY_BREAK
case 41:
YY_RULE_SETUP
#line 170 "scanner.l"
#line 193 "scanner.l"
{
yylval->ival = strtoul(yytext, NULL, 16);
return(TOK_HEX);
int ok;
unsigned long long llval = libconfig_parse_hex64(yytext,&ok,0);
if (!ok)
return (TOK_ERROR);

if (llval < INT_MAX)
{
yylval->ival = (int) llval;
return TOK_HEX;
}

yylval->llval = llval;
return(TOK_HEX64);
}
YY_BREAK
case 42:
YY_RULE_SETUP
#line 174 "scanner.l"
#line 208 "scanner.l"
{
yylval->llval = libconfig_parse_hex64(yytext);
return(TOK_HEX64);
int ok;
unsigned long long llval = libconfig_parse_hex64(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);
yylval->llval = llval;
return (TOK_HEX64);
}
YY_BREAK
case 43:
YY_RULE_SETUP
#line 178 "scanner.l"
#line 216 "scanner.l"
{ return(TOK_ARRAY_START); }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 179 "scanner.l"
#line 217 "scanner.l"
{ return(TOK_ARRAY_END); }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 180 "scanner.l"
#line 218 "scanner.l"
{ return(TOK_LIST_START); }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 181 "scanner.l"
#line 219 "scanner.l"
{ return(TOK_LIST_END); }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 182 "scanner.l"
#line 220 "scanner.l"
{ return(TOK_SEMICOLON); }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 183 "scanner.l"
#line 221 "scanner.l"
{ return(TOK_GARBAGE); }
YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(SINGLE_LINE_COMMENT):
case YY_STATE_EOF(MULTI_LINE_COMMENT):
case YY_STATE_EOF(STRING):
case YY_STATE_EOF(INCLUDE):
#line 185 "scanner.l"
#line 223 "scanner.l"
{
const char *error = NULL;
FILE *fp;
Expand Down Expand Up @@ -1506,10 +1544,10 @@ case YY_STATE_EOF(INCLUDE):
YY_BREAK
case 49:
YY_RULE_SETUP
#line 218 "scanner.l"
#line 256 "scanner.l"
ECHO;
YY_BREAK
#line 1512 "scanner.c"
#line 1550 "scanner.c"

case YY_END_OF_BUFFER:
{
Expand Down Expand Up @@ -2638,7 +2676,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)

#define YYTABLES_NAME "yytables"

#line 218 "scanner.l"
#line 256 "scanner.l"


void *libconfig_yyalloc(size_t bytes, void *yyscanner)
Expand Down
2 changes: 1 addition & 1 deletion lib/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ extern int yylex \
#undef yyTABLES_NAME
#endif

#line 218 "scanner.l"
#line 256 "scanner.l"


#line 720 "scanner.h"
Expand Down
58 changes: 48 additions & 10 deletions lib/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ include_open ^[ \t]*@include[ \t]+\"
{float} { yylval->fval = atof(yytext); return(TOK_FLOAT); }
{integer} {
int ok;
long long llval = libconfig_parse_integer(yytext, &ok);
long long llval = libconfig_parse_integer(yytext, &ok,0);
if(!ok)
return(TOK_ERROR);

Expand All @@ -158,22 +158,60 @@ include_open ^[ \t]*@include[ \t]+\"
return(TOK_INTEGER);
}
}
{integer64} { yylval->llval = atoll(yytext); return(TOK_INTEGER64); }
{integer64} {
int ok;
long long llval = libconfig_parse_integer(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);

yylval->llval = llval;
return(TOK_INTEGER64);
}
{bin} {
yylval->ival = strtoul(yytext+2, NULL,2);
return(TOK_BIN);
int ok;
unsigned long long llval = libconfig_parse_bin64(yytext,&ok,0);
if (!ok)
return (TOK_ERROR);

if (llval < INT_MAX)
{
yylval->ival = (int) llval;
return TOK_BIN;
}

yylval->llval = llval;
return(TOK_BIN64);
}
{bin64} {
yylval->llval = libconfig_parse_bin64(yytext);
return(TOK_BIN64);
int ok;
unsigned long long llval = libconfig_parse_bin64(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);
yylval->llval = llval;
return (TOK_BIN64);
}
{hex} {
yylval->ival = strtoul(yytext, NULL, 16);
return(TOK_HEX);
int ok;
unsigned long long llval = libconfig_parse_hex64(yytext,&ok,0);
if (!ok)
return (TOK_ERROR);

if (llval < INT_MAX)
{
yylval->ival = (int) llval;
return TOK_HEX;
}

yylval->llval = llval;
return(TOK_HEX64);
}
{hex64} {
yylval->llval = libconfig_parse_hex64(yytext);
return(TOK_HEX64);
int ok;
unsigned long long llval = libconfig_parse_hex64(yytext,&ok,1);
if (!ok)
return (TOK_ERROR);
yylval->llval = llval;
return (TOK_HEX64);
}
\[ { return(TOK_ARRAY_START); }
\] { return(TOK_ARRAY_END); }
Expand Down
Loading