stdlib: formatting on the strto* functions

* Name the private function __strto_{int,fp} (with leading double
  underscores) to avoid name conflicts
* Fix comments of the wrong style
* Fix missing leading double underscores in stdlib_p.h
This commit is contained in:
Lephenixnoir 2021-05-24 10:07:48 +02:00
parent df9073e6ff
commit 3a9a60db78
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
10 changed files with 43 additions and 56 deletions

View file

@ -4,23 +4,25 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
/* Parse an integer from a string. This is the base function for strtol, /*
strtoul, strtoll, and strtoull. ** Parse an integer from a string. This is the base function for strtol,
** strtoul, strtoll, and strtoull.
This function does not set errno, and instead returns the error code **
according to conversion rules. Setting errno is troublesome because it's a ** This function does not set errno, and instead returns the error code
global state that cannot be reverted and thus cannot be tested. ** according to conversion rules. Setting errno is troublesome because it's a
** global state that cannot be reverted and thus cannot be tested.
If outl is non-NULL, strto_int produces a long or an unsigned long result **
(depending on use_unsigned). Signedness only affects the range of values ** If outl is non-NULL, strto_int produces a long or an unsigned long result
that are considered to be ERANGE, and both results are stored in *outl. ** (depending on use_unsigned). Signedness only affects the range of values
Similarly, if outll is non-NULL, strto_int produces a long long or unsigned ** that are considered to be ERANGE, and both results are stored in *outl.
long long result. Only one pointer should be non-NULL. ** Similarly, if outll is non-NULL, strto_int produces a long long or unsigned
** long long result. Only one pointer should be non-NULL.
On platforms where long is 32-bit, 64-bit operations are performed only if **
outll is non-NULL. This is because multiplications with overflow can be ** On platforms where long is 32-bit, 64-bit operations are performed only if
expensive. */ ** outll is non-NULL. This is because multiplications with overflow can be
int strto_int( ** expensive.
*/
int __strto_int(
char const * restrict __ptr, char const * restrict __ptr,
char ** restrict __endptr, char ** restrict __endptr,
int __base, int __base,
@ -28,17 +30,19 @@ int strto_int(
long long *__outll, long long *__outll,
bool __use_unsigned); bool __use_unsigned);
/* Parse a floating-point value from a string. This is the base function for /*
strtod, strtof, and strtold. ** Parse a floating-point value from a string. This is the base function for
** strtod, strtof, and strtold.
This function is similar to strto_int(). If returns the error code to set in **
errno, and can produce one of three outputs depending on which of out, outf ** This function is similar to strto_int(). If returns the error code to set in
and outl is set. */ ** errno, and can produce one of three outputs depending on which of out, outf
int strto_fp( ** and outl is set.
*/
int __strto_fp(
char const * restrict __ptr, char const * restrict __ptr,
char ** restrict __endptr, char ** restrict __endptr,
double *out, double *__out,
float *outf, float *__outf,
long double *outl); long double *__outl);
#endif /*__STDLIB_P_H__*/ #endif /*__STDLIB_P_H__*/

View file

@ -27,16 +27,6 @@
# error long double larger than 128 bits is not supported # error long double larger than 128 bits is not supported
#endif #endif
/* Basically strncasecmp. */
static int ncasecmp(char const *left, char const *right, size_t n)
{
for(size_t i = 0; i < n; i++) {
int diff = tolower(left[i]) - tolower(right[i]);
if(diff) return diff;
}
return 0;
}
/* /*
** Parse digits and exponent into integers, in decimal or hexadecimal notation. ** Parse digits and exponent into integers, in decimal or hexadecimal notation.
** **
@ -122,7 +112,7 @@ static void parse_digits(char const * restrict *ptr0, bool *valid,
*valid = true; *valid = true;
} }
int strto_fp(char const * restrict ptr, char ** restrict endptr, double *out, int __strto_fp(char const * restrict ptr, char ** restrict endptr, double *out,
float *outf, long double *outl) float *outf, long double *outl)
{ {
/* Save the value of ptr in endptr, in case format is invalid */ /* Save the value of ptr in endptr, in case format is invalid */
@ -145,7 +135,7 @@ int strto_fp(char const * restrict ptr, char ** restrict endptr, double *out,
if(outl) *outl = 0.0l; if(outl) *outl = 0.0l;
/* NaN possibly with an argument */ /* NaN possibly with an argument */
if(!ncasecmp(ptr, "nan", 3)) { if(!strncasecmp(ptr, "nan", 3)) {
char const *arg = ""; char const *arg = "";
ptr += 3; ptr += 3;
if(ptr[0] == '(') { if(ptr[0] == '(') {
@ -159,13 +149,13 @@ int strto_fp(char const * restrict ptr, char ** restrict endptr, double *out,
if(outl) *outl = __builtin_nanl(arg); if(outl) *outl = __builtin_nanl(arg);
} }
/* Infinity */ /* Infinity */
else if(!ncasecmp(ptr, "infinity", 8)) { else if(!strncasecmp(ptr, "infinity", 8)) {
if(out) *out = __builtin_inf(); if(out) *out = __builtin_inf();
if(outf) *outf = __builtin_inff(); if(outf) *outf = __builtin_inff();
if(outl) *outl = __builtin_infl(); if(outl) *outl = __builtin_infl();
ptr += 8; ptr += 8;
} }
else if(!ncasecmp(ptr, "inf", 3)) { else if(!strncasecmp(ptr, "inf", 3)) {
if(out) *out = __builtin_inf(); if(out) *out = __builtin_inf();
if(outf) *outf = __builtin_inff(); if(outf) *outf = __builtin_inff();
if(outl) *outl = __builtin_infl(); if(outl) *outl = __builtin_infl();

View file

@ -4,14 +4,7 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
/* Parse an integer from a string. Base function for strtol, strtoul, strtoll, int __strto_int(char const * restrict ptr, char ** restrict endptr, int base,
and strtoull. This function:
-> Does not set errno, and instead return the potential error code. Setting
errno would prevent these functions from calling each other as they all
have different ranges, resulting in undue ERANGE.
-> Can parse into both long and long long, depending on what pointer is
non-NULL. */
int strto_int(char const * restrict ptr, char ** restrict endptr, int base,
long *outl, long long *outll, bool use_unsigned) long *outl, long long *outll, bool use_unsigned)
{ {
/* Save the value of ptr in endptr now in case the format is invalid */ /* Save the value of ptr in endptr now in case the format is invalid */

View file

@ -4,7 +4,7 @@
double strtod(char const * restrict ptr, char ** restrict endptr) double strtod(char const * restrict ptr, char ** restrict endptr)
{ {
double d = 0; double d = 0;
int err = strto_fp(ptr, endptr, &d, NULL, NULL); int err = __strto_fp(ptr, endptr, &d, NULL, NULL);
if(err != 0) errno = err; if(err != 0) errno = err;
return d; return d;
} }

View file

@ -4,7 +4,7 @@
float strtof(char const * restrict ptr, char ** restrict endptr) float strtof(char const * restrict ptr, char ** restrict endptr)
{ {
float f = 0; float f = 0;
int err = strto_fp(ptr, endptr, NULL, &f, NULL); int err = __strto_fp(ptr, endptr, NULL, &f, NULL);
if(err != 0) errno = err; if(err != 0) errno = err;
return f; return f;
} }

View file

@ -4,7 +4,7 @@
long int strtol(char const * restrict ptr, char ** restrict endptr, int base) long int strtol(char const * restrict ptr, char ** restrict endptr, int base)
{ {
long n = 0; long n = 0;
int err = strto_int(ptr, endptr, base, &n, NULL, false); int err = __strto_int(ptr, endptr, base, &n, NULL, false);
if(err != 0) errno = err; if(err != 0) errno = err;
return n; return n;
} }

View file

@ -4,7 +4,7 @@
long double strtold(char const * restrict ptr, char ** restrict endptr) long double strtold(char const * restrict ptr, char ** restrict endptr)
{ {
long double ld = 0; long double ld = 0;
int err = strto_fp(ptr, endptr, NULL, NULL, &ld); int err = __strto_fp(ptr, endptr, NULL, NULL, &ld);
if(err != 0) errno = err; if(err != 0) errno = err;
return ld; return ld;
} }

View file

@ -5,7 +5,7 @@ long long int strtoll(char const * restrict ptr, char ** restrict endptr,
int base) int base)
{ {
long long n = 0; long long n = 0;
int err = strto_int(ptr, endptr, base, NULL, &n, false); int err = __strto_int(ptr, endptr, base, NULL, &n, false);
if(err != 0) errno = err; if(err != 0) errno = err;
return n; return n;
} }

View file

@ -5,7 +5,7 @@ unsigned long int strtoul(char const * restrict ptr, char ** restrict endptr,
int base) int base)
{ {
unsigned long n = 0; unsigned long n = 0;
int err = strto_int(ptr, endptr, base, (long *)&n, NULL, true); int err = __strto_int(ptr, endptr, base, (long *)&n, NULL, true);
if(err != 0) errno = err; if(err != 0) errno = err;
return n; return n;
} }

View file

@ -5,7 +5,7 @@ unsigned long long int strtoull(char const * restrict ptr,
char ** restrict endptr, int base) char ** restrict endptr, int base)
{ {
unsigned long long n = 0; unsigned long long n = 0;
int err = strto_int(ptr, endptr, base, NULL, (long long *)&n, true); int err = __strto_int(ptr, endptr, base, NULL, (long long *)&n, true);
if(err != 0) errno = err; if(err != 0) errno = err;
return n; return n;
} }