More implementation of the C standard library.
This commit is contained in:
parent
2a612d2d83
commit
b965486de3
@ -5,6 +5,6 @@ bastl_sources = Split('''
|
|||||||
src/new.cpp
|
src/new.cpp
|
||||||
''')
|
''')
|
||||||
|
|
||||||
env.Append(KERNEL_SOURCES = [env.File(f) for f in bastl_sources])
|
# env.Append(KERNEL_SOURCES = [env.File(f) for f in bastl_sources])
|
||||||
|
|
||||||
Return('env')
|
Return('env')
|
27
targets/_any/bastl/include/cctype
Normal file
27
targets/_any/bastl/include/cctype
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_CCTYPE_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_CCTYPE_INCLUDED
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
using ::isalnum;
|
||||||
|
using ::isalpha;
|
||||||
|
using ::islower;
|
||||||
|
using ::isupper;
|
||||||
|
using ::isdigit;
|
||||||
|
using ::isxdigit;
|
||||||
|
using ::iscntrl;
|
||||||
|
using ::isgraph;
|
||||||
|
using ::isspace;
|
||||||
|
using ::isblank;
|
||||||
|
using ::isprint;
|
||||||
|
using ::ispunct;
|
||||||
|
using ::tolower;
|
||||||
|
using ::toupper;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_CCTYPE_INCLUDED)
|
9
targets/_any/bastl/include/cerrno
Normal file
9
targets/_any/bastl/include/cerrno
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_CERRNO_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_CERRNO_INCLUDED
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_CERRNO_INCLUDED)
|
@ -16,6 +16,21 @@ using ::uint8_t;
|
|||||||
using ::uint16_t;
|
using ::uint16_t;
|
||||||
using ::uint32_t;
|
using ::uint32_t;
|
||||||
using ::uint64_t;
|
using ::uint64_t;
|
||||||
|
|
||||||
|
using ::intptr_t;
|
||||||
|
using ::uintptr_t;
|
||||||
|
|
||||||
|
using ::int_fast8_t;
|
||||||
|
using ::int_fast16_t;
|
||||||
|
using ::int_fast32_t;
|
||||||
|
using ::int_fast64_t;
|
||||||
|
using ::uint_fast8_t;
|
||||||
|
using ::uint_fast16_t;
|
||||||
|
using ::uint_fast32_t;
|
||||||
|
using ::uint_fast64_t;
|
||||||
|
|
||||||
|
using ::intmax_t;
|
||||||
|
using ::uintmax_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_CSTDINT_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_CSTDINT_INCLUDED)
|
||||||
|
@ -8,12 +8,16 @@
|
|||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
using ::strlen;
|
|
||||||
|
|
||||||
using ::memcmp;
|
using ::memcmp;
|
||||||
using ::memcpy;
|
using ::memcpy;
|
||||||
using ::memmove;
|
using ::memmove;
|
||||||
using ::memset;
|
using ::memset;
|
||||||
|
|
||||||
|
|
||||||
|
using ::strcat;
|
||||||
|
using ::strchr;
|
||||||
|
using ::strcpy;
|
||||||
|
using ::strlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_CSTRING_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_CSTRING_INCLUDED)
|
||||||
|
82
targets/_any/bastl/include/string_view
Normal file
82
targets/_any/bastl/include/string_view
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_STRING_VIEW_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_STRING_VIEW_INCLUDED
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<typename CharT, typename Traits = char_traits<CharT>>
|
||||||
|
class basic_string_view
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using traits_type = Traits;
|
||||||
|
using value_type = CharT;
|
||||||
|
using pointer = CharT*;
|
||||||
|
using const_pointer = const CharT*;
|
||||||
|
using reference = CharT&;
|
||||||
|
using const_reference = const CharT&;
|
||||||
|
using iterator = const CharT*;
|
||||||
|
using const_iterator = const CharT*;
|
||||||
|
// TODO: reverse iterators
|
||||||
|
using size_type = size_t;
|
||||||
|
using difference_type = ptrdiff_t;
|
||||||
|
private:
|
||||||
|
const_pointer _begin = nullptr;
|
||||||
|
const_pointer _end = nullptr;
|
||||||
|
public:
|
||||||
|
constexpr basic_string_view() noexcept = default;
|
||||||
|
constexpr basic_string_view(const basic_string_view&) noexcept = default;
|
||||||
|
constexpr basic_string_view(const_pointer s, size_type count) noexcept : _begin(s), _end(s + count) {}
|
||||||
|
constexpr basic_string_view(const_pointer s) noexcept : _begin(s), _end(s)
|
||||||
|
{
|
||||||
|
while (*_end) { ++_end; }
|
||||||
|
}
|
||||||
|
template<typename It, typename End>
|
||||||
|
constexpr basic_string_view(It first, End last) noexcept : _begin(first), _end(last) {}
|
||||||
|
constexpr basic_string_view(nullptr_t) = delete;
|
||||||
|
|
||||||
|
constexpr basic_string_view& operator=(const basic_string_view&) noexcept = default;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr iterator begin() const noexcept { return _begin; }
|
||||||
|
[[nodiscard]] constexpr const_iterator cbegin() const noexcept { return _begin; }
|
||||||
|
[[nodiscard]] constexpr iterator end() const noexcept { return _end; }
|
||||||
|
[[nodiscard]] constexpr const_iterator cend() const noexcept { return _end; }
|
||||||
|
// TODO: reverse iterators
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _begin[pos]; }
|
||||||
|
[[nodiscard]] constexpr const_reference at(size_type pos) const
|
||||||
|
{
|
||||||
|
if (pos >= size()) {
|
||||||
|
__ba_throw out_of_range();
|
||||||
|
}
|
||||||
|
return _begin[pos];
|
||||||
|
}
|
||||||
|
[[nodiscard]] constexpr const_reference front() const noexcept { return *_begin; }
|
||||||
|
[[nodiscard]] constexpr const_reference back() const noexcept { return _end[-1]; }
|
||||||
|
[[nodiscard]] constexpr const_pointer data() const noexcept { return _begin; }
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr size_type size() const noexcept { return _end - _begin; }
|
||||||
|
[[nodiscard]] constexpr size_type length() const noexcept { return _end - _begin; }
|
||||||
|
[[nodiscard]] constexpr size_type max_size() const noexcept { return numeric_limits<size_type>::max(); }
|
||||||
|
[[nodiscard]] constexpr bool empty() const noexcept { return size() == 0; }
|
||||||
|
|
||||||
|
constexpr void remove_prefix(size_type n) noexcept { _begin += n; }
|
||||||
|
constexpr void remove_suffix(size_type n) noexcept { _end -= n; }
|
||||||
|
|
||||||
|
constexpr void swap(basic_string_view& v) noexcept
|
||||||
|
{
|
||||||
|
swap(_begin, v._begin);
|
||||||
|
swap(_end, v._end);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using string_view = basic_string_view<char>;
|
||||||
|
using wstring_view = basic_string_view<wchar_t>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_STRING_VIEW_INCLUDED)
|
@ -4,7 +4,7 @@
|
|||||||
#if !defined(BAD_APPLE_OS_UTILITY_INCLUDED)
|
#if !defined(BAD_APPLE_OS_UTILITY_INCLUDED)
|
||||||
#define BAD_APPLE_OS_UTILITY_INCLUDED
|
#define BAD_APPLE_OS_UTILITY_INCLUDED
|
||||||
|
|
||||||
#include "type_traits"
|
#include <type_traits>
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
Import('env')
|
Import('env')
|
||||||
|
|
||||||
init_sources = Split('''
|
init_sources = Split('''
|
||||||
src/main.c
|
src/main.cpp
|
||||||
''')
|
''')
|
||||||
|
|
||||||
init_env = env.Clone()
|
init_env = env.Clone()
|
||||||
@ -11,6 +11,7 @@ init_env['CC'] = 'x86_64-elf-baos-gcc'
|
|||||||
init_env['CXX'] = 'x86_64-elf-baos-g++'
|
init_env['CXX'] = 'x86_64-elf-baos-g++'
|
||||||
init_env['LD'] = 'x86_64-elf-baos-g++'
|
init_env['LD'] = 'x86_64-elf-baos-g++'
|
||||||
init_env.Append(CXXFLAGS = ['-fno-exceptions', '-fno-rtti', '-std=c++20'])
|
init_env.Append(CXXFLAGS = ['-fno-exceptions', '-fno-rtti', '-std=c++20'])
|
||||||
|
init_env.Append(LINKFLAGS = ['-nostdlib++']) # TODO: this should be changed in GCC, but I can't find a way to do it
|
||||||
init_env.Append(CPPPATH = ['#targets/_any/bastl/include', '#targets/_any/stdlib/include', '#targets/_any/kernel/include'])
|
init_env.Append(CPPPATH = ['#targets/_any/bastl/include', '#targets/_any/stdlib/include', '#targets/_any/kernel/include'])
|
||||||
|
|
||||||
prog_init = init_env.Program(
|
prog_init = init_env.Program(
|
||||||
|
@ -55,4 +55,15 @@ inline void serialWriteString(std::uint16_t port, const char* str) noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void serialWriteString(std::uint16_t port, const char* str, size_t count) noexcept
|
||||||
|
{
|
||||||
|
for (size_t pos = 0; pos < count; ++pos)
|
||||||
|
{
|
||||||
|
if (str[pos] == '\n') {
|
||||||
|
serialWrite(port, '\r');
|
||||||
|
}
|
||||||
|
serialWrite(port, str[pos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_SERIAL_HPP_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_SERIAL_HPP_INCLUDED)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
namespace baos
|
namespace baos
|
||||||
{
|
{
|
||||||
@ -47,6 +48,33 @@ public:
|
|||||||
--mBufferedElements;
|
--mBufferedElements;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isDataContinuous() const noexcept
|
||||||
|
{
|
||||||
|
return mBufferedElements <= mPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void normalize() noexcept
|
||||||
|
{
|
||||||
|
std::array<T, SIZE> tempElements;
|
||||||
|
auto it = tempElements.begin();
|
||||||
|
while (next(*it)) { ++it; }
|
||||||
|
mBufferedElements = it - tempElements.begin();
|
||||||
|
mElements = std::move(tempElements);
|
||||||
|
mPosition = mBufferedElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<T> getAll(bool reset = true) noexcept
|
||||||
|
{
|
||||||
|
if (!isDataContinuous()) {
|
||||||
|
normalize();
|
||||||
|
}
|
||||||
|
std::span<T> result = {mElements.data() + mPosition - mBufferedElements, mBufferedElements};
|
||||||
|
if (reset) {
|
||||||
|
mBufferedElements = 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ void sysFileRead(unsigned fileDescriptor, char* buffer, std::size_t count) noexc
|
|||||||
|
|
||||||
void sysFileWrite(unsigned fileDescriptor, const char* buffer, std::size_t count) noexcept
|
void sysFileWrite(unsigned fileDescriptor, const char* buffer, std::size_t count) noexcept
|
||||||
{
|
{
|
||||||
|
serialWriteString(PORT_COM1, buffer, count);
|
||||||
for (std::size_t index = 0; index < count; ++index) {
|
for (std::size_t index = 0; index < count; ++index) {
|
||||||
serialWrite(PORT_COM1, buffer[index]);
|
serialWrite(PORT_COM1, buffer[index]);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ env['CRT0_PATH'] = env.File(f'src/crt0.{env["TARGET_ARCH"]}.s').abspath
|
|||||||
|
|
||||||
stdlib_sources = Split(f'''
|
stdlib_sources = Split(f'''
|
||||||
src/assert.cpp
|
src/assert.cpp
|
||||||
|
src/ctype.cpp
|
||||||
|
src/errno.cpp
|
||||||
src/stdio.cpp
|
src/stdio.cpp
|
||||||
src/stdlib.cpp
|
src/stdlib.cpp
|
||||||
src/string.cpp
|
src/string.cpp
|
||||||
|
28
targets/_any/stdlib/include/ctype.h
Normal file
28
targets/_any/stdlib/include/ctype.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_CTYPE_H_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_CTYPE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "./detail/common.h"
|
||||||
|
|
||||||
|
BA_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
BA_CXX_NODISCARD int isalnum(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isalpha(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int islower(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isupper(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isdigit(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isxdigit(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int iscntrl(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isgraph(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isspace(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isblank(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int isprint(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int ispunct(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int tolower(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD int toupper(int ch) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
|
BA_EXTERN_C_END
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_CTYPE_H_INCLUDED)
|
@ -1,7 +1,170 @@
|
|||||||
|
// shamelessly stolen from my Linux distro (which means this is GPL code!)
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if !defined(BAD_APPLE_OS_ERRNO_H_INCLUDED)
|
#if !defined(BAD_APPLE_OS_ERRNO_H_INCLUDED)
|
||||||
#define BAD_APPLE_OS_ERRNO_H_INCLUDED
|
#define BAD_APPLE_OS_ERRNO_H_INCLUDED
|
||||||
|
|
||||||
|
#include "./detail/common.h"
|
||||||
|
|
||||||
|
#define errno (*__errno())
|
||||||
|
|
||||||
|
#define EPERM 1 /* Operation not permitted */
|
||||||
|
#define ENOENT 2 /* No such file or directory */
|
||||||
|
#define ESRCH 3 /* No such process */
|
||||||
|
#define EINTR 4 /* Interrupted system call */
|
||||||
|
#define EIO 5 /* I/O error */
|
||||||
|
#define ENXIO 6 /* No such device or address */
|
||||||
|
#define E2BIG 7 /* Argument list too long */
|
||||||
|
#define ENOEXEC 8 /* Exec format error */
|
||||||
|
#define EBADF 9 /* Bad file number */
|
||||||
|
#define ECHILD 10 /* No child processes */
|
||||||
|
#define EAGAIN 11 /* Try again */
|
||||||
|
#define ENOMEM 12 /* Out of memory */
|
||||||
|
#define EACCES 13 /* Permission denied */
|
||||||
|
#define EFAULT 14 /* Bad address */
|
||||||
|
#define ENOTBLK 15 /* Block device required */
|
||||||
|
#define EBUSY 16 /* Device or resource busy */
|
||||||
|
#define EEXIST 17 /* File exists */
|
||||||
|
#define EXDEV 18 /* Cross-device link */
|
||||||
|
#define ENODEV 19 /* No such device */
|
||||||
|
#define ENOTDIR 20 /* Not a directory */
|
||||||
|
#define EISDIR 21 /* Is a directory */
|
||||||
|
#define EINVAL 22 /* Invalid argument */
|
||||||
|
#define ENFILE 23 /* File table overflow */
|
||||||
|
#define EMFILE 24 /* Too many open files */
|
||||||
|
#define ENOTTY 25 /* Not a typewriter */
|
||||||
|
#define ETXTBSY 26 /* Text file busy */
|
||||||
|
#define EFBIG 27 /* File too large */
|
||||||
|
#define ENOSPC 28 /* No space left on device */
|
||||||
|
#define ESPIPE 29 /* Illegal seek */
|
||||||
|
#define EROFS 30 /* Read-only file system */
|
||||||
|
#define EMLINK 31 /* Too many links */
|
||||||
|
#define EPIPE 32 /* Broken pipe */
|
||||||
|
#define EDOM 33 /* Math argument out of domain of func */
|
||||||
|
#define ERANGE 34 /* Math result not representable */
|
||||||
|
|
||||||
|
#define EDEADLK 35 /* Resource deadlock would occur */
|
||||||
|
#define ENAMETOOLONG 36 /* File name too long */
|
||||||
|
#define ENOLCK 37 /* No record locks available */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This error code is special: arch syscall entry code will return
|
||||||
|
* -ENOSYS if users try to call a syscall that doesn't exist. To keep
|
||||||
|
* failures of syscalls that really do exist distinguishable from
|
||||||
|
* failures due to attempts to use a nonexistent syscall, syscall
|
||||||
|
* implementations should refrain from returning -ENOSYS.
|
||||||
|
*/
|
||||||
|
#define ENOSYS 38 /* Invalid system call number */
|
||||||
|
|
||||||
|
#define ENOTEMPTY 39 /* Directory not empty */
|
||||||
|
#define ELOOP 40 /* Too many symbolic links encountered */
|
||||||
|
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||||
|
#define ENOMSG 42 /* No message of desired type */
|
||||||
|
#define EIDRM 43 /* Identifier removed */
|
||||||
|
#define ECHRNG 44 /* Channel number out of range */
|
||||||
|
#define EL2NSYNC 45 /* Level 2 not synchronized */
|
||||||
|
#define EL3HLT 46 /* Level 3 halted */
|
||||||
|
#define EL3RST 47 /* Level 3 reset */
|
||||||
|
#define ELNRNG 48 /* Link number out of range */
|
||||||
|
#define EUNATCH 49 /* Protocol driver not attached */
|
||||||
|
#define ENOCSI 50 /* No CSI structure available */
|
||||||
|
#define EL2HLT 51 /* Level 2 halted */
|
||||||
|
#define EBADE 52 /* Invalid exchange */
|
||||||
|
#define EBADR 53 /* Invalid request descriptor */
|
||||||
|
#define EXFULL 54 /* Exchange full */
|
||||||
|
#define ENOANO 55 /* No anode */
|
||||||
|
#define EBADRQC 56 /* Invalid request code */
|
||||||
|
#define EBADSLT 57 /* Invalid slot */
|
||||||
|
|
||||||
|
#define EDEADLOCK EDEADLK
|
||||||
|
|
||||||
|
#define EBFONT 59 /* Bad font file format */
|
||||||
|
#define ENOSTR 60 /* Device not a stream */
|
||||||
|
#define ENODATA 61 /* No data available */
|
||||||
|
#define ETIME 62 /* Timer expired */
|
||||||
|
#define ENOSR 63 /* Out of streams resources */
|
||||||
|
#define ENONET 64 /* Machine is not on the network */
|
||||||
|
#define ENOPKG 65 /* Package not installed */
|
||||||
|
#define EREMOTE 66 /* Object is remote */
|
||||||
|
#define ENOLINK 67 /* Link has been severed */
|
||||||
|
#define EADV 68 /* Advertise error */
|
||||||
|
#define ESRMNT 69 /* Srmount error */
|
||||||
|
#define ECOMM 70 /* Communication error on send */
|
||||||
|
#define EPROTO 71 /* Protocol error */
|
||||||
|
#define EMULTIHOP 72 /* Multihop attempted */
|
||||||
|
#define EDOTDOT 73 /* RFS specific error */
|
||||||
|
#define EBADMSG 74 /* Not a data message */
|
||||||
|
#define EOVERFLOW 75 /* Value too large for defined data type */
|
||||||
|
#define ENOTUNIQ 76 /* Name not unique on network */
|
||||||
|
#define EBADFD 77 /* File descriptor in bad state */
|
||||||
|
#define EREMCHG 78 /* Remote address changed */
|
||||||
|
#define ELIBACC 79 /* Can not access a needed shared library */
|
||||||
|
#define ELIBBAD 80 /* Accessing a corrupted shared library */
|
||||||
|
#define ELIBSCN 81 /* .lib section in a.out corrupted */
|
||||||
|
#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
|
||||||
|
#define ELIBEXEC 83 /* Cannot exec a shared library directly */
|
||||||
|
#define EILSEQ 84 /* Illegal byte sequence */
|
||||||
|
#define ERESTART 85 /* Interrupted system call should be restarted */
|
||||||
|
#define ESTRPIPE 86 /* Streams pipe error */
|
||||||
|
#define EUSERS 87 /* Too many users */
|
||||||
|
#define ENOTSOCK 88 /* Socket operation on non-socket */
|
||||||
|
#define EDESTADDRREQ 89 /* Destination address required */
|
||||||
|
#define EMSGSIZE 90 /* Message too long */
|
||||||
|
#define EPROTOTYPE 91 /* Protocol wrong type for socket */
|
||||||
|
#define ENOPROTOOPT 92 /* Protocol not available */
|
||||||
|
#define EPROTONOSUPPORT 93 /* Protocol not supported */
|
||||||
|
#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
|
||||||
|
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||||
|
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||||
|
#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
|
||||||
|
#define EADDRINUSE 98 /* Address already in use */
|
||||||
|
#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
|
||||||
|
#define ENETDOWN 100 /* Network is down */
|
||||||
|
#define ENETUNREACH 101 /* Network is unreachable */
|
||||||
|
#define ENETRESET 102 /* Network dropped connection because of reset */
|
||||||
|
#define ECONNABORTED 103 /* Software caused connection abort */
|
||||||
|
#define ECONNRESET 104 /* Connection reset by peer */
|
||||||
|
#define ENOBUFS 105 /* No buffer space available */
|
||||||
|
#define EISCONN 106 /* Transport endpoint is already connected */
|
||||||
|
#define ENOTCONN 107 /* Transport endpoint is not connected */
|
||||||
|
#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
|
||||||
|
#define ETOOMANYREFS 109 /* Too many references: cannot splice */
|
||||||
|
#define ETIMEDOUT 110 /* Connection timed out */
|
||||||
|
#define ECONNREFUSED 111 /* Connection refused */
|
||||||
|
#define EHOSTDOWN 112 /* Host is down */
|
||||||
|
#define EHOSTUNREACH 113 /* No route to host */
|
||||||
|
#define EALREADY 114 /* Operation already in progress */
|
||||||
|
#define EINPROGRESS 115 /* Operation now in progress */
|
||||||
|
#define ESTALE 116 /* Stale file handle */
|
||||||
|
#define EUCLEAN 117 /* Structure needs cleaning */
|
||||||
|
#define ENOTNAM 118 /* Not a XENIX named type file */
|
||||||
|
#define ENAVAIL 119 /* No XENIX semaphores available */
|
||||||
|
#define EISNAM 120 /* Is a named type file */
|
||||||
|
#define EREMOTEIO 121 /* Remote I/O error */
|
||||||
|
#define EDQUOT 122 /* Quota exceeded */
|
||||||
|
|
||||||
|
#define ENOMEDIUM 123 /* No medium found */
|
||||||
|
#define EMEDIUMTYPE 124 /* Wrong medium type */
|
||||||
|
#define ECANCELED 125 /* Operation Canceled */
|
||||||
|
#define ENOKEY 126 /* Required key not available */
|
||||||
|
#define EKEYEXPIRED 127 /* Key has expired */
|
||||||
|
#define EKEYREVOKED 128 /* Key has been revoked */
|
||||||
|
#define EKEYREJECTED 129 /* Key was rejected by service */
|
||||||
|
|
||||||
|
/* for robust mutexes */
|
||||||
|
#define EOWNERDEAD 130 /* Owner died */
|
||||||
|
#define ENOTRECOVERABLE 131 /* State not recoverable */
|
||||||
|
|
||||||
|
#define ERFKILL 132 /* Operation not possible due to RF-kill */
|
||||||
|
|
||||||
|
#define EHWPOISON 133 /* Memory page has hardware error */
|
||||||
|
|
||||||
|
BA_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
BA_CXX_NODISCARD int* __errno() BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BA_EXTERN_C_END
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_ERRNO_H_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_ERRNO_H_INCLUDED)
|
||||||
|
@ -33,6 +33,7 @@ int vprintf(const char* BA_C_RESTRICT format, va_list vlist) BA_CXX_NOEXCEPT;
|
|||||||
int sprintf(char* BA_C_RESTRICT buffer, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT;
|
int sprintf(char* BA_C_RESTRICT buffer, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT;
|
||||||
int snprintf(char* BA_C_RESTRICT buffer, size_t bufferSize, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 3, 4)));
|
int snprintf(char* BA_C_RESTRICT buffer, size_t bufferSize, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 3, 4)));
|
||||||
int vsnprintf(char* BA_C_RESTRICT buffer, size_t bufferSize, const char* BA_C_RESTRICT format, va_list vlist) BA_CXX_NOEXCEPT;
|
int vsnprintf(char* BA_C_RESTRICT buffer, size_t bufferSize, const char* BA_C_RESTRICT format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||||
|
int vsprintf(char* BA_C_RESTRICT buffer, const char* BA_C_RESTRICT format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
int fclose(FILE* stream) BA_CXX_NOEXCEPT;
|
int fclose(FILE* stream) BA_CXX_NOEXCEPT;
|
||||||
int fflush(FILE* stream) BA_CXX_NOEXCEPT;
|
int fflush(FILE* stream) BA_CXX_NOEXCEPT;
|
||||||
@ -40,6 +41,8 @@ int fgetc(FILE* stream) BA_CXX_NOEXCEPT;
|
|||||||
FILE* fopen(const char* BA_C_RESTRICT filename, const char* BA_C_RESTRICT mode) BA_CXX_NOEXCEPT;
|
FILE* fopen(const char* BA_C_RESTRICT filename, const char* BA_C_RESTRICT mode) BA_CXX_NOEXCEPT;
|
||||||
char* fgets(char* buffer, int count, FILE* stream) BA_CXX_NOEXCEPT;
|
char* fgets(char* buffer, int count, FILE* stream) BA_CXX_NOEXCEPT;
|
||||||
int fprintf(FILE* BA_C_RESTRICT stream, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 2, 3)));
|
int fprintf(FILE* BA_C_RESTRICT stream, const char* BA_C_RESTRICT format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 2, 3)));
|
||||||
|
int fputc(int ch, FILE* stream) BA_CXX_NOEXCEPT;
|
||||||
|
int fputs(const char* BA_C_RESTRICT str, FILE* BA_C_RESTRICT stream) BA_CXX_NOEXCEPT;
|
||||||
size_t fread(void* BA_C_RESTRICT buffer, size_t size, size_t count, FILE* BA_C_RESTRICT stream) BA_CXX_NOEXCEPT;
|
size_t fread(void* BA_C_RESTRICT buffer, size_t size, size_t count, FILE* BA_C_RESTRICT stream) BA_CXX_NOEXCEPT;
|
||||||
int fseek(FILE* stream, long offset, int origin) BA_CXX_NOEXCEPT;
|
int fseek(FILE* stream, long offset, int origin) BA_CXX_NOEXCEPT;
|
||||||
long ftell(FILE* stream) BA_CXX_NOEXCEPT;
|
long ftell(FILE* stream) BA_CXX_NOEXCEPT;
|
||||||
@ -49,6 +52,7 @@ int vfprintf(FILE* BA_C_RESTRICT stream, const char* BA_C_RESTRICT format, va_li
|
|||||||
|
|
||||||
inline int getc(FILE* stream) BA_CXX_NOEXCEPT { return fgetc(stream); }
|
inline int getc(FILE* stream) BA_CXX_NOEXCEPT { return fgetc(stream); }
|
||||||
inline int getchar() BA_CXX_NOEXCEPT { return fgetc(stdin); }
|
inline int getchar() BA_CXX_NOEXCEPT { return fgetc(stdin); }
|
||||||
|
inline int putc(int ch, FILE* stream) BA_CXX_NOEXCEPT { return fputc(ch, stream); }
|
||||||
|
|
||||||
BA_EXTERN_C_END
|
BA_EXTERN_C_END
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ BA_CXX_NORETURN void exit(int exitCode) BA_CXX_NOEXCEPT;
|
|||||||
BA_CXX_NODISCARD char* getenv(const char* name) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD char* getenv(const char* name) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
BA_CXX_NODISCARD int abs(int n) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD int abs(int n) BA_CXX_NOEXCEPT;
|
||||||
|
BA_CXX_NODISCARD double atof(const char* str) BA_CXX_NOEXCEPT;
|
||||||
BA_CXX_NODISCARD int atoi(const char* str) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD int atoi(const char* str) BA_CXX_NOEXCEPT;
|
||||||
|
|
||||||
BA_CXX_NODISCARD void* calloc(size_t num, size_t size) BA_CXX_NOEXCEPT;
|
BA_CXX_NODISCARD void* calloc(size_t num, size_t size) BA_CXX_NOEXCEPT;
|
||||||
|
79
targets/_any/stdlib/src/ctype.cpp
Normal file
79
targets/_any/stdlib/src/ctype.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int isalnum(int ch) noexcept
|
||||||
|
{
|
||||||
|
return isdigit(ch) || isalpha(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int isalpha(int ch) noexcept
|
||||||
|
{
|
||||||
|
return islower(ch) || isupper(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int islower(int ch) noexcept
|
||||||
|
{
|
||||||
|
return ch >= 'a' && ch <= 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
int isupper(int ch) noexcept
|
||||||
|
{
|
||||||
|
return ch >= 'A' && ch <= 'Z';
|
||||||
|
}
|
||||||
|
|
||||||
|
int isdigit(int ch) noexcept
|
||||||
|
{
|
||||||
|
return ch >= '0' && ch <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
int isxdigit(int ch) noexcept
|
||||||
|
{
|
||||||
|
return isdigit(ch) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
int iscntrl(int ch) noexcept
|
||||||
|
{
|
||||||
|
return (ch >= 0x00 && ch <= 0x1F) || ch == 0x7F;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isgraph(int ch) noexcept
|
||||||
|
{
|
||||||
|
return isalnum(ch) || ispunct(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int isspace(int ch) noexcept
|
||||||
|
{
|
||||||
|
static const char SPACE_CHARS[] = " \f\n\r\t\v";
|
||||||
|
return strchr(SPACE_CHARS, ch) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isblank(int ch) noexcept
|
||||||
|
{
|
||||||
|
return ch == ' ' || ch == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
int isprint(int ch) noexcept
|
||||||
|
{
|
||||||
|
return isgraph(ch) || isspace(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ispunct(int ch) noexcept
|
||||||
|
{
|
||||||
|
static const char PUNCTUATION_CHARS[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
|
||||||
|
return strchr(PUNCTUATION_CHARS, ch) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tolower(int ch) noexcept
|
||||||
|
{
|
||||||
|
return isupper(ch) ? (ch - 'A' + 'a') : ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int toupper(int ch) noexcept
|
||||||
|
{
|
||||||
|
return islower(ch) ? (ch - 'a' + 'A') : ch;
|
||||||
|
}
|
||||||
|
}
|
15
targets/_any/stdlib/src/errno.cpp
Normal file
15
targets/_any/stdlib/src/errno.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constinit int gErrno = 0; // TODO: make this thread-local once there are threads
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int* __errno() noexcept
|
||||||
|
{
|
||||||
|
return &gErrno;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <bit>
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "os/tools/printf_helper.hpp"
|
#include "os/tools/printf_helper.hpp"
|
||||||
#include "os/tools/ringbuffer.hpp"
|
#include "os/tools/ringbuffer.hpp"
|
||||||
@ -17,34 +20,64 @@
|
|||||||
struct __file
|
struct __file
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
static constexpr unsigned BUFFER_SIZE = 4096;
|
|
||||||
|
|
||||||
baos::RingBuffer<char, BUFFER_SIZE> mBuffer;
|
|
||||||
bool mEof = false;
|
bool mEof = false;
|
||||||
bool mError = false;
|
bool mError = false;
|
||||||
protected:
|
|
||||||
virtual bool underflow() noexcept = 0;
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] bool isEof() const noexcept { return mEof; }
|
[[nodiscard]] bool isEof() const noexcept { return mEof; }
|
||||||
[[nodiscard]] bool isError() const noexcept { return mError; }
|
[[nodiscard]] bool isError() const noexcept { return mError; }
|
||||||
|
|
||||||
bool readChar(char& outChar) noexcept
|
virtual bool readChar(char& outChar) noexcept { return false; }
|
||||||
|
virtual bool readLine(std::string& outLine) noexcept { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct BufferPrinter
|
||||||
|
{
|
||||||
|
char* pos = nullptr;
|
||||||
|
char* end = nullptr;
|
||||||
|
|
||||||
|
void putchar(int chr) noexcept // NOLINT
|
||||||
|
{
|
||||||
|
if (pos != end)
|
||||||
|
{
|
||||||
|
*pos = static_cast<char>(chr);
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InFile : public __file
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static constexpr unsigned BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
|
baos::RingBuffer<char, BUFFER_SIZE> mBuffer;
|
||||||
|
protected:
|
||||||
|
virtual bool underflow() noexcept = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool readChar(char& outChar) noexcept override
|
||||||
|
{
|
||||||
|
while (!mBuffer.next(outChar))
|
||||||
|
{
|
||||||
|
if (!underflow())
|
||||||
{
|
{
|
||||||
while (!mBuffer.next(outChar)) {
|
|
||||||
if (!underflow()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readLine(std::string& outLine) noexcept
|
bool readLine(std::string& outLine) noexcept override
|
||||||
{
|
{
|
||||||
outLine.clear();
|
outLine.clear();
|
||||||
while(true)
|
while (true)
|
||||||
|
{
|
||||||
|
while (mBuffer.empty())
|
||||||
|
{
|
||||||
|
if (!underflow())
|
||||||
{
|
{
|
||||||
while (mBuffer.empty()) {
|
|
||||||
if (!underflow()) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,35 +104,46 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace
|
class OutFile : public __file
|
||||||
{
|
{
|
||||||
struct RegularPrinter
|
protected:
|
||||||
{
|
static constexpr unsigned BUFFER_SIZE = 4096;
|
||||||
void putchar(int chr) noexcept // NOLINT
|
|
||||||
|
baos::RingBuffer<char, BUFFER_SIZE> mWriteBuffer;
|
||||||
|
protected:
|
||||||
|
virtual void overflow() noexcept = 0;
|
||||||
|
public:
|
||||||
|
void putChar(char chr) noexcept
|
||||||
{
|
{
|
||||||
::putchar(chr);
|
while (mWriteBuffer.full()) {
|
||||||
|
overflow();
|
||||||
|
}
|
||||||
|
mWriteBuffer.append(chr);
|
||||||
|
if (chr == '\n')
|
||||||
|
{
|
||||||
|
overflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void putString(std::string_view str) noexcept
|
||||||
|
{
|
||||||
|
for (char chr : str)
|
||||||
|
{
|
||||||
|
putChar(chr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush() noexcept
|
||||||
|
{
|
||||||
|
overflow();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferPrinter
|
class StdinFile : public InFile
|
||||||
{
|
|
||||||
char* pos = nullptr;
|
|
||||||
char* end = nullptr;
|
|
||||||
|
|
||||||
void putchar(int chr) noexcept // NOLINT
|
|
||||||
{
|
|
||||||
if (pos != end)
|
|
||||||
{
|
|
||||||
*pos = static_cast<char>(chr);
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class StdinFile : public __file
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool underflow() noexcept override
|
bool underflow() noexcept override
|
||||||
@ -114,49 +158,52 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class StdoutFile : public OutFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void overflow() noexcept override
|
||||||
|
{
|
||||||
|
std::span<char> chars = mWriteBuffer.getAll();
|
||||||
|
if (!chars.empty())
|
||||||
|
{
|
||||||
|
#if defined(__baos_kernel_source__)
|
||||||
|
serialWriteString(PORT_COM1, chars.data(), chars.size());
|
||||||
|
tty::write(chars.data(), chars.size());
|
||||||
|
#else
|
||||||
|
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, chars.data(), chars.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FilePrinter
|
||||||
|
{
|
||||||
|
OutFile& file;
|
||||||
|
|
||||||
|
void putchar(int chr) noexcept
|
||||||
|
{
|
||||||
|
file.putChar(static_cast<char>(chr));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
StdinFile gStdin;
|
StdinFile gStdin;
|
||||||
|
StdoutFile gStdout;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
FILE* __stdin = &gStdin;
|
FILE* __stdin = &gStdin;
|
||||||
|
FILE* __stdout = &gStdout;
|
||||||
|
|
||||||
// TODO: line-buffering
|
|
||||||
int putchar(int chr) noexcept
|
int putchar(int chr) noexcept
|
||||||
{
|
{
|
||||||
#if defined(__baos_kernel_source__)
|
return fputc(chr, stdout);
|
||||||
tty::putChar(static_cast<char>(chr));
|
|
||||||
if (chr == '\n')
|
|
||||||
{
|
|
||||||
serialWrite(PORT_COM1, '\r');
|
|
||||||
serialWrite(PORT_COM1, '\n');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serialWrite(PORT_COM1, static_cast<std::uint8_t>(chr));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
char asChar = static_cast<char>(chr);
|
|
||||||
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, &asChar, 1);
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int puts(const char* str) noexcept
|
int puts(const char* str) noexcept
|
||||||
{
|
{
|
||||||
#if defined(__baos_kernel_source__)
|
return fputs(str, stdout);
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
putchar(*str);
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
baos::doSyscall(baos::Syscall::FILE_WRITE, 0, str, std::strlen(str));
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int printf(const char* format, ...) noexcept
|
int printf(const char* format, ...) noexcept
|
||||||
@ -168,9 +215,18 @@ int printf(const char* format, ...) noexcept
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT
|
int vprintf(const char* format, va_list vlist) noexcept
|
||||||
{
|
{
|
||||||
return baos::PrintFHelper<RegularPrinter>().vprintf(format, vlist);
|
return vfprintf(stdout, format, vlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf(char* buffer, const char* format, ...) noexcept
|
||||||
|
{
|
||||||
|
va_list parameters;
|
||||||
|
va_start(parameters, format);
|
||||||
|
const int result = vsprintf(buffer, format, parameters);
|
||||||
|
va_end(parameters);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snprintf(char* buffer, size_t bufferSize, const char* format, ...) noexcept
|
int snprintf(char* buffer, size_t bufferSize, const char* format, ...) noexcept
|
||||||
@ -196,6 +252,30 @@ int vsnprintf(char* buffer, size_t bufferSize, const char* format, va_list vlist
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vsprintf(char* buffer, const char* format, va_list vlist) noexcept
|
||||||
|
{
|
||||||
|
BufferPrinter printer{
|
||||||
|
.pos = buffer,
|
||||||
|
.end = std::bit_cast<char*>(std::numeric_limits<std::uintptr_t>::max())
|
||||||
|
};
|
||||||
|
const int length = baos::PrintFHelper(printer).vprintf(format, vlist);
|
||||||
|
buffer[length] = '\0';
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fclose(FILE* stream) noexcept
|
||||||
|
{
|
||||||
|
(void) stream;
|
||||||
|
// TODO: implement
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fflush(FILE* stream) noexcept
|
||||||
|
{
|
||||||
|
static_cast<OutFile*>(stream)->flush();
|
||||||
|
return stream->isError() ? EOF : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int fgetc(FILE* stream) noexcept
|
int fgetc(FILE* stream) noexcept
|
||||||
{
|
{
|
||||||
char chr;
|
char chr;
|
||||||
@ -232,6 +312,32 @@ char* fgets(char* buffer, int count, FILE* stream) noexcept
|
|||||||
buffer[pos] = '\0';
|
buffer[pos] = '\0';
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fprintf(FILE* stream, const char* format, ...) noexcept
|
||||||
|
{
|
||||||
|
va_list parameters;
|
||||||
|
va_start(parameters, format);
|
||||||
|
const int result = vfprintf(stream, format, parameters);
|
||||||
|
va_end(parameters);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputc(int ch, FILE* stream) noexcept
|
||||||
|
{
|
||||||
|
static_cast<OutFile*>(stream)->putChar(static_cast<char>(ch));
|
||||||
|
return stream->isError() ? EOF : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fputs(const char* str, FILE* stream) noexcept
|
||||||
|
{
|
||||||
|
static_cast<OutFile*>(stream)->putString(str);
|
||||||
|
return stream->isError() ? EOF : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfprintf(FILE* stream, const char* format, va_list vlist) noexcept
|
||||||
|
{
|
||||||
|
return baos::PrintFHelper(FilePrinter(*static_cast<OutFile*>(stream))).vprintf(format, vlist);
|
||||||
|
}
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
|
@ -58,6 +58,20 @@ void* memset(void* dest, int value, size_t count) noexcept
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* strchr(const char* str, int ch) noexcept
|
||||||
|
{
|
||||||
|
for (const char* chr = str;; ++chr)
|
||||||
|
{
|
||||||
|
if (*chr == ch) {
|
||||||
|
return const_cast<char*>(chr);
|
||||||
|
}
|
||||||
|
++chr;
|
||||||
|
if (!*chr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t strlen(const char* str) noexcept
|
size_t strlen(const char* str) noexcept
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user