Depend on memset, strlen, strcpy (#2)

This commit is contained in:
Alex Kotov 2021-12-15 15:45:40 +05:00 committed by GitHub
parent 894a96c991
commit aaa96d70ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 215 additions and 237 deletions

View File

@ -12,8 +12,8 @@ jobs:
strategy:
matrix:
cc: ['gcc', 'clang', 'tcc']
assert: ['--enable-assert', '--disable-assert']
opt: ['', '-O0', '-O3']
assert: ['--enable-assert', '--disable-assert']
werror:
- cflag: '-Werror'
mb2: '--disable-multiboot2'
@ -30,6 +30,6 @@ jobs:
- name: make
run: make
- name: check
run: make check
run: make check || cat test-suite.log
- name: install
run: sudo make install

2
.gitignore vendored
View File

@ -45,11 +45,11 @@
/tests/multiboot2_print2
/tests/test_cmdline
/tests/test_elf
/tests/test_itoa
/tests/test_multiboot2_helpers
/tests/test_multiboot2_print
/tests/test_multiboot2_validation
/tests/test_pfa
/tests/test_pfa_assert
/tests/test_printf
/tests/test_stdlib
/tests/test_units_human

View File

@ -12,15 +12,16 @@ lib_LIBRARIES = libkernaux.a
TESTS = \
examples/printf \
examples/printf_va \
tests/test_printf \
tests/test_stdlib
tests/test_itoa \
tests/test_printf
noinst_PROGRAMS = $(TESTS)
libkernaux_a_SOURCES = \
src/assert.c \
src/printf.c \
src/stdlib.c
src/itoa.c \
src/libc.c \
src/printf.c
if ARCH_I386
libkernaux_a_SOURCES += src/arch/i386.S
@ -119,6 +120,10 @@ tests_test_elf_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_elf.c
tests_test_itoa_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_itoa.c
tests_test_multiboot2_helpers_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_multiboot2_helpers.c
@ -143,10 +148,6 @@ tests_test_printf_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_printf.c
tests_test_stdlib_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_stdlib.c
tests_test_units_human_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/test_units_human.c

View File

@ -36,14 +36,14 @@ API
* [Example](/examples/pfa.c)
* [ELF utils](/include/kernaux/elf.h) *(work in progress)*
* [Architecture-specific helpers](/include/kernaux/arch/)
* [libc replacement](/include/kernaux/libc.h)
* `memset`
* `strcpy`
* `strlen`
* [itoa replacement](/include/kernaux/itoa.h) *(work in progress)*
* [printf replacement](/include/kernaux/printf.h) *(work in progress)*
* [printf](/examples/printf.c)
* [printf_va](/examples/printf_va.c)
* [stdlib replacement](/include/kernaux/stdlib.h)
* `memset`
* `strlen`
* `strncpy`
* `itoa` *(work in progress)*
@ -75,6 +75,7 @@ without it in `$PATH`:
```
./configure \
--host='i386-elf' \
--enable-libc \
AR="$(which i386-elf-ar)" \
CC="$(which i386-elf-gcc)" \
RANLIB="$(which i386-elf-ranlib)" \

View File

@ -10,35 +10,58 @@ AC_CONFIG_SRCDIR([src/pfa.c])
AC_CANONICAL_HOST
AC_ARG_ENABLE([assert], AS_HELP_STRING([--enable-assert], [enable runtime assertions]))
AC_ARG_ENABLE([cmdline], AS_HELP_STRING([--disable-cmdline], [disable command line parser]))
AC_ARG_ENABLE([console], AS_HELP_STRING([--disable-console], [disable serial console]))
AC_ARG_ENABLE([elf], AS_HELP_STRING([--disable-elf], [disable ELF utils]))
AC_ARG_ENABLE([multiboot2], AS_HELP_STRING([--disable-multiboot2], [disable Multiboot 2 information parser]))
AC_ARG_ENABLE([pfa], AS_HELP_STRING([--disable-pfa], [disable Page Frame Allocator]))
AC_ARG_ENABLE([units], AS_HELP_STRING([--disable-units], [disable measurement units utils]))
AC_ARG_ENABLE([cmdline], AS_HELP_STRING([--disable-cmdline], [disable command line parser]))
AC_ARG_ENABLE([console], AS_HELP_STRING([--disable-console], [disable serial console]))
AC_ARG_ENABLE([elf], AS_HELP_STRING([--disable-elf], [disable ELF utils]))
AC_ARG_ENABLE([multiboot2], AS_HELP_STRING([--disable-multiboot2], [disable Multiboot 2 information parser]))
AC_ARG_ENABLE([pfa], AS_HELP_STRING([--disable-pfa], [disable Page Frame Allocator]))
AC_ARG_ENABLE([units], AS_HELP_STRING([--disable-units], [disable measurement units utils]))
AM_CONDITIONAL([ARCH_I386], [test "$host_cpu" = i386])
AM_CONDITIONAL([ARCH_X86_64], [test "$host_cpu" = x86_64])
AC_ARG_ENABLE([assert], AS_HELP_STRING([--enable-assert], [enable runtime assertions]))
AC_ARG_ENABLE([libc], AS_HELP_STRING([--enable-libc], [enable libc replacement]))
AC_ARG_ENABLE([libc-memset], AS_HELP_STRING([--enable-libc-memset], [enable memset replacement]))
AC_ARG_ENABLE([libc-strcpy], AS_HELP_STRING([--enable-libc-strcpy], [enable strcpy replacement]))
AC_ARG_ENABLE([libc-strlen], AS_HELP_STRING([--enable-libc-strlen], [enable strlen replacement]))
AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" != no])
AM_CONDITIONAL([ENABLE_CMDLINE], [test "$enable_cmdline" != no])
AM_CONDITIONAL([ENABLE_CONSOLE], [test "$enable_console" != no])
AM_CONDITIONAL([ENABLE_ELF], [test "$enable_elf" != no])
AM_CONDITIONAL([ENABLE_MULTIBOOT2], [test "$enable_multiboot2" != no])
AM_CONDITIONAL([ENABLE_PFA], [test "$enable_pfa" != no])
AM_CONDITIONAL([ENABLE_UNITS], [test "$enable_units" != no])
AC_DEFUN([do_enable_libc],
[
if test -z "$enable_libc_memset"; then enable_libc_memset=yes; fi
if test -z "$enable_libc_strcpy"; then enable_libc_strcpy=yes; fi
if test -z "$enable_libc_strlen"; then enable_libc_strlen=yes; fi
])
AS_IF([test "$enable_libc" = yes], do_enable_libc)
AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ARCH_I386], [1], [architecture is i386])])
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ARCH_X86_64], [1], [architecture is x86_64])])
AM_CONDITIONAL([ARCH_I386], [test "$host_cpu" = i386])
AM_CONDITIONAL([ARCH_X86_64], [test "$host_cpu" = x86_64])
AS_IF([test "$enable_assert" != no], [AC_DEFINE([ENABLE_ASSERT], [1], [enabled runtime assertions])])
AS_IF([test "$enable_cmdline" != no], [AC_DEFINE([ENABLE_CMDLINE], [1], [enabled command line parser])])
AS_IF([test "$enable_console" != no], [AC_DEFINE([ENABLE_CONSOLE], [1], [enabled serial console])])
AS_IF([test "$enable_elf" != no], [AC_DEFINE([ENABLE_ELF], [1], [enabled ELF utils])])
AS_IF([test "$enable_multiboot2" != no], [AC_DEFINE([ENABLE_MULTIBOOT2], [1], [enabled Multiboot 2 information parser])])
AS_IF([test "$enable_pfa" != no], [AC_DEFINE([ENABLE_PFA], [1], [enabled Page Frame Allocator])])
AS_IF([test "$enable_units", != no], [AC_DEFINE([ENABLE_UNITS], [1], [enabled measurement units utils])])
AM_CONDITIONAL([ENABLE_CMDLINE], [test "$enable_cmdline" != no])
AM_CONDITIONAL([ENABLE_CONSOLE], [test "$enable_console" != no])
AM_CONDITIONAL([ENABLE_ELF], [test "$enable_elf" != no])
AM_CONDITIONAL([ENABLE_MULTIBOOT2], [test "$enable_multiboot2" != no])
AM_CONDITIONAL([ENABLE_PFA], [test "$enable_pfa" != no])
AM_CONDITIONAL([ENABLE_UNITS], [test "$enable_units" != no])
AM_CONDITIONAL([ENABLE_ASSERT], [test "$enable_assert" = yes])
AM_CONDITIONAL([ENABLE_LIBC], [test "$enable_libc" = yes])
AM_CONDITIONAL([ENABLE_LIBC_MEMSET], [test "$enable_libc_memset" = yes])
AM_CONDITIONAL([ENABLE_LIBC_STRCPY], [test "$enable_libc_strcpy" = yes])
AM_CONDITIONAL([ENABLE_LIBC_STRLEN], [test "$enable_libc_strlen" = yes])
AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ARCH_I386], [1], [architecture is i386])])
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ARCH_X86_64], [1], [architecture is x86_64])])
AS_IF([test "$enable_cmdline" != no], [AC_DEFINE([ENABLE_CMDLINE], [1], [enabled command line parser])])
AS_IF([test "$enable_console" != no], [AC_DEFINE([ENABLE_CONSOLE], [1], [enabled serial console])])
AS_IF([test "$enable_elf" != no], [AC_DEFINE([ENABLE_ELF], [1], [enabled ELF utils])])
AS_IF([test "$enable_multiboot2" != no], [AC_DEFINE([ENABLE_MULTIBOOT2], [1], [enabled Multiboot 2 information parser])])
AS_IF([test "$enable_pfa" != no], [AC_DEFINE([ENABLE_PFA], [1], [enabled Page Frame Allocator])])
AS_IF([test "$enable_units", != no], [AC_DEFINE([ENABLE_UNITS], [1], [enabled measurement units utils])])
AS_IF([test "$enable_assert" = yes], [AC_DEFINE([ENABLE_ASSERT], [1], [enabled runtime assertions])])
AS_IF([test "$enable_libc" = yes], [AC_DEFINE([ENABLE_LIBC], [1], [enabled libc replacement])])
AS_IF([test "$enable_libc_memset" = yes], [AC_DEFINE([ENABLE_LIBC_MEMSET], [1], [enabled memset replacement])])
AS_IF([test "$enable_libc_strcpy" = yes], [AC_DEFINE([ENABLE_LIBC_STRCPY], [1], [enabled strcpy replacement])])
AS_IF([test "$enable_libc_strlen" = yes], [AC_DEFINE([ENABLE_LIBC_STRLEN], [1], [enabled strlen replacement])])
AM_INIT_AUTOMAKE([1.9 subdir-objects -Wall -Werror])

View File

@ -5,8 +5,9 @@ nobase_include_HEADERS = \
kernaux/assert.h \
kernaux/cmdline.h \
kernaux/console.h \
kernaux/itoa.h \
kernaux/libc.h \
kernaux/multiboot2.h \
kernaux/pfa.h \
kernaux/printf.h \
kernaux/stdlib.h \
kernaux/units.h

View File

@ -2,8 +2,11 @@
#include <kernaux/cmdline.h>
#include <kernaux/console.h>
#include <kernaux/elf.h>
#include <kernaux/itoa.h>
#include <kernaux/multiboot2.h>
#include <kernaux/pfa.h>
#include <kernaux/printf.h>
#include <kernaux/stdlib.h>
#include <kernaux/units.h>
// We don't include <kernaux/libc.h> because it may
// conflict with actual freestanding or hosted libc.

14
include/kernaux/itoa.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef KERNAUX_INCLUDED_ITOA
#define KERNAUX_INCLUDED_ITOA 1
#ifdef __cplusplus
extern "C" {
#endif
void kernaux_itoa(int d, char *buf, int base);
#ifdef __cplusplus
}
#endif
#endif

18
include/kernaux/libc.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef KERNAUX_INCLUDED_LIBC
#define KERNAUX_INCLUDED_LIBC 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
void *memset(void *s, int c, size_t n);
char *strcpy(char *dest, const char *src);
size_t strlen(const char *s);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,22 +0,0 @@
#ifndef KERNAUX_INCLUDED_STDLIB
#define KERNAUX_INCLUDED_STDLIB 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
void *kernaux_memset(void *buffer, int value, size_t size);
size_t kernaux_strlen(const char *s);
char *kernaux_strncpy(char *dest, const char *src, size_t slen);
void kernaux_itoa(int d, char *buf, int base);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,3 +1,6 @@
#ifndef _ASSERT_H
#define _ASSERT_H
#include <kernaux/assert.h>
#ifdef ENABLE_ASSERT
@ -8,3 +11,5 @@
#define assert_return(cond) { assert(cond); if (!(cond)) return; }
#define assert_retval(cond, val) { assert(cond); if (!(cond)) return (val); }
#endif

View File

@ -3,7 +3,7 @@
#endif
#include <kernaux/cmdline.h>
#include <kernaux/stdlib.h>
#include <kernaux/libc.h>
#include <stddef.h>
@ -37,14 +37,14 @@ bool kernaux_cmdline_parse(
return false;
}
kernaux_memset(error_msg, '\0', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
memset(error_msg, '\0', KERNAUX_CMDLINE_ERROR_MSG_SIZE_MAX);
*argc = 0;
for (unsigned int index = 0; index < argv_count_max; ++index) {
argv[index] = NULL;
}
kernaux_memset(buffer, '\0', argv_count_max * arg_size_max);
memset(buffer, '\0', argv_count_max * arg_size_max);
if (cmdline[0] == '\0') {
return true;
@ -70,7 +70,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == '\\') {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
@ -79,7 +79,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == '"') {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
@ -88,12 +88,12 @@ bool kernaux_cmdline_parse(
}
else {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -112,7 +112,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == '\\') {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
@ -121,7 +121,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == '"') {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
@ -130,12 +130,12 @@ bool kernaux_cmdline_parse(
}
else {
if (*argc >= argv_count_max) {
kernaux_strncpy(error_msg, "too many args", 13);
strcpy(error_msg, "too many args");
goto fail;
}
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -149,7 +149,7 @@ bool kernaux_cmdline_parse(
case TOKEN:
if (cur == '\0') {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -159,7 +159,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == ' ') {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -171,12 +171,12 @@ bool kernaux_cmdline_parse(
state = BACKSLASH;
}
else if (cur == '"') {
kernaux_strncpy(error_msg, "unescaped quotation mark", 24);
strcpy(error_msg, "unescaped quotation mark");
goto fail;
}
else {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -187,12 +187,12 @@ bool kernaux_cmdline_parse(
case BACKSLASH:
if (cur == '\0') {
kernaux_strncpy(error_msg, "EOL after backslash", 19);
strcpy(error_msg, "EOL after backslash");
goto fail;
}
else {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -204,7 +204,7 @@ bool kernaux_cmdline_parse(
case QUOTE:
if (cur == '\0') {
kernaux_strncpy(error_msg, "EOL inside quote", 16);
strcpy(error_msg, "EOL inside quote");
goto fail;
}
else if (cur == '\\') {
@ -212,7 +212,7 @@ bool kernaux_cmdline_parse(
}
else if (cur == '"') {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -222,7 +222,7 @@ bool kernaux_cmdline_parse(
}
else {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -233,12 +233,12 @@ bool kernaux_cmdline_parse(
case QUOTE_BACKSLASH:
if (cur == '\0') {
kernaux_strncpy(error_msg, "EOL after backslash inside quote", 32);
strcpy(error_msg, "EOL after backslash inside quote");
goto fail;
}
else {
if (buffer_size >= arg_size_max) {
kernaux_strncpy(error_msg, "arg too long", 12);
strcpy(error_msg, "arg too long");
goto fail;
}
@ -263,7 +263,7 @@ fail:
argv[index] = NULL;
}
kernaux_memset(buffer, '\0', argv_count_max * arg_size_max);
memset(buffer, '\0', argv_count_max * arg_size_max);
return false;
}

View File

@ -7,12 +7,12 @@
#endif
#include <kernaux/console.h>
#include <kernaux/libc.h>
#include <kernaux/printf.h>
#include <kernaux/stdlib.h>
void kernaux_console_print(const char *const s)
{
kernaux_console_write(s, kernaux_strlen(s));
kernaux_console_write(s, strlen(s));
}
void kernaux_console_putc(const char c __attribute__((unused)))

View File

@ -2,43 +2,7 @@
#include "config.h"
#endif
#include <kernaux/stdlib.h>
void *kernaux_memset(void *const buffer, const int value, const size_t size)
{
unsigned char *const s = buffer;
for (size_t i = 0; i < size; ++i) {
s[i] = value;
}
return buffer;
}
size_t kernaux_strlen(const char *const s)
{
size_t result = 0;
while (s[result]) {
++result;
}
return result;
}
char *kernaux_strncpy(
char *const dest,
const char *const src,
const size_t slen
) {
for (size_t i = 0; i < slen; ++i) {
dest[i] = src[i];
}
dest[slen] = '\0';
return dest;
}
#include <kernaux/itoa.h>
void kernaux_itoa(const int d, char *buf, const int base)
{

32
src/libc.c Normal file
View File

@ -0,0 +1,32 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/libc.h>
#ifdef ENABLE_LIBC_MEMSET
void *memset(void *s, int c, size_t n)
{
char *ss = s;
while (n-- > 0) *ss++ = c;
return s;
}
#endif // ENABLE_LIBC_MEMSET
#ifdef ENABLE_LIBC_STRCPY
char *strcpy(char *dest, const char *src)
{
char *tmp = dest;
while ((*dest++ = *src++) != '\0');
return tmp;
}
#endif // ENABLE_LIBC_STRCPY
#ifdef ENABLE_LIBC_STRLEN
size_t strlen(const char *s)
{
const char *ss = s;
while (*ss != '\0') ++ss;
return ss - s;
}
#endif // ENABLE_LIBC_STRLEN

View File

@ -2,8 +2,8 @@
#include "config.h"
#endif
#include <kernaux/libc.h>
#include <kernaux/pfa.h>
#include <kernaux/stdlib.h>
#include "assert.h"
@ -41,7 +41,7 @@ static void KernAux_PFA_mark(
void KernAux_PFA_initialize(const KernAux_PFA pfa)
{
assert_return(pfa);
kernaux_memset(pfa->flags, 0, sizeof(pfa->flags));
memset(pfa->flags, 0, sizeof(pfa->flags));
}
bool KernAux_PFA_is_available(const KernAux_PFA pfa, const size_t page_addr)

View File

@ -2,8 +2,8 @@
#include "config.h"
#endif
#include <kernaux/itoa.h>
#include <kernaux/printf.h>
#include <kernaux/stdlib.h>
#include <stdbool.h>

View File

@ -2,7 +2,8 @@
#include "config.h"
#endif
#include <kernaux/stdlib.h>
#include <kernaux/itoa.h>
#include <kernaux/libc.h>
#include <kernaux/units.h>
#define TMP_BUFFER_SIZE (64)
@ -36,10 +37,10 @@ bool kernaux_units_human_raw(
*(tmp++) = '\0';
const size_t tmp_size = kernaux_strlen(tmp_buffer) + 1;
const size_t tmp_size = strlen(tmp_buffer) + 1;
if (tmp_size > buffer_size) return false;
kernaux_strncpy(buffer, tmp_buffer, tmp_size);
strcpy(buffer, tmp_buffer);
return true;
}
@ -82,10 +83,10 @@ bool kernaux_units_human_dec(
*(tmp++) = '\0';
const size_t tmp_size = kernaux_strlen(tmp_buffer) + 1;
const size_t tmp_size = strlen(tmp_buffer) + 1;
if (tmp_size > buffer_size) return false;
kernaux_strncpy(buffer, tmp_buffer, tmp_size);
strcpy(buffer, tmp_buffer);
return true;
}
@ -131,9 +132,9 @@ bool kernaux_units_human_bin(
*(tmp++) = '\0';
const size_t tmp_size = kernaux_strlen(tmp_buffer) + 1;
const size_t tmp_size = strlen(tmp_buffer) + 1;
if (tmp_size > buffer_size) return false;
kernaux_strncpy(buffer, tmp_buffer, tmp_size);
strcpy(buffer, tmp_buffer);
return true;
}

37
tests/test_itoa.c Normal file
View File

@ -0,0 +1,37 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/itoa.h>
#include <assert.h>
#include <string.h>
int main()
{
{
char buffer[10];
kernaux_itoa(495, buffer, 'd');
assert(buffer[0] == '4');
assert(buffer[1] == '9');
assert(buffer[2] == '5');
assert(buffer[3] == '\0');
}
{
char buffer[10];
kernaux_itoa(-7012, buffer, 'd');
assert(buffer[0] == '-');
assert(buffer[1] == '7');
assert(buffer[2] == '0');
assert(buffer[3] == '1');
assert(buffer[4] == '2');
assert(buffer[5] == '\0');
}
return 0;
}

View File

@ -1,100 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/stdlib.h>
#include <assert.h>
int main()
{
// kernaux_memset
{
unsigned char buffer[10] =
{32, 13, 254, 165, 98, 36, 169, 152, 233, 222};
assert(kernaux_memset(buffer, 0, sizeof(buffer)) == buffer);
for (unsigned int i = 0; i < sizeof(buffer); ++i) {
assert(buffer[i] == 0);
}
}
{
unsigned char buffer[10] =
{32, 13, 254, 165, 98, 36, 169, 152, 233, 222};
assert(kernaux_memset(buffer, 143, sizeof(buffer)) == buffer);
for (unsigned int i = 0; i < sizeof(buffer); ++i) {
assert(buffer[i] == 143);
}
}
{
unsigned char buffer[10] =
{32, 13, 254, 165, 98, 36, 169, 152, 233, 222};
assert(kernaux_memset(buffer, 0x89ABCDEF, sizeof(buffer)) == buffer);
for (unsigned int i = 0; i < sizeof(buffer); ++i) {
assert(buffer[i] == 0xEF);
}
}
// kernaux_strlen
assert(kernaux_strlen("") == 0);
assert(kernaux_strlen("\0abcde") == 0);
assert(kernaux_strlen("12345") == 5);
assert(kernaux_strlen("12345\0abcde") == 5);
// kernaux_strncpy
{
const char src[] = "Hello, World!";
char dest[sizeof(src)];
kernaux_memset(dest, 0, sizeof(dest));
kernaux_strncpy(dest, src, kernaux_strlen(src));
assert(kernaux_strlen(dest) == kernaux_strlen(src));
for (
const char *src_p = src, *dest_p = dest;
*src_p;
++src_p, ++dest_p
) {
assert(*src_p == *dest_p);
}
}
// kernaux_itoa
{
char buffer[10];
kernaux_itoa(495, buffer, 'd');
assert(buffer[0] == '4');
assert(buffer[1] == '9');
assert(buffer[2] == '5');
assert(buffer[3] == '\0');
}
{
char buffer[10];
kernaux_itoa(-7012, buffer, 'd');
assert(buffer[0] == '-');
assert(buffer[1] == '7');
assert(buffer[2] == '0');
assert(buffer[3] == '1');
assert(buffer[4] == '2');
assert(buffer[5] == '\0');
}
return 0;
}