📄 grok
字号:
/* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount. */ value_nv += (NV)(bit - '0'); continue; } if (bit == '_' && len && allow_underscores && (bit = s[1]) && (bit == '0' || bit == '1')) { --len; ++s; goto redo; } if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal binary digit '%c' ignored", *s); break; } if ( ( overflowed && value_nv > 4294967295.0)#if UVSIZE > 4 || (!overflowed && value > 0xffffffff )#endif ) { warn("Binary number > 0b11111111111111111111111111111111 non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX;}#endif#endif#ifndef grok_hex#if { NEED grok_hex }UVgrok_hex(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result){ const char *s = start; STRLEN len = *len_p; UV value = 0; NV value_nv = 0; const UV max_div_16 = UV_MAX / 16; bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; bool overflowed = FALSE; const char *xdigit; if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { /* strip off leading x or 0x. for compatibility silently suffer "x" and "0x" as valid hex numbers. */ if (len >= 1) { if (s[0] == 'x') { s++; len--; } else if (len >= 2 && s[0] == '0' && s[1] == 'x') { s+=2; len-=2; } } } for (; len-- && *s; s++) { xdigit = strchr((char *) PL_hexdigit, *s); if (xdigit) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. With gcc seems to be much straighter code than old scan_hex. */ redo: if (!overflowed) { if (value <= max_div_16) { value = (value << 4) | ((xdigit - PL_hexdigit) & 15); continue; } warn("Integer overflow in hexadecimal number"); overflowed = TRUE; value_nv = (NV) value; } value_nv *= 16.0; /* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 16-tuples. */ value_nv += (NV)((xdigit - PL_hexdigit) & 15); continue; } if (*s == '_' && len && allow_underscores && s[1] && (xdigit = strchr((char *) PL_hexdigit, s[1]))) { --len; ++s; goto redo; } if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal hexadecimal digit '%c' ignored", *s); break; } if ( ( overflowed && value_nv > 4294967295.0)#if UVSIZE > 4 || (!overflowed && value > 0xffffffff )#endif ) { warn("Hexadecimal number > 0xffffffff non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX;}#endif#endif#ifndef grok_oct#if { NEED grok_oct }UVgrok_oct(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result){ const char *s = start; STRLEN len = *len_p; UV value = 0; NV value_nv = 0; const UV max_div_8 = UV_MAX / 8; bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; bool overflowed = FALSE; for (; len-- && *s; s++) { /* gcc 2.95 optimiser not smart enough to figure that this subtraction out front allows slicker code. */ int digit = *s - '0'; if (digit >= 0 && digit <= 7) { /* Write it in this wonky order with a goto to attempt to get the compiler to make the common case integer-only loop pretty tight. */ redo: if (!overflowed) { if (value <= max_div_8) { value = (value << 3) | digit; continue; } /* Bah. We're just overflowed. */ warn("Integer overflow in octal number"); overflowed = TRUE; value_nv = (NV) value; } value_nv *= 8.0; /* If an NV has not enough bits in its mantissa to * represent a UV this summing of small low-order numbers * is a waste of time (because the NV cannot preserve * the low-order bits anyway): we could just remember when * did we overflow and in the end just multiply value_nv by the * right amount of 8-tuples. */ value_nv += (NV)digit; continue; } if (digit == ('_' - '0') && len && allow_underscores && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) { --len; ++s; goto redo; } /* Allow \octal to work the DWIM way (that is, stop scanning * as soon as non-octal characters are seen, complain only iff * someone seems to want to use the digits eight and nine). */ if (digit == 8 || digit == 9) { if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) warn("Illegal octal digit '%c' ignored", *s); } break; } if ( ( overflowed && value_nv > 4294967295.0)#if UVSIZE > 4 || (!overflowed && value > 0xffffffff )#endif ) { warn("Octal number > 037777777777 non-portable"); } *len_p = s - start; if (!overflowed) { *flags = 0; return value; } *flags = PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = value_nv; return UV_MAX;}#endif#endif=xsinit#define NEED_grok_number#define NEED_grok_numeric_radix#define NEED_grok_bin#define NEED_grok_hex#define NEED_grok_oct=xsubsUVgrok_number(string) SV *string PREINIT: const char *pv; STRLEN len; CODE: pv = SvPV(string, len); if (!grok_number(pv, len, &RETVAL)) XSRETURN_UNDEF; OUTPUT: RETVALUVgrok_bin(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = grok_bin(pv, &len, &flags, NULL); OUTPUT: RETVALUVgrok_hex(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = grok_hex(pv, &len, &flags, NULL); OUTPUT: RETVALUVgrok_oct(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = grok_oct(pv, &len, &flags, NULL); OUTPUT: RETVALUVPerl_grok_number(string) SV *string PREINIT: const char *pv; STRLEN len; CODE: pv = SvPV(string, len); if (!Perl_grok_number(aTHX_ pv, len, &RETVAL)) XSRETURN_UNDEF; OUTPUT: RETVALUVPerl_grok_bin(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = Perl_grok_bin(aTHX_ pv, &len, &flags, NULL); OUTPUT: RETVALUVPerl_grok_hex(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = Perl_grok_hex(aTHX_ pv, &len, &flags, NULL); OUTPUT: RETVALUVPerl_grok_oct(string) SV *string PREINIT: char *pv; I32 flags; STRLEN len; CODE: pv = SvPV(string, len); RETVAL = Perl_grok_oct(aTHX_ pv, &len, &flags, NULL); OUTPUT: RETVAL=tests plan => 10ok(&Devel::PPPort::grok_number("42"), 42);ok(!defined(&Devel::PPPort::grok_number("A")));ok(&Devel::PPPort::grok_bin("10000001"), 129);ok(&Devel::PPPort::grok_hex("deadbeef"), 0xdeadbeef);ok(&Devel::PPPort::grok_oct("377"), 255);ok(&Devel::PPPort::Perl_grok_number("42"), 42);ok(!defined(&Devel::PPPort::Perl_grok_number("A")));ok(&Devel::PPPort::Perl_grok_bin("10000001"), 129);ok(&Devel::PPPort::Perl_grok_hex("deadbeef"), 0xdeadbeef);ok(&Devel::PPPort::Perl_grok_oct("377"), 255);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -