Skip to content
Merged
Changes from all 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
80 changes: 53 additions & 27 deletions numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,36 +975,62 @@ Perl_grok_infnan(pTHX_ const char** sp, const char* send)
}

/*
=for apidoc grok_number_flags

Recognise (or not) a number. The type of the number is returned
(0 if unrecognised), otherwise it is a bit-ORed combination of
C<IS_NUMBER_IN_UV>, C<IS_NUMBER_GREATER_THAN_UV_MAX>, C<IS_NUMBER_NOT_INT>,
C<IS_NUMBER_NEG>, C<IS_NUMBER_INFINITY>, C<IS_NUMBER_NAN> (defined in perl.h).

If the value of the number can fit in a UV, it is returned in C<*valuep>.
C<IS_NUMBER_IN_UV> will be set to indicate that C<*valuep> is valid, C<IS_NUMBER_IN_UV>
will never be set unless C<*valuep> is valid, but C<*valuep> may have been assigned
to during processing even though C<IS_NUMBER_IN_UV> is not set on return.
If C<valuep> is C<NULL>, C<IS_NUMBER_IN_UV> will be set for the same cases as when
C<valuep> is non-C<NULL>, but no actual assignment (or SEGV) will occur.

C<IS_NUMBER_NOT_INT> will be set with C<IS_NUMBER_IN_UV> if trailing decimals were
seen (in which case C<*valuep> gives the true value truncated to an integer), and
C<IS_NUMBER_NEG> if the number is negative (in which case C<*valuep> holds the
absolute value). C<IS_NUMBER_IN_UV> is not set if C<e> notation was used or the
number is larger than a UV.

C<flags> allows only C<PERL_SCAN_TRAILING>, which allows for trailing
non-numeric text on an otherwise successful I<grok>, setting
C<IS_NUMBER_TRAILING> on the result.

=for apidoc grok_number
=for apidoc_item grok_number_flags

Look for a number in the C<len> bytes starting at C<pv>. If one isn't found,
return 0; otherwise return its type (and optionally its value). In
C<grok_number> all C<len> bytes must be either leading C<L</isSPACE>>
characters or part of the number. The same is true in C<grok_number_flags>
unless C<flags> contains the C<PERL_SCAN_TRAILING> bit, which allows for
trailing non-numeric text. (This is the only difference between the two
functions.)

The returned type is the ORing of various bits (#defined in F<perl.h>) as
described below:

If the number is negative, the returned type will include the C<IS_NUMBER_NEG>
bit.

If the absolute value of the integral portion of the found number fits in a UV,
the returned type will include the C<IS_NUMBER_IN_UV> bit. If it won't fit,
instead the C<IS_NUMBER_GREATER_THAN_UV_MAX> bit will be included.

If the found number is not an integer, the returned type will include
the C<IS_NUMBER_NOT_INT> bit. This happens either if the number
is expressed in exponential C<e> notation, or if it includes a decimal
point (radix) character. If exponential notation is used, then neither
IS_NUMBER_IN_UV nor IS_NUMBER_GREATER_THAN_UV_MAX bits are set.
Otherwise, the integer part of the number is used to determine the
C<IS_NUMBER_IN_UV> and C<IS_NUMBER_GREATER_THAN_UV_MAX> bits.

If the found number is a string indicating it is infinity, the
C<IS_NUMBER_INFINITY> and C<IS_NUMBER_NOT_INT> bits are included in the
returned type.

If the found number is a string indicating it is not a number, the
C<IS_NUMBER_NAN> and C<IS_NUMBER_NOT_INT> bits are included in the
returned type.

You can get the number's absolute integral value returned to you by calling
these functions with a non-NULL C<valuep> argument. If the returned type
includes the C<IS_NUMBER_IN_UV> bit, C<*valuep> will be set to the correct
value. Otherwise, it could well have been zapped with garbage.

In C<grok_number_flags> when C<flags> contains the C<PERL_SCAN_TRAILING>
bit, and trailing non-numeric text was found, the returned type will include
the C<IS_NUMBER_TRAILING> bit.

=for apidoc Amnh||IS_NUMBER_GREATER_THAN_UV_MAX
=for apidoc Amnh||IS_NUMBER_INFINITY
=for apidoc Amnh||IS_NUMBER_IN_UV
=for apidoc Amnh||IS_NUMBER_NAN
=for apidoc Amnh||IS_NUMBER_NEG
=for apidoc Amnh||IS_NUMBER_NOT_INT
=for apidoc Amnh||IS_NUMBER_TRAILING
=for apidoc Amnh||PERL_SCAN_TRAILING

=for apidoc grok_number

Identical to C<grok_number_flags()> with C<flags> set to zero.

=cut
*/
int
Expand Down