mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-03-19 17:30:27 +08:00
Fix ncgen handling of octal constants (with leading 0).
re: https://github.com/Unidata/netcdf-c/issues/1330 The ncgen utility is documented to accept octal integer constants if the leading digit is zero. This was not implemented. Fix ncgen.l to properly handle such constants. Also add a test to c0.cdl.
This commit is contained in:
parent
4372b260ae
commit
98caf87116
@ -251,6 +251,7 @@ ENDIF(MSVC)
|
||||
add_sh_test(ncdump tst_inttags4)
|
||||
ENDIF(USE_NETCDF4)
|
||||
|
||||
add_sh_test(ncdump test_radix)
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
@ -4,10 +4,10 @@
|
||||
|
||||
# Ed Hartnett, Dennis Heimbigner, Ward Fisher
|
||||
|
||||
#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
#sh_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
#TESTS_ENVIRONMENT = export SETX=1;
|
||||
SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
sh_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
TESTS_ENVIRONMENT = export SETX=1;
|
||||
|
||||
# Put together AM_CPPFLAGS and AM_LDFLAGS.
|
||||
include $(top_srcdir)/lib_flags.am
|
||||
@ -54,7 +54,7 @@ TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ref_ctest \
|
||||
ref_ctest64 tst_output.sh tst_lengths.sh tst_calendars.sh \
|
||||
run_utf8_tests.sh tst_nccopy3.sh tst_nccopy3_subset.sh \
|
||||
tst_charfill.sh tst_iter.sh tst_formatx3.sh tst_bom.sh \
|
||||
tst_dimsizes.sh run_ncgen_tests.sh tst_ncgen4_classic.sh
|
||||
tst_dimsizes.sh run_ncgen_tests.sh tst_ncgen4_classic.sh test_radix.sh
|
||||
|
||||
# The tst_nccopy3.sh test uses output from a bunch of other
|
||||
# tests. This records the dependency so parallel builds work.
|
||||
@ -133,7 +133,8 @@ tst_hdf5_offset.sh run_ncgen_nc4_tests.sh tst_nccopy3_subset.sh \
|
||||
ref_nccopy3_subset.nc ref_test_corrupt_magic.nc tst_ncgen_shared.sh \
|
||||
tst_ncgen4.sh tst_ncgen4_classic.sh tst_ncgen4_diff.sh \
|
||||
tst_ncgen4_cycle.sh tst_null_byte_padding.sh \
|
||||
ref_null_byte_padding_test.nc ref_tst_irish_rover.nc ref_provenance_v1.nc
|
||||
ref_null_byte_padding_test.nc ref_tst_irish_rover.nc ref_provenance_v1.nc \
|
||||
ref_tst_radix.cdl tst_radix.cdl test_radix.sh
|
||||
|
||||
# The L512.bin file is file containing exactly 512 bytes each of value 0.
|
||||
# It is used for creating hdf5 files with varying offsets for testing.
|
||||
@ -163,4 +164,5 @@ compound_datasize_test.nc compound_datasize_test2.nc ncf199.nc \
|
||||
tst_c0.cdl tst_c0_4.cdl tst_c0_4c.cdl tst_c0_64.cdl \
|
||||
tst_compound_datasize_test.cdl tst_compound_datasize_test2.cdl \
|
||||
tst_ncf199.cdl tst_tst_gattenum.cdl tst_tst_usuffix.cdl ctest.c \
|
||||
ctest64.c nccopy3_subset_out.nc camrun.c tst_ncf213.cdl tst_ncf213.nc
|
||||
ctest64.c nccopy3_subset_out.nc camrun.c tst_ncf213.cdl tst_ncf213.nc \
|
||||
tst_radix.nc tmp_radix.cdl
|
||||
|
19
ncdump/ref_tst_radix.cdl
Normal file
19
ncdump/ref_tst_radix.cdl
Normal file
@ -0,0 +1,19 @@
|
||||
netcdf tst_radix {
|
||||
dimensions:
|
||||
d = 2 ;
|
||||
variables:
|
||||
byte b(d);
|
||||
short s(d);
|
||||
int i(d);
|
||||
|
||||
// global attributes:
|
||||
:attr1 = 83s ;
|
||||
:attr2 = 83b ;
|
||||
data:
|
||||
|
||||
b = -128, 127 ;
|
||||
|
||||
s = _, 32766 ;
|
||||
|
||||
i = -2147483646, 2147483647 ;
|
||||
}
|
16
ncdump/test_radix.sh
Executable file
16
ncdump/test_radix.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "x$srcdir" = x ; then srcdir=`pwd`; fi
|
||||
. ../test_common.sh
|
||||
|
||||
set -e
|
||||
|
||||
echo "*** Test integer constant radix specifications"
|
||||
echo "*** creating tst_radix.nc from tst_radix.cdl..."
|
||||
${NCGEN} -lb -o tst_radix.nc $srcdir/tst_radix.cdl
|
||||
echo "*** creating tmp_radix.cdl from radix.nc..."
|
||||
${NCDUMP} tst_radix.nc > tmp_radix.cdl
|
||||
echo "*** comparing tmp_radix.cdl to ref_tst_radix.cdl..."
|
||||
diff -b -w tmp_radix.cdl $srcdir/ref_tst_radix.cdl
|
||||
|
||||
exit 0
|
19
ncdump/tst_radix.cdl
Normal file
19
ncdump/tst_radix.cdl
Normal file
@ -0,0 +1,19 @@
|
||||
netcdf tst_radix {
|
||||
dimensions:
|
||||
d = 2 ;
|
||||
variables:
|
||||
byte b(d);
|
||||
short s(d);
|
||||
int i(d);
|
||||
|
||||
// global attributes:
|
||||
:attr1 = 0123s ;
|
||||
:attr2 = '\123' ;
|
||||
data:
|
||||
|
||||
b = -0200, 0177 ;
|
||||
|
||||
s = -077777, 077776 ;
|
||||
|
||||
i = -017777777776, 017777777777 ;
|
||||
}
|
@ -82,6 +82,7 @@ static unsigned int MAX_UINT = NC_MAX_UINT;
|
||||
#define TAGCHARS "BbSsLlUu"
|
||||
|
||||
#define tstdecimal(ch) ((ch) >= '0' && (ch) <= '9')
|
||||
#define tstoctal(ch) ((ch) == '0')
|
||||
|
||||
/*Mnemonics*/
|
||||
#define ISIDENT 1
|
||||
@ -115,7 +116,7 @@ unsigned char ubyte_val; /* last byte value read */
|
||||
|
||||
static Symbol* makepath(char* text);
|
||||
static int lexdebug(int);
|
||||
static unsigned long long parseULL(char* text, int*);
|
||||
static unsigned long long parseULL(int radix, char* text, int*);
|
||||
static nc_type downconvert(unsigned long long uint64, int*, int, int);
|
||||
static int tagmatch(nc_type nct, int tag);
|
||||
static int nct2lexeme(nc_type nct);
|
||||
@ -380,6 +381,7 @@ NIL|nil|Nil {
|
||||
We need to try to see what size of integer ((u)int).
|
||||
Technically, the user should specify, but...
|
||||
If out of any integer range, then complain
|
||||
Also, if the digits begin with 0, then assume octal.
|
||||
*/
|
||||
int slen = strlen(ncgtext);
|
||||
char* stag = NULL;
|
||||
@ -390,28 +392,40 @@ NIL|nil|Nil {
|
||||
nc_type nct = 0;
|
||||
char* pos = NULL;
|
||||
int hasU = 0;
|
||||
int radix = 10;
|
||||
|
||||
pos = ncgtext;
|
||||
|
||||
/* capture the tag string */
|
||||
tag = collecttag(ncgtext,&stag);
|
||||
tag = collecttag(pos,&stag);
|
||||
if(tag == NC_NAT) {
|
||||
sprintf(errstr,"Illegal integer suffix: %s",stag);
|
||||
yyerror(errstr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* drop the tag from the input text */
|
||||
ncgtext[slen - strlen(stag)] = '\0';
|
||||
hasU = isuinttype(tag);
|
||||
if(!tstdecimal(c)) {
|
||||
pos = ncgtext+1;
|
||||
isneg = (c == '-');
|
||||
} else
|
||||
pos = ncgtext;
|
||||
|
||||
/* Capture the sign, if any */
|
||||
isneg = (c == '-');
|
||||
/* skip leading sign */
|
||||
if(c == '-' || c == '+')
|
||||
pos++;
|
||||
|
||||
c = pos[0];
|
||||
if(tstoctal(c))
|
||||
radix = 8;
|
||||
else
|
||||
radix = 10;
|
||||
|
||||
if(isneg && hasU) {
|
||||
sprintf(errstr,"Unsigned integer cannot be signed: %s",ncgtext);
|
||||
yyerror(errstr);
|
||||
goto done;
|
||||
}
|
||||
uint64_val = parseULL(pos,&fail);
|
||||
uint64_val = parseULL(radix, pos,&fail);
|
||||
if(fail) {
|
||||
sprintf(errstr,"integer constant out of range: %s",ncgtext);
|
||||
yyerror(errstr);
|
||||
@ -648,24 +662,26 @@ Parse a simple string of digits into an unsigned long long
|
||||
Return the value.
|
||||
*/
|
||||
static unsigned long long
|
||||
parseULL(char* text, int* failp)
|
||||
parseULL(int radix, char* text, int* failp)
|
||||
{
|
||||
extern int errno;
|
||||
char* endptr;
|
||||
unsigned long long uint64 = 0;
|
||||
|
||||
errno = 0; endptr = NULL;
|
||||
assert(tstdecimal(text[0]));
|
||||
#ifdef HAVE_STRTOULL
|
||||
uint64 = strtoull(text,&endptr,10);
|
||||
uint64 = strtoull(text,&endptr,radix);
|
||||
if(errno == ERANGE) {
|
||||
if(failp) *failp = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
#else /*!(defined HAVE_STRTOLL && defined HAVE_STRTOULL)*/
|
||||
sscanf((char*)text, "%llu", &uint64);
|
||||
#else /*!defined HAVE_STRTOULL*/
|
||||
/* Have no useful way to detect out of range */
|
||||
#endif /*!(defined HAVE_STRTOLL && defined HAVE_STRTOULL)*/
|
||||
if(radix == 8)
|
||||
sscanf((char*)text, "%llo", &uint64);
|
||||
else
|
||||
sscanf((char*)text, "%llu", &uint64);
|
||||
#endif /*!defined HAVE_STRTOULL*/
|
||||
return uint64;
|
||||
}
|
||||
|
||||
|
156
ncgen/ncgenl.c
156
ncgen/ncgenl.c
@ -1464,6 +1464,7 @@ static unsigned int MAX_UINT = NC_MAX_UINT;
|
||||
#define TAGCHARS "BbSsLlUu"
|
||||
|
||||
#define tstdecimal(ch) ((ch) >= '0' && (ch) <= '9')
|
||||
#define tstoctal(ch) ((ch) == '0')
|
||||
|
||||
/*Mnemonics*/
|
||||
#define ISIDENT 1
|
||||
@ -1497,7 +1498,7 @@ unsigned char ubyte_val; /* last byte value read */
|
||||
|
||||
static Symbol* makepath(char* text);
|
||||
static int lexdebug(int);
|
||||
static unsigned long long parseULL(char* text, int*);
|
||||
static unsigned long long parseULL(int radix, char* text, int*);
|
||||
static nc_type downconvert(unsigned long long uint64, int*, int, int);
|
||||
static int tagmatch(nc_type nct, int tag);
|
||||
static int nct2lexeme(nc_type nct);
|
||||
@ -1520,7 +1521,7 @@ struct Specialtoken specials[] = {
|
||||
{NULL,0} /* null terminate */
|
||||
};
|
||||
|
||||
#line 1523 "ncgenl.c"
|
||||
#line 1524 "ncgenl.c"
|
||||
|
||||
/* The most correct (validating) version of UTF8 character set
|
||||
(Taken from: http://www.w3.org/2005/03/23-lex-U)
|
||||
@ -1563,7 +1564,7 @@ ID ([A-Za-z_]|{UTF8})([A-Z.@#\[\]a-z_0-9+-]|{UTF8})*
|
||||
/* Note: this definition of string will work for utf8 as well,
|
||||
although it is a very relaxed definition
|
||||
*/
|
||||
#line 1566 "ncgenl.c"
|
||||
#line 1567 "ncgenl.c"
|
||||
|
||||
#define INITIAL 0
|
||||
#define ST_C_COMMENT 1
|
||||
@ -1782,9 +1783,9 @@ YY_DECL
|
||||
}
|
||||
|
||||
{
|
||||
#line 220 "ncgen.l"
|
||||
#line 221 "ncgen.l"
|
||||
|
||||
#line 1787 "ncgenl.c"
|
||||
#line 1788 "ncgenl.c"
|
||||
|
||||
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
|
||||
{
|
||||
@ -1843,14 +1844,14 @@ do_action: /* This label is used only to access EOF actions. */
|
||||
|
||||
case 1:
|
||||
YY_RULE_SETUP
|
||||
#line 221 "ncgen.l"
|
||||
#line 222 "ncgen.l"
|
||||
{ /* whitespace */
|
||||
break;
|
||||
}
|
||||
YY_BREAK
|
||||
case 2:
|
||||
YY_RULE_SETUP
|
||||
#line 225 "ncgen.l"
|
||||
#line 226 "ncgen.l"
|
||||
{ /* comment */
|
||||
break;
|
||||
}
|
||||
@ -1858,7 +1859,7 @@ YY_RULE_SETUP
|
||||
case 3:
|
||||
/* rule 3 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 229 "ncgen.l"
|
||||
#line 230 "ncgen.l"
|
||||
{int len; char* s = NULL;
|
||||
/* In netcdf4, this will be used in a variety
|
||||
of places, so only remove escapes */
|
||||
@ -1882,7 +1883,7 @@ yytext[MAXTRST-1] = '\0';
|
||||
YY_BREAK
|
||||
case 4:
|
||||
YY_RULE_SETUP
|
||||
#line 250 "ncgen.l"
|
||||
#line 251 "ncgen.l"
|
||||
{ /* drop leading 0x; pad to even number of chars */
|
||||
char* p = yytext+2;
|
||||
int len = yyleng - 2;
|
||||
@ -1897,118 +1898,118 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 5:
|
||||
YY_RULE_SETUP
|
||||
#line 262 "ncgen.l"
|
||||
#line 263 "ncgen.l"
|
||||
{return lexdebug(COMPOUND);}
|
||||
YY_BREAK
|
||||
case 6:
|
||||
YY_RULE_SETUP
|
||||
#line 263 "ncgen.l"
|
||||
#line 264 "ncgen.l"
|
||||
{return lexdebug(ENUM);}
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 264 "ncgen.l"
|
||||
#line 265 "ncgen.l"
|
||||
{return lexdebug(OPAQUE_);}
|
||||
YY_BREAK
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 266 "ncgen.l"
|
||||
#line 267 "ncgen.l"
|
||||
{return lexdebug(FLOAT_K);}
|
||||
YY_BREAK
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 267 "ncgen.l"
|
||||
#line 268 "ncgen.l"
|
||||
{return lexdebug(CHAR_K);}
|
||||
YY_BREAK
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 268 "ncgen.l"
|
||||
#line 269 "ncgen.l"
|
||||
{return lexdebug(BYTE_K);}
|
||||
YY_BREAK
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 269 "ncgen.l"
|
||||
#line 270 "ncgen.l"
|
||||
{return lexdebug(UBYTE_K);}
|
||||
YY_BREAK
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 270 "ncgen.l"
|
||||
#line 271 "ncgen.l"
|
||||
{return lexdebug(SHORT_K);}
|
||||
YY_BREAK
|
||||
case 13:
|
||||
YY_RULE_SETUP
|
||||
#line 271 "ncgen.l"
|
||||
#line 272 "ncgen.l"
|
||||
{return lexdebug(USHORT_K);}
|
||||
YY_BREAK
|
||||
case 14:
|
||||
YY_RULE_SETUP
|
||||
#line 272 "ncgen.l"
|
||||
#line 273 "ncgen.l"
|
||||
{return lexdebug(INT_K);}
|
||||
YY_BREAK
|
||||
case 15:
|
||||
YY_RULE_SETUP
|
||||
#line 273 "ncgen.l"
|
||||
#line 274 "ncgen.l"
|
||||
{return lexdebug(UINT_K);}
|
||||
YY_BREAK
|
||||
case 16:
|
||||
YY_RULE_SETUP
|
||||
#line 274 "ncgen.l"
|
||||
#line 275 "ncgen.l"
|
||||
{return lexdebug(INT64_K);}
|
||||
YY_BREAK
|
||||
case 17:
|
||||
YY_RULE_SETUP
|
||||
#line 275 "ncgen.l"
|
||||
#line 276 "ncgen.l"
|
||||
{return lexdebug(UINT64_K);}
|
||||
YY_BREAK
|
||||
case 18:
|
||||
YY_RULE_SETUP
|
||||
#line 276 "ncgen.l"
|
||||
#line 277 "ncgen.l"
|
||||
{return lexdebug(DOUBLE_K);}
|
||||
YY_BREAK
|
||||
case 19:
|
||||
YY_RULE_SETUP
|
||||
#line 277 "ncgen.l"
|
||||
#line 278 "ncgen.l"
|
||||
{return lexdebug(STRING_K);}
|
||||
YY_BREAK
|
||||
case 20:
|
||||
YY_RULE_SETUP
|
||||
#line 279 "ncgen.l"
|
||||
#line 280 "ncgen.l"
|
||||
{int32_val = -1;
|
||||
return lexdebug(NC_UNLIMITED_K);}
|
||||
YY_BREAK
|
||||
case 21:
|
||||
YY_RULE_SETUP
|
||||
#line 282 "ncgen.l"
|
||||
#line 283 "ncgen.l"
|
||||
{return lexdebug(TYPES);}
|
||||
YY_BREAK
|
||||
case 22:
|
||||
YY_RULE_SETUP
|
||||
#line 283 "ncgen.l"
|
||||
#line 284 "ncgen.l"
|
||||
{return lexdebug(DIMENSIONS);}
|
||||
YY_BREAK
|
||||
case 23:
|
||||
YY_RULE_SETUP
|
||||
#line 284 "ncgen.l"
|
||||
#line 285 "ncgen.l"
|
||||
{return lexdebug(VARIABLES);}
|
||||
YY_BREAK
|
||||
case 24:
|
||||
YY_RULE_SETUP
|
||||
#line 285 "ncgen.l"
|
||||
#line 286 "ncgen.l"
|
||||
{return lexdebug(DATA);}
|
||||
YY_BREAK
|
||||
case 25:
|
||||
YY_RULE_SETUP
|
||||
#line 286 "ncgen.l"
|
||||
#line 287 "ncgen.l"
|
||||
{return lexdebug(GROUP);}
|
||||
YY_BREAK
|
||||
case 26:
|
||||
YY_RULE_SETUP
|
||||
#line 288 "ncgen.l"
|
||||
#line 289 "ncgen.l"
|
||||
{BEGIN(TEXT);return lexdebug(NETCDF);}
|
||||
YY_BREAK
|
||||
case 27:
|
||||
YY_RULE_SETUP
|
||||
#line 290 "ncgen.l"
|
||||
#line 291 "ncgen.l"
|
||||
{ /* missing value (pre-2.4 backward compatibility) */
|
||||
if (yytext[0] == '-') {
|
||||
double_val = NEGNC_INFINITE;
|
||||
@ -2021,7 +2022,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 28:
|
||||
YY_RULE_SETUP
|
||||
#line 299 "ncgen.l"
|
||||
#line 300 "ncgen.l"
|
||||
{ /* missing value (pre-2.4 backward compatibility) */
|
||||
double_val = NAN;
|
||||
specialconstants = 1;
|
||||
@ -2030,7 +2031,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 29:
|
||||
YY_RULE_SETUP
|
||||
#line 305 "ncgen.l"
|
||||
#line 306 "ncgen.l"
|
||||
{/* missing value (pre-2.4 backward compatibility)*/
|
||||
if (yytext[0] == '-') {
|
||||
float_val = NEGNC_INFINITEF;
|
||||
@ -2043,7 +2044,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 30:
|
||||
YY_RULE_SETUP
|
||||
#line 314 "ncgen.l"
|
||||
#line 315 "ncgen.l"
|
||||
{ /* missing value (pre-2.4 backward compatibility) */
|
||||
float_val = NANF;
|
||||
specialconstants = 1;
|
||||
@ -2052,7 +2053,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 31:
|
||||
YY_RULE_SETUP
|
||||
#line 320 "ncgen.l"
|
||||
#line 321 "ncgen.l"
|
||||
{
|
||||
#ifdef USE_NETCDF4
|
||||
if(l_flag == L_C || l_flag == L_BINARY)
|
||||
@ -2065,7 +2066,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 32:
|
||||
YY_RULE_SETUP
|
||||
#line 330 "ncgen.l"
|
||||
#line 331 "ncgen.l"
|
||||
{
|
||||
bbClear(lextext);
|
||||
bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
|
||||
@ -2076,7 +2077,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 33:
|
||||
YY_RULE_SETUP
|
||||
#line 339 "ncgen.l"
|
||||
#line 340 "ncgen.l"
|
||||
{struct Specialtoken* st;
|
||||
bbClear(lextext);
|
||||
bbAppendn(lextext,(char*)yytext,yyleng+1); /* include null */
|
||||
@ -2090,7 +2091,7 @@ YY_RULE_SETUP
|
||||
case 34:
|
||||
/* rule 34 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 349 "ncgen.l"
|
||||
#line 350 "ncgen.l"
|
||||
{
|
||||
int c;
|
||||
char* p; char* q;
|
||||
@ -2110,7 +2111,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 35:
|
||||
YY_RULE_SETUP
|
||||
#line 366 "ncgen.l"
|
||||
#line 367 "ncgen.l"
|
||||
{ char* id = NULL; int len;
|
||||
len = strlen(yytext);
|
||||
len = unescape(yytext,len,ISIDENT,&id);
|
||||
@ -2125,12 +2126,13 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 36:
|
||||
YY_RULE_SETUP
|
||||
#line 378 "ncgen.l"
|
||||
#line 379 "ncgen.l"
|
||||
{
|
||||
/*
|
||||
We need to try to see what size of integer ((u)int).
|
||||
Technically, the user should specify, but...
|
||||
If out of any integer range, then complain
|
||||
Also, if the digits begin with 0, then assume octal.
|
||||
*/
|
||||
int slen = strlen(ncgtext);
|
||||
char* stag = NULL;
|
||||
@ -2141,28 +2143,40 @@ YY_RULE_SETUP
|
||||
nc_type nct = 0;
|
||||
char* pos = NULL;
|
||||
int hasU = 0;
|
||||
int radix = 10;
|
||||
|
||||
pos = ncgtext;
|
||||
|
||||
/* capture the tag string */
|
||||
tag = collecttag(ncgtext,&stag);
|
||||
tag = collecttag(pos,&stag);
|
||||
if(tag == NC_NAT) {
|
||||
sprintf(errstr,"Illegal integer suffix: %s",stag);
|
||||
yyerror(errstr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* drop the tag from the input text */
|
||||
ncgtext[slen - strlen(stag)] = '\0';
|
||||
hasU = isuinttype(tag);
|
||||
if(!tstdecimal(c)) {
|
||||
pos = ncgtext+1;
|
||||
isneg = (c == '-');
|
||||
} else
|
||||
pos = ncgtext;
|
||||
|
||||
/* Capture the sign, if any */
|
||||
isneg = (c == '-');
|
||||
/* skip leading sign */
|
||||
if(c == '-' || c == '+')
|
||||
pos++;
|
||||
|
||||
c = pos[0];
|
||||
if(tstoctal(c))
|
||||
radix = 8;
|
||||
else
|
||||
radix = 10;
|
||||
|
||||
if(isneg && hasU) {
|
||||
sprintf(errstr,"Unsigned integer cannot be signed: %s",ncgtext);
|
||||
yyerror(errstr);
|
||||
goto done;
|
||||
}
|
||||
uint64_val = parseULL(pos,&fail);
|
||||
uint64_val = parseULL(radix, pos,&fail);
|
||||
if(fail) {
|
||||
sprintf(errstr,"integer constant out of range: %s",ncgtext);
|
||||
yyerror(errstr);
|
||||
@ -2193,7 +2207,7 @@ done: return 0;
|
||||
YY_BREAK
|
||||
case 37:
|
||||
YY_RULE_SETUP
|
||||
#line 443 "ncgen.l"
|
||||
#line 457 "ncgen.l"
|
||||
{
|
||||
int c;
|
||||
int token = 0;
|
||||
@ -2244,7 +2258,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 38:
|
||||
YY_RULE_SETUP
|
||||
#line 490 "ncgen.l"
|
||||
#line 504 "ncgen.l"
|
||||
{
|
||||
if (sscanf((char*)yytext, "%le", &double_val) != 1) {
|
||||
sprintf(errstr,"bad long or double constant: %s",(char*)yytext);
|
||||
@ -2255,7 +2269,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 39:
|
||||
YY_RULE_SETUP
|
||||
#line 497 "ncgen.l"
|
||||
#line 511 "ncgen.l"
|
||||
{
|
||||
if (sscanf((char*)yytext, "%e", &float_val) != 1) {
|
||||
sprintf(errstr,"bad float constant: %s",(char*)yytext);
|
||||
@ -2267,7 +2281,7 @@ YY_RULE_SETUP
|
||||
case 40:
|
||||
/* rule 40 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 504 "ncgen.l"
|
||||
#line 518 "ncgen.l"
|
||||
{
|
||||
(void) sscanf((char*)&yytext[1],"%c",&byte_val);
|
||||
return lexdebug(BYTE_CONST);
|
||||
@ -2275,7 +2289,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 41:
|
||||
YY_RULE_SETUP
|
||||
#line 508 "ncgen.l"
|
||||
#line 522 "ncgen.l"
|
||||
{
|
||||
int oct = unescapeoct(&yytext[2]);
|
||||
if(oct < 0) {
|
||||
@ -2288,7 +2302,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 42:
|
||||
YY_RULE_SETUP
|
||||
#line 517 "ncgen.l"
|
||||
#line 531 "ncgen.l"
|
||||
{
|
||||
int hex = unescapehex(&yytext[3]);
|
||||
if(byte_val < 0) {
|
||||
@ -2301,7 +2315,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 43:
|
||||
YY_RULE_SETUP
|
||||
#line 526 "ncgen.l"
|
||||
#line 540 "ncgen.l"
|
||||
{
|
||||
switch ((char)yytext[2]) {
|
||||
case 'a': byte_val = '\007'; break; /* not everyone under-
|
||||
@ -2323,7 +2337,7 @@ YY_RULE_SETUP
|
||||
case 44:
|
||||
/* rule 44 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 544 "ncgen.l"
|
||||
#line 558 "ncgen.l"
|
||||
{
|
||||
lineno++ ;
|
||||
break;
|
||||
@ -2331,7 +2345,7 @@ YY_RULE_SETUP
|
||||
YY_BREAK
|
||||
case 45:
|
||||
YY_RULE_SETUP
|
||||
#line 549 "ncgen.l"
|
||||
#line 563 "ncgen.l"
|
||||
{/*initial*/
|
||||
BEGIN(ST_C_COMMENT);
|
||||
break;
|
||||
@ -2340,21 +2354,21 @@ YY_RULE_SETUP
|
||||
case 46:
|
||||
/* rule 46 can match eol */
|
||||
YY_RULE_SETUP
|
||||
#line 554 "ncgen.l"
|
||||
#line 568 "ncgen.l"
|
||||
{/* continuation */
|
||||
break;
|
||||
}
|
||||
YY_BREAK
|
||||
case 47:
|
||||
YY_RULE_SETUP
|
||||
#line 558 "ncgen.l"
|
||||
#line 572 "ncgen.l"
|
||||
{/* final */
|
||||
BEGIN(INITIAL);
|
||||
break;
|
||||
}
|
||||
YY_BREAK
|
||||
case YY_STATE_EOF(ST_C_COMMENT):
|
||||
#line 563 "ncgen.l"
|
||||
#line 577 "ncgen.l"
|
||||
{/* final, error */
|
||||
fprintf(stderr,"unterminated /**/ comment");
|
||||
BEGIN(INITIAL);
|
||||
@ -2363,17 +2377,17 @@ case YY_STATE_EOF(ST_C_COMMENT):
|
||||
YY_BREAK
|
||||
case 48:
|
||||
YY_RULE_SETUP
|
||||
#line 569 "ncgen.l"
|
||||
#line 583 "ncgen.l"
|
||||
{/* Note: this next rule will not work for UTF8 characters */
|
||||
return lexdebug(yytext[0]) ;
|
||||
}
|
||||
YY_BREAK
|
||||
case 49:
|
||||
YY_RULE_SETUP
|
||||
#line 572 "ncgen.l"
|
||||
#line 586 "ncgen.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 2376 "ncgenl.c"
|
||||
#line 2390 "ncgenl.c"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
case YY_STATE_EOF(TEXT):
|
||||
yyterminate();
|
||||
@ -3379,7 +3393,7 @@ void yyfree (void * ptr )
|
||||
|
||||
#define YYTABLES_NAME "yytables"
|
||||
|
||||
#line 572 "ncgen.l"
|
||||
#line 586 "ncgen.l"
|
||||
|
||||
static int
|
||||
lexdebug(int token)
|
||||
@ -3459,24 +3473,26 @@ Parse a simple string of digits into an unsigned long long
|
||||
Return the value.
|
||||
*/
|
||||
static unsigned long long
|
||||
parseULL(char* text, int* failp)
|
||||
parseULL(int radix, char* text, int* failp)
|
||||
{
|
||||
extern int errno;
|
||||
char* endptr;
|
||||
unsigned long long uint64 = 0;
|
||||
|
||||
errno = 0; endptr = NULL;
|
||||
assert(tstdecimal(text[0]));
|
||||
#ifdef HAVE_STRTOULL
|
||||
uint64 = strtoull(text,&endptr,10);
|
||||
uint64 = strtoull(text,&endptr,radix);
|
||||
if(errno == ERANGE) {
|
||||
if(failp) *failp = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
#else /*!(defined HAVE_STRTOLL && defined HAVE_STRTOULL)*/
|
||||
sscanf((char*)text, "%llu", &uint64);
|
||||
#else /*!defined HAVE_STRTOULL*/
|
||||
/* Have no useful way to detect out of range */
|
||||
#endif /*!(defined HAVE_STRTOLL && defined HAVE_STRTOULL)*/
|
||||
if(radix == 8)
|
||||
sscanf((char*)text, "%llo", &uint64);
|
||||
else
|
||||
sscanf((char*)text, "%llu", &uint64);
|
||||
#endif /*!defined HAVE_STRTOULL*/
|
||||
return uint64;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user