Add libc func "atoi" (part of #28)

This commit is contained in:
Alex Kotov 2022-01-23 23:41:07 +05:00
parent cae4884a08
commit 94e2028bc8
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
6 changed files with 29 additions and 6 deletions

View File

@ -1,7 +1,7 @@
2022-01-23 Alex Kotov <kotovalexarian@gmail.com>
* include/kernaux/assert.h: Require semicolon after macros
* include/kernaux/libc.h: Add funcs "isdigit", "isspace"
* include/kernaux/libc.h: Add funcs "atoi", "isdigit", "isspace"
2022-01-22 Alex Kotov <kotovalexarian@gmail.com>

View File

@ -89,6 +89,7 @@ stable options.
* `--with-libc` - provides the replacement for some standard C functions. Useful
in freestanding environment, where no libc is present. You can also separately
include or exclude components:
* `--with[out]-libc-atoi`
* `--with[out]-libc-isdigit`
* `--with[out]-libc-isspace`
* `--with[out]-libc-memset`

View File

@ -35,6 +35,7 @@ AC_ARG_WITH( [units], AS_HELP_STRING([--without-units], [without m
dnl Packages (disabled by default)
AC_ARG_WITH( [libc], AS_HELP_STRING([--with-libc], [with libc replacement]))
AC_ARG_WITH( [libc-atoi], AS_HELP_STRING([--with-libc-atoi], [with atoi replacement]))
AC_ARG_WITH( [libc-isdigit], AS_HELP_STRING([--with-libc-isdigit], [with isdigit replacement]))
AC_ARG_WITH( [libc-isspace], AS_HELP_STRING([--with-libc-isspace], [with isspace replacement]))
AC_ARG_WITH( [libc-memset], AS_HELP_STRING([--with-libc-memset], [with memset replacement]))
@ -61,6 +62,7 @@ AS_IF([test "$with_all" = no], do_without_all)
AC_DEFUN([do_with_libc],
[
if test -z "$with_libc_atoi"; then with_libc_atoi=yes; fi
if test -z "$with_libc_isdigit"; then with_libc_isdigit=yes; fi
if test -z "$with_libc_isspace"; then with_libc_isspace=yes; fi
if test -z "$with_libc_memset"; then with_libc_memset=yes; fi
@ -104,6 +106,7 @@ AM_CONDITIONAL([WITH_PRINTF], [test "$with_printf" != no])
AM_CONDITIONAL([WITH_UNITS], [test "$with_units" != no])
dnl Packages (disabled by default)
AM_CONDITIONAL([WITH_LIBC_ATOI], [test "$with_libc_atoi" = yes])
AM_CONDITIONAL([WITH_LIBC_ISDIGIT], [test "$with_libc_isdigit" = yes])
AM_CONDITIONAL([WITH_LIBC_ISSPACE], [test "$with_libc_isspace" = yes])
AM_CONDITIONAL([WITH_LIBC_MEMSET], [test "$with_libc_memset" = yes])
@ -138,6 +141,7 @@ AS_IF([test "$with_printf" != no], [AC_DEFINE([WITH_PRINTF], [1]
AS_IF([test "$with_units", != no], [AC_DEFINE([WITH_UNITS], [1], [with measurement units utils])])
dnl Packages (disabled by default)
AS_IF([test "$with_libc_atoi" = yes], [AC_DEFINE([WITH_LIBC_ATOI], [1], [with atoi replacement])])
AS_IF([test "$with_libc_isdigit" = yes], [AC_DEFINE([WITH_LIBC_ISDIGIT], [1], [with isdigit replacement])])
AS_IF([test "$with_libc_isspace" = yes], [AC_DEFINE([WITH_LIBC_ISSPACE], [1], [with isspace replacement])])
AS_IF([test "$with_libc_memset" = yes], [AC_DEFINE([WITH_LIBC_MEMSET], [1], [with memset replacement])])

View File

@ -11,6 +11,9 @@ extern "C" {
int isdigit(int c);
int isspace(int c);
// <stdlib.h>
int atoi(const char *str);
// <string.h>
void *memset(void *s, int c, size_t n);
char *strcpy(char *dest, const char *src);

View File

@ -4,6 +4,23 @@
#include <kernaux/libc.h>
#include <stdbool.h>
#ifdef WITH_LIBC_ATOI
int atoi(const char *str)
{
while (isspace(*str)) ++str;
bool is_negative = false;
switch (*str) {
case '-': is_negative = true;
case '+': ++str;
}
int result = 0;
while (isdigit(*str)) result = 10 * result - (*str++ - '0');
return is_negative ? result : -result;
}
#endif // WITH_LIBC_ATOI
#ifdef WITH_LIBC_ISDIGIT
int isdigit(const int c)
{

View File

@ -444,11 +444,9 @@ void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
// internal ASCII string to unsigned int conversion
unsigned int _atoi(const char** str)
{
unsigned int i = 0u;
while (isdigit(**str)) {
i = i * 10u + (unsigned int)(*((*str)++) - '0');
}
return i;
const int result = atoi(*str);
while (isdigit(**str)) (*str)++;
return result;
}
// output the specified string in reverse, taking care of any zero-padding