[libc] Bring libc in-tree
Moving libc from its separate repo into this one, minor resulting build fixes, and a hacky way to add -I for libc headers in builds.
This commit is contained in:
178
modules.yaml
178
modules.yaml
@@ -77,6 +77,8 @@ modules:
|
|||||||
kind: exe
|
kind: exe
|
||||||
target: user
|
target: user
|
||||||
output: nulldrv
|
output: nulldrv
|
||||||
|
deps:
|
||||||
|
- libc
|
||||||
source:
|
source:
|
||||||
- src/drivers/nulldrv/main.cpp
|
- src/drivers/nulldrv/main.cpp
|
||||||
- src/drivers/nulldrv/main.s
|
- src/drivers/nulldrv/main.s
|
||||||
@@ -115,6 +117,182 @@ modules:
|
|||||||
- src/libraries/kutil/printf.c
|
- src/libraries/kutil/printf.c
|
||||||
- src/libraries/kutil/vm_space.cpp
|
- src/libraries/kutil/vm_space.cpp
|
||||||
|
|
||||||
|
|
||||||
|
libc:
|
||||||
|
kind: lib
|
||||||
|
output: libc.a
|
||||||
|
includes:
|
||||||
|
- src/libraries/libc/include
|
||||||
|
target: user
|
||||||
|
defines:
|
||||||
|
- DISABLE_SSE
|
||||||
|
- LACKS_UNISTD_H
|
||||||
|
- LACKS_FCNTL_H
|
||||||
|
- LACKS_SYS_PARAM_H
|
||||||
|
- LACKS_SYS_MMAN_H
|
||||||
|
- LACKS_SCHED_H
|
||||||
|
- LACKS_STRINGS_H
|
||||||
|
- HAVE_MMAP=0
|
||||||
|
#- LACKS_STRING_H
|
||||||
|
#- LACKS_ERRNO_H
|
||||||
|
#- LACKS_STDLIB_H
|
||||||
|
#- LACKS_TIME_H
|
||||||
|
source:
|
||||||
|
- src/libraries/libc/arch/x86_64/_Exit.s
|
||||||
|
- src/libraries/libc/ctype/isalnum.c
|
||||||
|
- src/libraries/libc/ctype/isalpha.c
|
||||||
|
- src/libraries/libc/ctype/isblank.c
|
||||||
|
- src/libraries/libc/ctype/iscntrl.c
|
||||||
|
- src/libraries/libc/ctype/isdigit.c
|
||||||
|
- src/libraries/libc/ctype/isgraph.c
|
||||||
|
- src/libraries/libc/ctype/islower.c
|
||||||
|
- src/libraries/libc/ctype/isprint.c
|
||||||
|
- src/libraries/libc/ctype/ispunct.c
|
||||||
|
- src/libraries/libc/ctype/isspace.c
|
||||||
|
- src/libraries/libc/ctype/isupper.c
|
||||||
|
- src/libraries/libc/ctype/isxdigit.c
|
||||||
|
- src/libraries/libc/ctype/tolower.c
|
||||||
|
- src/libraries/libc/ctype/toupper.c
|
||||||
|
- src/libraries/libc/inttypes/imaxabs.c
|
||||||
|
- src/libraries/libc/inttypes/imaxdiv.c
|
||||||
|
- src/libraries/libc/inttypes/strtoimax.c
|
||||||
|
- src/libraries/libc/inttypes/strtoumax.c
|
||||||
|
- src/libraries/libc/locale/localeconv.c
|
||||||
|
- src/libraries/libc/locale/setlocale.c
|
||||||
|
- src/libraries/libc/j6libc/assert.c
|
||||||
|
- src/libraries/libc/j6libc/errno.c
|
||||||
|
- src/libraries/libc/j6libc/allocpages.c
|
||||||
|
- src/libraries/libc/j6libc/atomax.c
|
||||||
|
- src/libraries/libc/j6libc/closeall.c
|
||||||
|
- src/libraries/libc/j6libc/close.c
|
||||||
|
- src/libraries/libc/j6libc/digits.c
|
||||||
|
- src/libraries/libc/j6libc/filemode.c
|
||||||
|
- src/libraries/libc/j6libc/fillbuffer.c
|
||||||
|
- src/libraries/libc/j6libc/flushbuffer.c
|
||||||
|
- src/libraries/libc/j6libc/is_leap.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_collate.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_ctype.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_messages.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_monetary.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_numeric.c
|
||||||
|
- src/libraries/libc/j6libc/load_lc_time.c
|
||||||
|
- src/libraries/libc/j6libc/load_lines.c
|
||||||
|
- src/libraries/libc/j6libc/open.c
|
||||||
|
- src/libraries/libc/j6libc/prepread.c
|
||||||
|
- src/libraries/libc/j6libc/prepwrite.c
|
||||||
|
- src/libraries/libc/j6libc/print.c
|
||||||
|
- src/libraries/libc/j6libc/rename.c
|
||||||
|
- src/libraries/libc/j6libc/scan.c
|
||||||
|
- src/libraries/libc/j6libc/seed.c
|
||||||
|
- src/libraries/libc/j6libc/seek.c
|
||||||
|
- src/libraries/libc/j6libc/stdinit.c
|
||||||
|
- src/libraries/libc/j6libc/strtox_main.c
|
||||||
|
- src/libraries/libc/j6libc/strtox_prelim.c
|
||||||
|
- src/libraries/libc/j6libc/sbrk.c
|
||||||
|
- src/libraries/libc/signal/raise.c
|
||||||
|
- src/libraries/libc/signal/signal.c
|
||||||
|
- src/libraries/libc/stdio/clearerr.c
|
||||||
|
- src/libraries/libc/stdio/fclose.c
|
||||||
|
- src/libraries/libc/stdio/feof.c
|
||||||
|
- src/libraries/libc/stdio/ferror.c
|
||||||
|
- src/libraries/libc/stdio/fflush.c
|
||||||
|
- src/libraries/libc/stdio/fgetc.c
|
||||||
|
- src/libraries/libc/stdio/fgetpos.c
|
||||||
|
- src/libraries/libc/stdio/fgets.c
|
||||||
|
- src/libraries/libc/stdio/fopen.c
|
||||||
|
- src/libraries/libc/stdio/fprintf.c
|
||||||
|
- src/libraries/libc/stdio/fputc.c
|
||||||
|
- src/libraries/libc/stdio/fputs.c
|
||||||
|
- src/libraries/libc/stdio/fread.c
|
||||||
|
- src/libraries/libc/stdio/freopen.c
|
||||||
|
- src/libraries/libc/stdio/fscanf.c
|
||||||
|
- src/libraries/libc/stdio/fseek.c
|
||||||
|
- src/libraries/libc/stdio/fsetpos.c
|
||||||
|
- src/libraries/libc/stdio/ftell.c
|
||||||
|
- src/libraries/libc/stdio/fwrite.c
|
||||||
|
- src/libraries/libc/stdio/getc.c
|
||||||
|
- src/libraries/libc/stdio/getchar.c
|
||||||
|
- src/libraries/libc/stdio/perror.c
|
||||||
|
- src/libraries/libc/stdio/printf.c
|
||||||
|
- src/libraries/libc/stdio/putc.c
|
||||||
|
- src/libraries/libc/stdio/putchar.c
|
||||||
|
- src/libraries/libc/stdio/puts.c
|
||||||
|
- src/libraries/libc/stdio/remove.c
|
||||||
|
- src/libraries/libc/stdio/rename.c
|
||||||
|
- src/libraries/libc/stdio/rewind.c
|
||||||
|
- src/libraries/libc/stdio/scanf.c
|
||||||
|
- src/libraries/libc/stdio/setbuf.c
|
||||||
|
- src/libraries/libc/stdio/setvbuf.c
|
||||||
|
- src/libraries/libc/stdio/snprintf.c
|
||||||
|
- src/libraries/libc/stdio/sprintf.c
|
||||||
|
- src/libraries/libc/stdio/sscanf.c
|
||||||
|
- src/libraries/libc/stdio/tmpfile.c
|
||||||
|
- src/libraries/libc/stdio/tmpnam.c
|
||||||
|
- src/libraries/libc/stdio/ungetc.c
|
||||||
|
- src/libraries/libc/stdio/vfprintf.c
|
||||||
|
- src/libraries/libc/stdio/vfscanf.c
|
||||||
|
- src/libraries/libc/stdio/vprintf.c
|
||||||
|
- src/libraries/libc/stdio/vscanf.c
|
||||||
|
- src/libraries/libc/stdio/vsnprintf.c
|
||||||
|
- src/libraries/libc/stdio/vsprintf.c
|
||||||
|
- src/libraries/libc/stdio/vsscanf.c
|
||||||
|
- src/libraries/libc/stdlib/abort.c
|
||||||
|
- src/libraries/libc/stdlib/abs.c
|
||||||
|
- src/libraries/libc/stdlib/atexit.c
|
||||||
|
- src/libraries/libc/stdlib/atoi.c
|
||||||
|
- src/libraries/libc/stdlib/atol.c
|
||||||
|
- src/libraries/libc/stdlib/atoll.c
|
||||||
|
- src/libraries/libc/stdlib/bsearch.c
|
||||||
|
- src/libraries/libc/stdlib/div.c
|
||||||
|
- src/libraries/libc/stdlib/exit.c
|
||||||
|
- src/libraries/libc/stdlib/_Exit.c
|
||||||
|
- src/libraries/libc/stdlib/getenv.c
|
||||||
|
- src/libraries/libc/stdlib/labs.c
|
||||||
|
- src/libraries/libc/stdlib/ldiv.c
|
||||||
|
- src/libraries/libc/stdlib/llabs.c
|
||||||
|
- src/libraries/libc/stdlib/lldiv.c
|
||||||
|
- src/libraries/libc/stdlib/malloc.c
|
||||||
|
- src/libraries/libc/stdlib/qsort.c
|
||||||
|
- src/libraries/libc/stdlib/rand.c
|
||||||
|
- src/libraries/libc/stdlib/srand.c
|
||||||
|
- src/libraries/libc/stdlib/strtol.c
|
||||||
|
- src/libraries/libc/stdlib/strtoll.c
|
||||||
|
- src/libraries/libc/stdlib/strtoul.c
|
||||||
|
- src/libraries/libc/stdlib/strtoull.c
|
||||||
|
- src/libraries/libc/stdlib/system.c
|
||||||
|
- src/libraries/libc/string/memchr.c
|
||||||
|
- src/libraries/libc/string/memcmp.c
|
||||||
|
- src/libraries/libc/string/memcpy.c
|
||||||
|
- src/libraries/libc/string/memmove.c
|
||||||
|
- src/libraries/libc/string/memset.c
|
||||||
|
- src/libraries/libc/string/strcat.c
|
||||||
|
- src/libraries/libc/string/strchr.c
|
||||||
|
- src/libraries/libc/string/strcmp.c
|
||||||
|
- src/libraries/libc/string/strcoll.c
|
||||||
|
- src/libraries/libc/string/strcpy.c
|
||||||
|
- src/libraries/libc/string/strcspn.c
|
||||||
|
- src/libraries/libc/string/strerror.c
|
||||||
|
- src/libraries/libc/string/strlen.c
|
||||||
|
- src/libraries/libc/string/strncat.c
|
||||||
|
- src/libraries/libc/string/strncmp.c
|
||||||
|
- src/libraries/libc/string/strncpy.c
|
||||||
|
- src/libraries/libc/string/strpbrk.c
|
||||||
|
- src/libraries/libc/string/strrchr.c
|
||||||
|
- src/libraries/libc/string/strspn.c
|
||||||
|
- src/libraries/libc/string/strstr.c
|
||||||
|
- src/libraries/libc/string/strtok.c
|
||||||
|
- src/libraries/libc/string/strxfrm.c
|
||||||
|
- src/libraries/libc/time/asctime.c
|
||||||
|
- src/libraries/libc/time/clock.c
|
||||||
|
- src/libraries/libc/time/ctime.c
|
||||||
|
- src/libraries/libc/time/difftime.c
|
||||||
|
- src/libraries/libc/time/gmtime.c
|
||||||
|
- src/libraries/libc/time/localtime.c
|
||||||
|
- src/libraries/libc/time/mktime.c
|
||||||
|
- src/libraries/libc/time/strftime.c
|
||||||
|
- src/libraries/libc/time/time.c
|
||||||
|
- src/libraries/libc/time/timespec_get.c
|
||||||
|
|
||||||
makerd:
|
makerd:
|
||||||
kind: exe
|
kind: exe
|
||||||
target: native
|
target: native
|
||||||
|
|||||||
@@ -22,5 +22,10 @@ build ${builddir}/cpp.defs : dump_cpp_defs | {{ buildfile }}
|
|||||||
build ${builddir}/c.run : dump_c_run | {{ buildfile }}
|
build ${builddir}/c.run : dump_c_run | {{ buildfile }}
|
||||||
build ${builddir}/cpp.run : dump_cpp_run | {{ buildfile }}
|
build ${builddir}/cpp.run : dump_cpp_run | {{ buildfile }}
|
||||||
|
|
||||||
|
default ${builddir}/c.defs
|
||||||
|
default ${builddir}/cpp.defs
|
||||||
|
default ${builddir}/c.run
|
||||||
|
default ${builddir}/cpp.run
|
||||||
|
|
||||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ ccflags = $ccflags $
|
|||||||
-D__ELF__ $
|
-D__ELF__ $
|
||||||
-D__JSIX__ $
|
-D__JSIX__ $
|
||||||
-isystem${srcroot}/sysroot/include $
|
-isystem${srcroot}/sysroot/include $
|
||||||
|
-isystem${srcroot}/src/libraries/libc/include $
|
||||||
--sysroot="${srcroot}/sysroot"
|
--sysroot="${srcroot}/sysroot"
|
||||||
|
|
||||||
cxxflags = $cxxflags $
|
cxxflags = $cxxflags $
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ ccflags = $ccflags $
|
|||||||
-D__ELF__ $
|
-D__ELF__ $
|
||||||
-D__JSIX__ $
|
-D__JSIX__ $
|
||||||
-isystem${srcroot}/sysroot/include $
|
-isystem${srcroot}/sysroot/include $
|
||||||
|
-isystem${srcroot}/src/libraries/libc/include $
|
||||||
--sysroot="${srcroot}/sysroot"
|
--sysroot="${srcroot}/sysroot"
|
||||||
|
|
||||||
cxxflags = $cxxflags $
|
cxxflags = $cxxflags $
|
||||||
@@ -38,9 +39,6 @@ ldflags = $ldflags $
|
|||||||
--sysroot="${srcroot}/sysroot" $
|
--sysroot="${srcroot}/sysroot" $
|
||||||
-L "${srcroot}/sysroot/lib" $
|
-L "${srcroot}/sysroot/lib" $
|
||||||
|
|
||||||
libs = $libs $
|
|
||||||
-lc
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
# vim: ft=ninja et ts=4 sts=4 sw=4
|
# vim: ft=ninja et ts=4 sts=4 sw=4
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <algorithm>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ void console::put_hex(T x, int width, char pad)
|
|||||||
int len = 1;
|
int len = 1;
|
||||||
for (int i = chars - 1; i >= 0; --i) {
|
for (int i = chars - 1; i >= 0; --i) {
|
||||||
uint8_t nibble = (x >> (i*4)) & 0xf;
|
uint8_t nibble = (x >> (i*4)) & 0xf;
|
||||||
if (nibble) len = std::max(i + 1, len);
|
if (nibble) len = len > i + 1 ? len : i + 1;
|
||||||
message[chars - i - 1] = digits[nibble];
|
message[chars - i - 1] = digits[nibble];
|
||||||
}
|
}
|
||||||
message[chars] = 0;
|
message[chars] = 0;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#include <algorithm>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "kernel_args.h"
|
#include "kernel_args.h"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "kutil/assert.h"
|
#include "kutil/assert.h"
|
||||||
#include "kutil/vm_space.h"
|
#include "kutil/vm_space.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
/// \file avl_tree.h
|
/// \file avl_tree.h
|
||||||
/// Templated container class for an AVL tree
|
/// Templated container class for an AVL tree
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "kutil/assert.h"
|
#include "kutil/assert.h"
|
||||||
#include "kutil/slab_allocated.h"
|
#include "kutil/slab_allocated.h"
|
||||||
@@ -72,7 +71,7 @@ private:
|
|||||||
{
|
{
|
||||||
int left = height(m_left);
|
int left = height(m_left);
|
||||||
int right = height(m_right);
|
int right = height(m_right);
|
||||||
m_height = std::max(left, right) + 1;
|
m_height = left > right ? left : right;
|
||||||
return left - right;
|
return left - right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
/// \file vector.h
|
/// \file vector.h
|
||||||
/// Definition of a simple dynamic vector collection for use in kernel space
|
/// Definition of a simple dynamic vector collection for use in kernel space
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "kutil/memory.h"
|
#include "kutil/memory.h"
|
||||||
|
|
||||||
@@ -175,7 +174,7 @@ public:
|
|||||||
void set_capacity(size_t capacity)
|
void set_capacity(size_t capacity)
|
||||||
{
|
{
|
||||||
T *new_array = reinterpret_cast<T*>(kalloc(capacity * sizeof(T)));
|
T *new_array = reinterpret_cast<T*>(kalloc(capacity * sizeof(T)));
|
||||||
size_t size = std::min(capacity, m_size);
|
size_t size = capacity > m_size ? m_size : capacity;
|
||||||
|
|
||||||
kutil::memcpy(new_array, m_elements, size * sizeof(T));
|
kutil::memcpy(new_array, m_elements, size * sizeof(T));
|
||||||
|
|
||||||
|
|||||||
5
src/libraries/libc/arch/x86_64/_Exit.s
Normal file
5
src/libraries/libc/arch/x86_64/_Exit.s
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
global _PDCLIB_Exit
|
||||||
|
_PDCLIB_Exit:
|
||||||
|
; arg should already be in rdi
|
||||||
|
mov rax, 0x11 ; Exit syscall
|
||||||
|
syscall
|
||||||
13
src/libraries/libc/ctype/isalnum.c
Normal file
13
src/libraries/libc/ctype/isalnum.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isalnum( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isalnum( int c )
|
||||||
|
{
|
||||||
|
return ( isdigit( c ) || isalpha( c ) );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isalpha.c
Normal file
13
src/libraries/libc/ctype/isalpha.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isalpha( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isalpha( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_ALPHA );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isblank.c
Normal file
13
src/libraries/libc/ctype/isblank.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isblank( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isblank( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_BLANK );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/iscntrl.c
Normal file
13
src/libraries/libc/ctype/iscntrl.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* iscntrl( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int iscntrl( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_CNTRL );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isdigit.c
Normal file
13
src/libraries/libc/ctype/isdigit.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isdigit( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isdigit( int c )
|
||||||
|
{
|
||||||
|
return ( c >= _PDCLIB_lc_ctype.digits_low && c <= _PDCLIB_lc_ctype.digits_high );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isgraph.c
Normal file
13
src/libraries/libc/ctype/isgraph.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isgraph( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isgraph( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_GRAPH );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/islower.c
Normal file
13
src/libraries/libc/ctype/islower.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* islower( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int islower( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_LOWER );
|
||||||
|
}
|
||||||
14
src/libraries/libc/ctype/isprint.c
Normal file
14
src/libraries/libc/ctype/isprint.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* isprint( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isprint( int c )
|
||||||
|
{
|
||||||
|
/* FIXME: Space as of current locale charset, not source charset. */
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/ispunct.c
Normal file
13
src/libraries/libc/ctype/ispunct.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* ispunct( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int ispunct( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_PUNCT );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isspace.c
Normal file
13
src/libraries/libc/ctype/isspace.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isspace( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isspace( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_SPACE );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/isupper.c
Normal file
13
src/libraries/libc/ctype/isupper.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* isupper( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isupper( int c )
|
||||||
|
{
|
||||||
|
return ( _PDCLIB_lc_ctype.entry[c].flags & _PDCLIB_CTYPE_UPPER );
|
||||||
|
}
|
||||||
15
src/libraries/libc/ctype/isxdigit.c
Normal file
15
src/libraries/libc/ctype/isxdigit.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* isxdigit( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int isxdigit( int c )
|
||||||
|
{
|
||||||
|
return ( isdigit( c )
|
||||||
|
|| ( c >= _PDCLIB_lc_ctype.Xdigits_low && c <= _PDCLIB_lc_ctype.Xdigits_high )
|
||||||
|
|| ( c >= _PDCLIB_lc_ctype.xdigits_low && c <= _PDCLIB_lc_ctype.xdigits_high ) );
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/tolower.c
Normal file
13
src/libraries/libc/ctype/tolower.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* tolower( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int tolower( int c )
|
||||||
|
{
|
||||||
|
return _PDCLIB_lc_ctype.entry[c].lower;
|
||||||
|
}
|
||||||
13
src/libraries/libc/ctype/toupper.c
Normal file
13
src/libraries/libc/ctype/toupper.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/* toupper( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int toupper( int c )
|
||||||
|
{
|
||||||
|
return _PDCLIB_lc_ctype.entry[c].upper;
|
||||||
|
}
|
||||||
29
src/libraries/libc/include/assert.h
Normal file
29
src/libraries/libc/include/assert.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Diagnostics <assert.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/aux.h"
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
void _PDCLIB_assert( const char * const, const char * const, const char * const );
|
||||||
|
|
||||||
|
/* If NDEBUG is set, assert() is a null operation. */
|
||||||
|
#undef assert
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define assert( ignore ) ( (void) 0 )
|
||||||
|
#else
|
||||||
|
#define assert( expression ) ( ( expression ) ? (void) 0 \
|
||||||
|
: _PDCLIB_assert( "Assertion failed: " #expression \
|
||||||
|
", function ", __func__, \
|
||||||
|
", file " __FILE__ \
|
||||||
|
", line " _PDCLIB_symbol2string( __LINE__ ) \
|
||||||
|
"." _PDCLIB_endl ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
96
src/libraries/libc/include/ctype.h
Normal file
96
src/libraries/libc/include/ctype.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Character handling <ctype.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* Character classification functions */
|
||||||
|
|
||||||
|
/* Note that there is a difference between "whitespace" (any printing, non-
|
||||||
|
graph character, like horizontal and vertical tab), and "blank" (the literal
|
||||||
|
' ' space character).
|
||||||
|
|
||||||
|
There will be masking macros for each of these later on, but right now I
|
||||||
|
focus on the functions only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Returns isalpha( c ) || isdigit( c ) */
|
||||||
|
int isalnum( int c );
|
||||||
|
|
||||||
|
/* Returns isupper( c ) || islower( c ) in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
alphabetic characters which are neither control characters, digits,
|
||||||
|
punctation, or whitespace.
|
||||||
|
*/
|
||||||
|
int isalpha( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character isspace() and used for seperating words within
|
||||||
|
a line of text. In the "C" locale, only ' ' and '\t' are considered blanks.
|
||||||
|
*/
|
||||||
|
int isblank( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character is a control character. */
|
||||||
|
int iscntrl( int c );
|
||||||
|
|
||||||
|
/* Returns true if the character is a decimal digit. Locale-independent. */
|
||||||
|
int isdigit( int c );
|
||||||
|
|
||||||
|
/* Returns true for every printing character except space (' ').
|
||||||
|
NOTE: This definition differs from that of iswgraph() in <wctype.h>,
|
||||||
|
which considers any iswspace() character, not only ' '.
|
||||||
|
*/
|
||||||
|
int isgraph( int c );
|
||||||
|
|
||||||
|
/* Returns true for lowercase letters in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
characters which are neither control characters, digits, punctation, or
|
||||||
|
space (' '). In a locale other than the "C" locale, a character might test
|
||||||
|
true for both islower() and isupper().
|
||||||
|
*/
|
||||||
|
int islower( int c );
|
||||||
|
|
||||||
|
/* Returns true for every printing character including space (' '). */
|
||||||
|
int isprint( int c );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of punctuation charcters; these
|
||||||
|
may not be whitespace or alphanumeric. In the "C" locale, returns true
|
||||||
|
for every printing character that is not whitespace or alphanumeric.
|
||||||
|
*/
|
||||||
|
int ispunct( int c );
|
||||||
|
|
||||||
|
/* Returns true for every standard whitespace character (' ', '\f', '\n', '\r',
|
||||||
|
'\t', '\v') in the "C" locale. In any other locale, also returns true for a
|
||||||
|
locale-specific set of characters for which isalnum() is false.
|
||||||
|
*/
|
||||||
|
int isspace( int c );
|
||||||
|
|
||||||
|
/* Returns true for uppercase letters in the "C" locale.
|
||||||
|
In any other locale, also returns true for a locale-specific set of
|
||||||
|
characters which are neither control characters, digits, punctation, or
|
||||||
|
space (' '). In a locale other than the "C" locale, a character might test
|
||||||
|
true for both islower() and isupper().
|
||||||
|
*/
|
||||||
|
int isupper( int c );
|
||||||
|
|
||||||
|
/* Returns true for any hexadecimal-digit character. Locale-independent. */
|
||||||
|
int isxdigit( int c );
|
||||||
|
|
||||||
|
/* Character case mapping functions */
|
||||||
|
|
||||||
|
/* Converts an uppercase letter to a corresponding lowercase letter. Input that
|
||||||
|
is not an uppercase letter remains unchanged.
|
||||||
|
*/
|
||||||
|
int tolower( int c );
|
||||||
|
|
||||||
|
/* Converts a lowercase letter to a corresponding uppercase letter. Input that
|
||||||
|
is not a lowercase letter remains unchanged.
|
||||||
|
*/
|
||||||
|
int toupper( int c );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
15
src/libraries/libc/include/errno.h
Normal file
15
src/libraries/libc/include/errno.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Errors <errno.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
#define errno (*_PDCLIB_errno_func())
|
||||||
|
|
||||||
|
#define ERANGE _PDCLIB_ERANGE
|
||||||
|
#define EDOM _PDCLIB_EDOM
|
||||||
|
#define ENOMEM _PDCLIB_ENOMEM
|
||||||
|
#define EINVAL _PDCLIB_EINVAL
|
||||||
71
src/libraries/libc/include/float.h
Normal file
71
src/libraries/libc/include/float.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Characteristics of floating types <float.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/config.h"
|
||||||
|
|
||||||
|
#define FLT_ROUNDS _PDCLIB_FLT_ROUNDS
|
||||||
|
#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD
|
||||||
|
#define DECIMAL_DIG _PDCLIB_DECIMAL_DIG
|
||||||
|
|
||||||
|
/* Radix of exponent representation */
|
||||||
|
#define FLT_RADIX __FLT_RADIX__
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a float */
|
||||||
|
#define FLT_MANT_DIG __FLT_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a float */
|
||||||
|
#define FLT_DIG __FLT_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum float greater than 1.0 */
|
||||||
|
#define FLT_EPSILON __FLT_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
|
||||||
|
#define FLT_MIN_EXP __FLT_MIN_EXP__
|
||||||
|
/* Minimum normalised float */
|
||||||
|
#define FLT_MIN __FLT_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised float */
|
||||||
|
#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
|
||||||
|
#define FLT_MAX_EXP __FLT_MAX_EXP__
|
||||||
|
/* Maximum float */
|
||||||
|
#define FLT_MAX __FLT_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable float */
|
||||||
|
#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
|
||||||
|
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a double */
|
||||||
|
#define DBL_MANT_DIG __DBL_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a double */
|
||||||
|
#define DBL_DIG __DBL_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum double greater than 1.0 */
|
||||||
|
#define DBL_EPSILON __DBL_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
|
||||||
|
#define DBL_MIN_EXP __DBL_MIN_EXP__
|
||||||
|
/* Minimum normalised double */
|
||||||
|
#define DBL_MIN __DBL_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised double */
|
||||||
|
#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
|
||||||
|
#define DBL_MAX_EXP __DBL_MAX_EXP__
|
||||||
|
/* Maximum double */
|
||||||
|
#define DBL_MAX __DBL_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable double */
|
||||||
|
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
||||||
|
|
||||||
|
/* Number of base-FLT_RADIX digits in the significand of a long double */
|
||||||
|
#define LDBL_MANT_DIG __LDBL_MANT_DIG__
|
||||||
|
/* Number of decimal digits of precision in a long double */
|
||||||
|
#define LDBL_DIG __LDBL_DIG__
|
||||||
|
/* Difference between 1.0 and the minimum long double greater than 1.0 */
|
||||||
|
#define LDBL_EPSILON __LDBL_EPSILON__
|
||||||
|
/* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
|
||||||
|
#define LDBL_MIN_EXP __LDBL_MIN_EXP__
|
||||||
|
/* Minimum normalised long double */
|
||||||
|
#define LDBL_MIN __LDBL_MIN__
|
||||||
|
/* Minimum int x such that 10**x is a normalised long double */
|
||||||
|
#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
|
||||||
|
/* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
|
||||||
|
#define LDBL_MAX_EXP __LDBL_MAX_EXP__
|
||||||
|
/* Maximum long double */
|
||||||
|
#define LDBL_MAX __LDBL_MAX__
|
||||||
|
/* Maximum int x such that 10**x is a representable long double */
|
||||||
|
#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
|
||||||
250
src/libraries/libc/include/inttypes.h
Normal file
250
src/libraries/libc/include/inttypes.h
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Format conversion of integer types <inttypes.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
typedef struct _PDCLIB_imaxdiv_t imaxdiv_t;
|
||||||
|
|
||||||
|
#define PRId8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
|
||||||
|
#define PRId16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
|
||||||
|
#define PRId32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
|
||||||
|
#define PRId64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
|
||||||
|
|
||||||
|
#define PRIdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
|
||||||
|
#define PRIdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
|
||||||
|
#define PRIdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
|
||||||
|
#define PRIdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
|
||||||
|
|
||||||
|
#define PRIdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) )
|
||||||
|
#define PRIdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) )
|
||||||
|
#define PRIdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) )
|
||||||
|
#define PRIdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) )
|
||||||
|
|
||||||
|
#define PRIdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) )
|
||||||
|
#define PRIdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) )
|
||||||
|
|
||||||
|
#define PRIi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
|
||||||
|
#define PRIi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
|
||||||
|
#define PRIi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
|
||||||
|
#define PRIi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
|
||||||
|
|
||||||
|
#define PRIiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
|
||||||
|
#define PRIiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
|
||||||
|
#define PRIiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
|
||||||
|
#define PRIiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
|
||||||
|
|
||||||
|
#define PRIiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) )
|
||||||
|
#define PRIiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) )
|
||||||
|
#define PRIiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) )
|
||||||
|
#define PRIiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) )
|
||||||
|
|
||||||
|
#define PRIiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) )
|
||||||
|
#define PRIiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) )
|
||||||
|
|
||||||
|
#define PRIo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
|
||||||
|
#define PRIo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
|
||||||
|
#define PRIo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
|
||||||
|
#define PRIo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
|
||||||
|
|
||||||
|
#define PRIoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
|
||||||
|
#define PRIoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
|
||||||
|
#define PRIoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
|
||||||
|
#define PRIoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
|
||||||
|
|
||||||
|
#define PRIoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) )
|
||||||
|
#define PRIoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) )
|
||||||
|
#define PRIoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) )
|
||||||
|
#define PRIoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) )
|
||||||
|
|
||||||
|
#define PRIoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) )
|
||||||
|
#define PRIoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) )
|
||||||
|
|
||||||
|
#define PRIu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
|
||||||
|
#define PRIu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
|
||||||
|
#define PRIu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
|
||||||
|
#define PRIu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
|
||||||
|
|
||||||
|
#define PRIuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
|
||||||
|
#define PRIuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
|
||||||
|
#define PRIuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
|
||||||
|
#define PRIuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
|
||||||
|
|
||||||
|
#define PRIuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) )
|
||||||
|
#define PRIuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) )
|
||||||
|
#define PRIuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) )
|
||||||
|
#define PRIuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) )
|
||||||
|
|
||||||
|
#define PRIuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) )
|
||||||
|
#define PRIuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) )
|
||||||
|
|
||||||
|
#define PRIx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
|
||||||
|
#define PRIx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
|
||||||
|
#define PRIx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
|
||||||
|
#define PRIx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
|
||||||
|
|
||||||
|
#define PRIxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
|
||||||
|
#define PRIxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
|
||||||
|
#define PRIxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
|
||||||
|
#define PRIxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
|
||||||
|
|
||||||
|
#define PRIxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) )
|
||||||
|
#define PRIxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) )
|
||||||
|
#define PRIxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) )
|
||||||
|
#define PRIxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) )
|
||||||
|
|
||||||
|
#define PRIxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) )
|
||||||
|
#define PRIxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) )
|
||||||
|
|
||||||
|
#define PRIX8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) )
|
||||||
|
#define PRIX16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) )
|
||||||
|
#define PRIX32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) )
|
||||||
|
#define PRIX64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) )
|
||||||
|
|
||||||
|
#define PRIXLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, X ) )
|
||||||
|
#define PRIXLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, X ) )
|
||||||
|
#define PRIXLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, X ) )
|
||||||
|
#define PRIXLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, X ) )
|
||||||
|
|
||||||
|
#define PRIXFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, X ) )
|
||||||
|
#define PRIXFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, X ) )
|
||||||
|
#define PRIXFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, X ) )
|
||||||
|
#define PRIXFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, X ) )
|
||||||
|
|
||||||
|
#define PRIXMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, X ) )
|
||||||
|
#define PRIXPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, X ) )
|
||||||
|
|
||||||
|
#define SCNd8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
|
||||||
|
#define SCNd16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
|
||||||
|
#define SCNd32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
|
||||||
|
#define SCNd64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
|
||||||
|
|
||||||
|
#define SCNdLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, d ) )
|
||||||
|
#define SCNdLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, d ) )
|
||||||
|
#define SCNdLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, d ) )
|
||||||
|
#define SCNdLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, d ) )
|
||||||
|
|
||||||
|
#define SCNdFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, d ) )
|
||||||
|
#define SCNdFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, d ) )
|
||||||
|
#define SCNdFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, d ) )
|
||||||
|
#define SCNdFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, d ) )
|
||||||
|
|
||||||
|
#define SCNdMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, d ) )
|
||||||
|
#define SCNdPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, d ) )
|
||||||
|
|
||||||
|
#define SCNi8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
|
||||||
|
#define SCNi16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
|
||||||
|
#define SCNi32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
|
||||||
|
#define SCNi64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
|
||||||
|
|
||||||
|
#define SCNiLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, i ) )
|
||||||
|
#define SCNiLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, i ) )
|
||||||
|
#define SCNiLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, i ) )
|
||||||
|
#define SCNiLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, i ) )
|
||||||
|
|
||||||
|
#define SCNiFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, i ) )
|
||||||
|
#define SCNiFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, i ) )
|
||||||
|
#define SCNiFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, i ) )
|
||||||
|
#define SCNiFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, i ) )
|
||||||
|
|
||||||
|
#define SCNiMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, i ) )
|
||||||
|
#define SCNiPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, i ) )
|
||||||
|
|
||||||
|
#define SCNo8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
|
||||||
|
#define SCNo16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
|
||||||
|
#define SCNo32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
|
||||||
|
#define SCNo64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
|
||||||
|
|
||||||
|
#define SCNoLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, o ) )
|
||||||
|
#define SCNoLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, o ) )
|
||||||
|
#define SCNoLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, o ) )
|
||||||
|
#define SCNoLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, o ) )
|
||||||
|
|
||||||
|
#define SCNoFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, o ) )
|
||||||
|
#define SCNoFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, o ) )
|
||||||
|
#define SCNoFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, o ) )
|
||||||
|
#define SCNoFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, o ) )
|
||||||
|
|
||||||
|
#define SCNoMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, o ) )
|
||||||
|
#define SCNoPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, o ) )
|
||||||
|
|
||||||
|
#define SCNu8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
|
||||||
|
#define SCNu16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
|
||||||
|
#define SCNu32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
|
||||||
|
#define SCNu64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
|
||||||
|
|
||||||
|
#define SCNuLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, u ) )
|
||||||
|
#define SCNuLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, u ) )
|
||||||
|
#define SCNuLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, u ) )
|
||||||
|
#define SCNuLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, u ) )
|
||||||
|
|
||||||
|
#define SCNuFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, u ) )
|
||||||
|
#define SCNuFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, u ) )
|
||||||
|
#define SCNuFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, u ) )
|
||||||
|
#define SCNuFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, u ) )
|
||||||
|
|
||||||
|
#define SCNuMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, u ) )
|
||||||
|
#define SCNuPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, u ) )
|
||||||
|
|
||||||
|
#define SCNx8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
|
||||||
|
#define SCNx16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
|
||||||
|
#define SCNx32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
|
||||||
|
#define SCNx64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
|
||||||
|
|
||||||
|
#define SCNxLEAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_8_CONV, x ) )
|
||||||
|
#define SCNxLEAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_16_CONV, x ) )
|
||||||
|
#define SCNxLEAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_32_CONV, x ) )
|
||||||
|
#define SCNxLEAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_64_CONV, x ) )
|
||||||
|
|
||||||
|
#define SCNxFAST8 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST8_CONV, x ) )
|
||||||
|
#define SCNxFAST16 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST16_CONV, x ) )
|
||||||
|
#define SCNxFAST32 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST32_CONV, x ) )
|
||||||
|
#define SCNxFAST64 _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_FAST64_CONV, x ) )
|
||||||
|
|
||||||
|
#define SCNxMAX _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_MAX_CONV, x ) )
|
||||||
|
#define SCNxPTR _PDCLIB_symbol2string( _PDCLIB_concat( _PDCLIB_PTR_CONV, x ) )
|
||||||
|
|
||||||
|
/* 7.8.2 Functions for greatest-width integer types */
|
||||||
|
|
||||||
|
/* Calculate the absolute value of j */
|
||||||
|
intmax_t imaxabs( intmax_t j );
|
||||||
|
|
||||||
|
/* Return quotient (quot) and remainder (rem) of an integer division in the
|
||||||
|
imaxdiv_t struct.
|
||||||
|
*/
|
||||||
|
imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom );
|
||||||
|
|
||||||
|
/* Seperate the character array nptr into three parts: A (possibly empty)
|
||||||
|
sequence of whitespace characters, a character representation of an integer
|
||||||
|
to the given base, and trailing invalid characters (including the terminating
|
||||||
|
null character). If base is 0, assume it to be 10, unless the integer
|
||||||
|
representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
|
||||||
|
8). If given, base can be anything from 0 to 36, using the 26 letters of the
|
||||||
|
base alphabet (both lowercase and uppercase) as digits 10 through 35.
|
||||||
|
The integer representation is then converted into the return type of the
|
||||||
|
function. It can start with a '+' or '-' sign. If the sign is '-', the result
|
||||||
|
of the conversion is negated.
|
||||||
|
If the conversion is successful, the converted value is returned. If endptr
|
||||||
|
is not a NULL pointer, a pointer to the first trailing invalid character is
|
||||||
|
returned in *endptr.
|
||||||
|
If no conversion could be performed, zero is returned (and nptr in *endptr,
|
||||||
|
if endptr is not a NULL pointer). If the converted value does not fit into
|
||||||
|
the return type, the functions return INTMAX_MIN, INTMAX_MAX, or UINTMAX_MAX,
|
||||||
|
respectively, depending on the sign of the integer representation and the
|
||||||
|
return type, and errno is set to ERANGE.
|
||||||
|
*/
|
||||||
|
/* This function is equivalent to strtol() / strtoul() in <stdlib.h>, but on
|
||||||
|
the potentially larger type.
|
||||||
|
*/
|
||||||
|
intmax_t strtoimax( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
uintmax_t strtoumax( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
|
||||||
|
/* TODO: wcstoimax(), wcstoumax() */
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
18
src/libraries/libc/include/iso646.h
Normal file
18
src/libraries/libc/include/iso646.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Alternative spellings <iso646.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define and &&
|
||||||
|
#define and_eq &=
|
||||||
|
#define bitand &
|
||||||
|
#define bitor |
|
||||||
|
#define compl ~
|
||||||
|
#define not !
|
||||||
|
#define not_eq !=
|
||||||
|
#define or ||
|
||||||
|
#define or_eq |=
|
||||||
|
#define xor ^
|
||||||
|
#define xor_eq ^=
|
||||||
57
src/libraries/libc/include/j6libc/aux.h
Normal file
57
src/libraries/libc/include/j6libc/aux.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Auxiliary PDCLib code <aux.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* You should not have to edit anything in this file; if you DO have to, it */
|
||||||
|
/* would be considered a bug / missing feature: notify the author(s). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Standard Version */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Many a compiler gets this wrong, so you might have to hardcode it instead. */
|
||||||
|
|
||||||
|
#if __STDC__ != 1
|
||||||
|
#error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define restrict __restrict__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __STDC_HOSTED__
|
||||||
|
#error Compiler does not define _ _STDC_HOSTED_ _ (not standard-compliant)!
|
||||||
|
#elif __STDC_HOSTED__ == 0
|
||||||
|
#define _PDCLIB_HOSTED 0
|
||||||
|
#elif __STDC_HOSTED__ == 1
|
||||||
|
#define _PDCLIB_HOSTED 1
|
||||||
|
#else
|
||||||
|
#error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Helper macros: */
|
||||||
|
/* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending */
|
||||||
|
/* _PDCLIB_concat( x, y ) concatenates two preprocessor tokens with extending */
|
||||||
|
/* _PDCLIB_static_assert( e, m ) does a compile-time assertion of expression */
|
||||||
|
/* e, with m as the failure message. */
|
||||||
|
/* _PDCLIB_TYPE_SIGNED( type ) resolves to true if type is signed. */
|
||||||
|
/* _PDCLIB_TWOS_COMPLEMENT( type ) resolves to true if two's complement is */
|
||||||
|
/* used for type. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define _PDCLIB_cc( x, y ) x ## y
|
||||||
|
#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
|
||||||
|
|
||||||
|
#define _PDCLIB_static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
|
||||||
|
|
||||||
|
#define _PDCLIB_TYPE_SIGNED( type ) (((type) -1) < 0)
|
||||||
|
#define _PDCLIB_TWOS_COMPLEMENT( type ) ((type) ~ (type) 0 < 0 )
|
||||||
|
|
||||||
|
#define _PDCLIB_symbol2value( x ) #x
|
||||||
|
#define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
|
||||||
336
src/libraries/libc/include/j6libc/config.h
Normal file
336
src/libraries/libc/include/j6libc/config.h
Normal file
@@ -0,0 +1,336 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Internal PDCLib configuration <config.h>
|
||||||
|
(Generic Template)
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <j6libc/int_widths.h>
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Misc */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The character (sequence) your platform uses as newline. */
|
||||||
|
#define _PDCLIB_endl "\n"
|
||||||
|
|
||||||
|
/* exit() can signal success to the host environment by the value of zero or */
|
||||||
|
/* the constant EXIT_SUCCESS. Failure is signaled by EXIT_FAILURE. Note that */
|
||||||
|
/* any other return value is "implementation-defined", i.e. your environment */
|
||||||
|
/* is not required to handle it gracefully. Set your definitions here. */
|
||||||
|
#define _PDCLIB_SUCCESS 0
|
||||||
|
#define _PDCLIB_FAILURE -1
|
||||||
|
|
||||||
|
/* qsort() in <stdlib.h> requires a function that swaps two memory areas. */
|
||||||
|
/* Below is a naive implementation that can be improved significantly for */
|
||||||
|
/* specific platforms, e.g. by swapping int instead of char. */
|
||||||
|
#define _PDCLIB_memswp( i, j, size ) char tmp; do { tmp = *i; *i++ = *j; *j++ = tmp; } while ( --size );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Integers */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Assuming 8-bit char, two's-complement architecture here. 'short' being */
|
||||||
|
/* 16 bit, 'int' being either 16, 32 or 64 bit, 'long' being either 32 or 64 */
|
||||||
|
/* bit (but 64 bit only if 'int' is 32 bit), and 'long long' being 64 bit if */
|
||||||
|
/* 'long' is not, 64 or 128 bit otherwise. */
|
||||||
|
/* Author is quite willing to support other systems but would like to hear of */
|
||||||
|
/* interest in such support and details on the to-be-supported architecture */
|
||||||
|
/* first, before going to lengths about it. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Set to 0 if your 'char' type is unsigned. */
|
||||||
|
#ifdef __CHAR_UNSIGNED__
|
||||||
|
#define _PDCLIB_CHAR_SIGNED 0
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_CHAR_SIGNED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Width of the integer types short, int, long, and long long, in bytes. */
|
||||||
|
/* SHRT == 2, INT >= SHRT, LONG >= INT >= 4, LLONG >= LONG - check your */
|
||||||
|
/* compiler manuals. */
|
||||||
|
#define _PDCLIB_SHRT_BYTES 2
|
||||||
|
#define _PDCLIB_INT_BYTES 4
|
||||||
|
#ifdef __LP64__
|
||||||
|
#define _PDCLIB_LONG_BYTES 8
|
||||||
|
#else
|
||||||
|
#define _PDCLIB_LONG_BYTES 4
|
||||||
|
#endif
|
||||||
|
#define _PDCLIB_LLONG_BYTES 8
|
||||||
|
|
||||||
|
/* <stdlib.h> defines the div() function family that allows taking quotient */
|
||||||
|
/* and remainder of an integer division in one operation. Many platforms */
|
||||||
|
/* support this in hardware / opcode, and the standard permits ordering of */
|
||||||
|
/* the return structure in any way to fit the hardware. That is why those */
|
||||||
|
/* structs can be configured here. */
|
||||||
|
|
||||||
|
struct _PDCLIB_div_t
|
||||||
|
{
|
||||||
|
int quot;
|
||||||
|
int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_ldiv_t
|
||||||
|
{
|
||||||
|
long int quot;
|
||||||
|
long int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lldiv_t
|
||||||
|
{
|
||||||
|
long long int quot;
|
||||||
|
long long int rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* <inttypes.h> defines imaxdiv(), which is equivalent to the div() function */
|
||||||
|
/* family (see further above) with intmax_t as basis. */
|
||||||
|
|
||||||
|
struct _PDCLIB_imaxdiv_t
|
||||||
|
{
|
||||||
|
intmax_t quot;
|
||||||
|
intmax_t rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Time types */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* See <time.h> for a couple of comments on these types and their semantics. */
|
||||||
|
|
||||||
|
#define _PDCLIB_time long
|
||||||
|
|
||||||
|
#define _PDCLIB_clock long
|
||||||
|
#define _PDCLIB_CLOCKS_PER_SEC 1000000
|
||||||
|
|
||||||
|
#define _PDCLIB_TIME_UTC 1
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Floating Point */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Whether the implementation rounds toward zero (0), to nearest (1), toward
|
||||||
|
positive infinity (2), or toward negative infinity (3). (-1) signifies
|
||||||
|
indeterminable rounding, any other value implementation-specific rounding.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FLT_ROUNDS -1
|
||||||
|
|
||||||
|
/* Whether the implementation uses exact-width precision (0), promotes float
|
||||||
|
to double (1), or promotes float and double to long double (2). (-1)
|
||||||
|
signifies indeterminable behaviour, any other value implementation-specific
|
||||||
|
behaviour.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FLT_EVAL_METHOD -1
|
||||||
|
|
||||||
|
/* "Number of the decimal digits (n), such that any floating-point number in the
|
||||||
|
widest supported floating type with p(max) radix (b) digits can be rounded to
|
||||||
|
a floating-point number with (n) decimal digits and back again without change
|
||||||
|
to the value p(max) log(10)b if (b) is a power of 10, [1 + p(max) log(10)b]
|
||||||
|
otherwise."
|
||||||
|
64bit IEC 60559 double format (53bit mantissa) is DECIMAL_DIG 17.
|
||||||
|
80bit IEC 60559 double-extended format (64bit mantissa) is DECIMAL_DIG 21.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_DECIMAL_DIG 17
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Platform-dependent macros defined by the standard headers. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The offsetof macro
|
||||||
|
Contract: Expand to an integer constant expression of type size_t, which
|
||||||
|
represents the offset in bytes to the structure member from the beginning
|
||||||
|
of the structure. If the specified member is a bitfield, behaviour is
|
||||||
|
undefined.
|
||||||
|
There is no standard-compliant way to do this.
|
||||||
|
This implementation casts an integer zero to 'pointer to type', and then
|
||||||
|
takes the address of member. This is undefined behaviour but should work on
|
||||||
|
most compilers.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) )
|
||||||
|
|
||||||
|
/* Variable Length Parameter List Handling (<stdarg.h>)
|
||||||
|
The macros defined by <stdarg.h> are highly dependent on the calling
|
||||||
|
conventions used, and you probably have to replace them with builtins of
|
||||||
|
your compiler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined( __i386 )
|
||||||
|
|
||||||
|
/* The following generic implementation works only for pure
|
||||||
|
stack-based architectures, and only if arguments are aligned to pointer
|
||||||
|
type. Credits to Michael Moody, who contributed this to the Public Domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Internal helper macro. va_round is not part of <stdarg.h>. */
|
||||||
|
#define _PDCLIB_va_round( type ) ( (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) )
|
||||||
|
|
||||||
|
typedef char * _PDCLIB_va_list;
|
||||||
|
#define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) )
|
||||||
|
#define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 )
|
||||||
|
#define _PDCLIB_va_end( ap ) ( (ap) = (void *)0, (void)0 )
|
||||||
|
#define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 )
|
||||||
|
|
||||||
|
#elif defined( __x86_64 ) || defined( __arm__ )
|
||||||
|
|
||||||
|
/* No way to cover x86_64 or arm with a generic implementation, as it uses
|
||||||
|
register-based parameter passing. Using compiler builtins here.
|
||||||
|
*/
|
||||||
|
typedef __builtin_va_list _PDCLIB_va_list;
|
||||||
|
#define _PDCLIB_va_arg( ap, type ) ( __builtin_va_arg( ap, type ) )
|
||||||
|
#define _PDCLIB_va_copy( dest, src ) ( __builtin_va_copy( dest, src ) )
|
||||||
|
#define _PDCLIB_va_end( ap ) ( __builtin_va_end( ap ) )
|
||||||
|
#define _PDCLIB_va_start( ap, parmN ) ( __builtin_va_start( ap, parmN ) )
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Please create your own config.h. Using the existing one as-is will not work.
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* OS "glue", part 1 */
|
||||||
|
/* These are values and data type definitions that you would have to adapt to */
|
||||||
|
/* the capabilities and requirements of your OS. */
|
||||||
|
/* The actual *functions* of the OS interface are declared in glue.h. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Memory management -------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Set this to the page size of your OS. If your OS does not support paging, set
|
||||||
|
to an appropriate value. (Too small, and malloc() will call the kernel too
|
||||||
|
often. Too large, and you will waste memory.)
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_PAGESIZE 4096
|
||||||
|
|
||||||
|
/* Set this to the minimum memory node size. Any malloc() for a smaller size
|
||||||
|
will be satisfied by a malloc() of this size instead (to avoid excessive
|
||||||
|
fragmentation).
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_MINALLOC 8
|
||||||
|
|
||||||
|
/* I/O ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The type of the file descriptor returned by _PDCLIB_open(). */
|
||||||
|
typedef int _PDCLIB_fd_t;
|
||||||
|
|
||||||
|
/* The value (of type _PDCLIB_fd_t) returned by _PDCLIB_open() if the operation
|
||||||
|
failed.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_NOHANDLE ( (_PDCLIB_fd_t) -1 )
|
||||||
|
|
||||||
|
/* The default size for file buffers. Must be at least 256. */
|
||||||
|
#define _PDCLIB_BUFSIZ 1024
|
||||||
|
|
||||||
|
/* The minimum number of files the implementation can open simultaneously. Must
|
||||||
|
be at least 8. Depends largely on how the bookkeeping is done by fopen() /
|
||||||
|
freopen() / fclose(). The example implementation limits the number of open
|
||||||
|
files only by available memory.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FOPEN_MAX 8
|
||||||
|
|
||||||
|
/* Length of the longest filename the implementation guarantees to support. */
|
||||||
|
#define _PDCLIB_FILENAME_MAX 128
|
||||||
|
|
||||||
|
/* Maximum length of filenames generated by tmpnam(). (See tmpfile.c.) */
|
||||||
|
#define _PDCLIB_L_tmpnam 46
|
||||||
|
|
||||||
|
/* Number of distinct file names that can be generated by tmpnam(). */
|
||||||
|
#define _PDCLIB_TMP_MAX 50
|
||||||
|
|
||||||
|
/* The values of SEEK_SET, SEEK_CUR and SEEK_END, used by fseek().
|
||||||
|
Since at least one platform (POSIX) uses the same symbols for its own "seek"
|
||||||
|
function, we use whatever the host defines (if it does define them).
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_SEEK_SET 0
|
||||||
|
#define _PDCLIB_SEEK_CUR 1
|
||||||
|
#define _PDCLIB_SEEK_END 2
|
||||||
|
|
||||||
|
/* The number of characters that can be buffered with ungetc(). The standard
|
||||||
|
guarantees only one (1); anything larger would make applications relying on
|
||||||
|
this capability dependent on implementation-defined behaviour (not good).
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_UNGETCBUFSIZE 1
|
||||||
|
|
||||||
|
/* errno -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* These are the values that _PDCLIB_errno can be set to by the library.
|
||||||
|
|
||||||
|
By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable
|
||||||
|
to "translate" between errno values used by the hosting operating system and
|
||||||
|
those used and passed out by the library.
|
||||||
|
|
||||||
|
Example: In the example platform, the remove() function uses the unlink()
|
||||||
|
system call as backend. Linux sets its errno to EISDIR if you try to unlink()
|
||||||
|
a directory, but POSIX demands EPERM. Within the remove() function, you can
|
||||||
|
catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone
|
||||||
|
using PDCLib's <errno.h> will "see" EPERM instead of EISDIR (the _PDCLIB_*
|
||||||
|
prefix removed by <errno.h> mechanics).
|
||||||
|
|
||||||
|
If you do not want that kind of translation, you might want to "match" the
|
||||||
|
values used by PDCLib with those used by the host OS, as to avoid confusion.
|
||||||
|
|
||||||
|
The standard only defines three distinct errno values: ERANGE, EDOM, and
|
||||||
|
EILSEQ. The standard leaves it up to "the implementation" whether there are
|
||||||
|
any more beyond those three. There is some controversy as to whether errno is
|
||||||
|
such a good idea at all, so you might want to come up with a different error
|
||||||
|
reporting facility for your platform. Since errno values beyond the three
|
||||||
|
defined by the standard are not portable anyway (unless you look at POSIX),
|
||||||
|
having your own error reporting facility would not hurt anybody either.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_ERANGE 1
|
||||||
|
#define _PDCLIB_EDOM 2
|
||||||
|
#define _PDCLIB_EILSEQ 3
|
||||||
|
#define _PDCLIB_ENOMEM 12
|
||||||
|
#define _PDCLIB_EINVAL 22
|
||||||
|
|
||||||
|
/* The following is not strictly "configuration", but there is no better place
|
||||||
|
to explain it than here.
|
||||||
|
|
||||||
|
PDCLib strives to be as generic as possible, so by default it does NOT define
|
||||||
|
any values beyond the three standard ones above, even where it would have
|
||||||
|
been prudent and convenient to do so. Any errno "caught" from the host OS,
|
||||||
|
and some internal error conditions as well, are all lumped together into the
|
||||||
|
value of '_PDCLIB_ERROR'.
|
||||||
|
|
||||||
|
'_PDCLIB_ERROR' is STRICLY meant as a PLACEHOLDER only.
|
||||||
|
|
||||||
|
You should NEVER ship an adaption of PDCLib still using that particular
|
||||||
|
value. You should NEVER write code that *tests* for that value. Indeed it is
|
||||||
|
not even conforming, since errno values should be defined as beginning with
|
||||||
|
an uppercase 'E', and there is no mechanics in <errno.h> to unmask that
|
||||||
|
particular value (for exactly that reason).
|
||||||
|
|
||||||
|
There also is no error message available for this value through either the
|
||||||
|
strerror() or perror() functions. It is being reported as "unknown" error.
|
||||||
|
|
||||||
|
The idea is that you scan the source of PDCLib for occurrences of this macro
|
||||||
|
and replace _PDCLIB_ERROR with whatever additional errno value you came up
|
||||||
|
with for your platform.
|
||||||
|
|
||||||
|
If you cannot find it within you to do that, tell your clients to check for
|
||||||
|
an errno value larger than zero. That, at least, would be standard compliant
|
||||||
|
(and fully portable).
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_ERROR 4
|
||||||
|
|
||||||
|
/* The maximum value that errno can be set to. This is used to set the size */
|
||||||
|
/* of the array in struct _PDCLIB_lc_text_t holding error messages for the */
|
||||||
|
/* strerror() and perror() functions. (If you change this value because you */
|
||||||
|
/* are using additional errno values, you *HAVE* to provide appropriate error */
|
||||||
|
/* messages for *ALL* locales.) */
|
||||||
|
/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */
|
||||||
|
#define _PDCLIB_ERRNO_MAX 4
|
||||||
|
|
||||||
|
/* locale data -------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* The default path where PDCLib should look for its locale data. */
|
||||||
|
/* Must end with the appropriate separator character. */
|
||||||
|
#define _PDCLIB_LOCALE_PATH "/usr/share/pdclib/i18n"
|
||||||
|
|
||||||
|
/* The name of the environment variable that can be used to override that */
|
||||||
|
/* path setting. */
|
||||||
|
#define _PDCLIB_LOCALE_PATH_ENV PDCLIB_I18N
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
typedef unsigned int wint_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
9
src/libraries/libc/include/j6libc/cpp.h
Normal file
9
src/libraries/libc/include/j6libc/cpp.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define CPP_CHECK_BEGIN extern "C" {
|
||||||
|
#define CPP_CHECK_END }
|
||||||
|
#else
|
||||||
|
#define CPP_CHECK_BEGIN
|
||||||
|
#define CPP_CHECK_END
|
||||||
|
#endif
|
||||||
67
src/libraries/libc/include/j6libc/glue.h
Normal file
67
src/libraries/libc/include/j6libc/glue.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
/* OS glue functions declaration <glue.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* OS "glue", part 2 */
|
||||||
|
/* These are the functions you will have to touch, as they are where PDCLib */
|
||||||
|
/* interfaces with the operating system. */
|
||||||
|
/* They operate on data types partially defined by config.h. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* stdlib.h */
|
||||||
|
|
||||||
|
/* A system call that terminates the calling process, returning a given status
|
||||||
|
to the environment.
|
||||||
|
*/
|
||||||
|
_Noreturn void _PDCLIB_Exit( int status );
|
||||||
|
|
||||||
|
/* A system call that adds n pages of memory to the process heap (if n is
|
||||||
|
positive), or releases n pages from the process heap (if n is negative).
|
||||||
|
Return a (void *) pointing to the *former* end-of-heap if successful, NULL
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
void * _PDCLIB_allocpages( int n );
|
||||||
|
|
||||||
|
|
||||||
|
/* stdio.h */
|
||||||
|
|
||||||
|
/* A system call that opens a file identified by name in a given mode. Return
|
||||||
|
a file descriptor uniquely identifying that file.
|
||||||
|
(The mode is the return value of the _PDCLIB_filemode() function.)
|
||||||
|
*/
|
||||||
|
_PDCLIB_fd_t _PDCLIB_open( const char * const filename, unsigned int mode );
|
||||||
|
|
||||||
|
/* A system call that writes a stream's buffer.
|
||||||
|
Returns 0 on success, EOF on write error.
|
||||||
|
Sets stream error flags and errno appropriately on error.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* A system call that fills a stream's buffer.
|
||||||
|
Returns 0 on success, EOF on read error / EOF.
|
||||||
|
Sets stream EOF / error flags and errno appropriately on error.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* A system call that repositions within a file. Returns new offset on success,
|
||||||
|
-1 / errno on error.
|
||||||
|
*/
|
||||||
|
int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, int64_t offset, int whence );
|
||||||
|
|
||||||
|
/* A system call that closes a file identified by given file descriptor. Return
|
||||||
|
zero on success, non-zero otherwise.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_close( _PDCLIB_fd_t fd );
|
||||||
|
|
||||||
|
/* A system call that renames a file from given old name to given new name.
|
||||||
|
Return zero on success, non-zero otherwise. In case of failure, the file
|
||||||
|
must still be accessible by old name. Any handling of open files etc. is
|
||||||
|
done by standard rename() already.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_rename( const char * old, const char * new );
|
||||||
347
src/libraries/libc/include/j6libc/int.h
Normal file
347
src/libraries/libc/include/j6libc/int.h
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
#pragma once
|
||||||
|
/* PDCLib internal integer logic <int.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* You should not have to edit anything in this file; if you DO have to, it */
|
||||||
|
/* would be considered a bug / missing feature: notify the author(s). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "j6libc/config.h"
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/aux.h"
|
||||||
|
#include "j6libc/int_widths.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
#include "j6libc/wchar_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Various <stdio.h> internals */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Flags for representing mode (see fopen()). Note these must fit the same
|
||||||
|
status field as the _IO?BF flags in <stdio.h> and the internal flags below.
|
||||||
|
*/
|
||||||
|
#define _PDCLIB_FREAD 8u
|
||||||
|
#define _PDCLIB_FWRITE 16u
|
||||||
|
#define _PDCLIB_FAPPEND 32u
|
||||||
|
#define _PDCLIB_FRW 64u
|
||||||
|
#define _PDCLIB_FBIN 128u
|
||||||
|
|
||||||
|
/* Internal flags, made to fit the same status field as the flags above. */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* free() the buffer memory on closing (false for user-supplied buffer) */
|
||||||
|
#define _PDCLIB_FREEBUFFER 512u
|
||||||
|
/* stream has encountered error / EOF */
|
||||||
|
#define _PDCLIB_ERRORFLAG 1024u
|
||||||
|
#define _PDCLIB_EOFFLAG 2048u
|
||||||
|
/* stream is wide-oriented */
|
||||||
|
#define _PDCLIB_WIDESTREAM 4096u
|
||||||
|
/* stream is byte-oriented */
|
||||||
|
#define _PDCLIB_BYTESTREAM 8192u
|
||||||
|
/* file associated with stream should be remove()d on closing (tmpfile()) */
|
||||||
|
#define _PDCLIB_DELONCLOSE 16384u
|
||||||
|
/* stream handle should not be free()d on close (stdin, stdout, stderr) */
|
||||||
|
#define _PDCLIB_STATIC 32768u
|
||||||
|
|
||||||
|
/* Position / status structure for getpos() / fsetpos(). */
|
||||||
|
struct _PDCLIB_fpos_t
|
||||||
|
{
|
||||||
|
uint64_t offset; /* File position offset */
|
||||||
|
int status; /* Multibyte parsing state (unused, reserved) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FILE structure */
|
||||||
|
struct _PDCLIB_file_t
|
||||||
|
{
|
||||||
|
_PDCLIB_fd_t handle; /* OS file handle */
|
||||||
|
char * buffer; /* Pointer to buffer memory */
|
||||||
|
size_t bufsize; /* Size of buffer */
|
||||||
|
size_t bufidx; /* Index of current position in buffer */
|
||||||
|
size_t bufend; /* Index of last pre-read character in buffer */
|
||||||
|
struct _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */
|
||||||
|
size_t ungetidx; /* Number of ungetc()'ed characters */
|
||||||
|
unsigned char * ungetbuf; /* ungetc() buffer */
|
||||||
|
unsigned int status; /* Status flags; see above */
|
||||||
|
/* multibyte parsing status to be added later */
|
||||||
|
char * filename; /* Name the current stream has been opened with */
|
||||||
|
struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Various <time.h> internals */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
typedef _PDCLIB_time _PDCLIB_time_t;
|
||||||
|
typedef _PDCLIB_clock _PDCLIB_clock_t;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Internal data types */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Structure required by both atexit() and exit() for handling atexit functions */
|
||||||
|
struct _PDCLIB_exitfunc_t
|
||||||
|
{
|
||||||
|
struct _PDCLIB_exitfunc_t * next;
|
||||||
|
void (*func)( void );
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Structures required by malloc(), realloc(), and free(). */
|
||||||
|
struct _PDCLIB_headnode_t
|
||||||
|
{
|
||||||
|
struct _PDCLIB_memnode_t * first;
|
||||||
|
struct _PDCLIB_memnode_t * last;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_memnode_t
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
struct _PDCLIB_memnode_t * next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Status structure required by _PDCLIB_print(). */
|
||||||
|
struct _PDCLIB_status_t
|
||||||
|
{
|
||||||
|
int base; /* base to which the value shall be converted */
|
||||||
|
int_fast32_t flags; /* flags and length modifiers */
|
||||||
|
size_t n; /* print: maximum characters to be written */
|
||||||
|
/* scan: number matched conversion specifiers */
|
||||||
|
size_t i; /* number of characters read/written */
|
||||||
|
size_t current;/* chars read/written in the CURRENT conversion */
|
||||||
|
char * s; /* *sprintf(): target buffer */
|
||||||
|
/* *sscanf(): source string */
|
||||||
|
size_t width; /* specified field width */
|
||||||
|
int prec; /* specified field precision */
|
||||||
|
struct _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream */
|
||||||
|
_PDCLIB_va_list arg; /* argument stack */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Declaration of helper functions (implemented in functions/_PDCLIB). */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* This is the main function called by atoi(), atol() and atoll(). */
|
||||||
|
intmax_t _PDCLIB_atomax( const char * s );
|
||||||
|
|
||||||
|
/* Two helper functions used by strtol(), strtoul() and long long variants. */
|
||||||
|
const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base );
|
||||||
|
uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, int limdigit, char * sign );
|
||||||
|
|
||||||
|
/* Digits arrays used by various integer conversion functions */
|
||||||
|
extern const char _PDCLIB_digits[];
|
||||||
|
extern const char _PDCLIB_Xdigits[];
|
||||||
|
|
||||||
|
/* The worker for all printf() type of functions. The pointer spec should point
|
||||||
|
to the introducing '%' of a conversion specifier. The status structure is to
|
||||||
|
be that of the current printf() function, of which the members n, s, stream
|
||||||
|
and arg will be preserved; i will be updated; and all others will be trashed
|
||||||
|
by the function.
|
||||||
|
Returns a pointer to the first character not parsed as conversion specifier.
|
||||||
|
*/
|
||||||
|
const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );
|
||||||
|
|
||||||
|
/* The worker for all scanf() type of functions. The pointer spec should point
|
||||||
|
to the introducing '%' of a conversion specifier. The status structure is to
|
||||||
|
be that of the current scanf() function, of which the member stream will be
|
||||||
|
preserved; n, i, and s will be updated; and all others will be trashed by
|
||||||
|
the function.
|
||||||
|
Returns a pointer to the first character not parsed as conversion specifier,
|
||||||
|
or NULL in case of error.
|
||||||
|
FIXME: Should distinguish between matching and input error
|
||||||
|
*/
|
||||||
|
const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );
|
||||||
|
|
||||||
|
/* Parsing any fopen() style filemode string into a number of flags. */
|
||||||
|
unsigned int _PDCLIB_filemode( const char * mode );
|
||||||
|
|
||||||
|
/* Sanity checking and preparing of read buffer, should be called first thing
|
||||||
|
by any stdio read-data function.
|
||||||
|
Returns 0 on success, EOF on error.
|
||||||
|
On error, EOF / error flags and errno are set appropriately.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_prepread( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Sanity checking, should be called first thing by any stdio write-data
|
||||||
|
function.
|
||||||
|
Returns 0 on success, EOF on error.
|
||||||
|
On error, error flags and errno are set appropriately.
|
||||||
|
*/
|
||||||
|
int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream );
|
||||||
|
|
||||||
|
/* Closing all streams on program exit */
|
||||||
|
void _PDCLIB_closeall( void );
|
||||||
|
|
||||||
|
/* Check if a given year is a leap year. Parameter is offset to 1900. */
|
||||||
|
int _PDCLIB_is_leap( int year_offset );
|
||||||
|
|
||||||
|
/* Read a specified number of lines from a file stream; return a pointer to
|
||||||
|
allocated memory holding the lines (newlines replaced with zero terminators)
|
||||||
|
or NULL in case of error.
|
||||||
|
*/
|
||||||
|
char * _PDCLIB_load_lines( struct _PDCLIB_file_t * fh, size_t lines );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* errno */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* If PDCLib would call its error number "errno" directly, there would be no way
|
||||||
|
to catch its value from underlying system calls that also use it (i.e., POSIX
|
||||||
|
operating systems). That is why we use an internal name, providing a means to
|
||||||
|
access it through <errno.h>.
|
||||||
|
*/
|
||||||
|
extern int _PDCLIB_errno;
|
||||||
|
|
||||||
|
/* A mechanism for delayed evaluation. (Not sure if this is really necessary, so
|
||||||
|
no detailed documentation on the "why".)
|
||||||
|
*/
|
||||||
|
int * _PDCLIB_errno_func( void );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* <locale.h> support */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define _PDCLIB_LC_ALL 0
|
||||||
|
#define _PDCLIB_LC_COLLATE 1
|
||||||
|
#define _PDCLIB_LC_CTYPE 2
|
||||||
|
#define _PDCLIB_LC_MONETARY 3
|
||||||
|
#define _PDCLIB_LC_NUMERIC 4
|
||||||
|
#define _PDCLIB_LC_TIME 5
|
||||||
|
#define _PDCLIB_LC_MESSAGES 6
|
||||||
|
#define _PDCLIB_LC_COUNT 7
|
||||||
|
|
||||||
|
#define _PDCLIB_CTYPE_ALPHA 1
|
||||||
|
#define _PDCLIB_CTYPE_BLANK 2
|
||||||
|
#define _PDCLIB_CTYPE_CNTRL 4
|
||||||
|
#define _PDCLIB_CTYPE_GRAPH 8
|
||||||
|
#define _PDCLIB_CTYPE_PUNCT 16
|
||||||
|
#define _PDCLIB_CTYPE_SPACE 32
|
||||||
|
#define _PDCLIB_CTYPE_LOWER 64
|
||||||
|
#define _PDCLIB_CTYPE_UPPER 128
|
||||||
|
|
||||||
|
#define _PDCLIB_CHARSET_SIZE ( 1 << __CHAR_BIT__ )
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t
|
||||||
|
{
|
||||||
|
char * decimal_point;
|
||||||
|
char * thousands_sep;
|
||||||
|
char * grouping;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t
|
||||||
|
{
|
||||||
|
char * mon_decimal_point;
|
||||||
|
char * mon_thousands_sep;
|
||||||
|
char * mon_grouping;
|
||||||
|
char * positive_sign;
|
||||||
|
char * negative_sign;
|
||||||
|
char * currency_symbol;
|
||||||
|
char * int_curr_symbol;
|
||||||
|
char frac_digits;
|
||||||
|
char p_cs_precedes;
|
||||||
|
char n_cs_precedes;
|
||||||
|
char p_sep_by_space;
|
||||||
|
char n_sep_by_space;
|
||||||
|
char p_sign_posn;
|
||||||
|
char n_sign_posn;
|
||||||
|
char int_frac_digits;
|
||||||
|
char int_p_cs_precedes;
|
||||||
|
char int_n_cs_precedes;
|
||||||
|
char int_p_sep_by_space;
|
||||||
|
char int_n_sep_by_space;
|
||||||
|
char int_p_sign_posn;
|
||||||
|
char int_n_sign_posn;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_numeric_monetary_t
|
||||||
|
{
|
||||||
|
struct lconv * lconv;
|
||||||
|
int numeric_alloced;
|
||||||
|
int monetary_alloced;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_numeric_monetary_t _PDCLIB_lc_numeric_monetary;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_collate_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
/* 1..3 code points */
|
||||||
|
/* 1..8, 18 collation elements of 3 16-bit integers */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_collate_t _PDCLIB_lc_collate;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t
|
||||||
|
{
|
||||||
|
uint16_t flags;
|
||||||
|
unsigned char upper;
|
||||||
|
unsigned char lower;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
int digits_low;
|
||||||
|
int digits_high;
|
||||||
|
int Xdigits_low;
|
||||||
|
int Xdigits_high;
|
||||||
|
int xdigits_low;
|
||||||
|
int xdigits_high;
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t * entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_ctype_t _PDCLIB_lc_ctype;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_messages_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
char * errno_texts[_PDCLIB_ERRNO_MAX]; /* strerror() / perror() */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_messages_t _PDCLIB_lc_messages;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_time_t
|
||||||
|
{
|
||||||
|
int alloced;
|
||||||
|
char * month_name_abbr[12]; /* month names, abbreviated */
|
||||||
|
char * month_name_full[12]; /* month names, full */
|
||||||
|
char * day_name_abbr[7]; /* weekday names, abbreviated */
|
||||||
|
char * day_name_full[7]; /* weekday names, full */
|
||||||
|
char * date_time_format; /* date / time format for strftime( "%c" ) */
|
||||||
|
char * time_format_12h; /* 12-hour time format for strftime( "%r" ) */
|
||||||
|
char * date_format; /* date format for strftime( "%x" ) */
|
||||||
|
char * time_format; /* time format for strftime( "%X" ) */
|
||||||
|
char * am_pm[2]; /* AM / PM designation */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _PDCLIB_lc_time_t _PDCLIB_lc_time;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale );
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale );
|
||||||
|
struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale );
|
||||||
|
struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale );
|
||||||
|
struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale );
|
||||||
|
struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale );
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
/* Sanity checks */
|
||||||
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
_PDCLIB_static_assert( sizeof( short ) == _PDCLIB_SHRT_BYTES, "Compiler disagrees on _PDCLIB_SHRT_BYTES." );
|
||||||
|
_PDCLIB_static_assert( sizeof( int ) == _PDCLIB_INT_BYTES, "Compiler disagrees on _PDCLIB_INT_BYTES." );
|
||||||
|
_PDCLIB_static_assert( sizeof( long ) == _PDCLIB_LONG_BYTES, "Compiler disagrees on _PDCLIB_LONG_BYTES." );
|
||||||
|
_PDCLIB_static_assert( sizeof( long long ) == _PDCLIB_LLONG_BYTES, "Compiler disagrees on _PDCLIB_LLONG_BYTES." );
|
||||||
|
|
||||||
|
_PDCLIB_static_assert( ( (char)-1 < 0 ) == _PDCLIB_CHAR_SIGNED, "Compiler disagrees on _PDCLIB_CHAR_SIGNED." );
|
||||||
|
|
||||||
|
_PDCLIB_static_assert( sizeof( sizeof( int ) ) == sizeof( size_t ), "Compiler disagrees on size_t." );
|
||||||
|
_PDCLIB_static_assert( sizeof( wchar_t ) == sizeof( L'x' ), "Compiler disagrees on _PDCLIB_wchar." );
|
||||||
|
_PDCLIB_static_assert( sizeof( void * ) == sizeof( intptr_t ), "Compiler disagrees on intptr." );
|
||||||
|
_PDCLIB_static_assert( sizeof( &_PDCLIB_digits[1] - &_PDCLIB_digits[0] ) == sizeof( ptrdiff_t ), "Compiler disagrees on ptrdiff_t." );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
57
src/libraries/libc/include/j6libc/int_widths.h
Normal file
57
src/libraries/libc/include/j6libc/int_widths.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definitions: fixed-width integral types */
|
||||||
|
|
||||||
|
/* 7.18.1.1 Exact-width integer types. */
|
||||||
|
|
||||||
|
typedef __INT8_TYPE__ int8_t;
|
||||||
|
typedef __INT16_TYPE__ int16_t;
|
||||||
|
typedef __INT32_TYPE__ int32_t;
|
||||||
|
typedef __INT64_TYPE__ int64_t;
|
||||||
|
|
||||||
|
typedef __UINT8_TYPE__ uint8_t;
|
||||||
|
typedef __UINT16_TYPE__ uint16_t;
|
||||||
|
typedef __UINT32_TYPE__ uint32_t;
|
||||||
|
typedef __UINT64_TYPE__ uint64_t;
|
||||||
|
|
||||||
|
/* 7.18.1.2 Minimum-width integer types */
|
||||||
|
|
||||||
|
/* You are allowed to add more types here, e.g. int_least24_t. For the standard
|
||||||
|
types, int_leastN_t is equivalent to the corresponding exact type intN_t by
|
||||||
|
definition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef __INT_LEAST8_TYPE__ int_least8_t;
|
||||||
|
typedef __INT_LEAST16_TYPE__ int_least16_t;
|
||||||
|
typedef __INT_LEAST32_TYPE__ int_least32_t;
|
||||||
|
typedef __INT_LEAST64_TYPE__ int_least64_t;
|
||||||
|
|
||||||
|
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
|
||||||
|
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
|
||||||
|
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
|
||||||
|
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
|
||||||
|
|
||||||
|
/* 7.18.1.3 Fastest minimum-width integer types */
|
||||||
|
|
||||||
|
/* You are allowed to add more types here, e.g. int_fast24_t. */
|
||||||
|
|
||||||
|
typedef __INT_FAST8_TYPE__ int_fast8_t;
|
||||||
|
typedef __INT_FAST16_TYPE__ int_fast16_t;
|
||||||
|
typedef __INT_FAST32_TYPE__ int_fast32_t;
|
||||||
|
typedef __INT_FAST64_TYPE__ int_fast64_t;
|
||||||
|
|
||||||
|
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
|
||||||
|
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
|
||||||
|
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
|
||||||
|
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
|
||||||
|
|
||||||
|
/* 7.18.1.4 Integer types capable of holding object pointers */
|
||||||
|
|
||||||
|
typedef __INTPTR_TYPE__ intptr_t;
|
||||||
|
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||||
|
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||||
|
|
||||||
|
/* 7.18.1.5 Greatest-width integer types */
|
||||||
|
|
||||||
|
typedef __INTMAX_TYPE__ intmax_t;
|
||||||
|
typedef __UINTMAX_TYPE__ uintmax_t;
|
||||||
|
|
||||||
14
src/libraries/libc/include/j6libc/max_align_t.h
Normal file
14
src/libraries/libc/include/j6libc/max_align_t.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __has_include("__stddef_max_align_t.h")
|
||||||
|
#include "__stddef_max_align_t.h"
|
||||||
|
#elif __BIGGEST_ALIGNMENT__ == __SIZEOF_LONG_DOUBLE__
|
||||||
|
typedef long double max_align_t;
|
||||||
|
#elif __BIGGEST_ALIGNMENT__ == __SIZEOF_DOUBLE__
|
||||||
|
typedef double max_align_t;
|
||||||
|
#elif __BIGGEST_ALIGNMENT__ == __SIZEOF_LONG_LONG__
|
||||||
|
typedef long long max_align_t;
|
||||||
|
#else
|
||||||
|
#error Can't figure out size of max_align_t!
|
||||||
|
#endif
|
||||||
|
|
||||||
6
src/libraries/libc/include/j6libc/null.h
Normal file
6
src/libraries/libc/include/j6libc/null.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Constant definition: NULL */
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
14
src/libraries/libc/include/j6libc/sig_atomic_t.h
Normal file
14
src/libraries/libc/include/j6libc/sig_atomic_t.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definition: sig_atomic_t */
|
||||||
|
|
||||||
|
#if __is_identifier(sig_atomic_t)
|
||||||
|
#if __SIG_ATOMIC_WIDTH__ == 16
|
||||||
|
typedef int16_t sig_atomic_t;
|
||||||
|
#elif __SIG_ATOMIC_WIDTH__ == 32
|
||||||
|
typedef int32_t sig_atomic_t;
|
||||||
|
#elif __SIG_ATOMIC_WIDTH__ == 64
|
||||||
|
typedef int64_t sig_atomic_t;
|
||||||
|
#else
|
||||||
|
#error "Unknown size of sig_atomic_t" __SIG_ATOMIC_WIDTH__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
6
src/libraries/libc/include/j6libc/size_t.h
Normal file
6
src/libraries/libc/include/j6libc/size_t.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definition: size_t */
|
||||||
|
|
||||||
|
#if __is_identifier(size_t)
|
||||||
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
#endif
|
||||||
6
src/libraries/libc/include/j6libc/wchar_t.h
Normal file
6
src/libraries/libc/include/j6libc/wchar_t.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definition: wchar_t */
|
||||||
|
|
||||||
|
#if __is_identifier(wchar_t)
|
||||||
|
typedef __WCHAR_TYPE__ wchar_t;
|
||||||
|
#endif
|
||||||
6
src/libraries/libc/include/j6libc/wctype_t.h
Normal file
6
src/libraries/libc/include/j6libc/wctype_t.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definitions: wctype_t wctrans_t */
|
||||||
|
|
||||||
|
typedef uint32_t wctrans_t;
|
||||||
|
typedef uint32_t wctype_t ;
|
||||||
|
|
||||||
5
src/libraries/libc/include/j6libc/wint_t.h
Normal file
5
src/libraries/libc/include/j6libc/wint_t.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Type definition: wint_t */
|
||||||
|
|
||||||
|
typedef __WINT_TYPE__ wint_t;
|
||||||
|
|
||||||
36
src/libraries/libc/include/limits.h
Normal file
36
src/libraries/libc/include/limits.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Sizes of integer types <limits.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
/* TODO: Defined to 1 as multibyte characters are not supported yet. */
|
||||||
|
#define MB_LEN_MAX 1
|
||||||
|
|
||||||
|
#define SCHAR_MAX __SCHAR_MAX__
|
||||||
|
#define SCHAR_MIN ((-SCHAR_MAX) - 1)
|
||||||
|
#define UCHAR_MAX (((unsigned char)SCHAR_MAX << 1) | 1)
|
||||||
|
|
||||||
|
#define CHAR_BIT __CHAR_BIT__
|
||||||
|
#define CHAR_MAX SCHAR_MAX
|
||||||
|
#define CHAR_MIN SCHAR_MIN
|
||||||
|
|
||||||
|
#define SHRT_MAX __SHRT_MAX__
|
||||||
|
#define SHRT_MIN ((-SHRT_MAX) - 1)
|
||||||
|
#define USHRT_MAX (((unsigned short)SHRT_MAX << 1) | 1)
|
||||||
|
|
||||||
|
#define INT_MAX __INT_MAX__
|
||||||
|
#define INT_MIN ((-INT_MAX) - 1)
|
||||||
|
#define UINT_MAX (((unsigned int)INT_MAX << 1) | 1)
|
||||||
|
|
||||||
|
#define LONG_MAX __LONG_MAX__
|
||||||
|
#define LONG_MIN ((-LONG_MAX) - 1)
|
||||||
|
#define ULONG_MAX (((unsigned long)LONG_MAX << 1) | 1)
|
||||||
|
|
||||||
|
#define LLONG_MAX __LONG_LONG_MAX__
|
||||||
|
#define LLONG_MIN ((-LLONG_MAX) - 1)
|
||||||
|
#define ULLONG_MAX (((unsigned long long)LLONG_MAX << 1) | 1)
|
||||||
|
|
||||||
96
src/libraries/libc/include/locale.h
Normal file
96
src/libraries/libc/include/locale.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Localization <locale.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* The structure returned by localeconv().
|
||||||
|
|
||||||
|
The values for *_sep_by_space:
|
||||||
|
0 - no space
|
||||||
|
1 - if symbol and sign are adjacent, a space seperates them from the value;
|
||||||
|
otherwise a space seperates the symbol from the value
|
||||||
|
2 - if symbol and sign are adjacent, a space seperates them; otherwise a
|
||||||
|
space seperates the sign from the value
|
||||||
|
|
||||||
|
The values for *_sign_posn:
|
||||||
|
0 - Parentheses surround value and symbol
|
||||||
|
1 - sign precedes value and symbol
|
||||||
|
2 - sign succeeds value and symbol
|
||||||
|
3 - sign immediately precedes symbol
|
||||||
|
4 - sign immediately succeeds symbol
|
||||||
|
*/
|
||||||
|
struct lconv
|
||||||
|
{
|
||||||
|
char * decimal_point; /* decimal point character */ /* LC_NUMERIC */
|
||||||
|
char * thousands_sep; /* character for seperating groups of digits */ /* LC_NUMERIC */
|
||||||
|
char * grouping; /* string indicating the size of digit groups */ /* LC_NUMERIC */
|
||||||
|
char * mon_decimal_point; /* decimal point for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * mon_thousands_sep; /* thousands_sep for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * mon_grouping; /* grouping for monetary quantities */ /* LC_MONETARY */
|
||||||
|
char * positive_sign; /* string indicating nonnegative mty. qty. */ /* LC_MONETARY */
|
||||||
|
char * negative_sign; /* string indicating negative mty. qty. */ /* LC_MONETARY */
|
||||||
|
char * currency_symbol; /* local currency symbol (e.g. '$') */ /* LC_MONETARY */
|
||||||
|
char * int_curr_symbol; /* international currency symbol (e.g. "USD" */ /* LC_MONETARY */
|
||||||
|
char frac_digits; /* fractional digits in local monetary qty. */ /* LC_MONETARY */
|
||||||
|
char p_cs_precedes; /* if currency_symbol precedes positive qty. */ /* LC_MONETARY */
|
||||||
|
char n_cs_precedes; /* if currency_symbol precedes negative qty. */ /* LC_MONETARY */
|
||||||
|
char p_sep_by_space; /* if it is seperated by space from pos. qty. */ /* LC_MONETARY */
|
||||||
|
char n_sep_by_space; /* if it is seperated by space from neg. qty. */ /* LC_MONETARY */
|
||||||
|
char p_sign_posn; /* positioning of positive_sign for mon. qty. */ /* LC_MONETARY */
|
||||||
|
char n_sign_posn; /* positioning of negative_sign for mon. qty. */ /* LC_MONETARY */
|
||||||
|
char int_frac_digits; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_cs_precedes; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_sep_by_space; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_p_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
char int_n_sign_posn; /* Same as above, for international format */ /* LC_MONETARY */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* First arguments to setlocale().
|
||||||
|
NOTE: If you add to / modify these, look at functions/locale/setlocale.c
|
||||||
|
and keep things in sync.
|
||||||
|
*/
|
||||||
|
/* Entire locale */
|
||||||
|
#define LC_ALL _PDCLIB_LC_ALL
|
||||||
|
/* Collation (strcoll(), strxfrm()) */
|
||||||
|
#define LC_COLLATE _PDCLIB_LC_COLLATE
|
||||||
|
/* Character types (<ctype.h>, <wctype.h>) */
|
||||||
|
#define LC_CTYPE _PDCLIB_LC_CTYPE
|
||||||
|
/* Monetary formatting (as returned by localeconv) */
|
||||||
|
#define LC_MONETARY _PDCLIB_LC_MONETARY
|
||||||
|
/* Decimal-point character (for printf() / scanf() functions), string
|
||||||
|
conversions, nonmonetary formatting as returned by localeconv
|
||||||
|
*/
|
||||||
|
#define LC_NUMERIC _PDCLIB_LC_NUMERIC
|
||||||
|
/* Time formats (strftime(), wcsftime()) */
|
||||||
|
#define LC_TIME _PDCLIB_LC_TIME
|
||||||
|
/* Messages (not specified but allowed by C99, and specified by POSIX)
|
||||||
|
(used by perror() / strerror())
|
||||||
|
*/
|
||||||
|
#define LC_MESSAGES _PDCLIB_LC_MESSAGES
|
||||||
|
|
||||||
|
/* The category parameter can be any of the LC_* macros to specify if the call
|
||||||
|
to setlocale() shall affect the entire locale or only a portion thereof.
|
||||||
|
The category locale specifies which locale should be switched to, with "C"
|
||||||
|
being the minimal default locale, and "" being the locale-specific native
|
||||||
|
environment. A NULL pointer makes setlocale() return the *current* setting.
|
||||||
|
Otherwise, returns a pointer to a string associated with the specified
|
||||||
|
category for the new locale.
|
||||||
|
*/
|
||||||
|
char * setlocale( int category, const char * locale );
|
||||||
|
|
||||||
|
/* Returns a struct lconv initialized to the values appropriate for the current
|
||||||
|
locale setting.
|
||||||
|
*/
|
||||||
|
struct lconv * localeconv( void );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
86
src/libraries/libc/include/signal.h
Normal file
86
src/libraries/libc/include/signal.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Signal handling <string.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/config.h"
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/sig_atomic_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* Signals ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
/* A word on signals, to the people using PDCLib in their OS projects.
|
||||||
|
|
||||||
|
The definitions of the C standard leave about everything that *could* be
|
||||||
|
useful to be "implementation defined". Without additional, non-standard
|
||||||
|
arrangements, it is not possible to turn them into a useful tool.
|
||||||
|
|
||||||
|
This example implementation chose to "not generate any of these signals,
|
||||||
|
except as a result of explicit calls to the raise function", which is
|
||||||
|
allowed by the standard but of course does nothing for the usefulness of
|
||||||
|
<signal.h>.
|
||||||
|
|
||||||
|
A useful signal handling would:
|
||||||
|
1) make signal() a system call that registers the signal handler with the OS
|
||||||
|
2) make raise() a system call triggering an OS signal to the running process
|
||||||
|
3) make provisions that further signals of the same type are blocked until
|
||||||
|
the signal handler returns (optional for SIGILL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* These are the values used by Linux. */
|
||||||
|
|
||||||
|
/* Abnormal termination / abort() */
|
||||||
|
#define SIGABRT 6
|
||||||
|
/* Arithmetic exception / division by zero / overflow */
|
||||||
|
#define SIGFPE 8
|
||||||
|
/* Illegal instruction */
|
||||||
|
#define SIGILL 4
|
||||||
|
/* Interactive attention signal */
|
||||||
|
#define SIGINT 2
|
||||||
|
/* Invalid memory access */
|
||||||
|
#define SIGSEGV 11
|
||||||
|
/* Termination request */
|
||||||
|
#define SIGTERM 15
|
||||||
|
|
||||||
|
typedef void (*sighandler_t)(int);
|
||||||
|
|
||||||
|
/* The following should be defined to pointer values that could NEVER point to
|
||||||
|
a valid signal handler function. (They are used as special arguments to
|
||||||
|
signal().) Again, these are the values used by Linux.
|
||||||
|
*/
|
||||||
|
#define SIG_DFL (sighandler_t)0
|
||||||
|
#define SIG_ERR (sighandler_t)-1
|
||||||
|
#define SIG_IGN (sighandler_t)1
|
||||||
|
|
||||||
|
/* Installs a signal handler "func" for the given signal.
|
||||||
|
A signal handler is a function that takes an integer as argument (the signal
|
||||||
|
number) and returns void.
|
||||||
|
|
||||||
|
Note that a signal handler can do very little else than:
|
||||||
|
1) assign a value to a static object of type "volatile sig_atomic_t",
|
||||||
|
2) call signal() with the value of sig equal to the signal received,
|
||||||
|
3) call _Exit(),
|
||||||
|
4) call abort().
|
||||||
|
Virtually everything else is undefind.
|
||||||
|
|
||||||
|
The signal() function returns the previous installed signal handler, which
|
||||||
|
at program start may be SIG_DFL or SIG_ILL. (This implementation uses
|
||||||
|
SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is
|
||||||
|
returned and errno is set to an unspecified positive value.
|
||||||
|
*/
|
||||||
|
sighandler_t signal( int sig, sighandler_t func );
|
||||||
|
|
||||||
|
/* Raises the given signal (executing the registered signal handler with the
|
||||||
|
given signal number as parameter).
|
||||||
|
This implementation does not prevent further signals of the same time from
|
||||||
|
occuring, but executes signal( sig, SIG_DFL ) before entering the signal
|
||||||
|
handler (i.e., a second signal before the signal handler re-registers itself
|
||||||
|
or SIG_IGN will end the program).
|
||||||
|
Returns zero if successful, nonzero otherwise. */
|
||||||
|
int raise( int sig );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
12
src/libraries/libc/include/stdalign.h
Normal file
12
src/libraries/libc/include/stdalign.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Alignment <stdalign.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define alignas _Alignas
|
||||||
|
#define alignof _Alignof
|
||||||
|
|
||||||
|
#define __alignas_is_defined 1
|
||||||
|
#define __alignof_is_defined 1
|
||||||
15
src/libraries/libc/include/stdarg.h
Normal file
15
src/libraries/libc/include/stdarg.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Variable arguments <stdarg.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/config.h"
|
||||||
|
|
||||||
|
typedef _PDCLIB_va_list va_list;
|
||||||
|
|
||||||
|
#define va_arg( ap, type ) _PDCLIB_va_arg( ap, type )
|
||||||
|
#define va_copy( dest, src ) _PDCLIB_va_copy( dest, src )
|
||||||
|
#define va_end( ap ) _PDCLIB_va_end( ap )
|
||||||
|
#define va_start( ap, parmN ) _PDCLIB_va_start( ap, parmN )
|
||||||
14
src/libraries/libc/include/stdbool.h
Normal file
14
src/libraries/libc/include/stdbool.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Boolean type and values <stdbool.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#define bool _Bool
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __bool_true_false_are_defined 1
|
||||||
22
src/libraries/libc/include/stddef.h
Normal file
22
src/libraries/libc/include/stddef.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Common definitions <stddef.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/max_align_t.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
#include "j6libc/wchar_t.h"
|
||||||
|
|
||||||
|
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||||
|
|
||||||
|
#if ! __has_include("__stddef_max_align_t.h")
|
||||||
|
typedef long double max_align_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef offsetof
|
||||||
|
#define offsetof( type, member ) _PDCLIB_offsetof( type, member )
|
||||||
|
#endif
|
||||||
151
src/libraries/libc/include/stdint.h
Normal file
151
src/libraries/libc/include/stdint.h
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Integer types <stdint.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 7.18.2 Limits of specified-width integer types */
|
||||||
|
|
||||||
|
#include <j6libc/int.h>
|
||||||
|
#include <j6libc/int_widths.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#ifndef __STDC_LIMIT_MACROS
|
||||||
|
#define _PDCLIB_NO_LIMIT_MACROS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NO_LIMIT_MACROS
|
||||||
|
|
||||||
|
/* 7.18.2.1 Limits of exact-width integer types */
|
||||||
|
|
||||||
|
#define INT8_MAX __INT8_MAX__
|
||||||
|
#define INT8_MIN ((-INT8_MAX) - 1)
|
||||||
|
#define UINT8_MAX __UINT8_MAX__
|
||||||
|
|
||||||
|
#define INT16_MAX __INT16_MAX__
|
||||||
|
#define INT16_MIN ((-INT16_MAX) - 1)
|
||||||
|
#define UINT16_MAX __UINT16_MAX__
|
||||||
|
|
||||||
|
#define INT32_MAX __INT32_MAX__
|
||||||
|
#define INT32_MIN ((-INT32_MAX) - 1)
|
||||||
|
#define UINT32_MAX __UINT32_MAX__
|
||||||
|
|
||||||
|
#define INT64_MAX __INT64_MAX__
|
||||||
|
#define INT64_MIN ((-INT64_MAX) - 1)
|
||||||
|
#define UINT64_MAX __UINT64_MAX__
|
||||||
|
|
||||||
|
/* 7.18.2.2 Limits of minimum-width integer types */
|
||||||
|
|
||||||
|
/* For the standard widths, least and exact types are equivalent.
|
||||||
|
You are allowed to add more types here, e.g. int_least24_t.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
|
||||||
|
#define INT_LEAST8_MIN ((-INT_LEAST8_MAX) - 1)
|
||||||
|
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
|
||||||
|
|
||||||
|
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
|
||||||
|
#define INT_LEAST16_MIN ((-INT_LEAST16_MAX) - 1)
|
||||||
|
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
|
||||||
|
|
||||||
|
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
|
||||||
|
#define INT_LEAST32_MIN ((-INT_LEAST32_MAX) - 1)
|
||||||
|
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
|
||||||
|
|
||||||
|
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
|
||||||
|
#define INT_LEAST64_MIN ((-INT_LEAST64_MAX) - 1)
|
||||||
|
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
|
||||||
|
|
||||||
|
/* 7.18.2.3 Limits of fastest minimum-width integer types */
|
||||||
|
|
||||||
|
#define INT_FAST8_MAX __INT_FAST8_MAX__
|
||||||
|
#define INT_FAST8_MIN ((-INT_FAST8_MAX) - 1)
|
||||||
|
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
|
||||||
|
|
||||||
|
#define INT_FAST16_MAX __INT_FAST16_MAX__
|
||||||
|
#define INT_FAST16_MIN ((-INT_FAST16_MAX) - 1)
|
||||||
|
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
|
||||||
|
|
||||||
|
#define INT_FAST32_MAX __INT_FAST32_MAX__
|
||||||
|
#define INT_FAST32_MIN ((-INT_FAST32_MAX) - 1)
|
||||||
|
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
|
||||||
|
|
||||||
|
#define INT_FAST64_MAX __INT_FAST64_MAX__
|
||||||
|
#define INT_FAST64_MIN ((-INT_FAST64_MAX) - 1)
|
||||||
|
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
|
||||||
|
|
||||||
|
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
|
||||||
|
|
||||||
|
#define INTPTR_MAX __INTPTR_MAX__
|
||||||
|
#define INTPTR_MIN ((-INTPTR_MAX) - 1)
|
||||||
|
#define UINTPTR_MAX __UINTPTR_MAX__
|
||||||
|
|
||||||
|
/* 7.18.2.5 Limits of greatest-width integer types */
|
||||||
|
|
||||||
|
#define INTMAX_MAX __INTMAX_MAX__
|
||||||
|
#define INTMAX_MIN ((-INTMAX_MAX) - 1)
|
||||||
|
#define UINTMAX_MAX __UINTMAX_MAX__
|
||||||
|
|
||||||
|
/* 7.18.3 Limits of other integer types */
|
||||||
|
|
||||||
|
#define PTRDIFF_MAX __PTRDIFF_MAX__
|
||||||
|
#define PTRDIFF_MIN ((-PTRDIFF_MAX) - 1)
|
||||||
|
|
||||||
|
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
|
||||||
|
#define SIG_ATOMIC_MIN ((-SIG_ATOMIC_MAX) - 1)
|
||||||
|
|
||||||
|
#define SIZE_MAX __SIZE_MAX__
|
||||||
|
|
||||||
|
#define WCHAR_MAX __WCHAR_MAX__
|
||||||
|
#define WCHAR_MIN ((-WCHAR_MAX) - 1)
|
||||||
|
|
||||||
|
#define WINT_MAX __WINT_MAX__
|
||||||
|
#define WINT_MIN ((-WINT_MAX) - 1)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 7.18.4 Macros for integer constants */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#ifndef __STDC_CONSTANT_MACROS
|
||||||
|
#define _PDCLIB_NO_CONSTANT_MACROS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_NO_CONSTANT_MACROS
|
||||||
|
|
||||||
|
/* 7.18.4.1 Macros for minimum-width integer constants */
|
||||||
|
|
||||||
|
/* As the minimum-width types - for the required widths of 8, 16, 32, and 64
|
||||||
|
bits - are expressed in terms of the exact-width types, the mechanism for
|
||||||
|
these macros is to append the literal of that exact-width type to the macro
|
||||||
|
parameter.
|
||||||
|
This is considered a hack, as the author is not sure his understanding of
|
||||||
|
the requirements of this macro is correct. Any input appreciated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type int_leastN_t */
|
||||||
|
|
||||||
|
#define INT8_C( value ) _PDCLIB_concat( value, __INT8_C_SUFFIX__ )
|
||||||
|
#define INT16_C( value ) _PDCLIB_concat( value, __INT16_C_SUFFIX__ )
|
||||||
|
#define INT32_C( value ) _PDCLIB_concat( value, __INT32_C_SUFFIX__ )
|
||||||
|
#define INT64_C( value ) _PDCLIB_concat( value, __INT64_C_SUFFIX__ )
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type uint_leastN_t */
|
||||||
|
|
||||||
|
#define UINT8_C( value ) _PDCLIB_concat( value, __UINT8_C_SUFFIX__ )
|
||||||
|
#define UINT16_C( value ) _PDCLIB_concat( value, __UINT16_C_SUFFIX__ )
|
||||||
|
#define UINT32_C( value ) _PDCLIB_concat( value, __UINT32_C_SUFFIX__ )
|
||||||
|
#define UINT64_C( value ) _PDCLIB_concat( value, __UINT64_C_SUFFIX__ )
|
||||||
|
|
||||||
|
/* 7.18.4.2 Macros for greatest-width integer constants */
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type intmax_t */
|
||||||
|
#define INTMAX_C( value ) _PDCLIB_concat( value, __INTMAX_C_SUFFIX__ )
|
||||||
|
|
||||||
|
/* Expand to an integer constant of specified value and type uintmax_t */
|
||||||
|
#define UINTMAX_C( value ) _PDCLIB_concat( value, __UINTMAX_C_SUFFIX__ )
|
||||||
|
|
||||||
|
#endif
|
||||||
779
src/libraries/libc/include/stdio.h
Normal file
779
src/libraries/libc/include/stdio.h
Normal file
@@ -0,0 +1,779 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Input/output <stdio.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* See setvbuf(), third argument */
|
||||||
|
#define _IOFBF 1
|
||||||
|
#define _IOLBF 2
|
||||||
|
#define _IONBF 4
|
||||||
|
|
||||||
|
/* The following are platform-dependant, and defined in config.h. */
|
||||||
|
typedef struct _PDCLIB_fpos_t fpos_t;
|
||||||
|
typedef struct _PDCLIB_file_t FILE;
|
||||||
|
#define EOF -1
|
||||||
|
#define BUFSIZ _PDCLIB_BUFSIZ
|
||||||
|
#define FOPEN_MAX _PDCLIB_FOPEN_MAX
|
||||||
|
#define FILENAME_MAX _PDCLIB_FILENAME_MAX
|
||||||
|
#define L_tmpnam _PDCLIB_L_tmpnam
|
||||||
|
#define TMP_MAX _PDCLIB_TMP_MAX
|
||||||
|
|
||||||
|
/* See fseek(), third argument */
|
||||||
|
#define SEEK_CUR _PDCLIB_SEEK_CUR
|
||||||
|
#define SEEK_END _PDCLIB_SEEK_END
|
||||||
|
#define SEEK_SET _PDCLIB_SEEK_SET
|
||||||
|
|
||||||
|
extern FILE * stdin;
|
||||||
|
extern FILE * stdout;
|
||||||
|
extern FILE * stderr;
|
||||||
|
|
||||||
|
/* Operations on files */
|
||||||
|
|
||||||
|
/* Remove the given file.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
This implementation does detect if a file of that name is currently open,
|
||||||
|
and fails the remove in this case. This does not detect two distinct names
|
||||||
|
that merely result in the same file (e.g. "/home/user/foo" vs. "~/foo").
|
||||||
|
*/
|
||||||
|
int remove( const char * filename );
|
||||||
|
|
||||||
|
/* Rename the given old file to the given new name.
|
||||||
|
Returns zero if successful, non-zero otherwise.
|
||||||
|
This implementation does detect if the old filename corresponds to an open
|
||||||
|
file, and fails the rename in this case.
|
||||||
|
If there already is a file with the new filename, behaviour is defined by
|
||||||
|
the glue code (see functions/_PDCLIB/rename.c).
|
||||||
|
*/
|
||||||
|
int rename( const char * src, const char * dst );
|
||||||
|
|
||||||
|
/* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file
|
||||||
|
automatically if it is closed or the program exits normally (by returning
|
||||||
|
from main() or calling exit()).
|
||||||
|
Returns a pointer to a FILE handle for this file.
|
||||||
|
This implementation does not remove temporary files if the process aborts
|
||||||
|
abnormally (e.g. abort()).
|
||||||
|
*/
|
||||||
|
FILE * tmpfile( void );
|
||||||
|
|
||||||
|
/* Generate a file name that is not equal to any existing filename AT THE TIME
|
||||||
|
OF GENERATION. Generate a different name each time it is called.
|
||||||
|
Returns a pointer to an internal static buffer containing the filename if s
|
||||||
|
is a NULL pointer. (This is not thread-safe!)
|
||||||
|
Returns s if it is not a NULL pointer (s is then assumed to point to an array
|
||||||
|
of at least L_tmpnam characters).
|
||||||
|
Returns NULL if unable to generate a suitable name (because all possible
|
||||||
|
names already exist, or the function has been called TMP_MAX times already).
|
||||||
|
Note that this implementation cannot guarantee a file of the name generated
|
||||||
|
is not generated between the call to this function and a subsequent fopen().
|
||||||
|
*/
|
||||||
|
char * tmpnam( char * s );
|
||||||
|
|
||||||
|
/* File access functions */
|
||||||
|
|
||||||
|
/* Close the file associated with the given stream (after flushing its buffers).
|
||||||
|
Returns zero if successful, EOF if any errors occur.
|
||||||
|
*/
|
||||||
|
int fclose( FILE * stream );
|
||||||
|
|
||||||
|
/* Flush the buffers of the given output stream. If the stream is an input
|
||||||
|
stream, or an update stream with the last operation being an input operation,
|
||||||
|
behaviour is undefined.
|
||||||
|
If stream is a NULL pointer, perform the buffer flushing for all applicable
|
||||||
|
streams.
|
||||||
|
Returns zero if successful, EOF if a write error occurs.
|
||||||
|
Sets the error indicator of the stream if a write error occurs.
|
||||||
|
*/
|
||||||
|
int fflush( FILE * stream );
|
||||||
|
|
||||||
|
/* Open the file with the given filename in the given mode, and return a stream
|
||||||
|
handle for it in which error and end-of-file indicator are cleared. Defined
|
||||||
|
values for mode are:
|
||||||
|
|
||||||
|
READ MODES
|
||||||
|
text files binary files
|
||||||
|
without update "r" "rb"
|
||||||
|
with update "r+" "rb+" or "r+b"
|
||||||
|
|
||||||
|
Opening in read mode fails if no file with the given filename exists, or if
|
||||||
|
cannot be read.
|
||||||
|
|
||||||
|
WRITE MODES
|
||||||
|
text files binary files
|
||||||
|
without update "w" "wb"
|
||||||
|
with update "w+" "wb+" or "w+b"
|
||||||
|
|
||||||
|
With write modes, if a file with the given filename already exists, it is
|
||||||
|
truncated to zero length.
|
||||||
|
|
||||||
|
APPEND MODES
|
||||||
|
text files binary files
|
||||||
|
without update "a" "ab"
|
||||||
|
with update "a+" "ab+" or "a+b"
|
||||||
|
|
||||||
|
With update modes, if a file with the given filename already exists, it is
|
||||||
|
not truncated to zero length, but all writes are forced to end-of-file (this
|
||||||
|
regardless to fseek() calls). Note that binary files opened in append mode
|
||||||
|
might have their end-of-file padded with '\0' characters.
|
||||||
|
|
||||||
|
Update modes mean that both input and output functions can be performed on
|
||||||
|
the stream, but output must be terminated with a call to either fflush(),
|
||||||
|
fseek(), fsetpos(), or rewind() before input is performed, and input must
|
||||||
|
be terminated with a call to either fseek(), fsetpos(), or rewind() before
|
||||||
|
output is performed, unless input encountered end-of-file.
|
||||||
|
|
||||||
|
If a text file is opened with update mode, the implementation is at liberty
|
||||||
|
to open a binary stream instead. This implementation honors the exact mode
|
||||||
|
given.
|
||||||
|
|
||||||
|
The stream is fully buffered if and only if it can be determined not to
|
||||||
|
refer to an interactive device.
|
||||||
|
|
||||||
|
If the mode string begins with but is longer than one of the above sequences
|
||||||
|
the implementation is at liberty to ignore the additional characters, or do
|
||||||
|
implementation-defined things. This implementation only accepts the exact
|
||||||
|
modes above.
|
||||||
|
|
||||||
|
Returns a pointer to the stream handle if successfull, NULL otherwise.
|
||||||
|
*/
|
||||||
|
FILE * fopen( const char * restrict filename, const char * restrict mode );
|
||||||
|
|
||||||
|
/* Close any file currently associated with the given stream. Open the file
|
||||||
|
identified by the given filename with the given mode (equivalent to fopen()),
|
||||||
|
and associate it with the given stream. If filename is a NULL pointer,
|
||||||
|
attempt to change the mode of the given stream.
|
||||||
|
This implementation allows any mode changes on "real" files, and associating
|
||||||
|
of the standard streams with files. It does *not* support mode changes on
|
||||||
|
standard streams.
|
||||||
|
(Primary use of this function is to redirect stdin, stdout, and stderr.)
|
||||||
|
*/
|
||||||
|
FILE * freopen( const char * restrict filename, const char * restrict mode, FILE * restrict stream );
|
||||||
|
|
||||||
|
/* If buf is a NULL pointer, call setvbuf( stream, NULL, _IONBF, BUFSIZ ).
|
||||||
|
If buf is not a NULL pointer, call setvbuf( stream, buf, _IOFBF, BUFSIZ ).
|
||||||
|
*/
|
||||||
|
void setbuf( FILE * restrict stream, char * restrict buf );
|
||||||
|
|
||||||
|
/* Set the given stream to the given buffering mode. If buf is not a NULL
|
||||||
|
pointer, use buf as file buffer (of given size). If buf is a NULL pointer,
|
||||||
|
use a buffer of given size allocated internally. _IONBF causes unbuffered
|
||||||
|
behaviour, _IOLBF causes line-buffered behaviour, _IOFBF causes fully
|
||||||
|
buffered behaviour. Calling this function is only valid right after a file is
|
||||||
|
opened, and before any other operation (except for any unsuccessful calls to
|
||||||
|
setvbuf()) has been performed.
|
||||||
|
Returns zero if successful, nonzero otherwise.
|
||||||
|
*/
|
||||||
|
int setvbuf( FILE * restrict stream, char * restrict buf, int mode, size_t size );
|
||||||
|
|
||||||
|
/* Formatted input/output functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write output to the given stream, as defined by the given format string and
|
||||||
|
0..n subsequent arguments (the argument stack).
|
||||||
|
|
||||||
|
The format string is written to the given stream verbatim, except for any
|
||||||
|
conversion specifiers included, which start with the letter '%' and are
|
||||||
|
documented below. If the given conversion specifiers require more arguments
|
||||||
|
from the argument stack than provided, behaviour is undefined. Additional
|
||||||
|
arguments not required by conversion specifiers are evaluated but otherwise
|
||||||
|
ignored.
|
||||||
|
|
||||||
|
(The standard specifies the format string is allowed to contain multibyte
|
||||||
|
character sequences as long as it starts and ends in initial shift state,
|
||||||
|
but this is not yet supported by this implementation, which interprets the
|
||||||
|
format string as sequence of char.)
|
||||||
|
TODO: Add multibyte support to printf() functions.
|
||||||
|
|
||||||
|
A conversion specifier consists of:
|
||||||
|
- Zero or more flags (one of the characters "-+ #0").
|
||||||
|
- Optional minimum field width as decimal integer. Default is padding to the
|
||||||
|
left, using spaces. Note that 0 is taken as a flag, not the beginning of a
|
||||||
|
field width. Note also that a small field width will not result in the
|
||||||
|
truncation of a value.
|
||||||
|
- Optional precision (given as ".#" with # being a decimal integer),
|
||||||
|
specifying:
|
||||||
|
- the min. number of digits to appear (diouxX),
|
||||||
|
- the max. number of digits after the decimal point (aAeEfF),
|
||||||
|
- the max. number of significant digits (gG),
|
||||||
|
- the max. number of bytes to be written (s).
|
||||||
|
- behaviour with other conversion specifiers is undefined.
|
||||||
|
- Optional length modifier specifying the size of the argument (one of "hh",
|
||||||
|
"ll", or one of the characters "hljztL").
|
||||||
|
- Conversion specifier character specifying the type of conversion to be
|
||||||
|
applied (and the type of the next argument from the argument stack). One
|
||||||
|
of the characters "diouxXfFeEgGaAcspn%".
|
||||||
|
|
||||||
|
Minimum field width and/or precision may be given as asterisk ('*') instead
|
||||||
|
of a decimal integer. In this case, the next argument from the argument
|
||||||
|
stack is assumed to be an int value specifying the width / precision. A
|
||||||
|
negative field width is interpreted as flag '-' followed by a positive field
|
||||||
|
width. A negative precision is interpreted as if no precision was given.
|
||||||
|
|
||||||
|
FLAGS
|
||||||
|
- Left-justify the conversion result within its field width.
|
||||||
|
+ Prefix a '+' on positive signed conversion results. Prefix a '-' on
|
||||||
|
floating conversions resulting in negative zero, or negative values
|
||||||
|
rounding to zero.
|
||||||
|
space Prefix a space on positive signed conversion results, or if a signed
|
||||||
|
conversion results in no characters. If both '+' and ' ' are given,
|
||||||
|
' ' is ignored.
|
||||||
|
# Use an "alternative form" for
|
||||||
|
- 'o' conversion, increasing precision until the first digit of the
|
||||||
|
result is a zero;
|
||||||
|
- 'x' or 'X' conversion, prefixing "0x" or "0X" to nonzero results;
|
||||||
|
- "aAeEfF" conversions, always printing a decimal point even if no
|
||||||
|
digits are following;
|
||||||
|
- 'g' or 'G' conversions, always printing a decimal point even if no
|
||||||
|
digits are following, and not removing trailing zeroes.
|
||||||
|
- behaviour for other conversions is unspecified.
|
||||||
|
0 Use leading zeroes instead of spaces for field width padding. If both
|
||||||
|
'-' and '0' are given, '0' is ignored. If a precision is specified for
|
||||||
|
any of the "diouxX" conversions, '0' is ignored. Behaviour is only
|
||||||
|
defined for "diouxXaAeEfFgG".
|
||||||
|
|
||||||
|
LENGTH MODIFIERS
|
||||||
|
hh For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of char width. (It will have been subject to integer
|
||||||
|
promotion but will be converted back.) For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to signed char.
|
||||||
|
h For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of short int width. (It will have been subject to integer
|
||||||
|
promotion but will be converted back.) For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to short int.
|
||||||
|
l For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of long int width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to short int. For 'c' conversions, the argument
|
||||||
|
is assumed to be a wint_t. For 's' conversions, the argument is assumed
|
||||||
|
to be a pointer to wchar_t. No effect on "aAeEfFgG" conversions.
|
||||||
|
ll For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of long long int width. For 'n' conversions, the argument
|
||||||
|
is assumed to be a pointer to long long int.
|
||||||
|
j For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of intmax_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to intmax_t.
|
||||||
|
z For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of size_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to size_t.
|
||||||
|
t For "diouxX" conversions, the argument from the argument stack is
|
||||||
|
assumed to be of ptrdiff_t width. For 'n' conversions, the argument is
|
||||||
|
assumed to be a pointer to ptrdiff_t.
|
||||||
|
L For "aAeEfFgG" conversions, the argument from the argument stack is
|
||||||
|
assumed to be a long double.
|
||||||
|
Length modifiers appearing for any conversions not mentioned above will have
|
||||||
|
undefined behaviour.
|
||||||
|
If a length modifier appears with any conversion specifier other than as
|
||||||
|
specified above, the behavior is undefined.
|
||||||
|
|
||||||
|
CONVERSION SPECIFIERS
|
||||||
|
d,i The argument from the argument stack is assumed to be of type int, and
|
||||||
|
is converted to a signed decimal value with a minimum number of digits
|
||||||
|
as specified by the precision (default 1), padded with leading zeroes.
|
||||||
|
A zero value converted with precision zero yields no output.
|
||||||
|
o The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and is converted to an unsigned octal value, other behaviour being
|
||||||
|
as above.
|
||||||
|
u The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and converted to an unsigned decimal value, other behaviour being
|
||||||
|
as above.
|
||||||
|
x,X The argument from the argument stack is assumed to be of type unsigned
|
||||||
|
int, and converted to an unsigned hexadecimal value, using lowercase
|
||||||
|
"abcdef" for 'x' and uppercase "ABCDEF" for 'X' conversion, other
|
||||||
|
behaviour being as above.
|
||||||
|
f,F The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a decimal floating point in decimal-point notation,
|
||||||
|
with the number of digits after the decimal point as specified by the
|
||||||
|
precision (default 6) and the value being rounded appropriately. If
|
||||||
|
precision is zero (and the '#' flag is not given), no decimal point is
|
||||||
|
printed. At least one digit is always printed before the decimal point.
|
||||||
|
For 'f' conversions, an infinity value is printed as either [-]inf or
|
||||||
|
[-]infinity (, depending on the configuration of this implementation. A
|
||||||
|
NaN value is printed as [-]nan. For 'F' conversions uppercase characters
|
||||||
|
are used for these special values. The flags '-', '+' and ' ' apply as
|
||||||
|
usual to these special values, '#' and '0' have no effect.
|
||||||
|
e,E The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a decimal floating point in normalized exponential
|
||||||
|
notation ([?]d.ddd edd). "Normalized" means one nonzero digit before
|
||||||
|
the decimal point, unless the value is zero. The number of digits after
|
||||||
|
the decimal point is specified by the precision (default 6), the value
|
||||||
|
being rounded appropriately. If precision is zero (and the '#' flag is
|
||||||
|
not given), no decimal point is printed. The exponent has at least two
|
||||||
|
digits, and not more than necessary to represent the exponent. If the
|
||||||
|
value is zero, the exponent is zero. The 'e' written to indicate the
|
||||||
|
exponend is uppercase for 'E' conversions.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
g,G The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted according to either 'f' or 'e' format for 'g' conversions,
|
||||||
|
or 'F' or 'E' format for 'G' conversions, respectively, with the actual
|
||||||
|
conversion chosen depending on the value. 'e' / 'E' conversion is chosen
|
||||||
|
if the resulting exponent is < -4 or >= the precision (default 1).
|
||||||
|
Trailing zeroes are removed (unless the '#' flag is given). A decimal
|
||||||
|
point appears only if followed by a digit.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
a,A The argument from the argument stack is assumed to be of type double,
|
||||||
|
and converted to a floating point hexadecimal notation ([?]0xh.hhhh pd)
|
||||||
|
with one hexadecimal digit (being nonzero if the value is normalized,
|
||||||
|
and otherwise unspecified) before the decimal point, and the number of
|
||||||
|
digits after the decimal point being specified by the precision. If no
|
||||||
|
precision is given, the default is to print as many digits as nevessary
|
||||||
|
to give an exact representation of the value (if FLT_RADIX is a power of
|
||||||
|
2). If no precision is given and FLT_RADIX is not a power of 2, the
|
||||||
|
default is to print as many digits to distinguish values of type double
|
||||||
|
(possibly omitting trailing zeroes). (A precision p is sufficient to
|
||||||
|
distinguish values of the source type if 16^p-1 > b^n where b is
|
||||||
|
FLT_RADIX and n is the number of digits in the significand (to base b)
|
||||||
|
of the source type. A smaller p might suffice depending on the
|
||||||
|
implementation's scheme for determining the digit to the left of the
|
||||||
|
decimal point.) The error has the correct sign for the current rounding
|
||||||
|
direction.
|
||||||
|
Unless the '#' flag is given, no decimal-point is given for zero
|
||||||
|
precision.
|
||||||
|
The 'a' conversion uses lowercase "abcdef", "0x" and 'p', the 'A'
|
||||||
|
conversion uppercase "ABCDEF", "0X" and 'P'.
|
||||||
|
The exponent always has at least one digit, and not more than necessary
|
||||||
|
to represent the decimal exponent of 2. If the value is zero, the
|
||||||
|
exponent is zero.
|
||||||
|
Infinity or NaN values are represented as for 'f' and 'F' conversions,
|
||||||
|
respectively.
|
||||||
|
Binary implementations are at liberty to chose the hexadecimal digit to
|
||||||
|
the left of the decimal point so that subsequent digits align to nibble
|
||||||
|
boundaries.
|
||||||
|
c The argument from the argument stack is assumed to be of type int, and
|
||||||
|
converted to a character after the value has been cast to unsigned char.
|
||||||
|
If the 'l' length modifier is given, the argument is assumed to be of
|
||||||
|
type wint_t, and converted as by a "%ls" conversion with no precision
|
||||||
|
and a pointer to a two-element wchar_t array, with the first element
|
||||||
|
being the wint_t argument and the second a '\0' wide character.
|
||||||
|
s The argument from the argument stack is assumed to be a char array (i.e.
|
||||||
|
pointer to char). Characters from that array are printed until a zero
|
||||||
|
byte is encountered or as many bytes as specified by a given precision
|
||||||
|
have been written.
|
||||||
|
If the l length modifier is given, the argument from the argument stack
|
||||||
|
is assumed to be a wchar_t array (i.e. pointer to wchar_t). Wide
|
||||||
|
characters from that array are converted to multibyte characters as by
|
||||||
|
calls to wcrtomb() (using a mbstate_t object initialized to zero prior
|
||||||
|
to the first conversion), up to and including the terminating null wide
|
||||||
|
character. The resulting multibyte character sequence is then printed up
|
||||||
|
to but not including the terminating null character. If a precision is
|
||||||
|
given, it specifies the maximum number of bytes to be written (including
|
||||||
|
shift sequences). If the given precision would require access to a wide
|
||||||
|
character one past the end of the array, the array shall contain a '\0'
|
||||||
|
wide character. In no case is a partial multibyte character written.
|
||||||
|
Redundant shift sequences may result if the multibyte characters have a
|
||||||
|
state-dependent encoding.
|
||||||
|
TODO: Clarify these statements regarding %ls.
|
||||||
|
p The argument from the argument stack is assumed to be a void pointer,
|
||||||
|
and converted to a sequence of printing characters in an implementation-
|
||||||
|
defined manner.
|
||||||
|
This implementation casts the pointer to type intptr_t, and prints the
|
||||||
|
value as if a %#x conversion specifier was given.
|
||||||
|
n The argument from the argument stack is assumed to be a pointer to a
|
||||||
|
signed integer, into which the number of characters written so far by
|
||||||
|
this call to fprintf is stored. The behaviour, should any flags, field
|
||||||
|
widths, or precisions be given is undefined.
|
||||||
|
% A verbatim '%' character is written. No argument is taken from the
|
||||||
|
argument stack.
|
||||||
|
|
||||||
|
Returns the number of characters written if successful, a negative value
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
int fprintf( FILE * restrict stream, const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* TODO: fscanf() documentation */
|
||||||
|
/*
|
||||||
|
Read input from a given stream, as defined by the given format string, and
|
||||||
|
store converted input in the objects pointed to by 0..n subsequent arguments
|
||||||
|
(the argument stack).
|
||||||
|
|
||||||
|
The format string contains a sequence of directives that are expected to
|
||||||
|
match the input. If such a directive fails to match, the function returns
|
||||||
|
(matching error). It also returns if an input error occurs (input error).
|
||||||
|
|
||||||
|
Directives can be:
|
||||||
|
- one or more whitespaces, matching any number of whitespaces in the input;
|
||||||
|
- printing characters, matching the input verbatim;
|
||||||
|
- conversion specifications, which convert an input sequence into a value as
|
||||||
|
defined by the individual specifier, and store that value in a memory
|
||||||
|
location pointed to by the next pointer on the argument stack. Details are
|
||||||
|
documented below. If there is an insufficient number of pointers on the
|
||||||
|
argument stack, behaviour is undefined. Additional arguments not required
|
||||||
|
by any conversion specifications are evaluated, but otherwise ignored.
|
||||||
|
|
||||||
|
(The standard specifies the format string is allowed to contain multibyte
|
||||||
|
character sequences as long as it starts and ends in initial shift state,
|
||||||
|
but this is not yet supported by this implementation, which interprets the
|
||||||
|
format string as sequence of char.)
|
||||||
|
TODO: Add multibyte support to scanf() functions.
|
||||||
|
|
||||||
|
A conversion specifier consists of:
|
||||||
|
- Optional assignment-suppressing character ('*') that makes the conversion
|
||||||
|
read input as usual, but does not assign the conversion result.
|
||||||
|
- Optional maximum field width as decimal integer.
|
||||||
|
- Optional length modifier specifying the size of the argument (one of "hh",
|
||||||
|
"ll", or one of the characters "hljztL").
|
||||||
|
- Conversion specifier character specifying the type of conversion to be
|
||||||
|
applied (and the type of the next argument from the argument stack). One
|
||||||
|
of the characters "diouxXaAeEfFgGcs[pn%".
|
||||||
|
|
||||||
|
LENGTH MODIFIERS
|
||||||
|
hh For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of of char width.
|
||||||
|
h For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of short int width.
|
||||||
|
l For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of long int width.
|
||||||
|
For "aAeEfFgG" conversions, it is assumed to point to a variable of type
|
||||||
|
double.
|
||||||
|
For "cs[" conversions, it is assumed to point to a variable of type
|
||||||
|
wchar_t.
|
||||||
|
ll For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of long long int width.
|
||||||
|
j For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of intmax_t width.
|
||||||
|
z For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of size_t width.
|
||||||
|
t For "diouxXn" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of ptrdiff_t width.
|
||||||
|
L For "aAeEfFgG" conversions, the next pointer from the argument stack is
|
||||||
|
assumed to point to a variable of type long double.
|
||||||
|
Length modifiers appearing for any conversions not mentioned above will have
|
||||||
|
undefined behaviour.
|
||||||
|
If a length modifier appears with any conversion specifier other than as
|
||||||
|
specified above, the behavior is undefined.
|
||||||
|
|
||||||
|
CONVERSION SPECIFIERS
|
||||||
|
d Matches an (optionally signed) decimal integer of the format expected
|
||||||
|
by strtol() with base 10. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer.
|
||||||
|
i Matches an (optionally signed) integer of the format expected by
|
||||||
|
strtol() with base 0. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer.
|
||||||
|
o Matches an (optionally signed) octal integer of the format expected by
|
||||||
|
strtoul() with base 8. The next pointer from the argument stack is
|
||||||
|
assumed to point to an unsigned integer.
|
||||||
|
u Matches an (optionally signed) decimal integer of the format expected
|
||||||
|
by strtoul() with base 10. The next pointer from the argument stack is
|
||||||
|
assumed to point to an unsigned integer.
|
||||||
|
x Matches an (optionally signed) hexadecimal integer of the format
|
||||||
|
expected by strtoul() with base 16. The next pointer from the argument
|
||||||
|
stack is assumed to point to an unsigned integer.
|
||||||
|
aefg Matches an (optionally signed) floating point number, infinity, or not-
|
||||||
|
a-number-value of the format expected by strtod(). The next pointer
|
||||||
|
from the argument stack is assumed to point to a float.
|
||||||
|
c Matches a number of characters as specified by the field width (default
|
||||||
|
1). The next pointer from the argument stack is assumed to point to a
|
||||||
|
character array large enough to hold that many characters.
|
||||||
|
If the 'l' length modifier is given, the input is assumed to match a
|
||||||
|
sequence of multibyte characters (starting in the initial shift state),
|
||||||
|
which will be converted to a wide character sequence as by successive
|
||||||
|
calls to mbrtowc() with a mbstate_t object initialized to zero prior to
|
||||||
|
the first conversion. The next pointer from the argument stack is
|
||||||
|
assumed to point to a wchar_t array large enough to hold that many
|
||||||
|
characters.
|
||||||
|
In either case, note that no '\0' character is added to terminate the
|
||||||
|
sequence.
|
||||||
|
s Matches a sequence of non-white-space characters. The next pointer from
|
||||||
|
the argument stack is assumed to point to a character array large
|
||||||
|
enough to hold the sequence including terminating '\0' character.
|
||||||
|
If the 'l' length modifier is given, the input is assumed to match a
|
||||||
|
sequence of multibyte characters (starting in the initial shift state),
|
||||||
|
which will be converted to a wide character sequence as by a call to
|
||||||
|
mbrtowc() with a mbstate_t object initialized to zero prior to the
|
||||||
|
first conversion. The next pointer from the argument stack is assumed
|
||||||
|
to point to a wchar_t array large enough to hold the sequence including
|
||||||
|
terminating '\0' character.
|
||||||
|
[ Matches a nonempty sequence consisting of any of those characters
|
||||||
|
specified between itself and a corresponding closing bracket (']').
|
||||||
|
If the first character in the list is a circumflex ('^'), this matches
|
||||||
|
a nonempty sequence consisting of any characters NOT specified. If the
|
||||||
|
closing bracket appears as the first character in the scanset ("[]" or
|
||||||
|
"[^]", it is assumed to belong to the scanset, which then ends with the
|
||||||
|
NEXT closing bracket.
|
||||||
|
If there is a '-' character in the scanset which is not the first after
|
||||||
|
the opening bracket (or the circumflex, see above) or the last in the
|
||||||
|
scanset, behaviour is implementation-defined. This implementation
|
||||||
|
handles this character like any other.
|
||||||
|
|
||||||
|
The extend of the input field is determined byte-by-byte for the above
|
||||||
|
conversions ('c', 's', '['), with no special provisions being made for
|
||||||
|
multibyte characters. The resulting field is nevertheless a multibyte
|
||||||
|
sequence begining in intial shift state.
|
||||||
|
|
||||||
|
p Matches a sequence of characters as produced by the printf() "%p"
|
||||||
|
conversion. The next pointer from the argument stack is assumed to
|
||||||
|
point to a void pointer, which will be filled with the same location
|
||||||
|
as the pointer used in the printf() statement. Note that behaviour is
|
||||||
|
undefined if the input value is not the result of an earlier printf()
|
||||||
|
call.
|
||||||
|
n Does not read input. The next pointer from the argument stack is
|
||||||
|
assumed to point to a signed integer, into which the number of
|
||||||
|
characters read from input so far by this call to fscanf() is stored.
|
||||||
|
This does not affect the return value of fscanf(). The behaviour,
|
||||||
|
should an assignment-supressing character of field width be given,
|
||||||
|
is undefined.
|
||||||
|
This can be used to test the success of literal matches and suppressed
|
||||||
|
assignments.
|
||||||
|
% Matches a single, verbatim '%' character.
|
||||||
|
|
||||||
|
A, E, F, G and X are valid, and equivalent to their lowercase counterparts.
|
||||||
|
|
||||||
|
All conversions except [, c, or n imply that whitespace characters from the
|
||||||
|
input stream are consumed until a non-whitespace character is encountered.
|
||||||
|
Such whitespaces do not count against a maximum field width.
|
||||||
|
|
||||||
|
Conversions push at most one character back into the input stream. That
|
||||||
|
implies that some character sequences converted by the strtol() and strtod()
|
||||||
|
function families are not converted identically by the scnaf() function
|
||||||
|
family.
|
||||||
|
|
||||||
|
Returns the number of input items successfully assigned. This can be zero if
|
||||||
|
an early mismatch occurs. Returns EOF if an input failure occurs before the
|
||||||
|
first conversion.
|
||||||
|
*/
|
||||||
|
int fscanf( FILE * restrict stream, const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ). */
|
||||||
|
int printf( const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ). */
|
||||||
|
int scanf( const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the result is
|
||||||
|
written into the buffer pointed to by s, instead of stdout, and that any
|
||||||
|
characters beyond the (n-1)th are discarded. The (n)th character is
|
||||||
|
replaced by a '\0' character in this case.
|
||||||
|
Returns the number of characters that would have been written (not counting
|
||||||
|
the terminating '\0' character) if n had been sufficiently large, if
|
||||||
|
successful, and a negative number if an encoding error ocurred.
|
||||||
|
*/
|
||||||
|
int snprintf( char * restrict s, size_t n, const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the result is
|
||||||
|
written into the buffer pointed to by s, instead of stdout.
|
||||||
|
*/
|
||||||
|
int sprintf( char * restrict s, const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the input is read
|
||||||
|
from the buffer pointed to by s, instead of stdin.
|
||||||
|
*/
|
||||||
|
int sscanf( const char * restrict s, const char * restrict format, ... );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stream, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vfprintf( FILE * restrict stream, const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stream, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vfscanf( FILE * restrict stream, const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vprintf( const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vscanf( const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to snprintf( s, n, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vsnprintf( char * restrict s, size_t n, const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fprintf( stdout, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter, and the result is written to the buffer
|
||||||
|
pointed to by s, instead of stdout. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vsprintf( char * restrict s, const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Equivalent to fscanf( stdin, format, ... ), except that the argument stack
|
||||||
|
is passed as va_list parameter, and the input is read from the buffer
|
||||||
|
pointed to by s, instead of stdin. Note that va_list is not declared by
|
||||||
|
<stdio.h>.
|
||||||
|
*/
|
||||||
|
int vsscanf( const char * restrict s, const char * restrict format, _PDCLIB_va_list arg );
|
||||||
|
|
||||||
|
/* Character input/output functions */
|
||||||
|
|
||||||
|
/* Retrieve the next character from given stream.
|
||||||
|
Returns the character, EOF otherwise.
|
||||||
|
If end-of-file is reached, the EOF indicator of the stream is set.
|
||||||
|
If a read error occurs, the error indicator of the stream is set.
|
||||||
|
*/
|
||||||
|
int fgetc( FILE * stream );
|
||||||
|
|
||||||
|
/* Read at most n-1 characters from given stream into the array s, stopping at
|
||||||
|
\n or EOF. Terminate the read string with \n. If EOF is encountered before
|
||||||
|
any characters are read, leave the contents of s unchanged.
|
||||||
|
Returns s if successful, NULL otherwise.
|
||||||
|
If a read error occurs, the error indicator of the stream is set. In this
|
||||||
|
case, the contents of s are indeterminate.
|
||||||
|
*/
|
||||||
|
char * fgets( char * restrict s, int n, FILE * restrict stream );
|
||||||
|
|
||||||
|
/* Write the value c (cast to unsigned char) to the given stream.
|
||||||
|
Returns c if successful, EOF otherwise.
|
||||||
|
If a write error occurs, sets the error indicator of the stream is set.
|
||||||
|
*/
|
||||||
|
int fputc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Write the string s (not including the terminating \0) to the given stream.
|
||||||
|
Returns a value >=0 if successful, EOF otherwise.
|
||||||
|
This implementation does set the error indicator of the stream if a write
|
||||||
|
error occurs.
|
||||||
|
*/
|
||||||
|
int fputs( const char * restrict s, FILE * restrict stream );
|
||||||
|
|
||||||
|
/* Equivalent to fgetc( stream ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
int getc( FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to fgetc( stdin ). */
|
||||||
|
int getchar( void );
|
||||||
|
|
||||||
|
/* Equivalent to fputc( c, stream ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
int putc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to fputc( c, stdout ), but may be overloaded by a macro that
|
||||||
|
evaluates its parameter more than once.
|
||||||
|
*/
|
||||||
|
int putchar( int c );
|
||||||
|
|
||||||
|
/* Write the string s (not including the terminating \0) to stdout, and append
|
||||||
|
a newline to the output. Returns a value >= 0 when successful, EOF if a
|
||||||
|
write error occurred.
|
||||||
|
*/
|
||||||
|
int puts( const char * s );
|
||||||
|
|
||||||
|
/* Push the value c (cast to unsigned char) back onto the given (input) stream.
|
||||||
|
A character pushed back in this way will be delivered by subsequent read
|
||||||
|
operations (and skipped by subsequent file positioning operations) as if it
|
||||||
|
has not been read. The external representation of the stream is unaffected
|
||||||
|
by this pushback (it is a buffer operation). One character of pushback is
|
||||||
|
guaranteed, further pushbacks may fail. EOF as value for c does not change
|
||||||
|
the input stream and results in failure of the function.
|
||||||
|
For text files, the file position indicator is indeterminate until all
|
||||||
|
pushed-back characters are read. For binary files, the file position
|
||||||
|
indicator is decremented by each successful call of ungetc(). If the file
|
||||||
|
position indicator for a binary file was zero before the call of ungetc(),
|
||||||
|
behaviour is undefined. (Older versions of the library allowed such a call.)
|
||||||
|
Returns the pushed-back character if successful, EOF if it fails.
|
||||||
|
*/
|
||||||
|
int ungetc( int c, FILE * stream );
|
||||||
|
|
||||||
|
/* Direct input/output functions */
|
||||||
|
|
||||||
|
/* Read up to nmemb elements of given size from given stream into the buffer
|
||||||
|
pointed to by ptr. Returns the number of elements successfully read, which
|
||||||
|
may be less than nmemb if a read error or EOF is encountered. If a read
|
||||||
|
error is encountered, the value of the file position indicator is
|
||||||
|
indeterminate. If a partial element is read, its value is indeterminate.
|
||||||
|
If size or nmemb are zero, the function does nothing and returns zero.
|
||||||
|
*/
|
||||||
|
size_t fread( void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream );
|
||||||
|
|
||||||
|
/* Write up to nmemb elements of given size from buffer pointed to by ptr to
|
||||||
|
the given stream. Returns the number of elements successfully written, which
|
||||||
|
will be less than nmemb only if a write error is encountered. If a write
|
||||||
|
error is encountered, the value of the file position indicator is
|
||||||
|
indeterminate. If size or nmemb are zero, the function does nothing and
|
||||||
|
returns zero.
|
||||||
|
*/
|
||||||
|
size_t fwrite( const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream );
|
||||||
|
|
||||||
|
/* File positioning functions */
|
||||||
|
|
||||||
|
/* Store the current position indicator (and, where appropriate, the current
|
||||||
|
mbstate_t status object) for the given stream into the given pos object. The
|
||||||
|
actual contents of the object are unspecified, but it can be used as second
|
||||||
|
parameter to fsetpos() to reposition the stream to the exact position and
|
||||||
|
parse state at the time fgetpos() was called.
|
||||||
|
Returns zero if successful, nonzero otherwise.
|
||||||
|
TODO: Implementation-defined errno setting for fgetpos().
|
||||||
|
*/
|
||||||
|
int fgetpos( FILE * restrict stream, fpos_t * restrict pos );
|
||||||
|
|
||||||
|
/* Set the position indicator for the given stream to the given offset from:
|
||||||
|
- the beginning of the file if whence is SEEK_SET,
|
||||||
|
- the current value of the position indicator if whence is SEEK_CUR,
|
||||||
|
- end-of-file if whence is SEEK_END.
|
||||||
|
On text streams, non-zero offsets are only allowed with SEEK_SET, and must
|
||||||
|
have been returned by ftell() for the same file.
|
||||||
|
Any characters buffered by ungetc() are dropped, the end-of-file indicator
|
||||||
|
for the stream is cleared. If the given stream is an update stream, the next
|
||||||
|
operation after a successful fseek() may be either input or output.
|
||||||
|
Returns zero if successful, nonzero otherwise. If a read/write error occurs,
|
||||||
|
the error indicator for the given stream is set.
|
||||||
|
*/
|
||||||
|
int fseek( FILE * stream, long int offset, int whence );
|
||||||
|
|
||||||
|
/* Set the position indicator (and, where appropriate the mbstate_t status
|
||||||
|
object) for the given stream to the given pos object (created by an earlier
|
||||||
|
call to fgetpos() on the same file).
|
||||||
|
Any characters buffered by ungetc() are dropped, the end-of-file indicator
|
||||||
|
for the stream is cleared. If the given stream is an update stream, the next
|
||||||
|
operation after a successful fsetpos() may be either input or output.
|
||||||
|
Returns zero if successful, nonzero otherwise. If a read/write error occurs,
|
||||||
|
the error indicator for the given stream is set.
|
||||||
|
TODO: Implementation-defined errno setting for fsetpos().
|
||||||
|
*/
|
||||||
|
int fsetpos( FILE * stream, const fpos_t * pos );
|
||||||
|
|
||||||
|
/* Return the current offset of the given stream from the beginning of the
|
||||||
|
associated file. For text streams, the exact value returned is unspecified
|
||||||
|
(and may not be equal to the number of characters), but may be used in
|
||||||
|
subsequent calls to fseek().
|
||||||
|
Returns -1L if unsuccessful.
|
||||||
|
TODO: Implementation-defined errno setting for ftell().
|
||||||
|
*/
|
||||||
|
long int ftell( FILE * stream );
|
||||||
|
|
||||||
|
/* Equivalent to (void)fseek( stream, 0L, SEEK_SET ), except that the error
|
||||||
|
indicator for the stream is also cleared.
|
||||||
|
*/
|
||||||
|
void rewind( FILE * stream );
|
||||||
|
|
||||||
|
/* Error-handling functions */
|
||||||
|
|
||||||
|
/* Clear the end-of-file and error indicators for the given stream. */
|
||||||
|
void clearerr( FILE * stream );
|
||||||
|
|
||||||
|
/* Return zero if the end-of-file indicator for the given stream is not set,
|
||||||
|
nonzero otherwise.
|
||||||
|
*/
|
||||||
|
int feof( FILE * stream );
|
||||||
|
|
||||||
|
/* Return zero if the error indicator for the given stream is not set, nonzero
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
int ferror( FILE * stream );
|
||||||
|
|
||||||
|
/* If s is neither a NULL pointer nor an empty string, print the string to
|
||||||
|
stderr (with appended colon (':') and a space) first. In any case, print an
|
||||||
|
error message depending on the current value of errno (being the same as if
|
||||||
|
strerror( errno ) had been called).
|
||||||
|
*/
|
||||||
|
void perror( const char * s );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
232
src/libraries/libc/include/stdlib.h
Normal file
232
src/libraries/libc/include/stdlib.h
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
#pragma once
|
||||||
|
/* General utilities <stdlib.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
#include "j6libc/wchar_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* Numeric conversion functions */
|
||||||
|
|
||||||
|
/* TODO: atof(), strtof(), strtod(), strtold() */
|
||||||
|
|
||||||
|
double atof( const char * nptr );
|
||||||
|
double strtod( const char * restrict nptr, char * * restrict endptr );
|
||||||
|
float strtof( const char * restrict nptr, char * * restrict endptr );
|
||||||
|
long double strtold( const char * restrict nptr, char * * restrict endptr );
|
||||||
|
|
||||||
|
/* Seperate the character array nptr into three parts: A (possibly empty)
|
||||||
|
sequence of whitespace characters, a character representation of an integer
|
||||||
|
to the given base, and trailing invalid characters (including the terminating
|
||||||
|
null character). If base is 0, assume it to be 10, unless the integer
|
||||||
|
representation starts with 0x / 0X (setting base to 16) or 0 (setting base to
|
||||||
|
8). If given, base can be anything from 0 to 36, using the 26 letters of the
|
||||||
|
base alphabet (both lowercase and uppercase) as digits 10 through 35.
|
||||||
|
The integer representation is then converted into the return type of the
|
||||||
|
function. It can start with a '+' or '-' sign. If the sign is '-', the result
|
||||||
|
of the conversion is negated.
|
||||||
|
If the conversion is successful, the converted value is returned. If endptr
|
||||||
|
is not a NULL pointer, a pointer to the first trailing invalid character is
|
||||||
|
returned in *endptr.
|
||||||
|
If no conversion could be performed, zero is returned (and nptr in *endptr,
|
||||||
|
if endptr is not a NULL pointer). If the converted value does not fit into
|
||||||
|
the return type, the functions return LONG_MIN, LONG_MAX, ULONG_MAX,
|
||||||
|
LLONG_MIN, LLONG_MAX, or ULLONG_MAX respectively, depending on the sign of
|
||||||
|
the integer representation and the return type, and errno is set to ERANGE.
|
||||||
|
*/
|
||||||
|
/* There is strtoimax() and strtoumax() in <inttypes.h> operating on intmax_t /
|
||||||
|
uintmax_t, if the long long versions do not suit your needs.
|
||||||
|
*/
|
||||||
|
long int strtol( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
long long int strtoll( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
unsigned long int strtoul( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
unsigned long long int strtoull( const char * restrict nptr, char * * restrict endptr, int base );
|
||||||
|
|
||||||
|
/* These functions are the equivalent of (int)strtol( nptr, NULL, 10 ),
|
||||||
|
strtol( nptr, NULL, 10 ) and strtoll(nptr, NULL, 10 ) respectively, with the
|
||||||
|
exception that they do not have to handle overflow situations in any defined
|
||||||
|
way.
|
||||||
|
(PDCLib does not simply forward these to their strtox() equivalents, but
|
||||||
|
provides a simpler atox() function that saves a couple of tests and simply
|
||||||
|
continues with the conversion in case of overflow.)
|
||||||
|
*/
|
||||||
|
int atoi( const char * nptr );
|
||||||
|
long int atol( const char * nptr );
|
||||||
|
long long int atoll( const char * nptr );
|
||||||
|
|
||||||
|
/* Pseudo-random sequence generation functions */
|
||||||
|
|
||||||
|
extern unsigned long int _PDCLIB_seed;
|
||||||
|
|
||||||
|
#define RAND_MAX 32767
|
||||||
|
|
||||||
|
/* Returns the next number in a pseudo-random sequence, which is between 0 and
|
||||||
|
RAND_MAX.
|
||||||
|
(PDCLib uses the implementation suggested by the standard document, which is
|
||||||
|
next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;)
|
||||||
|
*/
|
||||||
|
int rand( void );
|
||||||
|
|
||||||
|
/* Initialize a new pseudo-random sequence with the starting seed. Same seeds
|
||||||
|
result in the same pseudo-random sequence. The default seed is 1.
|
||||||
|
*/
|
||||||
|
void srand( unsigned int seed );
|
||||||
|
|
||||||
|
/* Memory management functions */
|
||||||
|
|
||||||
|
/* Allocate a chunk of heap memory of given size. If request could not be
|
||||||
|
satisfied, return NULL. Otherwise, return a pointer to the allocated
|
||||||
|
memory. Memory contents are undefined.
|
||||||
|
*/
|
||||||
|
void * malloc( size_t size );
|
||||||
|
|
||||||
|
/* Allocate a chunk of heap memory that is large enough to hold nmemb elements
|
||||||
|
of the given size, and zero-initialize that memory. If request could not be
|
||||||
|
satisfied, return NULL. Otherwise, return a pointer to the allocated
|
||||||
|
memory.
|
||||||
|
*/
|
||||||
|
void * calloc( size_t nmemb, size_t size );
|
||||||
|
|
||||||
|
/* De-allocate a chunk of heap memory previously allocated using malloc(),
|
||||||
|
calloc(), or realloc(), and pointed to by ptr. If ptr does not match a
|
||||||
|
pointer previously returned by the mentioned allocation functions, or
|
||||||
|
free() has already been called for this ptr, behaviour is undefined.
|
||||||
|
*/
|
||||||
|
void free( void * ptr );
|
||||||
|
|
||||||
|
/* Resize a chunk of memory previously allocated with malloc() and pointed to
|
||||||
|
by ptr to the given size (which might be larger or smaller than the original
|
||||||
|
size). Returns a pointer to the reallocated memory, or NULL if the request
|
||||||
|
could not be satisfied. Note that the resizing might include a memcpy()
|
||||||
|
from the original location to a different one, so the return value might or
|
||||||
|
might not equal ptr. If size is larger than the original size, the value of
|
||||||
|
memory beyond the original size is undefined. If ptr is NULL, realloc()
|
||||||
|
behaves like malloc().
|
||||||
|
*/
|
||||||
|
void * realloc( void * ptr, size_t size );
|
||||||
|
|
||||||
|
/* Communication with the environment */
|
||||||
|
|
||||||
|
/* These two can be passed to exit() or _Exit() as status values, to signal
|
||||||
|
successful and unsuccessful program termination, respectively. EXIT_SUCCESS
|
||||||
|
can be replaced by 0. How successful or unsuccessful program termination are
|
||||||
|
signaled to the environment, and what happens if exit() or _Exit() are being
|
||||||
|
called with a value that is neither of the three, is defined by the hosting
|
||||||
|
OS and its glue function.
|
||||||
|
*/
|
||||||
|
#define EXIT_SUCCESS _PDCLIB_SUCCESS
|
||||||
|
#define EXIT_FAILURE _PDCLIB_FAILURE
|
||||||
|
|
||||||
|
/* Initiate abnormal process termination, unless programm catches SIGABRT and
|
||||||
|
does not return from the signal handler.
|
||||||
|
This implementantion flushes all streams, closes all files, and removes any
|
||||||
|
temporary files before exiting with EXIT_FAILURE.
|
||||||
|
abort() does not return.
|
||||||
|
*/
|
||||||
|
void abort( void );
|
||||||
|
|
||||||
|
/* Register a function that will be called on exit(), or when main() returns.
|
||||||
|
At least 32 functions can be registered this way, and will be called in
|
||||||
|
reverse order of registration (last-in, first-out).
|
||||||
|
Returns zero if registration is successfull, nonzero if it failed.
|
||||||
|
*/
|
||||||
|
int atexit( void (*func)( void ) );
|
||||||
|
|
||||||
|
/* Normal process termination. Functions registered by atexit() (see above) are
|
||||||
|
called, streams flushed, files closed and temporary files removed before the
|
||||||
|
program is terminated with the given status. (See comment for EXIT_SUCCESS
|
||||||
|
and EXIT_FAILURE above.)
|
||||||
|
exit() does not return.
|
||||||
|
*/
|
||||||
|
void exit( int status );
|
||||||
|
|
||||||
|
/* Normal process termination. Functions registered by atexit() (see above) are
|
||||||
|
NOT CALLED. This implementation DOES flush streams, close files and removes
|
||||||
|
temporary files before the program is teminated with the given status. (See
|
||||||
|
comment for EXIT_SUCCESS and EXIT_FAILURE above.)
|
||||||
|
_Exit() does not return.
|
||||||
|
*/
|
||||||
|
void _Exit( int status );
|
||||||
|
|
||||||
|
/* Search an environment-provided key-value map for the given key name, and
|
||||||
|
return a pointer to the associated value string (or NULL if key name cannot
|
||||||
|
be found). The value string pointed to might be overwritten by a subsequent
|
||||||
|
call to getenv(). The library never calls getenv() itself.
|
||||||
|
Details on the provided keys and how to set / change them are determined by
|
||||||
|
the hosting OS and its glue function.
|
||||||
|
*/
|
||||||
|
char * getenv( const char * name );
|
||||||
|
|
||||||
|
/* If string is a NULL pointer, system() returns nonzero if a command processor
|
||||||
|
is available, and zero otherwise. If string is not a NULL pointer, it is
|
||||||
|
passed to the command processor. If system() returns, it does so with a
|
||||||
|
value that is determined by the hosting OS and its glue function.
|
||||||
|
*/
|
||||||
|
int system( const char * string );
|
||||||
|
|
||||||
|
/* Searching and sorting */
|
||||||
|
|
||||||
|
/* Do a binary search for a given key in the array with a given base pointer,
|
||||||
|
which consists of nmemb elements that are of the given size each. To compare
|
||||||
|
the given key with an element from the array, the given function compar is
|
||||||
|
called (with key as first parameter and a pointer to the array member as
|
||||||
|
second parameter); the function should return a value less than, equal to,
|
||||||
|
or greater than 0 if the key is considered to be less than, equal to, or
|
||||||
|
greater than the array element, respectively.
|
||||||
|
The function returns a pointer to the first matching element found, or NULL
|
||||||
|
if no match is found.
|
||||||
|
*/
|
||||||
|
void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) );
|
||||||
|
|
||||||
|
/* Do a quicksort on an array with a given base pointer, which consists of
|
||||||
|
nmemb elements that are of the given size each. To compare two elements from
|
||||||
|
the array, the given function compar is called, which should return a value
|
||||||
|
less than, equal to, or greater than 0 if the first argument is considered
|
||||||
|
to be less than, equal to, or greater than the second argument, respectively.
|
||||||
|
If two elements are compared equal, their order in the sorted array is not
|
||||||
|
specified.
|
||||||
|
*/
|
||||||
|
void qsort( void * base, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) );
|
||||||
|
|
||||||
|
/* Integer arithmetic functions */
|
||||||
|
|
||||||
|
/* Return the absolute value of the argument. Note that on machines using two-
|
||||||
|
complement's notation (most modern CPUs), the largest negative value cannot
|
||||||
|
be represented as positive value. In this case, behaviour is unspecified.
|
||||||
|
*/
|
||||||
|
int abs( int j );
|
||||||
|
long int labs( long int j );
|
||||||
|
long long int llabs( long long int j );
|
||||||
|
|
||||||
|
/* These structures each have a member quot and a member rem, of type int (for
|
||||||
|
div_t), long int (for ldiv_t) and long long it (for lldiv_t) respectively.
|
||||||
|
The order of the members is platform-defined to allow the div() functions
|
||||||
|
below to be implemented efficiently.
|
||||||
|
*/
|
||||||
|
typedef struct _PDCLIB_div_t div_t;
|
||||||
|
typedef struct _PDCLIB_ldiv_t ldiv_t;
|
||||||
|
typedef struct _PDCLIB_lldiv_t lldiv_t;
|
||||||
|
|
||||||
|
/* Return quotient (quot) and remainder (rem) of an integer division in one of
|
||||||
|
the structs above.
|
||||||
|
*/
|
||||||
|
div_t div( int numer, int denom );
|
||||||
|
ldiv_t ldiv( long int numer, long int denom );
|
||||||
|
lldiv_t lldiv( long long int numer, long long int denom );
|
||||||
|
|
||||||
|
/* TODO: Multibyte / wide character conversion functions */
|
||||||
|
/* TODO: Macro MB_CUR_MAX */
|
||||||
|
int mblen( const char * s, size_t n );
|
||||||
|
int mbtowc( wchar_t * restrict pwc, const char * restrict s, size_t n );
|
||||||
|
int wctomb( char * s, wchar_t wc );
|
||||||
|
size_t mbstowcs( wchar_t * restrict pwcs, const char * restrict s, size_t n );
|
||||||
|
size_t wcstombs( char * restrict s, const wchar_t * restrict pwcs, size_t n );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
8
src/libraries/libc/include/stdnoreturn.h
Normal file
8
src/libraries/libc/include/stdnoreturn.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
/* _Noreturn <stdnoreturn.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define noreturn _Noreturn
|
||||||
178
src/libraries/libc/include/string.h
Normal file
178
src/libraries/libc/include/string.h
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
#pragma once
|
||||||
|
/* String handling <string.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* String function conventions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
In any of the following functions taking a size_t n to specify the length of
|
||||||
|
an array or size of a memory region, n may be 0, but the pointer arguments to
|
||||||
|
the call shall still be valid unless otherwise stated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copying functions */
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1. If the two areas overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
void * memcpy( void * restrict s1, const void * restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
||||||
|
area pointed to by s1. The two areas may overlap.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
void * memmove( void * restrict s1, const void * restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Copy the character array s2 (including terminating '\0' byte) into the
|
||||||
|
character array s1.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
char * strcpy( char * restrict s1, const char * restrict s2 );
|
||||||
|
|
||||||
|
/* Copy a maximum of n characters from the character array s2 into the character
|
||||||
|
array s1. If s2 is shorter than n characters, '\0' bytes will be appended to
|
||||||
|
the copy in s1 until n characters have been written. If s2 is longer than n
|
||||||
|
characters, NO terminating '\0' will be written to s1. If the arrays overlap,
|
||||||
|
behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
char * strncpy( char * restrict s1, const char * restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Concatenation functions */
|
||||||
|
|
||||||
|
/* Append the contents of the character array s2 (including terminating '\0') to
|
||||||
|
the character array s1 (first character of s2 overwriting the '\0' of s1). If
|
||||||
|
the arrays overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
char * strcat( char * restrict s1, const char * restrict s2 );
|
||||||
|
|
||||||
|
/* Append a maximum of n characters from the character array s1 to the character
|
||||||
|
array s1 (first character of s2 overwriting the '\0' of s1). A terminating
|
||||||
|
'\0' is ALWAYS appended, even if the full n characters have already been
|
||||||
|
written. If the arrays overlap, behaviour is undefined.
|
||||||
|
Returns the value of s1.
|
||||||
|
*/
|
||||||
|
char * strncat( char * restrict s1, const char * restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Comparison functions */
|
||||||
|
|
||||||
|
/* Compare the first n characters of the memory areas pointed to by s1 and s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
int memcmp( const void * s1, const void * s2, size_t n );
|
||||||
|
|
||||||
|
/* Compare the character arrays s1 and s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
int strcmp( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Compare the character arrays s1 and s2, interpreted as specified by the
|
||||||
|
LC_COLLATE category of the current locale.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
TODO: Currently a dummy wrapper for strcmp() as PDCLib does not yet support
|
||||||
|
locales.
|
||||||
|
*/
|
||||||
|
int strcoll( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Compare no more than the first n characters of the character arrays s1 and
|
||||||
|
s2.
|
||||||
|
Returns 0 if s1 == s2, a negative number if s1 < s2, and a positive number if
|
||||||
|
s1 > s2.
|
||||||
|
*/
|
||||||
|
int strncmp( const char * s1, const char * s2, size_t n );
|
||||||
|
|
||||||
|
/* Transform the character array s2 as appropriate for the LC_COLLATE setting of
|
||||||
|
the current locale. If length of resulting string is less than n, store it in
|
||||||
|
the character array pointed to by s1. Return the length of the resulting
|
||||||
|
string.
|
||||||
|
*/
|
||||||
|
size_t strxfrm( char * restrict s1, const char * restrict s2, size_t n );
|
||||||
|
|
||||||
|
/* Search functions */
|
||||||
|
|
||||||
|
/* Search the first n characters in the memory area pointed to by s for the
|
||||||
|
character c (interpreted as unsigned char).
|
||||||
|
Returns a pointer to the first instance found, or NULL.
|
||||||
|
*/
|
||||||
|
void * memchr( const void * s, int c, size_t n );
|
||||||
|
|
||||||
|
/* Search the character array s (including terminating '\0') for the character c
|
||||||
|
(interpreted as char).
|
||||||
|
Returns a pointer to the first instance found, or NULL.
|
||||||
|
*/
|
||||||
|
char * strchr( const char * s, int c );
|
||||||
|
|
||||||
|
/* Determine the length of the initial substring of character array s1 which
|
||||||
|
consists only of characters not from the character array s2.
|
||||||
|
Returns the length of that substring.
|
||||||
|
*/
|
||||||
|
size_t strcspn( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s1 for any character from the character array s2.
|
||||||
|
Returns a pointer to the first occurrence, or NULL.
|
||||||
|
*/
|
||||||
|
char * strpbrk( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s (including terminating '\0') for the character c
|
||||||
|
(interpreted as char).
|
||||||
|
Returns a pointer to the last instance found, or NULL.
|
||||||
|
*/
|
||||||
|
char * strrchr( const char * s, int c );
|
||||||
|
|
||||||
|
/* Determine the length of the initial substring of character array s1 which
|
||||||
|
consists only of characters from the character array s2.
|
||||||
|
Returns the length of that substring.
|
||||||
|
*/
|
||||||
|
size_t strspn( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* Search the character array s1 for the substring in character array s2.
|
||||||
|
Returns a pointer to that sbstring, or NULL. If s2 is of length zero,
|
||||||
|
returns s1.
|
||||||
|
*/
|
||||||
|
char * strstr( const char * s1, const char * s2 );
|
||||||
|
|
||||||
|
/* In a series of subsequent calls, parse a C string into tokens.
|
||||||
|
On the first call to strtok(), the first argument is a pointer to the to-be-
|
||||||
|
parsed C string. On subsequent calls, the first argument is NULL unless you
|
||||||
|
want to start parsing a new string. s2 holds an array of seperator characters
|
||||||
|
which can differ from call to call. Leading seperators are skipped, the first
|
||||||
|
trailing seperator overwritten with '\0'.
|
||||||
|
Returns a pointer to the next token.
|
||||||
|
WARNING: This function uses static storage, and as such is not reentrant.
|
||||||
|
*/
|
||||||
|
char * strtok( char * restrict s1, const char * restrict s2 );
|
||||||
|
|
||||||
|
/* Miscellaneous functions */
|
||||||
|
|
||||||
|
/* Write the character c (interpreted as unsigned char) to the first n
|
||||||
|
characters of the memory area pointed to by s.
|
||||||
|
Returns s.
|
||||||
|
*/
|
||||||
|
void * memset( void * s, int c, size_t n );
|
||||||
|
|
||||||
|
/* Map an error number to a (locale-specific) error message string. Error
|
||||||
|
numbers are typically errno values, but any number is mapped to a message.
|
||||||
|
TODO: PDCLib does not yet support locales.
|
||||||
|
*/
|
||||||
|
char * strerror( int errnum );
|
||||||
|
|
||||||
|
/* Returns the length of the string s (excluding terminating '\0').
|
||||||
|
*/
|
||||||
|
size_t strlen( const char * s );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
105
src/libraries/libc/include/time.h
Normal file
105
src/libraries/libc/include/time.h
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Date and time <time.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
/* These are defined to be "real types capable of representing types", with
|
||||||
|
"range and precision of times representable in [them being] implementation-
|
||||||
|
defined".
|
||||||
|
As part of struct timespec (see below), time_t is further defined as "a
|
||||||
|
linear count of seconds", with potentially different semantics from a
|
||||||
|
"normal" time_t.
|
||||||
|
For sake of simplicity, we used just that (common) definition of "seconds
|
||||||
|
since epoch" as integer.
|
||||||
|
*/
|
||||||
|
typedef _PDCLIB_time_t time_t;
|
||||||
|
typedef _PDCLIB_clock_t clock_t;
|
||||||
|
|
||||||
|
#define CLOCKS_PER_SEC _PDCLIB_CLOCKS_PER_SEC
|
||||||
|
#define TIME_UTC _PDCLIB_TIME_UTC
|
||||||
|
|
||||||
|
struct timespec
|
||||||
|
{
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tm
|
||||||
|
{
|
||||||
|
int tm_sec; /* 0-60 */
|
||||||
|
int tm_min; /* 0-59 */
|
||||||
|
int tm_hour; /* 0-23 */
|
||||||
|
int tm_mday; /* 1-31 */
|
||||||
|
int tm_mon; /* 0-11 */
|
||||||
|
int tm_year; /* years since 1900 */
|
||||||
|
int tm_wday; /* 0-6 */
|
||||||
|
int tm_yday; /* 0-365 */
|
||||||
|
int tm_isdst; /* >0 DST, 0 no DST, <0 information unavailable */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Returns the number of "clocks" in processor time since the invocation
|
||||||
|
of the program. Divide by CLOCKS_PER_SEC to get the value in seconds.
|
||||||
|
Returns -1 if the value cannot be represented in the return type or is
|
||||||
|
not available.
|
||||||
|
*/
|
||||||
|
clock_t clock( void );
|
||||||
|
|
||||||
|
/* Returns the difference between two calendar times in seconds. */
|
||||||
|
double difftime( time_t time1, time_t time0 );
|
||||||
|
|
||||||
|
/* Normalizes the values in the broken-down time pointed to by timeptr.
|
||||||
|
Returns the calender time specified by the broken-down time.
|
||||||
|
*/
|
||||||
|
time_t mktime( struct tm * timeptr );
|
||||||
|
|
||||||
|
/* Returns the current calender time. If timer is not a NULL pointer, stores
|
||||||
|
the current calender time at that address as well.
|
||||||
|
*/
|
||||||
|
time_t time( time_t * timer );
|
||||||
|
|
||||||
|
/* Sets the interval pointed to by ts to the current calender time, based
|
||||||
|
on the specified base.
|
||||||
|
Returns base, if successful, otherwise zero.
|
||||||
|
*/
|
||||||
|
int timespec_get( struct timespec * ts, int base );
|
||||||
|
|
||||||
|
/* Converts the broken-down time pointed to by timeptr into a string in the
|
||||||
|
form "Sun Sep 16 01:03:52 1973\n\0".
|
||||||
|
*/
|
||||||
|
char * asctime( const struct tm * timeptr );
|
||||||
|
|
||||||
|
/* Equivalent to asctime( localtime( timer ) ). */
|
||||||
|
char * ctime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as UTC.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if it
|
||||||
|
cannot be represented.
|
||||||
|
*/
|
||||||
|
struct tm * gmtime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Converts the calender time pointed to by timer into a broken-down time
|
||||||
|
expressed as local time.
|
||||||
|
Returns a pointer to the broken-down time, or a NULL pointer if if
|
||||||
|
cannot be represented.
|
||||||
|
*/
|
||||||
|
struct tm * localtime( const time_t * timer );
|
||||||
|
|
||||||
|
/* Writes the broken-down time pointed to by timeptr into the character
|
||||||
|
array pointed to by s. The string pointed to by format controls the
|
||||||
|
exact output. No more than maxsize charactrs will be written.
|
||||||
|
Returns the number of characters written (excluding the terminating
|
||||||
|
null character), or zero on failure.
|
||||||
|
*/
|
||||||
|
size_t strftime( char * restrict s, size_t maxsize, const char * restrict format, const struct tm * restrict timeptr );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
91
src/libraries/libc/include/wchar.h
Normal file
91
src/libraries/libc/include/wchar.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Wide character functions <wchar.h>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/null.h"
|
||||||
|
#include "j6libc/size_t.h"
|
||||||
|
#include "j6libc/wchar_t.h"
|
||||||
|
#include "j6libc/wctype_t.h"
|
||||||
|
#include "j6libc/wint_t.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
typedef unsigned long mbstate_t;
|
||||||
|
|
||||||
|
wint_t btowc(int);
|
||||||
|
int fwprintf(FILE *, const wchar_t *, ...);
|
||||||
|
int fwscanf(FILE *, const wchar_t *, ...);
|
||||||
|
int iswalnum(wint_t);
|
||||||
|
int iswalpha(wint_t);
|
||||||
|
int iswcntrl(wint_t);
|
||||||
|
int iswdigit(wint_t);
|
||||||
|
int iswgraph(wint_t);
|
||||||
|
int iswlower(wint_t);
|
||||||
|
int iswprint(wint_t);
|
||||||
|
int iswpunct(wint_t);
|
||||||
|
int iswspace(wint_t);
|
||||||
|
int iswupper(wint_t);
|
||||||
|
int iswxdigit(wint_t);
|
||||||
|
int iswctype(wint_t, wctype_t);
|
||||||
|
wint_t fgetwc(FILE *);
|
||||||
|
wchar_t *fgetws(wchar_t *, int, FILE *);
|
||||||
|
wint_t fputwc(wchar_t, FILE *);
|
||||||
|
int fputws(const wchar_t *, FILE *);
|
||||||
|
int fwide(FILE *, int);
|
||||||
|
wint_t getwc(FILE *);
|
||||||
|
wint_t getwchar(void);
|
||||||
|
int mbsinit(const mbstate_t *);
|
||||||
|
size_t mbrlen(const char *, size_t, mbstate_t *);
|
||||||
|
size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
|
||||||
|
size_t mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *);
|
||||||
|
wint_t putwc(wchar_t, FILE *);
|
||||||
|
wint_t putwchar(wchar_t);
|
||||||
|
int swprintf(wchar_t *, size_t, const wchar_t *, ...);
|
||||||
|
int swscanf(const wchar_t *, const wchar_t *, ...);
|
||||||
|
wint_t towlower(wint_t);
|
||||||
|
wint_t towupper(wint_t);
|
||||||
|
wint_t ungetwc(wint_t, FILE *);
|
||||||
|
int vfwprintf(FILE *, const wchar_t *, va_list);
|
||||||
|
int vwprintf(const wchar_t *, va_list);
|
||||||
|
int vswprintf(wchar_t *, size_t, const wchar_t *, va_list);
|
||||||
|
size_t wcrtomb(char *, wchar_t, mbstate_t *);
|
||||||
|
wchar_t *wcscat(wchar_t *, const wchar_t *);
|
||||||
|
wchar_t *wcschr(const wchar_t *, wchar_t);
|
||||||
|
int wcscmp(const wchar_t *, const wchar_t *);
|
||||||
|
int wcscoll(const wchar_t *, const wchar_t *);
|
||||||
|
wchar_t *wcscpy(wchar_t *, const wchar_t *);
|
||||||
|
size_t wcscspn(const wchar_t *, const wchar_t *);
|
||||||
|
size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
|
||||||
|
size_t wcslen(const wchar_t *);
|
||||||
|
wchar_t *wcsncat(wchar_t *, const wchar_t *, size_t);
|
||||||
|
int wcsncmp(const wchar_t *, const wchar_t *, size_t);
|
||||||
|
wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t);
|
||||||
|
wchar_t *wcspbrk(const wchar_t *, const wchar_t *);
|
||||||
|
wchar_t *wcsrchr(const wchar_t *, wchar_t);
|
||||||
|
size_t wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *);
|
||||||
|
size_t wcsspn(const wchar_t *, const wchar_t *);
|
||||||
|
wchar_t *wcsstr(const wchar_t *, const wchar_t *);
|
||||||
|
double wcstod(const wchar_t *, wchar_t **);
|
||||||
|
wchar_t *wcstok(wchar_t *, const wchar_t *, wchar_t **);
|
||||||
|
long int wcstol(const wchar_t *, wchar_t **, int);
|
||||||
|
unsigned long int wcstoul(const wchar_t *, wchar_t **, int);
|
||||||
|
wchar_t *wcswcs(const wchar_t *, const wchar_t *);
|
||||||
|
int wcswidth(const wchar_t *, size_t);
|
||||||
|
size_t wcsxfrm(wchar_t *, const wchar_t *, size_t);
|
||||||
|
int wctob(wint_t);
|
||||||
|
wctype_t wctype(const char *);
|
||||||
|
int wcwidth(wchar_t);
|
||||||
|
wchar_t *wmemchr(const wchar_t *, wchar_t, size_t);
|
||||||
|
int wmemcmp(const wchar_t *, const wchar_t *, size_t);
|
||||||
|
wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t);
|
||||||
|
wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t);
|
||||||
|
wchar_t *wmemset(wchar_t *, wchar_t, size_t);
|
||||||
|
int wprintf(const wchar_t *, ...);
|
||||||
|
int wscanf(const wchar_t *, ...);
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
138
src/libraries/libc/include/wctype.h
Normal file
138
src/libraries/libc/include/wctype.h
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#pragma once
|
||||||
|
/* Wide character classification and mapping utilities <wctype.h>
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/cpp.h"
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
#include "j6libc/wint_t.h"
|
||||||
|
|
||||||
|
CPP_CHECK_BEGIN
|
||||||
|
|
||||||
|
// wctrans_t
|
||||||
|
// wctype_t
|
||||||
|
|
||||||
|
#ifndef _PDCLIB_WEOF_DEFINED
|
||||||
|
#define _PDCLIB_WEOF_DEFINED _PDCLIB_WEOF_DEFINED
|
||||||
|
#define WEOF (wint_t)-1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wide character classification functions */
|
||||||
|
|
||||||
|
/* Returns iswalpha( wc ) || iswdigit( wc ) */
|
||||||
|
int iswalnum( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for wide characters for which either isupper( wc ) or
|
||||||
|
islower( wc ) is true, as well as a set of locale-specific wide
|
||||||
|
characters which are neither control characters, digits, punctuation,
|
||||||
|
or whitespace.
|
||||||
|
*/
|
||||||
|
int iswalpha( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the character iswspace() and used for separating words
|
||||||
|
within a line of text. In the "C" locale, only L' ' and L'\t' are
|
||||||
|
considered blanks.
|
||||||
|
*/
|
||||||
|
int iswblank( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a control character. */
|
||||||
|
int iswcntrl( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a decimal digit. Locale-
|
||||||
|
independent. */
|
||||||
|
int iswdigit( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns iswprint( wc ) && ! iswspace( wc ).
|
||||||
|
NOTE: This definition differs from that of isgraph() in <ctype.h>,
|
||||||
|
which considers only ' ', not all isspace() characters.
|
||||||
|
*/
|
||||||
|
int iswgraph( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for lowerspace wide characters, as well as a set of
|
||||||
|
locale-specific wide characters which are neither control charcters,
|
||||||
|
digits, punctuation, or whitespace.
|
||||||
|
*/
|
||||||
|
int iswlower( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for every printing wide character. */
|
||||||
|
int iswprint( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of punctuation characters that
|
||||||
|
are neither whitespace nor alphanumeric.
|
||||||
|
*/
|
||||||
|
int iswpunct( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for a locale-specific set of whitespace characters that
|
||||||
|
are neither alphanumeric, graphic, or punctuation.
|
||||||
|
*/
|
||||||
|
int iswspace( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true for upperspace wide characters, as well as a set of
|
||||||
|
locale-specific wide characters which are neither control charcters,
|
||||||
|
digits, punctuation, or whitespace.
|
||||||
|
*/
|
||||||
|
int iswupper( wint_t wc );
|
||||||
|
|
||||||
|
/* Returns true if the wide character is a hexadecimal digit. Locale-
|
||||||
|
independent. */
|
||||||
|
int iswxdigit( wint_t wc );
|
||||||
|
|
||||||
|
/* Extensible wide character classification functions */
|
||||||
|
|
||||||
|
/* Returns true if the wide character wc has the property described by
|
||||||
|
desc (which was retrieved by a previous call to wctype() without
|
||||||
|
changing the LC_CTYPE locale setting between the two calls).
|
||||||
|
*/
|
||||||
|
int iswctype( wint_t wc, wctype_t desc );
|
||||||
|
|
||||||
|
/* Returns a description object for a named character property, to be
|
||||||
|
used as parameter to the iswctype() function. Supported property
|
||||||
|
names are:
|
||||||
|
"alnum" -- alphanumeric, as per iswalnum()
|
||||||
|
"alpha" -- alphabetic, as per iswalpha()
|
||||||
|
"blank" -- blank, as per iswblank()
|
||||||
|
"cntrl" -- control, as per iswcntrl()
|
||||||
|
"digit" -- decimal digit, as per iswdigit()
|
||||||
|
"graph" -- graphic, as per iswgraph()
|
||||||
|
"lower" -- lowercase, as per iswlower()
|
||||||
|
"print" -- printing, as per iswprint()
|
||||||
|
"punct" -- punctuation, as per iswprint()
|
||||||
|
"space" -- whitespace, as per iswspace()
|
||||||
|
"upper" -- uppercase, as per iswupper()
|
||||||
|
"xdigit" -- hexadecimal digit, as per iswxdigit()
|
||||||
|
For unsupported properties, the function returns zero.
|
||||||
|
*/
|
||||||
|
wctype_t wctype( const char * property );
|
||||||
|
|
||||||
|
/* Wide character case mapping utilities */
|
||||||
|
|
||||||
|
/* Converts an uppercase letter to a corresponding lowercase letter. Input for
|
||||||
|
which no corresponding lowercase letter exists remains unchanged.
|
||||||
|
*/
|
||||||
|
wint_t towlower( wint_t wc );
|
||||||
|
|
||||||
|
/* Converts a lowercase letter to a corresponding uppercase letter. Input for
|
||||||
|
which no corresponding uppercase letter exists remains unchanged.
|
||||||
|
*/
|
||||||
|
wint_t towupper( wint_t wc );
|
||||||
|
|
||||||
|
/* Extensible wide character case mapping utilities */
|
||||||
|
|
||||||
|
/* Converts the wide character wc according to the transition described
|
||||||
|
by desc (which was retrieved by a previous call to wctrans() without
|
||||||
|
changing the LC_CTYPE locale setting between the two calls).
|
||||||
|
*/
|
||||||
|
wint_t towctrans( wint_t wc, wctrans_t desc );
|
||||||
|
|
||||||
|
/* Returns a description object for a named character transformation, to
|
||||||
|
be used as parameter to the towctrans() function. Supported transformation
|
||||||
|
properties are:
|
||||||
|
"tolower" -- lowercase mapping, as per towlower()
|
||||||
|
"toupper" -- uppercase mapping, as per towupper()
|
||||||
|
For unsupported properties, the function returns zero.
|
||||||
|
*/
|
||||||
|
wctrans_t wctrans( const char * property );
|
||||||
|
|
||||||
|
CPP_CHECK_END
|
||||||
12
src/libraries/libc/inttypes/imaxabs.c
Normal file
12
src/libraries/libc/inttypes/imaxabs.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* imaxabs( intmax_t )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
intmax_t imaxabs( intmax_t j )
|
||||||
|
{
|
||||||
|
return ( j >= 0 ) ? j : -j;
|
||||||
|
}
|
||||||
15
src/libraries/libc/inttypes/imaxdiv.c
Normal file
15
src/libraries/libc/inttypes/imaxdiv.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* lldiv( long long int, long long int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom )
|
||||||
|
{
|
||||||
|
imaxdiv_t rc;
|
||||||
|
rc.quot = numer / denom;
|
||||||
|
rc.rem = numer % denom;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
27
src/libraries/libc/inttypes/strtoimax.c
Normal file
27
src/libraries/libc/inttypes/strtoimax.c
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* strtoimax( const char *, char * *, int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
intmax_t strtoimax( const char * restrict nptr, char ** restrict endptr, int base )
|
||||||
|
{
|
||||||
|
intmax_t rc;
|
||||||
|
char sign = '+';
|
||||||
|
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
|
||||||
|
if ( base < 2 || base > 36 ) return 0;
|
||||||
|
if ( sign == '+' )
|
||||||
|
{
|
||||||
|
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MAX, (uintmax_t)( INTMAX_MAX / base ), (int)( INTMAX_MAX % base ), &sign );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = (intmax_t)_PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)INTMAX_MIN, (uintmax_t)( INTMAX_MIN / -base ), (int)( -( INTMAX_MIN % base ) ), &sign );
|
||||||
|
}
|
||||||
|
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
|
||||||
|
return ( sign == '+' ) ? rc : -rc;
|
||||||
|
}
|
||||||
20
src/libraries/libc/inttypes/strtoumax.c
Normal file
20
src/libraries/libc/inttypes/strtoumax.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* strtoumax( const char *, char * *, int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
uintmax_t strtoumax( const char * restrict nptr, char ** restrict endptr, int base )
|
||||||
|
{
|
||||||
|
uintmax_t rc;
|
||||||
|
char sign = '+';
|
||||||
|
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
|
||||||
|
if ( base < 2 || base > 36 ) return 0;
|
||||||
|
rc = _PDCLIB_strtox_main( &p, (unsigned)base, (uintmax_t)UINTMAX_MAX, (uintmax_t)( UINTMAX_MAX / base ), (int)( UINTMAX_MAX % base ), &sign );
|
||||||
|
if ( endptr != NULL ) *endptr = ( p != NULL ) ? (char *) p : (char *) nptr;
|
||||||
|
return ( sign == '+' ) ? rc : -rc;
|
||||||
|
}
|
||||||
10
src/libraries/libc/j6libc/Readme.txt
Normal file
10
src/libraries/libc/j6libc/Readme.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
This directory holds various "internals" of PDCLib:
|
||||||
|
|
||||||
|
- definitions of helper functions not specified by the standard (hidden in the
|
||||||
|
_PDCLIB_* namespace);
|
||||||
|
|
||||||
|
- definitions of data objects, both internal (like _PDCLIB_digits) and specified by
|
||||||
|
the standard (_PDCLIB_errno);
|
||||||
|
|
||||||
|
- test drivers for functionality that does not have its own implementation
|
||||||
|
file to put the test driver in (stdarg).
|
||||||
16
src/libraries/libc/j6libc/allocpages.c
Normal file
16
src/libraries/libc/j6libc/allocpages.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* _PDCLIB_allocpages( int const )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_allocpages() fit for use with
|
||||||
|
POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
void * _PDCLIB_allocpages( int const n )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
19
src/libraries/libc/j6libc/assert.c
Normal file
19
src/libraries/libc/j6libc/assert.c
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* _PDCLIB_assert( const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "j6libc/aux.h"
|
||||||
|
|
||||||
|
void _PDCLIB_assert( const char * const message1, const char * const function, const char * const message2 )
|
||||||
|
{
|
||||||
|
fputs( message1, stderr );
|
||||||
|
fputs( function, stderr );
|
||||||
|
fputs( message2, stderr );
|
||||||
|
abort();
|
||||||
|
}
|
||||||
25
src/libraries/libc/j6libc/atomax.c
Normal file
25
src/libraries/libc/j6libc/atomax.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* _PDCLIB_atomax( const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
intmax_t _PDCLIB_atomax( const char * s )
|
||||||
|
{
|
||||||
|
intmax_t rc = 0;
|
||||||
|
char sign = '+';
|
||||||
|
const char * x;
|
||||||
|
/* TODO: In other than "C" locale, additional patterns may be defined */
|
||||||
|
while ( isspace( *s ) ) ++s;
|
||||||
|
if ( *s == '+' ) ++s;
|
||||||
|
else if ( *s == '-' ) sign = *(s++);
|
||||||
|
/* TODO: Earlier version was missing tolower() but was not caught by tests */
|
||||||
|
while ( ( x = memchr( _PDCLIB_digits, tolower(*(s++)), 10 ) ) != NULL )
|
||||||
|
{
|
||||||
|
rc = rc * 10 + ( x - _PDCLIB_digits );
|
||||||
|
}
|
||||||
|
return ( sign == '+' ) ? rc : -rc;
|
||||||
|
}
|
||||||
16
src/libraries/libc/j6libc/close.c
Normal file
16
src/libraries/libc/j6libc/close.c
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* _PDCLIB_close( _PDCLIB_fd_t )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_close() fit for use with POSIX
|
||||||
|
kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_close( int fd )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
21
src/libraries/libc/j6libc/closeall.c
Normal file
21
src/libraries/libc/j6libc/closeall.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* _PDCLIB_closeall( void )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
|
||||||
|
|
||||||
|
void _PDCLIB_closeall( void )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * stream = _PDCLIB_filelist;
|
||||||
|
struct _PDCLIB_file_t * next;
|
||||||
|
while ( stream != NULL )
|
||||||
|
{
|
||||||
|
next = stream->next;
|
||||||
|
fclose( stream );
|
||||||
|
stream = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/libraries/libc/j6libc/digits.c
Normal file
12
src/libraries/libc/j6libc/digits.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* _PDCLIB_digits
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
const char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
/* For _PDCLIB/print.c only; obsolete with ctype.h */
|
||||||
|
const char _PDCLIB_Xdigits[] = "0123456789ABCDEF";
|
||||||
14
src/libraries/libc/j6libc/errno.c
Normal file
14
src/libraries/libc/j6libc/errno.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* _PDCLIB_errno
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
int _PDCLIB_errno = 0;
|
||||||
|
|
||||||
|
int * _PDCLIB_errno_func()
|
||||||
|
{
|
||||||
|
return &_PDCLIB_errno;
|
||||||
|
}
|
||||||
54
src/libraries/libc/j6libc/filemode.c
Normal file
54
src/libraries/libc/j6libc/filemode.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/* _PDCLIB_filemode( const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Helper function that parses the C-style mode string passed to fopen() into
|
||||||
|
the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary
|
||||||
|
mode).
|
||||||
|
*/
|
||||||
|
unsigned int _PDCLIB_filemode( const char * const mode )
|
||||||
|
{
|
||||||
|
unsigned rc = 0;
|
||||||
|
size_t i;
|
||||||
|
switch ( mode[0] )
|
||||||
|
{
|
||||||
|
case 'r':
|
||||||
|
rc |= _PDCLIB_FREAD;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
rc |= _PDCLIB_FWRITE;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
rc |= _PDCLIB_FAPPEND | _PDCLIB_FWRITE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Other than read, write, or append - invalid */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for ( i = 1; i < 4; ++i )
|
||||||
|
{
|
||||||
|
switch ( mode[i] )
|
||||||
|
{
|
||||||
|
case '+':
|
||||||
|
if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */
|
||||||
|
rc |= _PDCLIB_FRW;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */
|
||||||
|
rc |= _PDCLIB_FBIN;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
/* End of mode */
|
||||||
|
return rc;
|
||||||
|
default:
|
||||||
|
/* Other than read/write or binary - invalid. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Longer than three chars - invalid. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
19
src/libraries/libc/j6libc/fillbuffer.c
Normal file
19
src/libraries/libc/j6libc/fillbuffer.c
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_fillbuffer() fit for
|
||||||
|
use with POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
19
src/libraries/libc/j6libc/flushbuffer.c
Normal file
19
src/libraries/libc/j6libc/flushbuffer.c
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_flushbuffer() fit for
|
||||||
|
use with POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
14
src/libraries/libc/j6libc/is_leap.c
Normal file
14
src/libraries/libc/j6libc/is_leap.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* _PDCLIB_is_leap( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
int _PDCLIB_is_leap( int year_offset )
|
||||||
|
{
|
||||||
|
/* year given as offset from 1900, matching tm.tm_year in <time.h> */
|
||||||
|
long long year = year_offset + 1900ll;
|
||||||
|
return ( ( year % 4 ) == 0 && ( ( year % 25 ) != 0 || ( year % 400 ) == 0 ) );
|
||||||
|
}
|
||||||
44
src/libraries/libc/j6libc/load_lc_collate.c
Normal file
44
src/libraries/libc/j6libc/load_lc_collate.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* _PDCLIB_load_lc_collate( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_collate_t * rc = NULL;
|
||||||
|
const char * extension = "_collate.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_collate_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
/* TODO: Collation data */
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
74
src/libraries/libc/j6libc/load_lc_ctype.c
Normal file
74
src/libraries/libc/j6libc/load_lc_ctype.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/* _PDCLIB_load_lc_ctype( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_ctype_t * rc = NULL;
|
||||||
|
const char * extension = "_ctype.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_ctype_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_ctype_entry_t * entry;
|
||||||
|
|
||||||
|
if ( ( entry = malloc( sizeof( struct _PDCLIB_lc_ctype_entry_t ) * _PDCLIB_CHARSET_SIZE + 1 ) ) != NULL )
|
||||||
|
{
|
||||||
|
rc->entry = entry + 1;
|
||||||
|
rc->entry[ -1 ].flags = rc->entry[ -1 ].upper = rc->entry[ -1 ].lower = 0;
|
||||||
|
|
||||||
|
if ( fscanf( fh, "%x %x %x %x %x %x", &rc->digits_low, &_PDCLIB_lc_ctype.digits_high, &_PDCLIB_lc_ctype.Xdigits_low, &_PDCLIB_lc_ctype.Xdigits_high, &_PDCLIB_lc_ctype.xdigits_low, &_PDCLIB_lc_ctype.xdigits_high ) == 6 )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < _PDCLIB_CHARSET_SIZE; ++i )
|
||||||
|
{
|
||||||
|
if ( fscanf( fh, "%hx %hhx %hhx", &rc->entry[ i ].flags, &rc->entry[ i ].upper, &rc->entry[ i ].lower ) != 3 )
|
||||||
|
{
|
||||||
|
fclose( fh );
|
||||||
|
free( file );
|
||||||
|
free( rc->entry - 1 );
|
||||||
|
free( rc );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
60
src/libraries/libc/j6libc/load_lc_messages.c
Normal file
60
src/libraries/libc/j6libc/load_lc_messages.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/* _PDCLIB_load_lc_messages( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_messages_t * rc = NULL;
|
||||||
|
const char * extension = "_messages.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_messages_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, _PDCLIB_ERRNO_MAX );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < _PDCLIB_ERRNO_MAX; ++i )
|
||||||
|
{
|
||||||
|
rc->errno_texts[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
90
src/libraries/libc/j6libc/load_lc_monetary.c
Normal file
90
src/libraries/libc/j6libc/load_lc_monetary.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/* _PDCLIB_load_lc_monetary( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * rc = NULL;
|
||||||
|
const char * extension = "_monetary.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_lconv_monetary_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char buffer[ 14 ];
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 7 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
if ( fread( buffer, 1, 14, fh ) == 14 )
|
||||||
|
{
|
||||||
|
rc->mon_decimal_point = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->mon_thousands_sep = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->mon_grouping = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->positive_sign = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->negative_sign = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->currency_symbol = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->int_curr_symbol = data;
|
||||||
|
|
||||||
|
rc->frac_digits = buffer[ 0 ];
|
||||||
|
rc->p_cs_precedes = buffer[ 1 ];
|
||||||
|
rc->n_cs_precedes = buffer[ 2 ];
|
||||||
|
rc->p_sep_by_space = buffer[ 3 ];
|
||||||
|
rc->n_sep_by_space = buffer[ 4 ];
|
||||||
|
rc->p_sign_posn = buffer[ 5 ];
|
||||||
|
rc->n_sign_posn = buffer[ 6 ];
|
||||||
|
rc->int_frac_digits = buffer[ 7 ];
|
||||||
|
rc->int_p_cs_precedes = buffer[ 8 ];
|
||||||
|
rc->int_n_cs_precedes = buffer[ 9 ];
|
||||||
|
rc->int_p_sep_by_space = buffer[ 10 ];
|
||||||
|
rc->int_n_sep_by_space = buffer[ 11 ];
|
||||||
|
rc->int_p_sign_posn = buffer[ 12 ];
|
||||||
|
rc->int_n_sign_posn= buffer[ 13 ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( data );
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
56
src/libraries/libc/j6libc/load_lc_numeric.c
Normal file
56
src/libraries/libc/j6libc/load_lc_numeric.c
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/* _PDCLIB_load_lc_numeric( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * rc = NULL;
|
||||||
|
const char * extension = "_numeric.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_lconv_numeric_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 3 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
rc->decimal_point = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->thousands_sep = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
rc->grouping = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
79
src/libraries/libc/j6libc/load_lc_time.c
Normal file
79
src/libraries/libc/j6libc/load_lc_time.c
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* _PDCLIB_load_lc_time( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "j6libc/int.h"
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_lc_time_t * rc = NULL;
|
||||||
|
const char * extension = "_time.dat";
|
||||||
|
char * file = malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
|
||||||
|
|
||||||
|
if ( file )
|
||||||
|
{
|
||||||
|
FILE * fh;
|
||||||
|
|
||||||
|
strcpy( file, path );
|
||||||
|
strcat( file, locale );
|
||||||
|
strcat( file, extension );
|
||||||
|
|
||||||
|
if ( ( fh = fopen( file, "rb" ) ) != NULL )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( sizeof( struct _PDCLIB_lc_time_t ) ) ) != NULL )
|
||||||
|
{
|
||||||
|
char * data = _PDCLIB_load_lines( fh, 44 );
|
||||||
|
|
||||||
|
if ( data != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for ( i = 0; i < 12; ++i )
|
||||||
|
{
|
||||||
|
rc->month_name_abbr[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 12; ++i )
|
||||||
|
{
|
||||||
|
rc->month_name_full[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 7; ++i )
|
||||||
|
{
|
||||||
|
rc->day_name_abbr[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < 7; ++i )
|
||||||
|
{
|
||||||
|
rc->day_name_full[ i ] = data;
|
||||||
|
data += strlen( data ) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc->alloced = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free( rc );
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fh );
|
||||||
|
}
|
||||||
|
|
||||||
|
free( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
48
src/libraries/libc/j6libc/load_lines.c
Normal file
48
src/libraries/libc/j6libc/load_lines.c
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/* _PDCLIB_load_lines( FILE *, size_t )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char * _PDCLIB_load_lines( FILE * fh, size_t lines )
|
||||||
|
{
|
||||||
|
size_t required = 0;
|
||||||
|
long pos = ftell( fh );
|
||||||
|
char * rc = NULL;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* Count the number of characters */
|
||||||
|
while ( lines && ( c = fgetc( fh ) ) != EOF )
|
||||||
|
{
|
||||||
|
if ( c == '\n' )
|
||||||
|
{
|
||||||
|
--lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
++required;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! feof( fh ) )
|
||||||
|
{
|
||||||
|
if ( ( rc = malloc( required ) ) != NULL )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
fseek( fh, pos, SEEK_SET );
|
||||||
|
fread( rc, 1, required, fh );
|
||||||
|
|
||||||
|
for ( i = 0; i < required; ++i )
|
||||||
|
{
|
||||||
|
if ( rc[ i ] == '\n' )
|
||||||
|
{
|
||||||
|
rc[ i ] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
17
src/libraries/libc/j6libc/open.c
Normal file
17
src/libraries/libc/j6libc/open.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* _PDCLIB_open( const char * const, int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_open() fit for use with POSIX
|
||||||
|
kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_open( const char * const filename, unsigned int mode )
|
||||||
|
{
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
34
src/libraries/libc/j6libc/prepread.c
Normal file
34
src/libraries/libc/j6libc/prepread.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* _PDCLIB_prepread( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_prepread( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
if ( ( stream->bufidx > stream->bufend ) ||
|
||||||
|
( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) ||
|
||||||
|
! ( stream->status & ( _PDCLIB_FREAD | _PDCLIB_FRW ) ) )
|
||||||
|
{
|
||||||
|
/* Function called on illegal (e.g. output) stream.
|
||||||
|
See comments on implementation-defined errno values in
|
||||||
|
<config.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
stream->status |= _PDCLIB_FREAD | _PDCLIB_BYTESTREAM;
|
||||||
|
if ( ( stream->bufidx == stream->bufend ) && ( stream->ungetidx == 0 ) )
|
||||||
|
{
|
||||||
|
return _PDCLIB_fillbuffer( stream );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/libraries/libc/j6libc/prepwrite.c
Normal file
25
src/libraries/libc/j6libc/prepwrite.c
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* _PDCLIB_prepwrite( struct _PDCLIB_file_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
if ( ( stream->bufidx < stream->bufend ) || ( stream->ungetidx > 0 ) ||
|
||||||
|
( stream->status & ( _PDCLIB_FREAD | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) ||
|
||||||
|
! ( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) )
|
||||||
|
{
|
||||||
|
/* Function called on illegal (e.g. input) stream.
|
||||||
|
See the comments on implementation-defined errno values in
|
||||||
|
<config.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
stream->status |= _PDCLIB_ERRORFLAG;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
stream->status |= _PDCLIB_FWRITE | _PDCLIB_BYTESTREAM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
624
src/libraries/libc/j6libc/print.c
Normal file
624
src/libraries/libc/j6libc/print.c
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
/* _PDCLIB_print( const char *, struct _PDCLIB_status_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Using an integer's bits as flags for both the conversion flags and length
|
||||||
|
modifiers.
|
||||||
|
*/
|
||||||
|
/* FIXME: one too many flags to work on a 16-bit machine, join some (e.g. the
|
||||||
|
width flags) into a combined field.
|
||||||
|
*/
|
||||||
|
#define E_minus (1<<0)
|
||||||
|
#define E_plus (1<<1)
|
||||||
|
#define E_alt (1<<2)
|
||||||
|
#define E_space (1<<3)
|
||||||
|
#define E_zero (1<<4)
|
||||||
|
#define E_done (1<<5)
|
||||||
|
|
||||||
|
#define E_char (1<<6)
|
||||||
|
#define E_short (1<<7)
|
||||||
|
#define E_long (1<<8)
|
||||||
|
#define E_llong (1<<9)
|
||||||
|
#define E_intmax (1<<10)
|
||||||
|
#define E_size (1<<11)
|
||||||
|
#define E_ptrdiff (1<<12)
|
||||||
|
#define E_pointer (1<<13)
|
||||||
|
|
||||||
|
#define E_ldouble (1<<14)
|
||||||
|
|
||||||
|
#define E_lower (1<<15)
|
||||||
|
#define E_unsigned (1<<16)
|
||||||
|
|
||||||
|
/* This macro delivers a given character to either a memory buffer or a stream,
|
||||||
|
depending on the contents of 'status' (struct _PDCLIB_status_t).
|
||||||
|
x - the character to be delivered
|
||||||
|
i - pointer to number of characters already delivered in this call
|
||||||
|
n - pointer to maximum number of characters to be delivered in this call
|
||||||
|
s - the buffer into which the character shall be delivered
|
||||||
|
*/
|
||||||
|
#define PUT( x ) \
|
||||||
|
do { \
|
||||||
|
int character = x; \
|
||||||
|
if ( status->i < status->n ) { \
|
||||||
|
if ( status->stream != NULL ) \
|
||||||
|
putc( character, status->stream ); \
|
||||||
|
else \
|
||||||
|
status->s[status->i] = character; \
|
||||||
|
} \
|
||||||
|
++(status->i); \
|
||||||
|
} while ( 0 )
|
||||||
|
|
||||||
|
|
||||||
|
static void intformat( intmax_t value, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
/* At worst, we need two prefix characters (hex prefix). */
|
||||||
|
char preface[3] = "\0";
|
||||||
|
size_t preidx = 0;
|
||||||
|
if ( status->prec < 0 )
|
||||||
|
{
|
||||||
|
status->prec = 1;
|
||||||
|
}
|
||||||
|
if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) && ( value != 0 ) )
|
||||||
|
{
|
||||||
|
/* Octal / hexadecimal prefix for "%#" conversions */
|
||||||
|
preface[ preidx++ ] = '0';
|
||||||
|
if ( status->base == 16 )
|
||||||
|
{
|
||||||
|
preface[ preidx++ ] = ( status->flags & E_lower ) ? 'x' : 'X';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( value < 0 )
|
||||||
|
{
|
||||||
|
/* Negative sign for negative values - at all times. */
|
||||||
|
preface[ preidx++ ] = '-';
|
||||||
|
}
|
||||||
|
else if ( ! ( status->flags & E_unsigned ) )
|
||||||
|
{
|
||||||
|
/* plus sign / extra space are only for unsigned conversions */
|
||||||
|
if ( status->flags & E_plus )
|
||||||
|
{
|
||||||
|
preface[ preidx++ ] = '+';
|
||||||
|
}
|
||||||
|
else if ( status->flags & E_space )
|
||||||
|
{
|
||||||
|
preface[ preidx++ ] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
/* At this point, status->current has the number of digits queued up.
|
||||||
|
Determine if we have a precision requirement to pad those.
|
||||||
|
*/
|
||||||
|
size_t prec_pads = ( (size_t)status->prec > status->current ) ? ( (size_t)status->prec - status->current ) : 0;
|
||||||
|
if ( ! ( status->flags & ( E_minus | E_zero ) ) )
|
||||||
|
{
|
||||||
|
/* Space padding is only done if no zero padding or left alignment
|
||||||
|
is requested. Calculate the number of characters that WILL be
|
||||||
|
printed, including any prefixes determined above.
|
||||||
|
*/
|
||||||
|
/* The number of characters to be printed, plus prefixes if any. */
|
||||||
|
/* This line contained probably the most stupid, time-wasting bug
|
||||||
|
I've ever perpetrated. Greetings to Samface, DevL, and all
|
||||||
|
sceners at Breakpoint 2006.
|
||||||
|
*/
|
||||||
|
size_t characters = preidx + ( ( status->current > (size_t)status->prec ) ? status->current : (size_t)status->prec );
|
||||||
|
if ( status->width > characters )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for ( i = 0; i < status->width - characters; ++i )
|
||||||
|
{
|
||||||
|
PUT( ' ' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Now we did the padding, do the prefixes (if any). */
|
||||||
|
preidx = 0;
|
||||||
|
while ( preface[ preidx ] != '\0' )
|
||||||
|
{
|
||||||
|
PUT( preface[ preidx++ ] );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
/* Do the precision padding if necessary. */
|
||||||
|
while ( prec_pads-- > 0 )
|
||||||
|
{
|
||||||
|
PUT( '0' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
if ( ( ! ( status->flags & E_minus ) ) && ( status->flags & E_zero ) )
|
||||||
|
{
|
||||||
|
/* If field is not left aligned, and zero padding is requested, do
|
||||||
|
so.
|
||||||
|
*/
|
||||||
|
while ( status->current < status->width )
|
||||||
|
{
|
||||||
|
PUT( '0' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void int2base( intmax_t value, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
/* This function recursively converts a given integer value to a character
|
||||||
|
stream. The conversion is done under the control of a given status struct
|
||||||
|
and written either to a character string or a stream, depending on that
|
||||||
|
same status struct. The status struct also keeps the function from exceeding
|
||||||
|
snprintf() limits, and enables any necessary padding / prefixing of the
|
||||||
|
output once the number of characters to be printed is known, which happens
|
||||||
|
at the lowermost recursion level.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Special case: zero value, zero precision -- no output (but padding) */
|
||||||
|
if ( status->current == 0 && value == 0 && status->prec == 0 )
|
||||||
|
{
|
||||||
|
intformat( value, status );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Registering the character being printed at the end of the function here
|
||||||
|
already so it will be taken into account when the deepestmost recursion
|
||||||
|
does the prefix / padding stuff.
|
||||||
|
*/
|
||||||
|
++(status->current);
|
||||||
|
if ( ( value / status->base ) != 0 )
|
||||||
|
{
|
||||||
|
/* More digits to be done - recurse deeper */
|
||||||
|
int2base( value / status->base, status );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We reached the last digit, the deepest point of our recursion, and
|
||||||
|
only now know how long the number to be printed actually is. Now we
|
||||||
|
have to do the sign, prefix, width, and precision padding stuff
|
||||||
|
before printing the numbers while we resurface from the recursion.
|
||||||
|
*/
|
||||||
|
intformat( value, status );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recursion tail - print the current digit. */
|
||||||
|
int digit = value % status->base;
|
||||||
|
if ( digit < 0 )
|
||||||
|
{
|
||||||
|
digit *= -1;
|
||||||
|
}
|
||||||
|
if ( status->flags & E_lower )
|
||||||
|
{
|
||||||
|
/* Lowercase letters. Same array used for strto...(). */
|
||||||
|
PUT( _PDCLIB_digits[ digit ] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Uppercase letters. Array only used here, only 0-F. */
|
||||||
|
PUT( _PDCLIB_Xdigits[ digit ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uint2base( uintmax_t value, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
/* This function recursively converts a given integer value to a character
|
||||||
|
stream. The conversion is done under the control of a given status struct
|
||||||
|
and written either to a character string or a stream, depending on that
|
||||||
|
same status struct. The status struct also keeps the function from exceeding
|
||||||
|
snprintf() limits, and enables any necessary padding / prefixing of the
|
||||||
|
output once the number of characters to be printed is known, which happens
|
||||||
|
at the lowermost recursion level.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Special case: zero value, zero precision -- no output (but padding) */
|
||||||
|
if ( status->current == 0 && value == 0 && status->prec == 0 )
|
||||||
|
{
|
||||||
|
intformat( value, status );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Registering the character being printed at the end of the function here
|
||||||
|
already so it will be taken into account when the deepestmost recursion
|
||||||
|
does the prefix / padding stuff.
|
||||||
|
*/
|
||||||
|
++(status->current);
|
||||||
|
if ( ( value / status->base ) != 0 )
|
||||||
|
{
|
||||||
|
/* More digits to be done - recurse deeper */
|
||||||
|
uint2base( value / status->base, status );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We reached the last digit, the deepest point of our recursion, and
|
||||||
|
only now know how long the number to be printed actually is. Now we
|
||||||
|
have to do the sign, prefix, width, and precision padding stuff
|
||||||
|
before printing the numbers while we resurface from the recursion.
|
||||||
|
*/
|
||||||
|
intformat( value, status );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Recursion tail - print the current digit. */
|
||||||
|
int digit = value % status->base;
|
||||||
|
if ( digit < 0 )
|
||||||
|
{
|
||||||
|
digit *= -1;
|
||||||
|
}
|
||||||
|
if ( status->flags & E_lower )
|
||||||
|
{
|
||||||
|
/* Lowercase letters. Same array used for strto...(). */
|
||||||
|
PUT( _PDCLIB_digits[ digit ] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Uppercase letters. Array only used here, only 0-F. */
|
||||||
|
PUT( _PDCLIB_Xdigits[ digit ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void stringformat( const char * s, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
if ( status->flags & E_char )
|
||||||
|
{
|
||||||
|
status->prec = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( status->prec < 0 )
|
||||||
|
{
|
||||||
|
status->prec = strlen( s );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for ( i = 0; i < status->prec; ++i )
|
||||||
|
{
|
||||||
|
if ( s[i] == 0 )
|
||||||
|
{
|
||||||
|
status->prec = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! ( status->flags & E_minus ) && ( status->width > (size_t)status->prec ) )
|
||||||
|
{
|
||||||
|
while ( status->current < ( status->width - status->prec ) )
|
||||||
|
{
|
||||||
|
PUT( ' ' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( status->prec > 0 )
|
||||||
|
{
|
||||||
|
PUT( *(s++) );
|
||||||
|
--(status->prec);
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
if ( status->flags & E_minus )
|
||||||
|
{
|
||||||
|
while ( status->width > status->current )
|
||||||
|
{
|
||||||
|
PUT( ' ' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
const char * orig_spec = spec;
|
||||||
|
if ( *(++spec) == '%' )
|
||||||
|
{
|
||||||
|
/* %% -> print single '%' */
|
||||||
|
PUT( *spec );
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
/* Initializing status structure */
|
||||||
|
status->flags = 0;
|
||||||
|
status->base = 0;
|
||||||
|
status->current = 0;
|
||||||
|
status->width = 0;
|
||||||
|
status->prec = EOF;
|
||||||
|
|
||||||
|
/* First come 0..n flags */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
switch ( *spec )
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
/* left-aligned output */
|
||||||
|
status->flags |= E_minus;
|
||||||
|
++spec;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
/* positive numbers prefixed with '+' */
|
||||||
|
status->flags |= E_plus;
|
||||||
|
++spec;
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
/* alternative format (leading 0x for hex, 0 for octal) */
|
||||||
|
status->flags |= E_alt;
|
||||||
|
++spec;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
/* positive numbers prefixed with ' ' */
|
||||||
|
status->flags |= E_space;
|
||||||
|
++spec;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
/* right-aligned padding done with '0' instead of ' ' */
|
||||||
|
status->flags |= E_zero;
|
||||||
|
++spec;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* not a flag, exit flag parsing */
|
||||||
|
status->flags |= E_done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ( ! ( status->flags & E_done ) );
|
||||||
|
|
||||||
|
/* Optional field width */
|
||||||
|
if ( *spec == '*' )
|
||||||
|
{
|
||||||
|
/* Retrieve width value from argument stack */
|
||||||
|
int width = va_arg( status->arg, int );
|
||||||
|
if ( width < 0 )
|
||||||
|
{
|
||||||
|
status->flags |= E_minus;
|
||||||
|
status->width = abs( width );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status->width = width;
|
||||||
|
}
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If a width is given, strtol() will return its value. If not given,
|
||||||
|
strtol() will return zero. In both cases, endptr will point to the
|
||||||
|
rest of the conversion specifier - just what we need.
|
||||||
|
*/
|
||||||
|
status->width = (int)strtol( spec, (char**)&spec, 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional precision */
|
||||||
|
if ( *spec == '.' )
|
||||||
|
{
|
||||||
|
++spec;
|
||||||
|
if ( *spec == '*' )
|
||||||
|
{
|
||||||
|
/* Retrieve precision value from argument stack. A negative value
|
||||||
|
is as if no precision is given - as precision is initalized to
|
||||||
|
EOF (negative), there is no need for testing for negative here.
|
||||||
|
*/
|
||||||
|
status->prec = va_arg( status->arg, int );
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char * endptr;
|
||||||
|
status->prec = (int)strtol( spec, &endptr, 10 );
|
||||||
|
if ( spec == endptr )
|
||||||
|
{
|
||||||
|
/* Decimal point but no number - equals zero */
|
||||||
|
status->prec = 0;
|
||||||
|
}
|
||||||
|
spec = endptr;
|
||||||
|
}
|
||||||
|
/* Having a precision cancels out any zero flag. */
|
||||||
|
status->flags &= ~E_zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional length modifier
|
||||||
|
We step one character ahead in any case, and step back only if we find
|
||||||
|
there has been no length modifier (or step ahead another character if it
|
||||||
|
has been "hh" or "ll").
|
||||||
|
*/
|
||||||
|
switch ( *(spec++) )
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
if ( *spec == 'h' )
|
||||||
|
{
|
||||||
|
/* hh -> char */
|
||||||
|
status->flags |= E_char;
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* h -> short */
|
||||||
|
status->flags |= E_short;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if ( *spec == 'l' )
|
||||||
|
{
|
||||||
|
/* ll -> long long */
|
||||||
|
status->flags |= E_llong;
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* k -> long */
|
||||||
|
status->flags |= E_long;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
/* j -> intmax_t, which might or might not be long long */
|
||||||
|
status->flags |= E_intmax;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
/* z -> size_t, which might or might not be unsigned int */
|
||||||
|
status->flags |= E_size;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
/* t -> ptrdiff_t, which might or might not be long */
|
||||||
|
status->flags |= E_ptrdiff;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
/* L -> long double */
|
||||||
|
status->flags |= E_ldouble;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
--spec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conversion specifier */
|
||||||
|
switch ( *spec )
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 'i':
|
||||||
|
status->base = 10;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
status->base = 8;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
status->base = 10;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
status->base = 16;
|
||||||
|
status->flags |= ( E_lower | E_unsigned );
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
status->base = 16;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
/* TODO: wide chars. */
|
||||||
|
{
|
||||||
|
char c[1];
|
||||||
|
c[0] = (char)va_arg( status->arg, int );
|
||||||
|
status->flags |= E_char;
|
||||||
|
stringformat( c, status );
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
/* TODO: wide chars. */
|
||||||
|
stringformat( va_arg( status->arg, char * ), status );
|
||||||
|
return ++spec;
|
||||||
|
case 'p':
|
||||||
|
status->base = 16;
|
||||||
|
status->flags |= ( E_lower | E_unsigned | E_alt | E_pointer );
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
{
|
||||||
|
int * val = va_arg( status->arg, int * );
|
||||||
|
*val = status->i;
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* No conversion specifier. Bad conversion. */
|
||||||
|
return orig_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the actual output based on our findings */
|
||||||
|
if ( status->base != 0 )
|
||||||
|
{
|
||||||
|
/* Integer conversions */
|
||||||
|
/* TODO: Check for invalid flag combinations. */
|
||||||
|
if ( status->flags & E_unsigned )
|
||||||
|
{
|
||||||
|
uintmax_t value;
|
||||||
|
switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_size | E_pointer | E_intmax ) )
|
||||||
|
{
|
||||||
|
case E_char:
|
||||||
|
value = (uintmax_t)(unsigned char)va_arg( status->arg, int );
|
||||||
|
break;
|
||||||
|
case E_short:
|
||||||
|
value = (uintmax_t)(unsigned short)va_arg( status->arg, int );
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
value = (uintmax_t)va_arg( status->arg, unsigned int );
|
||||||
|
break;
|
||||||
|
case E_long:
|
||||||
|
value = (uintmax_t)va_arg( status->arg, unsigned long );
|
||||||
|
break;
|
||||||
|
case E_llong:
|
||||||
|
value = (uintmax_t)va_arg( status->arg, unsigned long long );
|
||||||
|
break;
|
||||||
|
case E_size:
|
||||||
|
value = (uintmax_t)va_arg( status->arg, size_t );
|
||||||
|
break;
|
||||||
|
case E_pointer:
|
||||||
|
value = (uintmax_t)(uintptr_t)va_arg( status->arg, void * );
|
||||||
|
break;
|
||||||
|
case E_intmax:
|
||||||
|
value = va_arg( status->arg, uintmax_t );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint2base(value, status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intmax_t value;
|
||||||
|
switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_intmax ) )
|
||||||
|
{
|
||||||
|
case E_char:
|
||||||
|
value = (intmax_t)(char)va_arg( status->arg, int );
|
||||||
|
break;
|
||||||
|
case E_short:
|
||||||
|
value = (intmax_t)(short)va_arg( status->arg, int );
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
value = (intmax_t)va_arg( status->arg, int );
|
||||||
|
break;
|
||||||
|
case E_long:
|
||||||
|
value = (intmax_t)va_arg( status->arg, long );
|
||||||
|
break;
|
||||||
|
case E_llong:
|
||||||
|
value = (intmax_t)va_arg( status->arg, long long );
|
||||||
|
break;
|
||||||
|
case E_ptrdiff:
|
||||||
|
value = (intmax_t)va_arg( status->arg, ptrdiff_t );
|
||||||
|
break;
|
||||||
|
case E_intmax:
|
||||||
|
value = va_arg( status->arg, intmax_t );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int2base(value, status);
|
||||||
|
}
|
||||||
|
if ( status->flags & E_minus )
|
||||||
|
{
|
||||||
|
while ( status->current < status->width )
|
||||||
|
{
|
||||||
|
PUT( ' ' );
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( status->i >= status->n && status->n > 0 )
|
||||||
|
{
|
||||||
|
status->s[status->n - 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
18
src/libraries/libc/j6libc/rename.c
Normal file
18
src/libraries/libc/j6libc/rename.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* _PDCLIB_rename( const char *, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_rename() fit for use with
|
||||||
|
POSIX kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int _PDCLIB_rename( const char * old, const char * new )
|
||||||
|
{
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
4
src/libraries/libc/j6libc/sbrk.c
Normal file
4
src/libraries/libc/j6libc/sbrk.c
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
void *sbrk(intptr_t) __attribute__ ((weak));
|
||||||
|
|
||||||
|
void *sbrk(intptr_t i) { return 0; }
|
||||||
595
src/libraries/libc/j6libc/scan.c
Normal file
595
src/libraries/libc/j6libc/scan.c
Normal file
@@ -0,0 +1,595 @@
|
|||||||
|
/* _PDCLIB_scan( const char *, struct _PDCLIB_status_t * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* Using an integer's bits as flags for both the conversion flags and length
|
||||||
|
modifiers.
|
||||||
|
*/
|
||||||
|
#define E_suppressed 1<<0
|
||||||
|
#define E_char 1<<6
|
||||||
|
#define E_short 1<<7
|
||||||
|
#define E_long 1<<8
|
||||||
|
#define E_llong 1<<9
|
||||||
|
#define E_intmax 1<<10
|
||||||
|
#define E_size 1<<11
|
||||||
|
#define E_ptrdiff 1<<12
|
||||||
|
#define E_pointer 1<<13
|
||||||
|
#define E_ldouble 1<<14
|
||||||
|
#define E_unsigned 1<<16
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function to get a character from the string or stream, whatever is
|
||||||
|
used for input. When reading from a string, returns EOF on end-of-string
|
||||||
|
so that handling of the return value can be uniform for both streams and
|
||||||
|
strings.
|
||||||
|
*/
|
||||||
|
static int GET( struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
int rc = EOF;
|
||||||
|
if ( status->stream != NULL )
|
||||||
|
{
|
||||||
|
rc = getc( status->stream );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = ( *status->s == '\0' ) ? EOF : (unsigned char)*((status->s)++);
|
||||||
|
}
|
||||||
|
if ( rc != EOF )
|
||||||
|
{
|
||||||
|
++(status->i);
|
||||||
|
++(status->current);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function to put a read character back into the string or stream,
|
||||||
|
whatever is used for input.
|
||||||
|
*/
|
||||||
|
static void UNGET( int c, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
if ( status->stream != NULL )
|
||||||
|
{
|
||||||
|
ungetc( c, status->stream ); /* TODO: Error? */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--(status->s);
|
||||||
|
}
|
||||||
|
--(status->i);
|
||||||
|
--(status->current);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Helper function to check if a character is part of a given scanset */
|
||||||
|
static int IN_SCANSET( const char * scanlist, const char * end_scanlist, int rc )
|
||||||
|
{
|
||||||
|
/* SOLAR */
|
||||||
|
int previous = -1;
|
||||||
|
while ( scanlist != end_scanlist )
|
||||||
|
{
|
||||||
|
if ( ( *scanlist == '-' ) && ( previous != -1 ) )
|
||||||
|
{
|
||||||
|
/* possible scangroup ("a-z") */
|
||||||
|
if ( ++scanlist == end_scanlist )
|
||||||
|
{
|
||||||
|
/* '-' at end of scanlist does not describe a scangroup */
|
||||||
|
return rc == '-';
|
||||||
|
}
|
||||||
|
while ( ++previous <= (unsigned char)*scanlist )
|
||||||
|
{
|
||||||
|
if ( previous == rc )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previous = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not a scangroup, check verbatim */
|
||||||
|
if ( rc == (unsigned char)*scanlist )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
previous = (unsigned char)(*scanlist++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
|
||||||
|
{
|
||||||
|
/* generic input character */
|
||||||
|
int rc;
|
||||||
|
const char * prev_spec;
|
||||||
|
const char * orig_spec = spec;
|
||||||
|
int value_parsed;
|
||||||
|
if ( *(++spec) == '%' )
|
||||||
|
{
|
||||||
|
/* %% -> match single '%' */
|
||||||
|
rc = GET( status );
|
||||||
|
switch ( rc )
|
||||||
|
{
|
||||||
|
case EOF:
|
||||||
|
/* input error */
|
||||||
|
if ( status->n == 0 )
|
||||||
|
{
|
||||||
|
status->n = -1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
case '%':
|
||||||
|
return ++spec;
|
||||||
|
default:
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Initializing status structure */
|
||||||
|
status->flags = 0;
|
||||||
|
status->base = -1;
|
||||||
|
status->current = 0;
|
||||||
|
status->width = 0;
|
||||||
|
status->prec = 0;
|
||||||
|
|
||||||
|
/* '*' suppresses assigning parsed value to variable */
|
||||||
|
if ( *spec == '*' )
|
||||||
|
{
|
||||||
|
status->flags |= E_suppressed;
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a width is given, strtol() will return its value. If not given,
|
||||||
|
strtol() will return zero. In both cases, endptr will point to the
|
||||||
|
rest of the conversion specifier - just what we need.
|
||||||
|
*/
|
||||||
|
prev_spec = spec;
|
||||||
|
status->width = (int)strtol( spec, (char**)&spec, 10 );
|
||||||
|
if ( spec == prev_spec )
|
||||||
|
{
|
||||||
|
status->width = SIZE_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional length modifier
|
||||||
|
We step one character ahead in any case, and step back only if we find
|
||||||
|
there has been no length modifier (or step ahead another character if it
|
||||||
|
has been "hh" or "ll").
|
||||||
|
*/
|
||||||
|
switch ( *(spec++) )
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
if ( *spec == 'h' )
|
||||||
|
{
|
||||||
|
/* hh -> char */
|
||||||
|
status->flags |= E_char;
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* h -> short */
|
||||||
|
status->flags |= E_short;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if ( *spec == 'l' )
|
||||||
|
{
|
||||||
|
/* ll -> long long */
|
||||||
|
status->flags |= E_llong;
|
||||||
|
++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* l -> long */
|
||||||
|
status->flags |= E_long;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'j':
|
||||||
|
/* j -> intmax_t, which might or might not be long long */
|
||||||
|
status->flags |= E_intmax;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
/* z -> size_t, which might or might not be unsigned int */
|
||||||
|
status->flags |= E_size;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
/* t -> ptrdiff_t, which might or might not be long */
|
||||||
|
status->flags |= E_ptrdiff;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
/* L -> long double */
|
||||||
|
status->flags |= E_ldouble;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
--spec;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conversion specifier */
|
||||||
|
|
||||||
|
/* whether valid input had been parsed */
|
||||||
|
value_parsed = 0;
|
||||||
|
|
||||||
|
switch ( *spec )
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
status->base = 10;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
status->base = 0;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
status->base = 8;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
status->base = 10;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
status->base = 16;
|
||||||
|
status->flags |= E_unsigned;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
char * c = va_arg( status->arg, char * );
|
||||||
|
/* for %c, default width is one */
|
||||||
|
if ( status->width == SIZE_MAX )
|
||||||
|
{
|
||||||
|
status->width = 1;
|
||||||
|
}
|
||||||
|
/* reading until width reached or input exhausted */
|
||||||
|
while ( ( status->current < status->width ) &&
|
||||||
|
( ( rc = GET( status ) ) != EOF ) )
|
||||||
|
{
|
||||||
|
*(c++) = rc;
|
||||||
|
value_parsed = 1;
|
||||||
|
}
|
||||||
|
/* width or input exhausted */
|
||||||
|
if ( value_parsed )
|
||||||
|
{
|
||||||
|
++status->n;
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* input error, no character read */
|
||||||
|
if ( status->n == 0 )
|
||||||
|
{
|
||||||
|
status->n = -1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
char * c = va_arg( status->arg, char * );
|
||||||
|
while ( ( status->current < status->width ) &&
|
||||||
|
( ( rc = GET( status ) ) != EOF ) )
|
||||||
|
{
|
||||||
|
if ( isspace( rc ) )
|
||||||
|
{
|
||||||
|
UNGET( rc, status );
|
||||||
|
if ( value_parsed )
|
||||||
|
{
|
||||||
|
/* matching sequence terminated by whitespace */
|
||||||
|
*c = '\0';
|
||||||
|
++status->n;
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* matching error */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* match */
|
||||||
|
value_parsed = 1;
|
||||||
|
*(c++) = rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* width or input exhausted */
|
||||||
|
if ( value_parsed )
|
||||||
|
{
|
||||||
|
*c = '\0';
|
||||||
|
++status->n;
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* input error, no character read */
|
||||||
|
if ( status->n == 0 )
|
||||||
|
{
|
||||||
|
status->n = -1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
const char * endspec = spec;
|
||||||
|
int negative_scanlist = 0;
|
||||||
|
char * c;
|
||||||
|
if ( *(++endspec) == '^' )
|
||||||
|
{
|
||||||
|
negative_scanlist = 1;
|
||||||
|
++endspec;
|
||||||
|
}
|
||||||
|
spec = endspec;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* TODO: This can run beyond a malformed format string */
|
||||||
|
++endspec;
|
||||||
|
} while ( *endspec != ']' );
|
||||||
|
/* read according to scanlist, equiv. to %s above */
|
||||||
|
c = va_arg( status->arg, char * );
|
||||||
|
while ( ( status->current < status->width ) &&
|
||||||
|
( ( rc = GET( status ) ) != EOF ) )
|
||||||
|
{
|
||||||
|
if ( negative_scanlist )
|
||||||
|
{
|
||||||
|
if ( IN_SCANSET( spec, endspec, rc ) )
|
||||||
|
{
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( ! IN_SCANSET( spec, endspec, rc ) )
|
||||||
|
{
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value_parsed = 1;
|
||||||
|
*(c++) = rc;
|
||||||
|
}
|
||||||
|
if ( value_parsed )
|
||||||
|
{
|
||||||
|
*c = '\0';
|
||||||
|
++status->n;
|
||||||
|
return ++endspec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( rc == EOF )
|
||||||
|
{
|
||||||
|
status->n = -1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'p':
|
||||||
|
status->base = 16;
|
||||||
|
status->flags |= E_pointer;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
{
|
||||||
|
int * val = va_arg( status->arg, int * );
|
||||||
|
*val = status->i;
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* No conversion specifier. Bad conversion. */
|
||||||
|
return orig_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( status->base != -1 )
|
||||||
|
{
|
||||||
|
/* integer conversion */
|
||||||
|
uintmax_t value = 0; /* absolute value read */
|
||||||
|
int prefix_parsed = 0;
|
||||||
|
int sign = 0;
|
||||||
|
while ( ( status->current < status->width ) &&
|
||||||
|
( ( rc = GET( status ) ) != EOF ) )
|
||||||
|
{
|
||||||
|
if ( isspace( rc ) )
|
||||||
|
{
|
||||||
|
if ( sign )
|
||||||
|
{
|
||||||
|
/* matching sequence terminated by whitespace */
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* leading whitespace not counted against width */
|
||||||
|
status->current--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ! sign )
|
||||||
|
{
|
||||||
|
/* no sign parsed yet */
|
||||||
|
switch ( rc )
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
sign = -1;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
sign = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* not a sign; put back character */
|
||||||
|
sign = 1;
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ! prefix_parsed )
|
||||||
|
{
|
||||||
|
/* no prefix (0x... for hex, 0... for octal) parsed yet */
|
||||||
|
prefix_parsed = 1;
|
||||||
|
if ( rc != '0' )
|
||||||
|
{
|
||||||
|
/* not a prefix; if base not yet set, set to decimal */
|
||||||
|
if ( status->base == 0 )
|
||||||
|
{
|
||||||
|
status->base = 10;
|
||||||
|
}
|
||||||
|
UNGET( rc, status );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* starts with zero, so it might be a prefix. */
|
||||||
|
/* check what follows next (might be 0x...) */
|
||||||
|
if ( ( status->current < status->width ) &&
|
||||||
|
( ( rc = GET( status ) ) != EOF ) )
|
||||||
|
{
|
||||||
|
if ( tolower( rc ) == 'x' )
|
||||||
|
{
|
||||||
|
/* 0x... would be prefix for hex base... */
|
||||||
|
if ( ( status->base == 0 ) ||
|
||||||
|
( status->base == 16 ) )
|
||||||
|
{
|
||||||
|
status->base = 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* ...unless already set to other value */
|
||||||
|
UNGET( rc, status );
|
||||||
|
value_parsed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 0... but not 0x.... would be octal prefix */
|
||||||
|
UNGET( rc, status );
|
||||||
|
if ( status->base == 0 )
|
||||||
|
{
|
||||||
|
status->base = 8;
|
||||||
|
}
|
||||||
|
/* in any case we have read a zero */
|
||||||
|
value_parsed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* failed to read beyond the initial zero */
|
||||||
|
value_parsed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char * digitptr = memchr( _PDCLIB_digits, tolower( rc ), status->base );
|
||||||
|
if ( digitptr == NULL )
|
||||||
|
{
|
||||||
|
/* end of input item */
|
||||||
|
UNGET( rc, status );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value *= status->base;
|
||||||
|
value += digitptr - _PDCLIB_digits;
|
||||||
|
value_parsed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* width or input exhausted, or non-matching character */
|
||||||
|
if ( ! value_parsed )
|
||||||
|
{
|
||||||
|
/* out of input before anything could be parsed - input error */
|
||||||
|
/* FIXME: if first character does not match, value_parsed is not set - but it is NOT an input error */
|
||||||
|
if ( ( status->n == 0 ) && ( rc == EOF ) )
|
||||||
|
{
|
||||||
|
status->n = -1;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* convert value to target type and assign to parameter */
|
||||||
|
if ( ! ( status->flags & E_suppressed ) )
|
||||||
|
{
|
||||||
|
switch ( status->flags & ( E_char | E_short | E_long | E_llong |
|
||||||
|
E_intmax | E_size | E_ptrdiff | E_pointer |
|
||||||
|
E_unsigned ) )
|
||||||
|
{
|
||||||
|
case E_char:
|
||||||
|
*( va_arg( status->arg, char * ) ) = (char)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_char | E_unsigned:
|
||||||
|
*( va_arg( status->arg, unsigned char * ) ) = (unsigned char)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_short:
|
||||||
|
*( va_arg( status->arg, short * ) ) = (short)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_short | E_unsigned:
|
||||||
|
*( va_arg( status->arg, unsigned short * ) ) = (unsigned short)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
*( va_arg( status->arg, int * ) ) = (int)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_unsigned:
|
||||||
|
*( va_arg( status->arg, unsigned int * ) ) = (unsigned int)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_long:
|
||||||
|
*( va_arg( status->arg, long * ) ) = (long)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_long | E_unsigned:
|
||||||
|
*( va_arg( status->arg, unsigned long * ) ) = (unsigned long)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_llong:
|
||||||
|
*( va_arg( status->arg, long long * ) ) = (long long)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_llong | E_unsigned:
|
||||||
|
*( va_arg( status->arg, unsigned long long * ) ) = (unsigned long long)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_intmax:
|
||||||
|
*( va_arg( status->arg, intmax_t * ) ) = (intmax_t)( value * sign );
|
||||||
|
break;
|
||||||
|
case E_intmax | E_unsigned:
|
||||||
|
*( va_arg( status->arg, uintmax_t * ) ) = (uintmax_t)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_size:
|
||||||
|
/* E_size always implies unsigned */
|
||||||
|
*( va_arg( status->arg, size_t * ) ) = (size_t)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_ptrdiff:
|
||||||
|
/* E_ptrdiff always implies signed */
|
||||||
|
*( va_arg( status->arg, ptrdiff_t * ) ) = (ptrdiff_t)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_pointer:
|
||||||
|
/* E_pointer always implies unsigned */
|
||||||
|
*( uintptr_t* )( va_arg( status->arg, void * ) ) = (uintptr_t)( value * sign );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
puts( "UNSUPPORTED SCANF FLAG COMBINATION" );
|
||||||
|
return NULL; /* behaviour unspecified */
|
||||||
|
}
|
||||||
|
++(status->n);
|
||||||
|
}
|
||||||
|
return ++spec;
|
||||||
|
}
|
||||||
|
/* TODO: Floats. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
7
src/libraries/libc/j6libc/seed.c
Normal file
7
src/libraries/libc/j6libc/seed.c
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* _PDCLIB_seed
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned long int _PDCLIB_seed = 1;
|
||||||
18
src/libraries/libc/j6libc/seek.c
Normal file
18
src/libraries/libc/j6libc/seek.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* int64_t _PDCLIB_seek( FILE *, int64_t, int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example implementation of _PDCLIB_seek() fit for use with POSIX
|
||||||
|
kernels.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, int64_t offset, int whence )
|
||||||
|
{
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
412
src/libraries/libc/j6libc/stdinit.c
Normal file
412
src/libraries/libc/j6libc/stdinit.c
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
/* _PDCLIB_stdinit
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is an example initialization of stdin, stdout and stderr to the integer
|
||||||
|
file descriptors 0, 1, and 2, respectively. This applies for a great variety
|
||||||
|
of operating systems, including POSIX compliant ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
|
||||||
|
descriptors 0, 1, and 2 respectively.
|
||||||
|
*/
|
||||||
|
/* TODO: This is proof-of-concept, requires finetuning. */
|
||||||
|
static char _PDCLIB_sin_buffer[BUFSIZ];
|
||||||
|
static char _PDCLIB_sout_buffer[BUFSIZ];
|
||||||
|
static char _PDCLIB_serr_buffer[BUFSIZ];
|
||||||
|
|
||||||
|
static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||||
|
static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||||
|
static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
|
||||||
|
|
||||||
|
static struct _PDCLIB_file_t _PDCLIB_serr = { 2, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_serr_ungetbuf, _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, NULL };
|
||||||
|
static struct _PDCLIB_file_t _PDCLIB_sout = { 1, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sout_ungetbuf, _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, &_PDCLIB_serr };
|
||||||
|
static struct _PDCLIB_file_t _PDCLIB_sin = { 0, _PDCLIB_sin_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sin_ungetbuf, _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC, NULL, &_PDCLIB_sout };
|
||||||
|
|
||||||
|
struct _PDCLIB_file_t * stdin = &_PDCLIB_sin;
|
||||||
|
struct _PDCLIB_file_t * stdout = &_PDCLIB_sout;
|
||||||
|
struct _PDCLIB_file_t * stderr = &_PDCLIB_serr;
|
||||||
|
|
||||||
|
/* FIXME: This approach is a possible attack vector. */
|
||||||
|
struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin;
|
||||||
|
|
||||||
|
/* "C" locale - defaulting to ASCII-7.
|
||||||
|
1 kByte (+ 4 byte) of <ctype.h> data.
|
||||||
|
Each line: flags, lowercase, uppercase, collation.
|
||||||
|
*/
|
||||||
|
static struct _PDCLIB_lc_ctype_entry_t _ctype_entries[ _PDCLIB_CHARSET_SIZE + 1 ] = {
|
||||||
|
{ /* EOF */ 0, 0, 0 },
|
||||||
|
{ /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00 },
|
||||||
|
{ /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01 },
|
||||||
|
{ /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02 },
|
||||||
|
{ /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03 },
|
||||||
|
{ /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04 },
|
||||||
|
{ /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05 },
|
||||||
|
{ /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06 },
|
||||||
|
{ /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07 },
|
||||||
|
{ /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08 },
|
||||||
|
{ /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09 },
|
||||||
|
{ /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A },
|
||||||
|
{ /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B },
|
||||||
|
{ /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C },
|
||||||
|
{ /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D },
|
||||||
|
{ /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E },
|
||||||
|
{ /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F },
|
||||||
|
{ /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10 },
|
||||||
|
{ /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11 },
|
||||||
|
{ /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12 },
|
||||||
|
{ /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13 },
|
||||||
|
{ /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14 },
|
||||||
|
{ /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15 },
|
||||||
|
{ /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16 },
|
||||||
|
{ /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17 },
|
||||||
|
{ /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18 },
|
||||||
|
{ /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19 },
|
||||||
|
{ /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A },
|
||||||
|
{ /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B },
|
||||||
|
{ /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C },
|
||||||
|
{ /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D },
|
||||||
|
{ /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E },
|
||||||
|
{ /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F },
|
||||||
|
{ /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20 },
|
||||||
|
{ /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21 },
|
||||||
|
{ /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22 },
|
||||||
|
{ /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23 },
|
||||||
|
{ /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24 },
|
||||||
|
{ /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25 },
|
||||||
|
{ /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26 },
|
||||||
|
{ /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27 },
|
||||||
|
{ /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28 },
|
||||||
|
{ /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29 },
|
||||||
|
{ /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A },
|
||||||
|
{ /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B },
|
||||||
|
{ /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C },
|
||||||
|
{ /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D },
|
||||||
|
{ /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E },
|
||||||
|
{ /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F },
|
||||||
|
{ /* '0' */ _PDCLIB_CTYPE_GRAPH, 0x30, 0x30 },
|
||||||
|
{ /* '1' */ _PDCLIB_CTYPE_GRAPH, 0x31, 0x31 },
|
||||||
|
{ /* '2' */ _PDCLIB_CTYPE_GRAPH, 0x32, 0x32 },
|
||||||
|
{ /* '3' */ _PDCLIB_CTYPE_GRAPH, 0x33, 0x33 },
|
||||||
|
{ /* '4' */ _PDCLIB_CTYPE_GRAPH, 0x34, 0x34 },
|
||||||
|
{ /* '5' */ _PDCLIB_CTYPE_GRAPH, 0x35, 0x35 },
|
||||||
|
{ /* '6' */ _PDCLIB_CTYPE_GRAPH, 0x36, 0x36 },
|
||||||
|
{ /* '7' */ _PDCLIB_CTYPE_GRAPH, 0x37, 0x37 },
|
||||||
|
{ /* '8' */ _PDCLIB_CTYPE_GRAPH, 0x38, 0x38 },
|
||||||
|
{ /* '9' */ _PDCLIB_CTYPE_GRAPH, 0x39, 0x39 },
|
||||||
|
{ /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A },
|
||||||
|
{ /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B },
|
||||||
|
{ /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C },
|
||||||
|
{ /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D },
|
||||||
|
{ /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E },
|
||||||
|
{ /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F },
|
||||||
|
{ /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40 },
|
||||||
|
{ /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x41, 0x61 },
|
||||||
|
{ /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x42, 0x62 },
|
||||||
|
{ /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x43, 0x63 },
|
||||||
|
{ /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x44, 0x64 },
|
||||||
|
{ /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x45, 0x65 },
|
||||||
|
{ /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x46, 0x66 },
|
||||||
|
{ /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67 },
|
||||||
|
{ /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68 },
|
||||||
|
{ /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69 },
|
||||||
|
{ /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A },
|
||||||
|
{ /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B },
|
||||||
|
{ /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C },
|
||||||
|
{ /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D },
|
||||||
|
{ /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E },
|
||||||
|
{ /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F },
|
||||||
|
{ /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70 },
|
||||||
|
{ /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71 },
|
||||||
|
{ /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72 },
|
||||||
|
{ /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73 },
|
||||||
|
{ /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74 },
|
||||||
|
{ /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75 },
|
||||||
|
{ /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76 },
|
||||||
|
{ /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77 },
|
||||||
|
{ /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78 },
|
||||||
|
{ /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79 },
|
||||||
|
{ /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A },
|
||||||
|
{ /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B },
|
||||||
|
{ /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C },
|
||||||
|
{ /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D },
|
||||||
|
{ /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E },
|
||||||
|
{ /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F },
|
||||||
|
{ /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60 },
|
||||||
|
{ /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x41, 0x61 },
|
||||||
|
{ /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x42, 0x62 },
|
||||||
|
{ /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x43, 0x63 },
|
||||||
|
{ /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x44, 0x64 },
|
||||||
|
{ /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x45, 0x65 },
|
||||||
|
{ /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x46, 0x66 },
|
||||||
|
{ /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67 },
|
||||||
|
{ /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68 },
|
||||||
|
{ /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69 },
|
||||||
|
{ /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A },
|
||||||
|
{ /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B },
|
||||||
|
{ /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C },
|
||||||
|
{ /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D },
|
||||||
|
{ /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E },
|
||||||
|
{ /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F },
|
||||||
|
{ /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70 },
|
||||||
|
{ /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71 },
|
||||||
|
{ /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72 },
|
||||||
|
{ /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73 },
|
||||||
|
{ /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74 },
|
||||||
|
{ /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75 },
|
||||||
|
{ /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76 },
|
||||||
|
{ /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77 },
|
||||||
|
{ /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78 },
|
||||||
|
{ /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79 },
|
||||||
|
{ /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A },
|
||||||
|
{ /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B },
|
||||||
|
{ /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C },
|
||||||
|
{ /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D },
|
||||||
|
{ /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E },
|
||||||
|
{ /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F },
|
||||||
|
{ 0x00, 0x80, 0x80 },
|
||||||
|
{ 0x00, 0x81, 0x81 },
|
||||||
|
{ 0x00, 0x82, 0x82 },
|
||||||
|
{ 0x00, 0x83, 0x83 },
|
||||||
|
{ 0x00, 0x84, 0x84 },
|
||||||
|
{ 0x00, 0x85, 0x85 },
|
||||||
|
{ 0x00, 0x86, 0x86 },
|
||||||
|
{ 0x00, 0x87, 0x87 },
|
||||||
|
{ 0x00, 0x88, 0x88 },
|
||||||
|
{ 0x00, 0x89, 0x89 },
|
||||||
|
{ 0x00, 0x8A, 0x8A },
|
||||||
|
{ 0x00, 0x8B, 0x8B },
|
||||||
|
{ 0x00, 0x8C, 0x8C },
|
||||||
|
{ 0x00, 0x8D, 0x8D },
|
||||||
|
{ 0x00, 0x8E, 0x8E },
|
||||||
|
{ 0x00, 0x8F, 0x8F },
|
||||||
|
{ 0x00, 0x90, 0x90 },
|
||||||
|
{ 0x00, 0x91, 0x91 },
|
||||||
|
{ 0x00, 0x92, 0x92 },
|
||||||
|
{ 0x00, 0x93, 0x93 },
|
||||||
|
{ 0x00, 0x94, 0x94 },
|
||||||
|
{ 0x00, 0x95, 0x95 },
|
||||||
|
{ 0x00, 0x96, 0x96 },
|
||||||
|
{ 0x00, 0x97, 0x97 },
|
||||||
|
{ 0x00, 0x98, 0x98 },
|
||||||
|
{ 0x00, 0x99, 0x99 },
|
||||||
|
{ 0x00, 0x9A, 0x9A },
|
||||||
|
{ 0x00, 0x9B, 0x9B },
|
||||||
|
{ 0x00, 0x9C, 0x9C },
|
||||||
|
{ 0x00, 0x9D, 0x9D },
|
||||||
|
{ 0x00, 0x9E, 0x9E },
|
||||||
|
{ 0x00, 0x9F, 0x9F },
|
||||||
|
{ 0x00, 0xA0, 0xA0 },
|
||||||
|
{ 0x00, 0xA1, 0xA1 },
|
||||||
|
{ 0x00, 0xA2, 0xA2 },
|
||||||
|
{ 0x00, 0xA3, 0xA3 },
|
||||||
|
{ 0x00, 0xA4, 0xA4 },
|
||||||
|
{ 0x00, 0xA5, 0xA5 },
|
||||||
|
{ 0x00, 0xA6, 0xA6 },
|
||||||
|
{ 0x00, 0xA7, 0xA7 },
|
||||||
|
{ 0x00, 0xA8, 0xA8 },
|
||||||
|
{ 0x00, 0xA9, 0xA9 },
|
||||||
|
{ 0x00, 0xAA, 0xAA },
|
||||||
|
{ 0x00, 0xAB, 0xAB },
|
||||||
|
{ 0x00, 0xAC, 0xAC },
|
||||||
|
{ 0x00, 0xAD, 0xAD },
|
||||||
|
{ 0x00, 0xAE, 0xAE },
|
||||||
|
{ 0x00, 0xAF, 0xAF },
|
||||||
|
{ 0x00, 0xB0, 0xB0 },
|
||||||
|
{ 0x00, 0xB1, 0xB1 },
|
||||||
|
{ 0x00, 0xB2, 0xB2 },
|
||||||
|
{ 0x00, 0xB3, 0xB3 },
|
||||||
|
{ 0x00, 0xB4, 0xB4 },
|
||||||
|
{ 0x00, 0xB5, 0xB5 },
|
||||||
|
{ 0x00, 0xB6, 0xB6 },
|
||||||
|
{ 0x00, 0xB7, 0xB7 },
|
||||||
|
{ 0x00, 0xB8, 0xB8 },
|
||||||
|
{ 0x00, 0xB9, 0xB9 },
|
||||||
|
{ 0x00, 0xBA, 0xBA },
|
||||||
|
{ 0x00, 0xBB, 0xBB },
|
||||||
|
{ 0x00, 0xBC, 0xBC },
|
||||||
|
{ 0x00, 0xBD, 0xBD },
|
||||||
|
{ 0x00, 0xBE, 0xBE },
|
||||||
|
{ 0x00, 0xBF, 0xBF },
|
||||||
|
{ 0x00, 0xC0, 0xC0 },
|
||||||
|
{ 0x00, 0xC1, 0xC1 },
|
||||||
|
{ 0x00, 0xC2, 0xC2 },
|
||||||
|
{ 0x00, 0xC3, 0xC3 },
|
||||||
|
{ 0x00, 0xC4, 0xC4 },
|
||||||
|
{ 0x00, 0xC5, 0xC5 },
|
||||||
|
{ 0x00, 0xC6, 0xC6 },
|
||||||
|
{ 0x00, 0xC7, 0xC7 },
|
||||||
|
{ 0x00, 0xC8, 0xC8 },
|
||||||
|
{ 0x00, 0xC9, 0xC9 },
|
||||||
|
{ 0x00, 0xCA, 0xCA },
|
||||||
|
{ 0x00, 0xCB, 0xCB },
|
||||||
|
{ 0x00, 0xCC, 0xCC },
|
||||||
|
{ 0x00, 0xCD, 0xCD },
|
||||||
|
{ 0x00, 0xCE, 0xCE },
|
||||||
|
{ 0x00, 0xCF, 0xCF },
|
||||||
|
{ 0x00, 0xD0, 0xD0 },
|
||||||
|
{ 0x00, 0xD1, 0xD1 },
|
||||||
|
{ 0x00, 0xD2, 0xD2 },
|
||||||
|
{ 0x00, 0xD3, 0xD3 },
|
||||||
|
{ 0x00, 0xD4, 0xD4 },
|
||||||
|
{ 0x00, 0xD5, 0xD5 },
|
||||||
|
{ 0x00, 0xD6, 0xD6 },
|
||||||
|
{ 0x00, 0xD7, 0xD7 },
|
||||||
|
{ 0x00, 0xD8, 0xD8 },
|
||||||
|
{ 0x00, 0xD9, 0xD9 },
|
||||||
|
{ 0x00, 0xDA, 0xDA },
|
||||||
|
{ 0x00, 0xDB, 0xDB },
|
||||||
|
{ 0x00, 0xDC, 0xDC },
|
||||||
|
{ 0x00, 0xDD, 0xDD },
|
||||||
|
{ 0x00, 0xDE, 0xDE },
|
||||||
|
{ 0x00, 0xDF, 0xDF },
|
||||||
|
{ 0x00, 0xE0, 0xE0 },
|
||||||
|
{ 0x00, 0xE1, 0xE1 },
|
||||||
|
{ 0x00, 0xE2, 0xE2 },
|
||||||
|
{ 0x00, 0xE3, 0xE3 },
|
||||||
|
{ 0x00, 0xE4, 0xE4 },
|
||||||
|
{ 0x00, 0xE5, 0xE5 },
|
||||||
|
{ 0x00, 0xE6, 0xE6 },
|
||||||
|
{ 0x00, 0xE7, 0xE7 },
|
||||||
|
{ 0x00, 0xE8, 0xE8 },
|
||||||
|
{ 0x00, 0xE9, 0xE9 },
|
||||||
|
{ 0x00, 0xEA, 0xEA },
|
||||||
|
{ 0x00, 0xEB, 0xEB },
|
||||||
|
{ 0x00, 0xEC, 0xEC },
|
||||||
|
{ 0x00, 0xED, 0xED },
|
||||||
|
{ 0x00, 0xEE, 0xEE },
|
||||||
|
{ 0x00, 0xEF, 0xEF },
|
||||||
|
{ 0x00, 0xF0, 0xF0 },
|
||||||
|
{ 0x00, 0xF1, 0xF1 },
|
||||||
|
{ 0x00, 0xF2, 0xF2 },
|
||||||
|
{ 0x00, 0xF3, 0xF3 },
|
||||||
|
{ 0x00, 0xF4, 0xF4 },
|
||||||
|
{ 0x00, 0xF5, 0xF5 },
|
||||||
|
{ 0x00, 0xF6, 0xF6 },
|
||||||
|
{ 0x00, 0xF7, 0xF7 },
|
||||||
|
{ 0x00, 0xF8, 0xF8 },
|
||||||
|
{ 0x00, 0xF9, 0xF9 },
|
||||||
|
{ 0x00, 0xFA, 0xFA },
|
||||||
|
{ 0x00, 0xFB, 0xFB },
|
||||||
|
{ 0x00, 0xFC, 0xFC },
|
||||||
|
{ 0x00, 0xFD, 0xFD },
|
||||||
|
{ 0x00, 0xFE, 0xFE },
|
||||||
|
{ 0x00, 0xFF, 0xFF }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_ctype_t _PDCLIB_lc_ctype = { 0, 0x30, 0x39, 0x41, 0x46, 0x61, 0x66, &_ctype_entries[1] };
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_collate_t _PDCLIB_lc_collate = { 0 };
|
||||||
|
|
||||||
|
struct lconv _PDCLIB_lconv = {
|
||||||
|
/* decimal_point */ (char *)".",
|
||||||
|
/* thousands_sep */ (char *)"",
|
||||||
|
/* grouping */ (char *)"",
|
||||||
|
/* mon_decimal_point */ (char *)"",
|
||||||
|
/* mon_thousands_sep */ (char *)"",
|
||||||
|
/* mon_grouping */ (char *)"",
|
||||||
|
/* positive_sign */ (char *)"",
|
||||||
|
/* negative_sign */ (char *)"",
|
||||||
|
/* currency_symbol */ (char *)"",
|
||||||
|
/* int_curr_symbol */ (char *)"",
|
||||||
|
/* frac_digits */ CHAR_MAX,
|
||||||
|
/* p_cs_precedes */ CHAR_MAX,
|
||||||
|
/* n_cs_precedes */ CHAR_MAX,
|
||||||
|
/* p_sep_by_space */ CHAR_MAX,
|
||||||
|
/* n_sep_by_space */ CHAR_MAX,
|
||||||
|
/* p_sign_posn */ CHAR_MAX,
|
||||||
|
/* n_sign_posn */ CHAR_MAX,
|
||||||
|
/* int_frac_digits */ CHAR_MAX,
|
||||||
|
/* int_p_cs_precedes */ CHAR_MAX,
|
||||||
|
/* int_n_cs_precedes */ CHAR_MAX,
|
||||||
|
/* int_p_sep_by_space */ CHAR_MAX,
|
||||||
|
/* int_n_sep_by_space */ CHAR_MAX,
|
||||||
|
/* int_p_sign_posn */ CHAR_MAX,
|
||||||
|
/* int_n_sign_posn */ CHAR_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_numeric_monetary_t _PDCLIB_lc_numeric_monetary = {
|
||||||
|
&_PDCLIB_lconv,
|
||||||
|
0, /* numeric_allocated */
|
||||||
|
0 /* monetary_allocated */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_messages_t _PDCLIB_lc_messages = {
|
||||||
|
0,
|
||||||
|
/* _PDCLIB_errno_texts */
|
||||||
|
{
|
||||||
|
/* no error */ (char *)"",
|
||||||
|
/* ERANGE */ (char *)"ERANGE (Range error)",
|
||||||
|
/* EDOM */ (char *)"EDOM (Domain error)",
|
||||||
|
/* EILSEQ */ (char *)"EILSEQ (Illegal sequence)"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_time_t _PDCLIB_lc_time = {
|
||||||
|
0,
|
||||||
|
/* _PDCLIB_month_name_abbr */
|
||||||
|
{
|
||||||
|
(char *)"Jan",
|
||||||
|
(char *)"Feb",
|
||||||
|
(char *)"Mar",
|
||||||
|
(char *)"Apr",
|
||||||
|
(char *)"May",
|
||||||
|
(char *)"Jun",
|
||||||
|
(char *)"Jul",
|
||||||
|
(char *)"Aug",
|
||||||
|
(char *)"Sep",
|
||||||
|
(char *)"Oct",
|
||||||
|
(char *)"Now",
|
||||||
|
(char *)"Dec"
|
||||||
|
},
|
||||||
|
/* _PDCLIB_month_name_full */
|
||||||
|
{
|
||||||
|
(char *)"January",
|
||||||
|
(char *)"February",
|
||||||
|
(char *)"March",
|
||||||
|
(char *)"April",
|
||||||
|
(char *)"May",
|
||||||
|
(char *)"June",
|
||||||
|
(char *)"July",
|
||||||
|
(char *)"August",
|
||||||
|
(char *)"September",
|
||||||
|
(char *)"October",
|
||||||
|
(char *)"November",
|
||||||
|
(char *)"December"
|
||||||
|
},
|
||||||
|
/* _PDCLIB_day_name_abbr */
|
||||||
|
{
|
||||||
|
(char *)"Sun",
|
||||||
|
(char *)"Mon",
|
||||||
|
(char *)"Tue",
|
||||||
|
(char *)"Wed",
|
||||||
|
(char *)"Thu",
|
||||||
|
(char *)"Fri",
|
||||||
|
(char *)"Sat"
|
||||||
|
},
|
||||||
|
/* _PDCLIB_day_name_full */
|
||||||
|
{
|
||||||
|
(char *)"Sunday",
|
||||||
|
(char *)"Monday",
|
||||||
|
(char *)"Tuesday",
|
||||||
|
(char *)"Wednesday",
|
||||||
|
(char *)"Thursday",
|
||||||
|
(char *)"Friday",
|
||||||
|
(char *)"Saturday"
|
||||||
|
},
|
||||||
|
/* date / time format */ (char *)"%a %b %e %T %Y",
|
||||||
|
/* 12h time format */ (char *)"%I:%M:%S %p",
|
||||||
|
/* date format */ (char *)"%m/%d/%y",
|
||||||
|
/* time format */ (char *)"%T",
|
||||||
|
/* AM / PM designation */
|
||||||
|
{
|
||||||
|
(char *)"AM",
|
||||||
|
(char *)"PM"
|
||||||
|
}
|
||||||
|
};
|
||||||
42
src/libraries/libc/j6libc/strtox_main.c
Normal file
42
src/libraries/libc/j6libc/strtox_main.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* _PDCLIB_strtox_main( const char * *, int, uintmax_t, uintmax_t, int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limval, int limdigit, char * sign )
|
||||||
|
{
|
||||||
|
uintmax_t rc = 0;
|
||||||
|
int digit = -1;
|
||||||
|
const char * x;
|
||||||
|
while ( ( x = memchr( _PDCLIB_digits, tolower(**p), base ) ) != NULL )
|
||||||
|
{
|
||||||
|
digit = x - _PDCLIB_digits;
|
||||||
|
if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) )
|
||||||
|
{
|
||||||
|
rc = rc * base + (unsigned)digit;
|
||||||
|
++(*p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errno = ERANGE;
|
||||||
|
/* TODO: Only if endptr != NULL - but do we really want *another* parameter? */
|
||||||
|
/* TODO: Earlier version was missing tolower() here but was not caught by tests */
|
||||||
|
while ( memchr( _PDCLIB_digits, tolower(**p), base ) != NULL ) ++(*p);
|
||||||
|
/* TODO: This is ugly, but keeps caller from negating the error value */
|
||||||
|
*sign = '+';
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( digit == -1 )
|
||||||
|
{
|
||||||
|
*p = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
50
src/libraries/libc/j6libc/strtox_prelim.c
Normal file
50
src/libraries/libc/j6libc/strtox_prelim.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* _PDCLIB_strtox_prelim( const char *, char *, int * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base )
|
||||||
|
{
|
||||||
|
/* skipping leading whitespace */
|
||||||
|
while ( isspace( *p ) ) ++p;
|
||||||
|
/* determining / skipping sign */
|
||||||
|
if ( *p != '+' && *p != '-' ) *sign = '+';
|
||||||
|
else *sign = *(p++);
|
||||||
|
/* determining base */
|
||||||
|
if ( *p == '0' )
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) )
|
||||||
|
{
|
||||||
|
*base = 16;
|
||||||
|
++p;
|
||||||
|
/* catching a border case here: "0x" followed by a non-digit should
|
||||||
|
be parsed as the unprefixed zero.
|
||||||
|
We have to "rewind" the parsing; having the base set to 16 if it
|
||||||
|
was zero previously does not hurt, as the result is zero anyway.
|
||||||
|
*/
|
||||||
|
if ( memchr( _PDCLIB_digits, tolower(*p), *base ) == NULL )
|
||||||
|
{
|
||||||
|
p -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( *base == 0 )
|
||||||
|
{
|
||||||
|
*base = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( ! *base )
|
||||||
|
{
|
||||||
|
*base = 10;
|
||||||
|
}
|
||||||
|
return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL;
|
||||||
|
}
|
||||||
12
src/libraries/libc/locale/localeconv.c
Normal file
12
src/libraries/libc/locale/localeconv.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* localeconv( void )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
struct lconv * localeconv( void )
|
||||||
|
{
|
||||||
|
return _PDCLIB_lc_numeric_monetary.lconv;
|
||||||
|
}
|
||||||
242
src/libraries/libc/locale/setlocale.c
Normal file
242
src/libraries/libc/locale/setlocale.c
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
/* setlocale( int, const char * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static const char * _PDCLIB_LC_category_name[ _PDCLIB_LC_COUNT ] = { NULL, "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_MESSAGES" };
|
||||||
|
|
||||||
|
static const char * _PDCLIB_default_locale( int category )
|
||||||
|
{
|
||||||
|
const char * s;
|
||||||
|
|
||||||
|
if ( ( s = getenv( "LC_ALL" ) ) == NULL )
|
||||||
|
{
|
||||||
|
if ( category == LC_ALL || ( s = getenv( _PDCLIB_LC_category_name[ category ] ) ) == NULL )
|
||||||
|
{
|
||||||
|
if ( ( s = getenv( "LANG" ) ) == NULL )
|
||||||
|
{
|
||||||
|
s = "C";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char * setlocale( int category, const char * locale )
|
||||||
|
{
|
||||||
|
/* All below is very much work-in-progress, so we do a dumb-dummy
|
||||||
|
return here.
|
||||||
|
*/
|
||||||
|
if ( locale == NULL || ! strcmp( locale, "C" ) )
|
||||||
|
{
|
||||||
|
return (char *)"C";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Path to locale data files - _PDCLIB_LOCALE_PATH unless overruled
|
||||||
|
by the environment variable whose name is defined by preprocessor
|
||||||
|
symbol _PDCLIB_LOCALE_PATH_ENV (defaulting to PDCLIB_I18N).
|
||||||
|
Both of these definitions are set in config.h.
|
||||||
|
*/
|
||||||
|
const char * path = _PDCLIB_LOCALE_PATH;
|
||||||
|
|
||||||
|
struct _PDCLIB_lc_lconv_numeric_t * numeric = NULL;
|
||||||
|
struct _PDCLIB_lc_lconv_monetary_t * monetary = NULL;
|
||||||
|
struct _PDCLIB_lc_collate_t * collate = NULL;
|
||||||
|
struct _PDCLIB_lc_ctype_t * ctype = NULL;
|
||||||
|
struct _PDCLIB_lc_messages_t * messages = NULL;
|
||||||
|
struct _PDCLIB_lc_time_t * time = NULL;
|
||||||
|
|
||||||
|
char * rc = (char *)locale;
|
||||||
|
|
||||||
|
if ( category < 0 || category >= _PDCLIB_LC_COUNT )
|
||||||
|
{
|
||||||
|
/* Bad category */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( locale == NULL )
|
||||||
|
{
|
||||||
|
/* NULL - Return current locale settings */
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strlen( locale ) == 0 )
|
||||||
|
{
|
||||||
|
/* "" - Use default locale */
|
||||||
|
locale = _PDCLIB_default_locale( category );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( getenv( _PDCLIB_symbol2string( _PDCLIB_LOCALE_PATH_ENV ) ) != NULL )
|
||||||
|
{
|
||||||
|
path = getenv( _PDCLIB_symbol2string( _PDCLIB_LOCALE_PATH_ENV ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have to do this in two runs. As we might be facing LC_ALL, we
|
||||||
|
need to be certain all the loads are successful before we start
|
||||||
|
to overwrite the current locale settings, because there is no way
|
||||||
|
this function could report a _partial_ success.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Run One -- get all the data for the new locale setting */
|
||||||
|
if ( category == LC_COLLATE || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( collate = _PDCLIB_load_lc_collate( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_CTYPE || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( ctype = _PDCLIB_load_lc_ctype( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_MONETARY || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( monetary = _PDCLIB_load_lc_monetary( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_NUMERIC || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( numeric = _PDCLIB_load_lc_numeric( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_TIME || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( time = _PDCLIB_load_lc_time( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_MESSAGES || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( ! ( messages = _PDCLIB_load_lc_messages( path, locale ) ) )
|
||||||
|
{
|
||||||
|
rc = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run Two -- continue or release resources */
|
||||||
|
if ( rc != NULL )
|
||||||
|
{
|
||||||
|
if ( category == LC_COLLATE || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_collate.alloced )
|
||||||
|
{
|
||||||
|
/* free resources */
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_collate = *collate;
|
||||||
|
free( collate );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_CTYPE || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_ctype.alloced )
|
||||||
|
{
|
||||||
|
free( _PDCLIB_lc_ctype.entry - 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_ctype = *ctype;
|
||||||
|
free( ctype );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_MONETARY || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_numeric_monetary.monetary_alloced )
|
||||||
|
{
|
||||||
|
free( _PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point );
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point = monetary->mon_decimal_point;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->mon_thousands_sep = monetary->mon_thousands_sep;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->mon_grouping = monetary->mon_grouping;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->positive_sign = monetary->positive_sign;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->negative_sign = monetary->negative_sign;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->currency_symbol = monetary->currency_symbol;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_curr_symbol = monetary->int_curr_symbol;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->frac_digits = monetary->frac_digits;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->p_cs_precedes = monetary->p_cs_precedes;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->n_cs_precedes = monetary->n_cs_precedes;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->p_sep_by_space = monetary->p_sep_by_space;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->n_sep_by_space = monetary->n_sep_by_space;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->p_sign_posn = monetary->p_sign_posn;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->n_sign_posn = monetary->n_sign_posn;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_frac_digits = monetary->int_frac_digits;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_p_cs_precedes = monetary->int_p_cs_precedes;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_n_cs_precedes = monetary->int_n_cs_precedes;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_p_sep_by_space = monetary->int_p_sep_by_space;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_n_sep_by_space = monetary->int_n_sep_by_space;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_p_sign_posn = monetary->int_p_sign_posn;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->int_n_sign_posn = monetary->int_n_sign_posn;
|
||||||
|
|
||||||
|
_PDCLIB_lc_numeric_monetary.monetary_alloced = 1;
|
||||||
|
|
||||||
|
free( monetary );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_NUMERIC || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_numeric_monetary.numeric_alloced )
|
||||||
|
{
|
||||||
|
free( _PDCLIB_lc_numeric_monetary.lconv->decimal_point );
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->decimal_point = numeric->decimal_point;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->thousands_sep = numeric->thousands_sep;
|
||||||
|
_PDCLIB_lc_numeric_monetary.lconv->grouping = numeric->grouping;
|
||||||
|
|
||||||
|
_PDCLIB_lc_numeric_monetary.numeric_alloced = 1;
|
||||||
|
|
||||||
|
free( numeric );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_TIME || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_time.alloced )
|
||||||
|
{
|
||||||
|
free( _PDCLIB_lc_time.month_name_abbr[ 0 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_time = *time;
|
||||||
|
free( time );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( category == LC_MESSAGES || category == LC_ALL )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_lc_messages.alloced )
|
||||||
|
{
|
||||||
|
free( _PDCLIB_lc_messages.errno_texts[ 0 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
_PDCLIB_lc_messages = *messages;
|
||||||
|
free( messages );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
63
src/libraries/libc/signal/raise.c
Normal file
63
src/libraries/libc/signal/raise.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* raise( int )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern void (*_PDCLIB_sigabrt)( int );
|
||||||
|
extern void (*_PDCLIB_sigfpe)( int );
|
||||||
|
extern void (*_PDCLIB_sigill)( int );
|
||||||
|
extern void (*_PDCLIB_sigint)( int );
|
||||||
|
extern void (*_PDCLIB_sigsegv)( int );
|
||||||
|
extern void (*_PDCLIB_sigterm)( int );
|
||||||
|
|
||||||
|
int raise( int sig )
|
||||||
|
{
|
||||||
|
void (*sighandler)( int ) = NULL;
|
||||||
|
const char * message;
|
||||||
|
switch ( sig )
|
||||||
|
{
|
||||||
|
case SIGABRT:
|
||||||
|
sighandler = _PDCLIB_sigabrt;
|
||||||
|
message = "Abnormal termination (SIGABRT)";
|
||||||
|
break;
|
||||||
|
case SIGFPE:
|
||||||
|
sighandler = _PDCLIB_sigfpe;
|
||||||
|
message = "Arithmetic exception (SIGFPE)";
|
||||||
|
break;
|
||||||
|
case SIGILL:
|
||||||
|
sighandler = _PDCLIB_sigill;
|
||||||
|
message = "Illegal instruction (SIGILL)";
|
||||||
|
break;
|
||||||
|
case SIGINT:
|
||||||
|
sighandler = _PDCLIB_sigint;
|
||||||
|
message = "Interactive attention signal (SIGINT)";
|
||||||
|
break;
|
||||||
|
case SIGSEGV:
|
||||||
|
sighandler = _PDCLIB_sigsegv;
|
||||||
|
message = "Invalid memory access (SIGSEGV)";
|
||||||
|
break;
|
||||||
|
case SIGTERM:
|
||||||
|
sighandler = _PDCLIB_sigterm;
|
||||||
|
message = "Termination request (SIGTERM)";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf( stderr, "Unknown signal #%d\n", sig );
|
||||||
|
_Exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
if ( sighandler == SIG_DFL )
|
||||||
|
{
|
||||||
|
fputs( message, stderr );
|
||||||
|
_Exit( EXIT_FAILURE );
|
||||||
|
}
|
||||||
|
else if ( sighandler != SIG_IGN )
|
||||||
|
{
|
||||||
|
sighandler = signal( sig, SIG_DFL );
|
||||||
|
sighandler( sig );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
58
src/libraries/libc/signal/signal.c
Normal file
58
src/libraries/libc/signal/signal.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* signal( int, void (*)( int ) )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void (*_PDCLIB_sigabrt)( int ) = SIG_DFL;
|
||||||
|
void (*_PDCLIB_sigfpe)( int ) = SIG_DFL;
|
||||||
|
void (*_PDCLIB_sigill)( int ) = SIG_DFL;
|
||||||
|
void (*_PDCLIB_sigint)( int ) = SIG_DFL;
|
||||||
|
void (*_PDCLIB_sigsegv)( int ) = SIG_DFL;
|
||||||
|
void (*_PDCLIB_sigterm)( int ) = SIG_DFL;
|
||||||
|
|
||||||
|
void (*signal( int sig, void (*func)( int ) ) )( int )
|
||||||
|
{
|
||||||
|
void (*oldhandler)( int );
|
||||||
|
if ( sig <= 0 || func == SIG_ERR )
|
||||||
|
{
|
||||||
|
return SIG_ERR;
|
||||||
|
}
|
||||||
|
switch ( sig )
|
||||||
|
{
|
||||||
|
case SIGABRT:
|
||||||
|
oldhandler = _PDCLIB_sigabrt;
|
||||||
|
_PDCLIB_sigabrt = func;
|
||||||
|
break;
|
||||||
|
case SIGFPE:
|
||||||
|
oldhandler = _PDCLIB_sigfpe;
|
||||||
|
_PDCLIB_sigfpe = func;
|
||||||
|
break;
|
||||||
|
case SIGILL:
|
||||||
|
oldhandler = _PDCLIB_sigill;
|
||||||
|
_PDCLIB_sigill = func;
|
||||||
|
break;
|
||||||
|
case SIGINT:
|
||||||
|
oldhandler = _PDCLIB_sigint;
|
||||||
|
_PDCLIB_sigint = func;
|
||||||
|
break;
|
||||||
|
case SIGSEGV:
|
||||||
|
oldhandler = _PDCLIB_sigsegv;
|
||||||
|
_PDCLIB_sigsegv = func;
|
||||||
|
break;
|
||||||
|
case SIGTERM:
|
||||||
|
oldhandler = _PDCLIB_sigterm;
|
||||||
|
_PDCLIB_sigterm = func;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* The standard calls for an unspecified "positive value". You
|
||||||
|
will probably want to define a specific value for this.
|
||||||
|
*/
|
||||||
|
_PDCLIB_errno = 1;
|
||||||
|
return SIG_ERR;
|
||||||
|
}
|
||||||
|
return oldhandler;
|
||||||
|
}
|
||||||
12
src/libraries/libc/stdio/clearerr.c
Normal file
12
src/libraries/libc/stdio/clearerr.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/* clearerr( FILE * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void clearerr( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
stream->status &= ~( _PDCLIB_ERRORFLAG | _PDCLIB_EOFFLAG );
|
||||||
|
}
|
||||||
67
src/libraries/libc/stdio/fclose.c
Normal file
67
src/libraries/libc/stdio/fclose.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/* fclose( FILE * )
|
||||||
|
|
||||||
|
This file is part of the Public Domain C Library (PDCLib).
|
||||||
|
Permission is granted to use, modify, and / or redistribute at will.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "j6libc/glue.h"
|
||||||
|
|
||||||
|
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
|
||||||
|
|
||||||
|
int fclose( struct _PDCLIB_file_t * stream )
|
||||||
|
{
|
||||||
|
struct _PDCLIB_file_t * current = _PDCLIB_filelist;
|
||||||
|
struct _PDCLIB_file_t * previous = NULL;
|
||||||
|
/* Checking that the FILE handle is actually one we had opened before. */
|
||||||
|
while ( current != NULL )
|
||||||
|
{
|
||||||
|
if ( stream == current )
|
||||||
|
{
|
||||||
|
/* Flush buffer */
|
||||||
|
if ( stream->status & _PDCLIB_FWRITE )
|
||||||
|
{
|
||||||
|
if ( _PDCLIB_flushbuffer( stream ) == EOF )
|
||||||
|
{
|
||||||
|
/* Flush failed, errno already set */
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Close handle */
|
||||||
|
_PDCLIB_close( stream->handle );
|
||||||
|
/* Remove stream from list */
|
||||||
|
if ( previous != NULL )
|
||||||
|
{
|
||||||
|
previous->next = stream->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_PDCLIB_filelist = stream->next;
|
||||||
|
}
|
||||||
|
/* Delete tmpfile() */
|
||||||
|
if ( stream->status & _PDCLIB_DELONCLOSE )
|
||||||
|
{
|
||||||
|
remove( stream->filename );
|
||||||
|
}
|
||||||
|
/* Free user buffer (SetVBuf allocated) */
|
||||||
|
if ( stream->status & _PDCLIB_FREEBUFFER )
|
||||||
|
{
|
||||||
|
free( stream->buffer );
|
||||||
|
}
|
||||||
|
/* Free stream */
|
||||||
|
if ( ! ( stream->status & _PDCLIB_STATIC ) )
|
||||||
|
{
|
||||||
|
free( stream );
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
previous = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
/* See the comments on implementation-defined errno values in
|
||||||
|
<config.h>.
|
||||||
|
*/
|
||||||
|
_PDCLIB_errno = _PDCLIB_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user