Compare commits

...

80 Commits

Author SHA1 Message Date
Heath Mitchell 4ade93eb6f Change dependency 2023-06-27 21:03:17 +02:00
Lephenixnoir 031e0ccb65
bump version to 1.4.5 2023-04-01 20:30:30 +02:00
Lephenixnoir 74b805e8b5
stdlib: automatically seed PRNG with srand(1) 2023-04-01 20:30:30 +02:00
Yann MAGNIN 7eb2a6e8ab
add shared lib generation support for Vhex 2023-04-01 20:30:30 +02:00
Yann MAGNIN c85182d07e
update vxSDK integration 2023-04-01 20:30:30 +02:00
Lephenixnoir 465655674b
dso: dynamically allocate destructor table
This saves static memory on mono targets where it's scarce.
2023-04-01 20:30:30 +02:00
Lephenixnoir 1da9d10226
alloca: provide <alloca.h> 2023-04-01 20:30:30 +02:00
Lephenixnoir 7c4de3e295
dso, stdlib: __cxa_atexit(), __dso_handle, atexit() (TEST) 2023-04-01 20:30:30 +02:00
Lephenixnoir 95e33092ec
stdlib: add fileno (DONE) 2023-04-01 20:30:29 +02:00
Lephenixnoir 26e54af8e0
stdlib: scanf-friendly strto* functions 2023-04-01 20:30:29 +02:00
Lephenixnoir fda0d950ed
time: fix strftime being called strftime2 2023-04-01 20:30:29 +02:00
Lephenixnoir eb83e7442f Merge pull request 'Fix signedness issues with strcmp and strncmp' (#4) from Heath123/fxlibc:heath123-patch-1 into master
Reviewed-on: https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc/pulls/4
2022-11-24 14:23:21 +01:00
Heath Mitchell aeeae3810d Update 'src/string/strcmp.c' 2022-11-24 13:36:02 +01:00
Heath Mitchell ee42660ea5 Update 'src/string/strncmp.c' 2022-11-24 13:30:46 +01:00
Lephenixnoir ddec761f61
bump version to 1.4.4 2022-08-21 20:09:54 +02:00
Lephenixnoir ca6c39bf56
meta: update build instructions 2022-08-21 17:11:28 +02:00
Lephenixnoir 4b61daa602
stdio: use non-zero values for SEEK_*
libstdc++ uses 0, SEEK_CUR, SEEK_END in an internal enumeration. By
having SEEK_CUR=0 we would have a duplicate case.
2022-08-19 15:49:54 +02:00
Lephenixnoir 8231557ff5
add declarations for unsupported functions for libstdc++
So that it compiles - it won't link but we can leave that for later.
2022-08-19 15:49:52 +02:00
Lephenixnoir 714e1cf605
signal: make sig_atomic_t a normal int
Using the _Atomic types is technically more accurate, but equivalent in
practice (glibc uses a normal int) and a bit of a headache for C++
targets since _Atomic is replaced with std::atomic.
2022-08-12 22:46:56 +02:00
Lephenixnoir ed52c1d7c2
sys/mman: fix missing include 2022-08-12 22:46:46 +02:00
Lephenixnoir 143029a837
stdint: do not rely on -ffreestanding
GCC's default stdint.h only defaults to stdint-gcc.h, which we want to
use, when using -ffreestanding. Make our wishes explicit to avoid
needing that flag.
2022-08-12 22:43:37 +02:00
Lephenixnoir 31ee6fdbee
cmake: remove the OpenLibm include path workaround
This is no longer needed when the fxSDK sysroot is in use; and anyway no
2022-08-12 22:40:20 +02:00
Lephenixnoir b38dd3f894
cmake: use *dynamic* fxSDK compiler path as default for gint
Previously FXSDK_COMPILER_INSTALL would be stored as the install prefix.
However, this prefix is subject to unannounced changes when the compiler
version is upgraded without reconfiguring the fxlibc, which happens in
the GiteaPC workflow.

This commit avoids the use of CMAKE_INSTALL_PREFIX when using gint with
no specified prefix, and instead uses another cached variable which
leaves the prefix to be dynamically resolved based on the uncached
variable FXSDK_COMPILER_INSTALL, like most repositories do (eg. gint).
We need the cached indicator because we frequently reconfigure and
CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT is not persistent.
2022-08-12 22:39:53 +02:00
Lephenixnoir 89c6c39405
stdio: support for UTF-8 %lc in printf() 2022-08-01 11:27:24 +01:00
Yann MAGNIN e8779145c2 fix vhex target folders 2022-07-30 18:55:40 +02:00
Yann MAGNIN ed77a97547 Merge branch 'dev' of https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc into dev 2022-07-30 17:57:55 +02:00
Yann MAGNIN bdf9566723 fxlibc - v1.4.3 : fix vhex missing headers
@update
> CMakeLists.txt
 | remove the generation of the shared version of the fxlibc (deprecated, unused)
> include/errno
 | add some error macros needed in vhex
> src/string/strerror
 | add EINTR support
 | add EAGAIN support
 | add ENOMEDIUM support
 | add EMEDIUMTYPE support

@fix
> include/target/vhex
 | add missing headers
2022-07-30 17:57:08 +02:00
Lephenixnoir 26d5b5d9ab
meta: chase the very last __restrict__ for C++ compatibility 2022-06-29 10:52:48 +01:00
Yann MAGNIN 619afe25da fxlibc - v1.4.2 : fix reallocarray() + remove old Vhex/Casiowin sources
@update
> CMakeLists.txt
  | remove casiowin-* target (unused)
  | remove x86-generic target (unused)
  | update files location
  | remove old vhex sources files (deprecated, unused)
> src/posix
  | remove this folder
> src/libc
  | move its content to src/
  | remove thread module
> src/stdlib/reallocarray
  | check if the multiplication overflow failed
  | set appropriate errno value if multiplication failed
2022-06-03 16:25:31 +02:00
Yann MAGNIN 996b2b8ded fxlibc - v1.4.1 : update Vhex stdlib
@update
> malloc  : do not use syscall, involve kmalloc
> realloc : do not use syscall, involve krealloc
> free    : do not use syscall, involve kfree

@fix
> _Exit : remove syscall
2022-05-14 11:49:08 +02:00
Lephenixnoir d50e44c563
C++ __restrict__, update STATUS, minor formatting 2022-03-31 10:12:01 +01:00
Lephenixnoir 94faa6cbea Merge pull request 'Add getline(3) & getdelim(3)' (#2) from Alice/fxlibc:dev into dev
Reviewed-on: https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc/pulls/2
2022-03-31 11:11:26 +02:00
Alice Rozengarden 3f5989ceab Add getline(3) & getdelim(3) 2022-03-30 23:49:44 +02:00
Lephenixnoir 3c29639988
string: fix a bug in SuperH memset 2022-03-26 15:19:15 +00:00
Lephenixnoir 4d464bde01
bump version to 1.4.0 2022-03-19 19:29:17 +00:00
Lephenixnoir 809238e5b8
errno: add EINTR and EAGAIN 2022-02-24 12:48:51 +01:00
Yann MAGNIN fa4adc5620 add PIC option + vxsdk support 2022-01-26 16:34:16 +01:00
Lephenixnoir 71866ed769
stdio: stdin/stdout/stderr, perror, final adjustments
Support for <stdio.h> will stop here for now.
2022-01-14 18:38:48 +01:00
Lephenixnoir ed873a652e
stdio: fgetc(), fgets(), tests for fputc() and fputs() (DONE) 2022-01-14 17:16:04 +01:00
Lephenixnoir 294fda9731
stdio: share the FILE implementation between all versions 2022-01-13 21:28:19 +01:00
Lephenixnoir f1512125d0
stdio: initial versions of fputc() and fputs() (TEST) 2022-01-13 21:21:23 +01:00
Lephenixnoir 6ec0c24e2d
stdio: ungetc(), update (+) and append (a) modes (DONE) 2022-01-12 10:20:30 +01:00
Lephenixnoir 06b66252c9
stdio: line buffering, test fgetpos and fsetpos (DONE) 2022-01-10 21:32:24 +01:00
Lephenixnoir 0c2f81e5bb
string: add and test a naive memrchr (DONE) 2022-01-10 21:21:03 +01:00
Lephenixnoir 909c7df815
stdio: fixes for initial fread() et fwrite() (TEST) 2022-01-10 17:10:49 +01:00
Lephenixnoir 4461bdb96a
stdio: basic fread/fwrite (WIP) 2022-01-05 21:26:06 +01:00
Lephenixnoir b6dbdf321d
stdio: error handling and positioning functions (WIP) 2022-01-02 22:09:06 +01:00
Lephenixnoir a12b84f1ef
stdio: opening primitives for FILE (WIP) 2022-01-02 19:22:43 +01:00
Lephenixnoir 51528170bb
stdio: FILE barebones with buffering model (WIP) 2022-01-02 19:22:42 +01:00
Lephenixnoir b53078776d
stdio: enable dprintf() and vdprintf() 2022-01-02 19:22:42 +01:00
Lephenixnoir 3046304497
stdlib: set errno=ENOMEM after failed malloc() 2022-01-02 19:22:42 +01:00
Lephenixnoir f7b85f18bd
time: do not depend on gint headers
They're usually not installed yet
2021-12-31 19:48:43 +01:00
Lephenixnoir bd0dd3a8d2
bump version to 1.3.0 2021-12-31 10:42:44 +01:00
Lephenixnoir dbfefe5172
errno: add ENOTEMPTY for rmdir() 2021-12-30 18:18:54 +01:00
Lephenixnoir 937b7bfb63
stat: definitions required to support stat(2) 2021-12-23 23:50:48 +01:00
Lephenixnoir e479393a9c
unistd, dirent: definitions for directory functions 2021-12-21 18:55:23 +01:00
Lephenixnoir c2feb94710
fcntl, unistd: declarations for the Unix file API 2021-12-13 18:37:04 +01:00
Lephenixnoir 92ccd8b1db
time: add support for C99 <time.h> (DONE) 2021-12-04 22:02:23 +01:00
Lephenixnoir e71f9867e2
support for shared libgcc in vhex 2021-11-07 18:05:33 +01:00
Lephenixnoir 164b33b26d
cmake: initial support for shared vhex library
Using the previously-tested trick with `ld -shared`.
2021-10-10 19:34:46 +02:00
Lephenixnoir df4c13b007
stdlib: fix bad memset in calloc() 2021-09-25 15:16:24 +02:00
Lephenixnoir a0ceeefaf4
string: fix strtok detecting NUL only after separators 2021-08-17 17:30:21 +02:00
Lephenixnoir ea35c18c41
stdlib: add qsort (TEST) 2021-06-28 23:54:43 +02:00
Lephenixnoir a6dbcfb227
add C++ header guards 2021-06-28 15:49:05 +02:00
Lephenixnoir f5571e2b3d
time: add general definitions 2021-06-13 18:26:04 +02:00
Lephenixnoir 6e42995388
stdio: add general file management definitions 2021-06-13 18:18:32 +02:00
Lephenixnoir 518a866750
use __restrict__ in headers for g++ compatibility 2021-06-13 18:17:40 +02:00
Lephenixnoir 6be2a3d52e
bump version to 1.2.0 2021-06-08 10:57:34 +02:00
Lephenixnoir dcaf203f46
stdio: improve printf extension API and type size support 2021-06-08 10:32:08 +02:00
Lephenixnoir ed8134970b
add nonstandard GNU endian.h 2021-06-08 10:05:00 +02:00
Lephenixnoir 009a2eef6e
stdlib: add TinyMT-based rand, and malloc/etc for gint 2021-06-07 22:00:41 +02:00
Lephenixnoir 625a6af459
stdio: add asprintf and vasprintf 2021-06-07 19:09:55 +02:00
Lephenixnoir f52e0923bc
stdio: move the printf implementation from gint 2021-06-07 18:57:11 +02:00
Lephenixnoir 66463bfe17
assert: fix silly mistake 2021-05-30 23:16:09 +02:00
Lephenixnoir d261db447b
add some function attributes 2021-05-30 15:09:33 +02:00
Lephenixnoir cd7fe7a329
signal: simple implementation (DONE)
This version of signal (which does not rely on a notion of userland
processes and is thus excluded from Vhex) follows C99 semantics but does
not generate any signals by default.

Basically, the signal function sets up function pointers and the signal
function calls them. Termination signals call exit() while other signals
call _Exit(), which is a quicker program termination similar to abort().

C99 allows programs to long jump out of signal handlers (!) which is
unbelievably scary because it would bypass stack switching code in Vhex
as well as normal interrupt handler termination in gint.
2021-05-30 15:09:33 +02:00
Lephenixnoir 04e910441a
cmake: fix install dirs reversing at second build 2021-05-30 00:03:21 +02:00
Lephenixnoir 4b90740d3b
stdlib: add exit() based on target-provided _Exit()
This is implemented for gint only currently; on Vhex, _Exit() is likely
just going to be a syscall. For CASIOWIN, this is slightly more
difficult, as there is no native exit syscall.
2021-05-29 16:45:35 +02:00
Lephenixnoir 73d6b2eb7c
setjmp: do not disable interrupts (#1) (DONE)
SR.BL=1 could cause problems if setjmp or longjmp is loader over a page
boundary and the second page is not loaded when interrupts are masked.

SR.IMASK=15 is another option, but it seems unnecessary per #1.

Blocking interrupts in longjmp did not make too much sense because the
blocked SR was immediately replaced by the restored one.
2021-05-29 11:18:02 +02:00
Lephenixnoir 13c3390b22
setjmp: expose setjmp and longjmp to sh-generic
... instead of vhex-generic, where it doesn't really belong because Vhex
might run on other architectures.
2021-05-29 09:56:47 +02:00
275 changed files with 5564 additions and 2369 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@
/prefix
*.txt
!CMakeLists.txt
.vxsdk/
# GiteaPC config files
giteapc-config.make

22
3rdparty/grisu2b_59_56/LICENSE vendored Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

14
3rdparty/grisu2b_59_56/README vendored Normal file
View File

@ -0,0 +1,14 @@
Grisu is an algorithm by Florian Loitsch to print the decimal representation of
floating-point numbers.
The original code from which this folder is extracted can be found at
<https://drive.google.com/open?id=0BwvYOx00EwKmejFIMjRORTFLcTA>.
Only a minimal variation, the Grisu2 rounding algorithm with α=-59 and γ=-56,
is present here. The code has been adapted to fit the limited runtime as well
as the use of OpenLibm.
See the original paper at <https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf>
and Florian Loitsch's home page at <https://florian.loitsch.com/publications>.
The files are licensed under the permissive conditions of the attached LICENSE.

58
3rdparty/grisu2b_59_56/diy_fp.h vendored Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <stdint.h>
typedef struct diy_fp_t {
uint64_t f;
int e;
} diy_fp_t;
static diy_fp_t minus(diy_fp_t x, diy_fp_t y) {
diy_fp_t r = {.f = x.f - y.f, .e = x.e};
return r;
}
/*
static diy_fp_t minus(diy_fp_t x, diy_fp_t y) {
assert(x.e == y.e);
assert(x.f >= y.f);
diy_fp_t r = {.f = x.f - y.f, .e = x.e};
return r;
}
*/
static diy_fp_t multiply(diy_fp_t x, diy_fp_t y) {
uint64_t a,b,c,d,ac,bc,ad,bd,tmp,h;
diy_fp_t r; uint64_t M32 = 0xFFFFFFFF;
a = x.f >> 32; b = x.f & M32;
c = y.f >> 32; d = y.f & M32;
ac = a*c; bc = b*c; ad = a*d; bd = b*d;
tmp = (bd>>32) + (ad&M32) + (bc&M32);
tmp += 1U << 31; /// mult_round
r.f = ac+(ad>>32)+(bc>>32)+(tmp >>32);
r.e = x.e + y.e + 64;
return r;
}

110
3rdparty/grisu2b_59_56/double.h vendored Normal file
View File

@ -0,0 +1,110 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "diy_fp.h"
#include "powers.h"
#include <stdbool.h>
typedef union {
double d;
uint64_t n;
} converter_t;
static uint64_t double_to_uint64(double d) { converter_t tmp; tmp.d = d; return tmp.n; }
static double uint64_to_double(uint64_t d64) { converter_t tmp; tmp.n = d64; return tmp.d; }
#define DP_SIGNIFICAND_SIZE 52
#define DP_EXPONENT_BIAS (0x3FF + DP_SIGNIFICAND_SIZE)
#define DP_MIN_EXPONENT (-DP_EXPONENT_BIAS)
#define DP_EXPONENT_MASK 0x7FF0000000000000
#define DP_SIGNIFICAND_MASK 0x000FFFFFFFFFFFFF
#define DP_HIDDEN_BIT 0x0010000000000000
static diy_fp_t normalize_diy_fp(diy_fp_t in) {
diy_fp_t res = in;
/* Normalize now */
/* the original number could have been a denormal. */
while (! (res.f & DP_HIDDEN_BIT))
{
res.f <<= 1;
res.e--;
}
/* do the final shifts in one go. Don't forget the hidden bit (the '-1') */
res.f <<= (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 1);
res.e = res.e - (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 1);
return res;
}
static diy_fp_t double2diy_fp(double d) {
uint64_t d64 = double_to_uint64(d);
int biased_e = (d64 & DP_EXPONENT_MASK) >> DP_SIGNIFICAND_SIZE;
uint64_t significand = (d64 & DP_SIGNIFICAND_MASK);
diy_fp_t res;
if (biased_e != 0)
{
res.f = significand + DP_HIDDEN_BIT;
res.e = biased_e - DP_EXPONENT_BIAS;
} else {
res.f = significand;
res.e = DP_MIN_EXPONENT + 1;
}
return res;
}
static diy_fp_t normalize_boundary(diy_fp_t in) {
diy_fp_t res = in;
/* Normalize now */
/* the original number could have been a denormal. */
while (! (res.f & (DP_HIDDEN_BIT << 1)))
{
res.f <<= 1;
res.e--;
}
/* do the final shifts in one go. Don't forget the hidden bit (the '-1') */
res.f <<= (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2);
res.e = res.e - (DIY_SIGNIFICAND_SIZE - DP_SIGNIFICAND_SIZE - 2);
return res;
}
static void normalized_boundaries(double d, diy_fp_t* out_m_minus, diy_fp_t* out_m_plus) {
diy_fp_t v = double2diy_fp(d);
diy_fp_t pl, mi;
bool significand_is_zero = v.f == DP_HIDDEN_BIT;
pl.f = (v.f << 1) + 1; pl.e = v.e - 1;
pl = normalize_boundary(pl);
if (significand_is_zero)
{
mi.f = (v.f << 2) - 1;
mi.e = v.e - 2;
} else {
mi.f = (v.f << 1) - 1;
mi.e = v.e - 1;
}
mi.f <<= mi.e - pl.e;
mi.e = pl.e;
*out_m_plus = pl;
*out_m_minus = mi;
}

27
3rdparty/grisu2b_59_56/grisu2.h vendored Normal file
View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
void grisu2(double v, char* buffer, int* length, int* K);

95
3rdparty/grisu2b_59_56/grisu2b_59_56.c vendored Normal file
View File

@ -0,0 +1,95 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "diy_fp.h"
#include "k_comp.h"
#include "double.h"
#include "powers.h"
#include <stdbool.h>
#include "grisu2.h"
#include <stdint.h>
#define TEN9 1000000000
void grisu_round(char* buffer, int len,
uint64_t delta, uint64_t rest,
uint64_t ten_kappa, uint64_t wp_w) {
while (rest < wp_w &&
delta - rest >= ten_kappa &&
(rest + ten_kappa < wp_w || /// closer
wp_w - rest > rest+ten_kappa - wp_w))
{
buffer[len-1]--; rest += ten_kappa;
}
}
void digit_gen(diy_fp_t W, diy_fp_t Mp, diy_fp_t delta,
char* buffer, int* len, int* K) {
uint32_t div; int d,kappa; diy_fp_t one, wp_w;
wp_w = minus(Mp, W);
one.f = ((uint64_t) 1) << -Mp.e; one.e = Mp.e;
uint32_t p1 = Mp.f >> -one.e; /// Mp_cut
uint64_t p2 = Mp.f & (one.f - 1);
*len = 0; kappa = 10; div = TEN9;
while (kappa > 0) {
d = p1 / div;
if (d || *len) buffer[(*len)++] = '0' + d; /// Mp_inv1
p1 %= div; kappa--;
uint64_t tmp = (((uint64_t)p1)<<-one.e)+p2;
if (tmp <= delta.f) { /// Mp_delta
*K += kappa;
grisu_round(buffer, *len, delta.f, tmp, ((uint64_t)div) << -one.e, wp_w.f);
return;
}
div /= 10;
}
uint64_t unit = 1;
while (1) {
p2 *= 10; delta.f *= 10; unit *= 10;
d = p2 >> -one.e;
if (d || *len) buffer[(*len)++] = '0' + d;
p2 &= one.f - 1; kappa--;
if (p2 < delta.f) {
*K += kappa;
grisu_round(buffer, *len, delta.f, p2, one.f, wp_w.f*unit);
return;
}
}
}
void grisu2(double v, char* buffer, int* length, int* K) {
diy_fp_t w_m, w_p;
int q = 64, alpha = -59, gamma = -56; int pos;
normalized_boundaries(v, &w_m, &w_p);
diy_fp_t w = normalize_diy_fp(double2diy_fp(v));
int mk = k_comp(w_p.e + q, alpha, gamma);
diy_fp_t c_mk = cached_power(mk);
diy_fp_t W = multiply(w, c_mk);
diy_fp_t Wp = multiply(w_p, c_mk);
diy_fp_t Wm = multiply(w_m, c_mk);
Wm.f++; Wp.f--;
diy_fp_t delta = minus(Wp, Wm);
*K = -mk;
digit_gen(W, Wp, delta, buffer, length, K);
}

32
3rdparty/grisu2b_59_56/k_comp.h vendored Normal file
View File

@ -0,0 +1,32 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <openlibm.h>
#define D_1_LOG2_10 0.30102999566398114 // 1 / lg(10)
static int k_comp(int e, int alpha, int gamma) {
return ceil((alpha-e+63) * D_1_LOG2_10);
}

27
3rdparty/grisu2b_59_56/powers.h vendored Normal file
View File

@ -0,0 +1,27 @@
/*
Copyright (c) 2009 Florian Loitsch
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include "diy_fp.h"
#include "powers_ten_round64.h"

File diff suppressed because one or more lines are too long

20
3rdparty/tinymt32/rand.c vendored Normal file
View File

@ -0,0 +1,20 @@
#include <stdlib.h>
#include "tinymt32.h"
static tinymt32_t random;
void srand(unsigned int seed)
{
tinymt32_init(&random, seed);
}
int rand(void)
{
return tinymt32_generate_uint32(&random) & 0x7fffffff;
}
__attribute__((constructor))
static void init_prng(void)
{
srand(1);
}

121
3rdparty/tinymt32/tinymt32.c vendored Normal file
View File

@ -0,0 +1,121 @@
/**
* @file tinymt32.c
*
* @brief Tiny Mersenne Twister only 127 bit internal state
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (The University of Tokyo)
*
* Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
* Hiroshima University and The University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
/* Note: this is a stripped-down version of TinyMT that only includes the
32-bit integer generator. For the full version, please see
<https://github.com/MersenneTwister-Lab/TinyMT>. */
#include "tinymt32.h"
#define TINYMT32_SH0 1
#define TINYMT32_SH1 10
#define TINYMT32_SH8 8
#define TINYMT32_MASK 0x7fffffff
/**
* This function changes internal state of tinymt32.
* Users should not call this function directly.
* @param random tinymt internal status
*/
static void tinymt32_next_state(tinymt32_t * random) {
uint32_t x;
uint32_t y;
y = random->status[3];
x = (random->status[0] & TINYMT32_MASK)
^ random->status[1]
^ random->status[2];
x ^= (x << TINYMT32_SH0);
y ^= (y >> TINYMT32_SH0) ^ x;
random->status[0] = random->status[1];
random->status[1] = random->status[2];
random->status[2] = x ^ (y << TINYMT32_SH1);
random->status[3] = y;
random->status[1] ^= -((int32_t)(y & 1)) & random->mat1;
random->status[2] ^= -((int32_t)(y & 1)) & random->mat2;
}
/**
* This function outputs 32-bit unsigned integer from internal state.
* Users should not call this function directly.
* @param random tinymt internal status
* @return 32-bit unsigned pseudorandom number
*/
static uint32_t tinymt32_temper(tinymt32_t * random) {
uint32_t t0, t1;
t0 = random->status[3];
#if defined(LINEARITY_CHECK)
t1 = random->status[0]
^ (random->status[2] >> TINYMT32_SH8);
#else
t1 = random->status[0]
+ (random->status[2] >> TINYMT32_SH8);
#endif
t0 ^= t1;
t0 ^= -((int32_t)(t1 & 1)) & random->tmat;
return t0;
}
/**
* This function outputs 32-bit unsigned integer from internal state.
* @param random tinymt internal status
* @return 32-bit unsigned integer r (0 <= r < 2^32)
*/
uint32_t tinymt32_generate_uint32(tinymt32_t * random) {
tinymt32_next_state(random);
return tinymt32_temper(random);
}
#define MIN_LOOP 8
#define PRE_LOOP 8
/**
* This function certificate the period of 2^127-1.
* @param random tinymt state vector.
*/
static void period_certification(tinymt32_t * random) {
if ((random->status[0] & TINYMT32_MASK) == 0 &&
random->status[1] == 0 &&
random->status[2] == 0 &&
random->status[3] == 0) {
random->status[0] = 'T';
random->status[1] = 'I';
random->status[2] = 'N';
random->status[3] = 'Y';
}
}
/**
* This function initializes the internal state array with a 32-bit
* unsigned integer seed.
* @param random tinymt state vector.
* @param seed a 32-bit unsigned integer used as a seed.
*/
void tinymt32_init(tinymt32_t * random, uint32_t seed) {
random->status[0] = seed;
random->status[1] = random->mat1;
random->status[2] = random->mat2;
random->status[3] = random->tmat;
for (int i = 1; i < MIN_LOOP; i++) {
random->status[i & 3] ^= i + UINT32_C(1812433253)
* (random->status[(i - 1) & 3]
^ (random->status[(i - 1) & 3] >> 30));
}
period_certification(random);
for (int i = 0; i < PRE_LOOP; i++) {
tinymt32_next_state(random);
}
}

40
3rdparty/tinymt32/tinymt32.h vendored Normal file
View File

@ -0,0 +1,40 @@
#ifndef TINYMT32_H
#define TINYMT32_H
/**
* @file tinymt32.h
*
* @brief Tiny Mersenne Twister only 127 bit internal state
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (University of Tokyo)
*
* Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto,
* Hiroshima University and The University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
/* Note: this is a stripped-down version of TinyMT that only includes the
32-bit integer generator. For the full version, please see
<https://github.com/MersenneTwister-Lab/TinyMT>. */
#include <stdint.h>
/**
* tinymt32 internal state vector and parameters
*/
struct TINYMT32_T {
uint32_t status[4];
uint32_t mat1;
uint32_t mat2;
uint32_t tmat;
};
typedef struct TINYMT32_T tinymt32_t;
uint32_t tinymt32_generate_uint32(tinymt32_t *random);
void tinymt32_init(tinymt32_t *random, uint32_t seed);
#endif

View File

@ -1,13 +1,10 @@
cmake_minimum_required(VERSION 3.15)
project(FxLibc VERSION 1.0.0 LANGUAGES C ASM)
project(FxLibc VERSION 1.4.5 LANGUAGES C ASM)
set(CMAKE_INSTALL_MESSAGE LAZY)
# Options
# * -DFXLIBC_TARGET=<vhex-sh, vhex-x86, casiowin-fx, casiowin-cg, gint>
# * -DSHARED
option(SHARED "Build a shared library")
option(STANDARD_NAMESPACE "Use libc.a and put headers in global include folder")
set(TARGET_FOLDERS ${FXLIBC_TARGET})
# Install paths
@ -15,29 +12,12 @@ set(LIBDIR "lib")
set(INCDIR "include")
if(FXLIBC_TARGET STREQUAL vhex-sh)
list(APPEND TARGET_FOLDERS vhex-generic sh-generic)
list(APPEND TARGET_FOLDERS vhex sh-generic)
set(FXLIBC_ARCH sh)
add_definitions(-D__SUPPORT_VHEX_KERNEL)
endif()
if(FXLIBC_TARGET STREQUAL vhex-x86)
list(APPEND TARGET_FOLDERS vhex-generic x86-generic)
set(FXLIBC_ARCH x86)
add_definitions(-D__SUPPORT_VHEX_KERNEL)
# TODO: Maybe add -nostdinc (but that removes compiler-provided headers like
# <stddef.h>), or use another compiler than the system one?
endif()
if(FXLIBC_TARGET STREQUAL casiowin-fx)
list(APPEND TARGET_FOLDERS sh-generic)
set(FXLIBC_ARCH sh)
add_definitions(-D__SUPPORT_CASIOWIN_FX9860G)
endif()
if(FXLIBC_TARGET STREQUAL casiowin-cg)
list(APPEND TARGET_FOLDERS sh-generic)
set(FXLIBC_ARCH sh)
add_definitions(-D__SUPPORT_CASIOWIN_FXCG50)
set(CMAKE_INSTALL_PREFIX "${VXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
set(INCDIR "${VXSDK_COMPILER_INSTALL}/include")
set(LIBDIR "${VXSDK_COMPILER_INSTALL}/lib")
endif()
if(FXLIBC_TARGET STREQUAL gint)
@ -47,9 +27,21 @@ if(FXLIBC_TARGET STREQUAL gint)
# Default to fxSDK install path
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${FXSDK_COMPILER_INSTALL}" CACHE PATH "..." FORCE)
set(LIBDIR ".")
set(INCDIR "include")
set(FXLIBC_PREFIX_IS_FXSDK 1 CACHE PATH "..." FORCE)
endif()
if(FXLIBC_PREFIX_IS_FXSDK)
# Use the fxSDK paths; these variables are uncached so we are always up-to-
# date, even if the compiler is upgraded without removing the fxlibc build
# folder (which happens with GiteaPC)
execute_process(
COMMAND fxsdk path include
OUTPUT_VARIABLE INCDIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(
COMMAND fxsdk path lib
OUTPUT_VARIABLE LIBDIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
endif()
@ -57,16 +49,16 @@ if(sh-generic IN_LIST TARGET_FOLDERS)
add_definitions(-D__SUPPORT_ARCH_SH)
endif()
if(x86-generic IN_LIST TARGET_FOLDERS)
add_definitions(-D__SUPPORT_ARCH_X86)
endif()
# TODO: Preprocessor definitions for configuration
# configure_file()
# libc.{a,so} libfxlibc.{a,so}
add_compile_options(-Wall -Wextra -std=c11 -ffreestanding -Os)
if(FXLIBC_PIC)
add_compile_options(-fpic)
endif()
if(FXLIBC_ARCH STREQUAL sh)
add_compile_options(
"$<$<COMPILE_LANGUAGE:C>:-m3;-mb>"
@ -76,164 +68,236 @@ endif()
# Building
set(SOURCES
# 3rdparty
3rdparty/grisu2b_59_56/grisu2b_59_56.c
3rdparty/tinymt32/rand.c
3rdparty/tinymt32/tinymt32.c
# C++ API details
src/dso.c
# assert
src/libc/assert/assert.c
src/assert/assert.c
# ctype
src/libc/ctype/isalnum.c
src/libc/ctype/isalpha.c
src/libc/ctype/isblank.c
src/libc/ctype/iscntrl.c
src/libc/ctype/isdigit.c
src/libc/ctype/isgraph.c
src/libc/ctype/islower.c
src/libc/ctype/isprint.c
src/libc/ctype/ispunct.c
src/libc/ctype/isspace.c
src/libc/ctype/isupper.c
src/libc/ctype/isxdigit.c
src/libc/ctype/tolower.c
src/libc/ctype/toupper.c
src/ctype/isalnum.c
src/ctype/isalpha.c
src/ctype/isblank.c
src/ctype/iscntrl.c
src/ctype/isdigit.c
src/ctype/isgraph.c
src/ctype/islower.c
src/ctype/isprint.c
src/ctype/ispunct.c
src/ctype/isspace.c
src/ctype/isupper.c
src/ctype/isxdigit.c
src/ctype/tolower.c
src/ctype/toupper.c
# errno
src/libc/errno/errno.c
src/errno/errno.c
# inttypes
src/libc/inttypes/imaxabs.c
src/libc/inttypes/imaxdiv.c
src/libc/inttypes/strtoimax.c
src/libc/inttypes/strtoumax.c
src/inttypes/imaxabs.c
src/inttypes/imaxdiv.c
src/inttypes/strtoimax.c
src/inttypes/strtoumax.c
# locale
src/libc/locale/setlocale.c
src/libc/locale/localeconv.c
src/locale/setlocale.c
src/locale/localeconv.c
# signal
src/signal/signal.c
src/signal/raise.c
# stdio
src/libc/stdio/vsnprintf.c
src/libc/stdio/sprintf.c
src/libc/stdio/dprintf.c
src/libc/stdio/snprintf.c
src/libc/stdio/puts.c
src/libc/stdio/vsprintf.c
src/libc/stdio/putc.c
src/libc/stdio/internal/printf_actions.c
src/libc/stdio/internal/printf_options.c
src/libc/stdio/internal/printf_common.c
src/libc/stdio/internal/printf.h
src/libc/stdio/vdprintf.c
src/libc/stdio/printf.c
src/stdio/asprintf.c
src/stdio/clearerr.c
src/stdio/dprintf.c
src/stdio/fclose.c
src/stdio/fdopen.c
src/stdio/ferror.c
src/stdio/feof.c
src/stdio/fflush.c
src/stdio/fgetc.c
src/stdio/fgetpos.c
src/stdio/fgets.c
src/stdio/fileno.c
src/stdio/fileutil.c
src/stdio/fopen.c
src/stdio/fprintf.c
src/stdio/fputc.c
src/stdio/fputs.c
src/stdio/fread.c
src/stdio/freopen.c
src/stdio/fseek.c
src/stdio/fsetpos.c
src/stdio/ftell.c
src/stdio/fwrite.c
src/stdio/getc.c
src/stdio/getchar.c
src/stdio/gets.c
src/stdio/getline.c
src/stdio/getdelim.c
src/stdio/perror.c
src/stdio/printf.c
src/stdio/printf/format_fixed.c
src/stdio/printf/format_fp.c
src/stdio/printf/format_usual.c
src/stdio/printf/print.c
src/stdio/printf/util.c
src/stdio/putc.c
src/stdio/putchar.c
src/stdio/puts.c
src/stdio/remove.c
src/stdio/rewind.c
src/stdio/scanf/scan.c
src/stdio/setbuf.c
src/stdio/setvbuf.c
src/stdio/snprintf.c
src/stdio/sprintf.c
src/stdio/streams.c
src/stdio/ungetc.c
src/stdio/vasprintf.c
src/stdio/vdprintf.c
src/stdio/vfprintf.c
src/stdio/vprintf.c
src/stdio/vsnprintf.c
src/stdio/vsprintf.c
# stdlib
src/libc/stdlib/abs.c
src/libc/stdlib/atof.c
src/libc/stdlib/atoi.c
src/libc/stdlib/atol.c
src/libc/stdlib/atoll.c
src/libc/stdlib/calloc.c
src/libc/stdlib/div.c
src/libc/stdlib/labs.c
src/libc/stdlib/ldiv.c
src/libc/stdlib/llabs.c
src/libc/stdlib/lldiv.c
src/libc/stdlib/reallocarray.c
src/libc/stdlib/strto_fp.c
src/libc/stdlib/strto_int.c
src/libc/stdlib/strtod.c
src/libc/stdlib/strtof.c
src/libc/stdlib/strtol.c
src/libc/stdlib/strtold.c
src/libc/stdlib/strtoll.c
src/libc/stdlib/strtoul.c
src/libc/stdlib/strtoull.c
src/stdlib/abort.c
src/stdlib/abs.c
src/stdlib/atexit.c
src/stdlib/atof.c
src/stdlib/atoi.c
src/stdlib/atol.c
src/stdlib/atoll.c
src/stdlib/calloc.c
src/stdlib/div.c
src/stdlib/exit.c
src/stdlib/labs.c
src/stdlib/ldiv.c
src/stdlib/llabs.c
src/stdlib/lldiv.c
src/stdlib/qsort.c
src/stdlib/reallocarray.c
src/stdlib/strto_fp.c
src/stdlib/strto_int.c
src/stdlib/strtod.c
src/stdlib/strtof.c
src/stdlib/strtol.c
src/stdlib/strtold.c
src/stdlib/strtoll.c
src/stdlib/strtoul.c
src/stdlib/strtoull.c
# string
src/libc/string/memchr.c
src/libc/string/memcmp.c
src/libc/string/memcpy.c
src/libc/string/memmove.c
src/libc/string/memset.c
src/libc/string/strcasecmp.c
src/libc/string/strcasestr.c
src/libc/string/strcat.c
src/libc/string/strchr.c
src/libc/string/strchrnul.c
src/libc/string/strcmp.c
src/libc/string/strcoll.c
src/libc/string/strcpy.c
src/libc/string/strcspn.c
src/libc/string/strdup.c
src/libc/string/strerror.c
src/libc/string/strlen.c
src/libc/string/strncasecmp.c
src/libc/string/strncat.c
src/libc/string/strncmp.c
src/libc/string/strncpy.c
src/libc/string/strndup.c
src/libc/string/strnlen.c
src/libc/string/strpbrk.c
src/libc/string/strrchr.c
src/libc/string/strspn.c
src/libc/string/strstr.c
src/libc/string/strstr_base.c
src/libc/string/strtok.c
src/libc/string/strxfrm.c)
src/string/memchr.c
src/string/memcmp.c
src/string/memcpy.c
src/string/memmove.c
src/string/memrchr.c
src/string/memset.c
src/string/strcasecmp.c
src/string/strcasestr.c
src/string/strcat.c
src/string/strchr.c
src/string/strchrnul.c
src/string/strcmp.c
src/string/strcoll.c
src/string/strcpy.c
src/string/strcspn.c
src/string/strdup.c
src/string/strerror.c
src/string/strlen.c
src/string/strncasecmp.c
src/string/strncat.c
src/string/strncmp.c
src/string/strncpy.c
src/string/strndup.c
src/string/strnlen.c
src/string/strpbrk.c
src/string/strrchr.c
src/string/strspn.c
src/string/strstr.c
src/string/strstr_base.c
src/string/strtok.c
src/string/strxfrm.c
# time
src/time/asctime.c
src/time/ctime.c
src/time/difftime.c
src/time/gmtime.c
src/time/localtime.c
src/time/mktime.c
src/time/strftime.c)
if(vhex-generic IN_LIST TARGET_FOLDERS)
# TODO
endif()
# Silence extended warnings on Grisu2b code
set_source_files_properties(3rdparty/grisu2b_59_56/grisu2b_59_56.c PROPERTIES
COMPILE_OPTIONS "-Wno-all;-Wno-extra")
if(vhex-sh IN_LIST TARGET_FOLDERS)
list(APPEND SOURCES
src/libc/signal/target/vhex-sh/kill.S
src/libc/signal/target/vhex-sh/signal.S
src/libc/stdlib/target/vhex-sh/free.S
src/libc/stdlib/target/vhex-sh/malloc.S
src/libc/stdlib/target/vhex-sh/realloc.S
src/posix/fcntl/target/vhex-sh/open.S
src/posix/sys/wait/target/vhex-sh/wait.S
src/posix/sys/wait/target/vhex-sh/waitpid.S
src/posix/unistd/target/vhex-sh/read.S
src/posix/unistd/target/vhex-sh/getppid.S
src/posix/unistd/target/vhex-sh/close.S
src/posix/unistd/target/vhex-sh/fork_execve.S
src/posix/unistd/target/vhex-sh/lseek.S
src/posix/unistd/target/vhex-sh/getpid.S
src/posix/unistd/target/vhex-sh/getpgid.S
src/posix/unistd/target/vhex-sh/setpgid.S
src/posix/unistd/target/vhex-sh/write.S)
src/stdlib/target/vhex-sh/free.c
src/stdlib/target/vhex-sh/malloc.c
src/stdlib/target/vhex-sh/realloc.c
)
endif()
if(sh-generic IN_LIST TARGET_FOLDERS)
list(APPEND SOURCES
src/libc/setjmp/target/sh-generic/setjmp.S
src/libc/setjmp/target/sh-generic/longjmp.S
src/libc/string/target/sh-generic/memchr.S
src/libc/string/target/sh-generic/memcmp.S
src/libc/string/target/sh-generic/memcpy.S
src/libc/string/target/sh-generic/memmove.S
src/libc/string/target/sh-generic/memset.S
src/libc/string/target/sh-generic/strlen.S
src/setjmp/target/sh-generic/setjmp.S
src/setjmp/target/sh-generic/longjmp.S
src/string/target/sh-generic/memchr.S
src/string/target/sh-generic/memcmp.S
src/string/target/sh-generic/memcpy.S
src/string/target/sh-generic/memmove.S
src/string/target/sh-generic/memset.S
src/string/target/sh-generic/strlen.S
src/target/sh-generic/cpucap.c)
endif()
if(casiowin-fx IN_LIST TARGET_FOLDERS)
if(gint IN_LIST TARGET_FOLDERS)
list(APPEND SOURCES
src/posix/unistd/target/casiowin-fx/close.S)
# stdlib
src/stdlib/target/gint/free.c
src/stdlib/target/gint/malloc.c
src/stdlib/target/gint/realloc.c
# time
src/time/target/gint/clock.c
src/time/target/gint/time.c)
endif()
# TODO: All targets
add_library(fxlibc ${SOURCES})
target_include_directories(fxlibc PRIVATE include/)
if(sh-generic IN_LIST TARGET_FOLDERS)
target_include_directories(fxlibc PRIVATE "${FXSDK_COMPILER_INSTALL}/include/openlibm")
#---
# Handle "target-specific" fxlibc output format
#---
if(FXLIBC_TARGET STREQUAL vhex-sh)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
add_library(fxlibcStatic STATIC ${SOURCES})
add_library(fxlibcShared SHARED ${SOURCES})
set(FXLIBC_TARGET_LIBS "fxlibcStatic;fxlibcShared")
else()
add_library(fxlibcStatic STATIC ${SOURCES})
set(FXLIBC_TARGET_LIBS "fxlibcStatic")
endif()
foreach(FOLDER IN LISTS TARGET_FOLDERS)
target_include_directories(fxlibc PRIVATE include/target/${FOLDER}/)
foreach(FXLIBC_LIB IN LISTS FXLIBC_TARGET_LIBS)
target_include_directories(${FXLIBC_LIB} PRIVATE include/)
foreach(FOLDER IN LISTS TARGET_FOLDERS)
target_include_directories(${FXLIBC_LIB} PRIVATE include/target/${FOLDER}/)
endforeach()
set_target_properties(${FXLIBC_LIB} PROPERTIES OUTPUT_NAME "c")
install(TARGETS ${FXLIBC_LIB} DESTINATION ${LIBDIR})
endforeach()
set_target_properties(fxlibc PROPERTIES
OUTPUT_NAME "c") # libc.a
# Install
install(TARGETS fxlibc DESTINATION ${LIBDIR})
#---
# Do not forget to install headers
#---
install(DIRECTORY include/ DESTINATION ${INCDIR} PATTERN "target" EXCLUDE)
foreach(FOLDER IN LISTS TARGET_FOLDERS)

View File

@ -1,4 +1,4 @@
# The FX C Library
# fxlibc: The FX C Library
This directory contains the sources of the FxLibc Library. See `CMakeLists.txt`
to see what release version you have.
@ -13,65 +13,65 @@ system.
---
## Dependencies
FxLibc requires a GCC compiler toolchain the PATH to build for any calculator.
You cannot build with your system compiler! The tutorial on Planète Casio
builds an `sh-elf` toolchain that supports all models using multilib.
builds an `sh-elf` toolchain that supports all models using multilib. See also
[Lephenixnoir/sh-elf-gcc](/Lephenixnoir/sh-elf-gcc).
For Vhex and gint targets, the headers of the kernel are also required.
For Vhex targets, the headers of the kernel are also required (but not for gint; the fxlibc is installed before gint).
---
## Building and installing FxLibc
FxLibc supports several targets:
* Vhex on SH targets (`vhex-sh`)
* CASIOWIN for fx-9860G-like calculators (`casiowin-fx`)
* CASIOWIN for fx-CG-series calculators (`casiowin-cg`)
* gint for all targets (`gint`)
* gint for all calculators (`gint`)
Each target supports different features depending on what the kernel/OS
provides.
#### Configuration and support
For automated gint/fxSDK setups using [GiteaPC](/Lephenixnoir/GiteaPC) is recommended. The instructions below are for manual installs.
#### Configuration
Configure with CMake; specify the target with `-DFXLIBC_TARGET`. For SH
platforms, set the toolchain to `cmake/toolchain-sh.cmake`.
The FxLibc supports shared libraries when building with Vhex (TODO); set
`-DSHARED=1` to enable this behavior.
You can either install FxLibc in the compiler's `include` folder (for Vhex), or another folder of your choice (eg. the fxSDK sysroot). If you choose non-standard folders you might need `-I` and `-L` options to use the library.
You can either install FxLibc in the compiler's `include` folder, or installl
in another location of your choice. In the second case, you will need a `-I`
option when using the library.
To use the compiler, set `PREFIX` like this:
```
% PREFIX=$(sh-elf-gcc -print-file-name=.)
```
To use another location, set `PREFIX` manually (recommended):
```
```bash
# Install in the compiler's include folder
% PREFIX="$(sh-elf-gcc -print-file-name=.)"
# Install in the fxSDK sysroot
% PREFIX="$(fxsdk path sysroot)"
# Custom target
% PREFIX="$HOME/.sh-prefix/"
# For gint, do not specify anything, the fxSDK will be used dynamically
```
Example for a static Vhex build:
```
```bash
% cmake -B build-vhex-sh -DFXLIBC_TARGET=vhex-sh -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sh.cmake -DCMAKE_INSTALL_PREFIX="$PREFIX"
```
#### Building
Or for a traditional gint/fxSDK build:
```bash
% cmake -B build-gint -DFXLIBC_TARGET=gint -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sh.cmake
```
#### Build and install
Build in the directory specified in `cmake -B`.
```
% make -C build
```
To install, run the `install` target.
```
% make -C build install
```bash
% make -C build-X
% make -C build-X install
```
---
@ -108,6 +108,17 @@ This work is licensed under a CC0 1.0 Universal License. To view a copy of this
license, visit: https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt
Or see the LICENSE file.
FxLibc also includes third-party code that is distributed under its own
license. Currently, this includes:
* A stripped-down version of the [TinyMT random number generator](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html)
([GitHub repository](https://github.com/MersenneTwister-Lab/TinyMT)) by
Mutsuo Saito and Makoto Matsumoto. See `3rdparty/tinymt32/LICENSE.txt`.
* A stripped-down version of the [Grisu2b floating-point representation
algorithm](https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf)
with α=-59 and γ=-56, by Florian Loitsch. See `3rdparty/grisu2b_59_56/README`
for details, and [the original code here](https://drive.google.com/open?id=0BwvYOx00EwKmejFIMjRORTFLcTA).
---
### Special thanks to

249
STATUS
View File

@ -31,50 +31,49 @@ TODO: Function/symbol/macro is not implemented/defined
BDEPS(...): Function/symbol/macro needs ... to build
LDEPS(...): Function/symbol/macro needs ... to link
TEST: Function/symbol/macro needs to be tested
DONE: Function/symbol/macro is defined, builds, links, and is tested
-: Function/symbol/macro is defined, builds, links, and is tested
7.2 <assert.h>
! 7.2.1 assert: LDEPS(fprintf,stderr,abort)
7.2.1 assert LDEPS(fprintf,stderr)
7.3 <complex.h> => OpenLibm
7.4 <ctype.h>
7.4.1 is*: DONE
7.4.2 to*: DONE
7.4.1 is* -
7.4.2 to* -
7.5 <errno.h>
7.5.2 EDOM EILSEQ ERANGE: DONE
7.5.2 EDOM, EILSEQ, ERANGE -
7.6 <fenv.h> => OpenLibm
7.7 <float.h> => GCC
7.8 <inttypes.h>
! 7.8.1 PRI* macros: LDEPS(*printf)
! 7.8.1 SCN* macros: LDEPS(*scanf)
7.8.2.1 imaxabs: DONE
7.8.2.2 imaxdiv: DONE
7.8.2.3 strtoimax strtoumax: DONE
! 7.8.2.4 wcstoimax wcstoumax: TODO
7.8.1 PRI* macros -
7.8.1 SCN* macros -
7.8.2.1 imaxabs -
7.8.2.2 imaxdiv -
7.8.2.3 strtoimax, strtoumax -
7.8.2.4 wcstoimax, wcstoumax TODO
7.9 <iso646.h> => GCC
7.10 <limits.h> => GCC
7.11 <locale.h>
! 7.11.1 setlocale: TEST
! 7.11.2 localeconv: TEST
7.11.1 setlocale TEST
7.11.2 localeconv TEST
7.12 <math.h> => OpenLibm
7.13 <setjmp.h>
! 7.13.1 setjmp: TEST
! 7.13.2 longjmp: TEST
7.13.1 setjmp -
7.13.2 longjmp -
7.14 <signal.h>
! 7.14.1 Macros and stuff: TODO
! 7.14.1.1 signal: TODO
! 7.14.1.2 raise: TODO
7.14.1.1 signal -
7.14.1.2 raise -
7.15 <stdarg.h> => GCC
@ -85,80 +84,149 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested
7.18 <stdint.h> => GCC
7.19 <stdio.h>
! 7.19.1 Introduction: TODO
! 7.19.4 Operations on files: TODO
! 7.19.5 File access functions: TODO
! 7.19.6 Formatted input/output functions: TODO
! 7.19.7 Character input/output functions: TODO
! 7.19.8 Direct input/output functions: TODO
! 7.19.9 File positioning functions: TODO
! 7.19.10 Error-handling functions: TODO
7.19.1 Introduction - (no wide-oriented streams *)
7.19.1 stdin, stdout, stderr -
7.19.4.1 remove TEST
7.19.4.2 rename TODO
7.19.4.3 tmpfile TODO
7.19.4.4 tmpnam TODO
7.19.5.1 fclose -
7.19.5.2 fflush - (fflush(NULL) not supported yet)
7.19.5.3 fopen -
(EXT) fdopen -
7.19.5.4 freopen -
7.19.5.5 setbuf -
7.19.5.6 setvbuf -
(EXT) fileno -
7.19.6.1 fprintf -
7.19.6.2 fscanf TODO
7.19.6.3 printf -
7.19.6.4 scanf TODO
7.19.6.5 snprintf -
7.19.6.6 sprintf -
7.19.6.7 sscanf TODO
7.19.6.8 vfprintf -
7.19.6.9 vfscanf TODO
7.19.6.10 vprintf -
7.19.6.11 vscanf TODO
7.19.6.12 vsnprintf -
7.19.6.13 vsprintf -
7.19.6.14 vsscanf TODO
(EXT) asprintf -
(EXT) vasprintf -
(EXT) dprintf -
(EXT) vdprintf -
7.19.7.1 fgetc -
7.19.7.2 fgets -
7.19.7.3 fputc -
7.19.7.4 fputs -
7.19.7.5 getc -
7.19.7.6 getchar -
7.19.7.7 gets -
7.19.7.8 putc -
7.19.7.9 putchar -
7.19.7.10 puts -
7.19.7.11 ungetc -
(EXT) getline -
(EXT) getdelim -
7.19.8.1 fread -
7.19.8.2 fwrite -
7.19.9.1 fgetpos -
7.19.9.2 fseek -
7.19.9.3 fsetpos -
7.19.9.4 ftell -
7.19.9.5 rewind -
7.19.10.1 clearerr -
7.19.10.2 feof -
7.19.10.3 ferror -
7.19.10.4 perror -
7.20 <stdlib.h>
7.20.1.1 atof: DONE
7.20.1.2 atoi, atol, atoll: DONE
7.20.1.3 strtod, strtof, strtold: DONE
7.20.1.4 strtol, strtoul, strtoll, strtoull: DONE
! 7.20.2 Pseudo-random sequence generation functions: TODO
! 7.20.3 Memory management functions: TODO (check existing code first)
! 7.20.4 Communication with the environment: TODO
! 7.20.5 Searching and sorting utilities: TODO
7.20.6.1 abs, labs, llabs: DONE
7.20.6.2 div, ldiv, lldiv: DONE
! 7.20.7 Multibyte/wide character conversion functions: TODO
! 7.20.8 Multibyte/wide string conversion functions: TODO
7.20 MB_CUR_MAX TODO
7.20.1.1 atof -
7.20.1.2 atoi, atol, atoll -
7.20.1.3 strtod, strtof, strtold -
7.20.1.4 strtol, strtoul -
7.20.1.4 strtoll, strtoull -
7.20.2.1 rand -
7.20.2.2 srand -
7.20.3.1 calloc -
7.20.3.2 free - (gint)
7.20.3.3 malloc - (gint)
7.20.3.4 realloc - (gint)
7.20.4.1 abort - (stream flushing/closing/etc?)
7.20.4.2 atexit TEST
7.20.4.3 exit - (stream flushing/closing/etc?)
7.20.4.4 _Exit - (gint)
7.20.4.5 getenv TODO
7.20.4.6 system TODO
7.20.5.1 bsearch TODO
7.20.5.2 qsort TEST
7.20.6.1 abs, labs, llabs -
7.20.6.2 div, ldiv, lldiv -
7.20.7 Multibyte/wide char conv TODO
7.20.8 Multibyte/wide string conv TODO
(EXT) __cxa_atexit TEST
(EXT) __cxa_finalize TEST
7.21 <string.h>
7.21.2.1 memcpy: DONE
7.21.2.2 memmove: DONE (Unoptimized: byte-by-byte)
7.21.2.3 strcpy: DONE
7.21.2.4 strncpy: DONE
7.21.3.1 strcat: DONE
7.21.3.2 strncat: DONE
7.21.4.1 memcmp: DONE
7.21.4.2 strcmp: DONE
7.21.4.3 strcoll: DONE
7.21.4.4 strncmp: DONE
7.21.4.5 strxfrm: DONE
7.21.5.1 memchr: DONE
7.21.5.2 strchr: DONE
7.21.5.3 strcspn: DONE
7.21.5.4 strpbrk: DONE
7.21.5.5 strrchr: DONE
7.21.5.6 strspn: DONE
7.21.5.7 strstr: DONE
7.21.5.8 strtok: DONE
7.21.6.1 memset: DONE
7.21.6.2 strerror: DONE
7.21.6.3 strlen: DONE
Extensions:
- strnlen: DONE
- strchrnul: DONE
- strcasestr: DONE
- strcasecmp: DONE
- strncasecmp: DONE
- strdup: DONE
- strndup: DONE
7.21.2.1 memcpy -
7.21.2.2 memmove - (Unoptimized: byte-by-byte)
7.21.2.3 strcpy -
7.21.2.4 strncpy -
7.21.3.1 strcat -
7.21.3.2 strncat -
7.21.4.1 memcmp -
7.21.4.2 strcmp -
7.21.4.3 strcoll -
7.21.4.4 strncmp -
7.21.4.5 strxfrm -
7.21.5.1 memchr -
7.21.5.2 strchr -
7.21.5.3 strcspn -
7.21.5.4 strpbrk -
7.21.5.5 strrchr -
7.21.5.6 strspn -
7.21.5.7 strstr -
7.21.5.8 strtok -
7.21.6.1 memset -
7.21.6.2 strerror -
7.21.6.3 strlen -
(EXT) strnlen -
(EXT) strchrnul -
(EXT) strcasestr -
(EXT) strcasecmp -
(EXT) strncasecmp -
(EXT) strdup -
(EXT) strndup -
(EXT) memrchr - (Unoptimized: byte-by-byte)
7.22 <tgmath.h> => GCC
7.23 <time.h>
! 7.23.1 Components of time: TODO
! 7.23.2.1 clock: TODO
! 7.23.2.2 difftime: TODO
! 7.23.2.3 mktime: TODO
! 7.23.2.4 time: TODO
! 7.23.3.1 asctime: TODO
! 7.23.3.2 ctime: TODO
! 7.23.3.3 gmtime: TODO
! 7.23.3.4 localtime: TODO
! 7.23.3.5 strftime: TODO
7.23.2.1 clock -
7.23.2.2 difftime -
7.23.2.3 mktime - (DST flag ignored)
7.23.2.4 time -
7.23.3.1 asctime -
7.23.3.2 ctime -
7.23.3.3 gmtime -
7.23.3.4 localtime - (No timezones; same as gmtime)
7.23.3.5 strftime - (No %g, %G, %U, %V, %W, %z, %Z)
7.24 <wchar.h>
TODO (not a priority)
7.24 <wchar.h> TODO (not a priority)
7.25 <wctype.h>
TODO (not a priority)
7.25 <wctype.h> TODO (not a priority)
(EXT) <alloca.h>
(EXT) alloca -
# Supporting locales
@ -170,3 +238,20 @@ What if we wanted to support more locales?
-> Fix the "TODO: locale: ..." messages wherever assumptions on the locale are
made in the code
-> Properly implement strcoll() and strxfrm()
-> Add support in strftime()
# Supporting text and binary files (newline translation)
Because of 7.19.2§1.223 we don't need to support newline translation.
# Support wide-oriented streams
This requires all the wide-char functions but also updating fpos_t to be a
structure with at least some mbstate_t member (7.19.2§6).
I really don't want to do that. Use multi-byte functions with UTF-8.
# Supporting timezones
-> Update localtime()
-> Add some timezone API

View File

@ -0,0 +1,24 @@
# Vhex toolchain file for chad Casio graphing calculators
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR sh)
set(CMAKE_C_COMPILER sh-elf-vhex-gcc)
set(CMAKE_CXX_COMPILER sh-elf-vhex-g++)
set(CMAKE_C_FLAGS_INIT "")
set(CMAKE_CXX_FLAGS_INIT "")
add_compile_options(-nostdlib)
add_link_options(-nostdlib)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
if(NOT DEFINED ENV{VXSDK_COMPILER_SYSROOT})
message(FATAL_ERROR "You should use the vxSDK to build this project")
endif()
set(VXSDK_COMPILER_INSTALL $ENV{VXSDK_COMPILER_SYSROOT})

View File

@ -1,4 +1,4 @@
# giteapc: version=1 depends=Lephenixnoir/sh-elf-gcc,Lephenixnoir/OpenLibm
# giteapc: version=1 depends=Heath123/sh-elf-gcc,Heath123/OpenLibm
-include giteapc-config.make

21
include/alloca.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __ALLOCA_H__
# define __ALLOCA_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#undef alloca
/* Allocate a block of memory on the stack. */
extern void *alloca(size_t __size);
#define alloca(size) __builtin_alloca(size)
#ifdef __cplusplus
}
#endif
#endif /*__ALLOCA_H__*/

View File

@ -9,6 +9,10 @@
#define __ASSERT_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Internal function that prints error message and aborts */
void __assert_fail(char const *__file, int __line, char const *__function,
char const *__expression);
@ -18,10 +22,14 @@ void __assert_fail(char const *__file, int __line, char const *__function,
#else
# define assert(expression) \
((expression) \
? (void)0 : \
? (void)0 \
: __assert_fail(__FILE__, __LINE__, __PRETTY_FUNCTION__, #expression))
#endif
#ifndef __cplusplus
# define static_assert _Static_assert
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,10 @@
#ifndef __CTYPE_H__
# define __CTYPE_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
** Character classification functions. These are all implemented as sets of
** comparisons. There is an approach with a 128-byte table, but it takes more
@ -103,4 +107,8 @@ extern int toupper(int c);
islower(__c0) ? (__c0 & 0xdf) : __c0; \
})
#ifdef __cplusplus
}
#endif
#endif /*__CTYPE_H__*/

65
include/dirent.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef __DIRENT_H__
# define __DIRENT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <bits/types/DIR.h>
#include <sys/types.h>
#define DT_UNKNOWN 0 /* Unknown type */
#define DT_BLK 1 /* Block device */
#define DT_CHR 2 /* Character device */
#define DT_DIR 3 /* Directory */
#define DT_FIFO 4 /* FIFO */
#define DT_LNK 5 /* Symbolic link */
#define DT_REG 6 /* Regular file */
#define DT_SOCK 7 /* Socket */
/* In gint d_ino is unused; but it's required by POSIX.1. */
struct dirent {
/* Inode number */
ino_t d_ino;
/* Type, to avoid doing an additional stat() on the file */
unsigned char d_type;
/* NUL-terminated file name */
char d_name[];
};
/* The underlying syscall to access directory entries is getdents(2). But it
has no unified interface and no glibc wrapper on Linux; it's basically
hidden. So we define the API directly at the level of readdir(3). gint does
not implement any lower-level interface and directly associates a DIR * with
a directory file descriptor. */
/* Open a directory to inspect its contents. */
extern DIR *opendir(const char *__name);
/* Get the directory file descriptory associated with __dp. */
extern int dirfd(DIR *__dp);
/* Open a directory file descriptor to use as a directory stream. */
extern DIR *fdopendir(int __fd);
/* Read an entry from an open directory. */
extern struct dirent *readdir(DIR *__dp);
/* Get the current position within the directory. The particular value should
not be interpreted; it is just suitable to use in seekdir(). */
extern long telldir(DIR *__dp);
/* Seek into the directory; __pos should have been returned by telldir(). */
extern void seekdir(DIR *__dp, long __pos);
/* Rewind a directory to its start. */
extern void rewinddir(DIR *__dp);
/* Close an open directory. */
extern int closedir(DIR *__dp);
#ifdef __cplusplus
}
#endif
#endif /*__DIRENT_H__*/

View File

@ -1,12 +1,100 @@
#ifndef __ERRNO_H__
# define __ERRNO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Initialized to 0 at startup. Currently not TLS, maybe in the future if
threads are supported. */
extern int errno;
#define EDOM 1
#define EILSEQ 2
#define ERANGE 3
#define EDOM 1 /* Outside of domain of math function. */
#define EILSEQ 2 /* Illegal multi-byte character sequence. */
#define ERANGE 3 /* Range error during text-to-numeric conversion. */
#define EACCES 4 /* File access denied. */
#define EEXIST 5 /* File already exists. */
#define EINVAL 6 /* Invalid argument in general; lots of uses. */
#define ENFILE 7 /* Out of file descriptors. */
#define ENOENT 8 /* File or folder does not exist. */
#define ENOMEM 9 /* System ran out of memory (RAM). */
#define EDQUOT 10 /* Out of inodes or memory space. */
#define ENOSPC 11 /* No space left on device. */
#define ENOTSUP 12 /* Operation not supported. */
#define EBADF 13 /* Invalid file descriptor. */
#define ESPIPE 14 /* File descriptor is unable to seek. */
#define EISDIR 15 /* File descriptor is a directory. */
#define ENOTDIR 16 /* File descriptor is not a directory. */
#define ENOTEMPTY 17 /* Directory is not empty. */
#define EINTR 18 /* Interrupted system call. */
#define EAGAIN 19 /* Resource temporarily unavailable. */
#define EIO 20 /* Input/Output error */
#define ENODEV 21 /* No such device */
#define ENOMEDIUM 22 /* No medium found */
#define EMEDIUMTYPE 23 /* Wrong medium type */
/* Error codes used by libstdc++. */
#define EAFNOSUPPORT 24
#define EADDRINUSE 25
#define EADDRNOTAVAIL 26
#define EISCONN 27
#define E2BIG 28
#define EFAULT 29
#define EPIPE 30
#define ECONNABORTED 31
#define EALREADY 32
#define ECONNREFUSED 33
#define ECONNRESET 34
#define EXDEV 35
#define EDESTADDRREQ 36
#define EBUSY 37
#define ENOEXEC 38
#define EFBIG 39
#define ENAMETOOLONG 40
#define ENOSYS 41
#define EHOSTUNREACH 42
#define ENOTTY 43
#define EMSGSIZE 44
#define ENETDOWN 45
#define ENETRESET 46
#define ENETUNREACH 47
#define ENOBUFS 48
#define ECHILD 49
#define ENOLCK 50
#define ENOMSG 51
#define ENOPROTOOPT 52
#define ENXIO 53
#define ESRCH 54
#define ENOTSOCK 55
#define ENOTCONN 56
#define EINPROGRESS 57
#define EPERM 58
#define EOPNOTSUPP 59
#define EWOULDBLOCK 60
#define EPROTONOSUPPORT 61
#define EROFS 62
#define EDEADLK 63
#define ETIMEDOUT 64
#define EMFILE 65
#define EMLINK 66
#define ELOOP 67
#define EPROTOTYPE 68
#define EBADMSG 69
#define EIDRM 70
#define ENOLINK 71
#define ENODATA 72
#define ENOSR 73
#define ECANCELED 74
#define EOWNERDEAD 75
#define EPROTO 76
#define ENOTRECOVERABLE 77
#define ETIME 78
#define ETXTBUSY 79
#define EOVERFLOW 80
#ifdef __cplusplus
}
#endif
#endif /*__ERRNO_H__*/

View File

@ -1,20 +1,36 @@
#ifndef __FCNTL_H__
# define __FCNTL_H__
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
/* also defined in <stdio.h> */
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
/* Access mode. */
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
/* Create file if nonexistent. */
#define O_CREAT 0x0004
/* Fail if not a directory. */
#define O_DIRECTORY 0x0008
/* Append and truncate modes. */
#define O_APPEND 0x0010
#define O_TRUNC 0x0020
/* Exclusive open requiring creation. */
#define O_EXCL 0x0040
/*
** Open FILE and return a new file descriptor for it, or -1 on error.
** OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set
** in OFLAG, the third argument is taken as a `mode_t', the mode of the
** created file.
*/
extern int open(const char *pathname, int flags, ...);
/* Create, truncate and open a file. */
extern int creat(char const *__path, mode_t __mode);
/* Open file and return a file descriptor, -1 on error. */
extern int open(char const *__path, int __flags, ... /* mode_t __mode */);
#ifdef __cplusplus
}
#endif
#endif /*__FCNTL_H__*/

269
include/fxlibc/printf.h Normal file
View File

@ -0,0 +1,269 @@
#ifndef __FXLIBC_PRINTF_H__
# define __FXLIBC_PRINTF_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
** This headers covers fxlibc-specific extensions to the *printf API. fxlibc
** provides an interface to define new converters, and a number of helpers to
** parse options, lay out strings, and generate output.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
/* Predefined formatters. */
/*
** Enable floating-point formatters %e, %E, %f, %F, %g, and %G. The formats are
** disabled by default because the representation algorithm has tables of
** powers of 10 and quite a bit of code, resulting in 10-15 kiB of additional
** size in every binary.
**
** Calling this functions pulls object files with floating-point representation
** code from the fxlibc library and registers formatters for all 6
** floating-point formats.
*/
extern void __printf_enable_fp(void);
/*
** Enable the fixed-point formatter %D. This format is a nonstandard extension
** for decimal fixed-point. It works like %d, except that the precision field
** represents a number of decimals.
**
** For instance, "%.3D" will print value 12345 as "12.345". This is simply
** integer display with a decimal dot inserted, and useful for applications
** that want some degree of decimal freedom without full-blown floating-point.
*/
extern void __printf_enable_fixed(void);
/* Base function for all formatted printing functions. */
/*
** Output specification; only one of the targets may be non-trivial.
** -> str != NULL
** -> fp != NULL
** -> fd >= 0
** The size field can be set independently.
*/
struct __printf_output {
/* Final output, after buffering */
char * __restrict__ str;
FILE *fp;
int fd;
/* Size of the final output */
size_t size;
/* The following members are set by __printf; do not write to them. */
/* Current output buffer, output position, and buffer limit */
char *buffer, *ptr, *limit;
/* Number of characters written so far */
size_t count;
};
/* Generic formatted printing. */
extern int __printf(
struct __printf_output * __restrict__ __out,
char const * __restrict__ __format,
va_list *__args);
/* Format extension API. */
struct __printf_format {
/* Minimal length of formatted string (padding can be added). */
uint16_t length;
/* How much significant characters of data, meaning varies. */
int16_t precision;
/* Size of targeted integer type (%o, %x, %i, %d, %u), in bytes */
uint8_t size;
/* (#) Alternative form: base prefixes, decimal point. */
uint8_t alternative :1;
/* ( ) Add a blank sign before nonnegative numbers. */
uint8_t blank_sign :1;
/* (+) Always add a sign before a number (overrides ' '). */
uint8_t force_sign :1;
/*
** Alignment options, from lowest priority to highest priority:
** NUL By default, align right
** (0) Left-pad numerical values with zeros
** (-) Align left by adding space on the right, dropping zeros
*/
uint8_t alignment;
/* Format specifier. */
char spec;
};
/*
** Type of format functions.
** -> __out specifies the output and is used when generating text
** -> __fmt contains the format options and specifier letter
** -> __args is a pointer to the variable list of arguments to read from
*/
typedef void __printf_formatter_t(
struct __printf_output *__out,
struct __printf_format *__fmt,
va_list *__args);
/*
** Register a new format.
**
** The formatter designated by the specified lowercase or uppercase letter
** (eg 'p' or 'P') is registered. This functions allows overriding default
** formatters, but this is very much discouraged. Letters with special meaning
** in the standard cannot be changed. A formatter can be removed of disabled by
** registering NULL.
**
** Here are the characters used/reserved in the C standard:
**
** a: Hexadecimal floating-point A: Hexadecimal floating-point
** b: _ B: _
** c: Character C: Deprecated synonym for lc
** d: Decimal integer D: _
** e: Exponent floating-point E: Exponent floating-point
** f: Floating-point F: Floating-point
** g: General floating-point G: General floating-point
** h: short or char size H: _
** i: Integer I: Locale-aware digits
** j: intmax_t size J: _
** k: _ K: _
** l: long or long long size L: long double size
** m: Error message from errno M: _
** n: Number of characters written N: _
** o: Octal integer O: _
** p: Pointer P: _
** q: Nonstandard synonym for ll Q: _
** r: _ R: _
** s: String S: Deprecated synonym for ls
** t: ptrdiff_t size T: _
** u: Unsigned decimal integer U: _
** v: _ V: _
** w: _ W: _
** x: Hexadecimal integer X: Hexadecimal integer
** y: _ Y: _
** z: size_t size Z: Old synonym for z
*/
void __printf_register(int __spec, __printf_formatter_t *__format);
/* Functions for formatters to output characters. */
/* Flush the buffer. (Don't call this directly.) */
extern void __printf_flush(struct __printf_output *__out);
/* Output a single character in the buffer (and possibly flush it). */
static inline void __printf_out(struct __printf_output *__out,
int __c)
{
if(__out->ptr >= __out->limit) __printf_flush(__out);
*(__out->ptr++) = __c;
}
/* Output the same character __n times. */
static inline void __printf_outn(struct __printf_output *__out,
int __c, int __n)
{
while(__n-- > 0) __printf_out(__out, __c);
}
/* Output a string. */
static inline void __printf_outstr(struct __printf_output *__out,
char const *__str, int __n)
{
for(int i = 0; i < __n; i++) __printf_out(__out, __str[i]);
}
/* Helper functions for formatters. */
/*
** Format geometry helper. The structure of a format is as follows:
**
** sign v |< zeros >| |< content >|
** _ _ _ _ _ _ _ _ _ + 0 x 0 0 0 0 0 0 8 a c 7 . 3 c _ _ _ _ _ _ _ _ _ _
** |< left_spaces >| ^^^ prefix |< right_spaces >|
**
** The sign character is absent if sign=0, the prefix is specified by length
** and is also absent if prefix=0.
*/
struct __printf_geometry
{
uint16_t left_spaces; /* Spaces before content */
uint8_t sign; /* Sign character (NUL, ' ', '+' or '-') */
uint8_t prefix; /* Base prefix ('0', '0x', etc) length */
uint16_t zeros; /* For integer displays, number of zeros */
uint16_t content; /* Content length in bytes */
uint16_t right_spaces; /* Spaces after content */
/* Style of display:
_PRINTF_GENERIC Sign ignored, 0-padding ignored
_PRINTF_INTEGER .precision causes 0-padding
_PRINTF_NUMERIC No effect */
enum { _PRINTF_GENERIC = 0, _PRINTF_INTEGER, _PRINTF_NUMERIC } style;
};
/*
** Calculate the geometry of a format.
**
** The caller provides as input __opt (as it received in the formatter
** function), and the following attributes of __geometry:
**
** - prefix: the length of the desired prefix (if unused, 0)
** - content: the natural content length for the provided data
** - sign: the sign of the input ('+' or '-'); for _PRINTF_GENERIC, 0
** - style, which affects the meaning of options
**
** This function outputs:
** - sign: will be changed to ' ' or NUL (0) depending on options
** - All fields of __geometry that are not part of the input
**
** The algorithm for laying out the format is as follows.
** 1. For numerical and integer formats, turn a "+" sign into " " if
** __opt->blank_sign is set, "+" if __opt->force_sign is set, NUL otherwise.
** 2. Compute the total amount of padding needed to reach __opt->length.
** 3. In integer style, if a precision is specified and more than content
** length plus sign and prefix, turn some padding into zeros.
** 4. If numerical and integer styles, if __opt->alignment == '0' turn all the
** padding into zeros.
** 5. Turn remaining padding into spaces at the left (if opt->alignment == NUL)
** or right (if opt->alignment == '-').
*/
extern void __printf_compute_geometry(
struct __printf_format *__opt,
struct __printf_geometry *__geometry);
/* Load a signed integer (__size is specified in __opt->size). */
extern int64_t __printf_load_i(int size, va_list *args);
/* Load an unsigned integer. */
extern uint64_t __printf_load_u(int size, va_list *args);
/*
** Generate the digits of __n in base 10, starting from the least significant
** digit. Returns number of digits. No NUL terminator is added.
*/
extern int __printf_digits10(char *__str, uint64_t __n);
/* Same in base 16. */
extern int __printf_digits16(char *__str, int uppercase, uint64_t __n);
/* Same in base 8. */
extern int __printf_digits8(char *__str, uint64_t __n);
#ifdef __cplusplus
}
#endif
#endif /*__FXLIBC_PRINTF_H__*/

View File

@ -1,10 +1,14 @@
#ifndef __INTTYPES_H__
# define __INTTYPES_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdlib.h>
/* Hide by default in C++ (7.8.1§1.181) */
/* Hide by default in C++ (7.8.1§1.182) */
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
/* Printing signed fixed-width types, decimal */
@ -245,14 +249,18 @@ extern imaxdiv_t imaxdiv(intmax_t __num, intmax_t __denom);
/* Parse an intmax_t from string. */
extern intmax_t strtoimax(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
/* Parse an uintmax_t from string. */
extern uintmax_t strtoumax(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
#ifdef __cplusplus
}
#endif
#endif /*__INTTYPES_H__*/

View File

@ -1,6 +1,10 @@
#ifndef __LOCALE_H__
# define __LOCALE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
struct lconv {
@ -40,4 +44,8 @@ struct lconv {
extern char *setlocale(int __category, char const *__locale);
extern struct lconv *localeconv(void);
#ifdef __cplusplus
}
#endif
#endif /*__LOCALE_H__*/

View File

@ -1,29 +1,30 @@
#ifndef __SETJMP_H__
# define __SETJMP_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/* Get '__jmp_buf' */
#include <bits/setjmp.h>
/* User jmp_buf alias */
/* Make jmp_buf an array type. (7.13§2) */
typedef struct __jmp_buf jmp_buf[1];
/*
** Store the calling environment in ENV, also saving the signal mask.
** Return 0.
*/
extern int setjmp(jmp_buf env);
/* Save the calling environment in __env (not the signal mask), return 0. */
__attribute__((returns_twice))
extern int setjmp(jmp_buf __env);
/* Standard requires setjmp to be a macro (7.13§1) */
#define setjmp setjmp
/*
** Store the calling environment in ENV, not saving the signal mask.
** Return 0.
*/
extern void longjmp(jmp_buf env, int val);
/* Restore the calling environment from __env, return __val to setjmp. */
__attribute__((noreturn))
extern void longjmp(jmp_buf __env, int __val);
#ifdef __cplusplus
}
#endif
#endif /*__SETJMP_H__*/

View File

@ -1,40 +1,58 @@
#ifndef __SIGNAL_H__
# define __SIGNAL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/* C99 API. */
typedef int sig_atomic_t;
/* Type of a signal handler.*/
typedef void (*__sighandler_t)(int);
#include <bits/signum.h>
/* Set the handler for __signum. */
extern __sighandler_t signal(int __signum, __sighandler_t __handler);
/* Raise signal __signum. */
extern int raise(int __signum);
/* POSIX API (Vhex only). */
#ifdef _POSIX_C_SOURCE
/* Type of signal set */
typedef uint32_t sigset_t;
typedef uint32_t kernel_sigset_t;
/* Type of a signal handler.*/
typedef void (*__sighandler_t)(int);
typedef __sighandler_t sighandler_t;
/*
** Get the system-specific definitions of `struct sigaction' and the `SA_*'
** and `SIG_*'. constants.
*/
#include <bits/sigaction.h>
#include <sys/types.h>
/* Get and/or change the set of blocked signals. */
extern int sigprocmask (int how, const sigset_t *restrict set,
sigset_t *restrict oldset);
extern int sigprocmask (int __how, const sigset_t * __restrict__ __set,
sigset_t * __restrict__ __oldset);
/*
** Send signal SIG to process number PID. If PID is zero, send SIG to all
** processes in the current process's process group. If PID is < -1, send SIG to
** all processes in process group - PID.
*/
extern int kill(pid_t pid, int sig);
extern int kill(pid_t __pid, int __sig);
/*
** Set the handler for the signal SIG to HANDLER, returning the old handler, or
** SIG_ERR on error. By default `signal' has the BSD semantic.
*/
extern void (*signal(int signum, void (*handler)(int)))(int);
#endif /*_POSIX_C_SOURCE*/
#ifdef __cplusplus
}
#endif
#endif /*__SIGNAL_H__*/

2
include/stdint.h Normal file
View File

@ -0,0 +1,2 @@
/* We rely on GCC's default version. */
#include "stdint-gcc.h"

View File

@ -1,10 +1,139 @@
#ifndef __STDIO_H__
# define __STDIO_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdarg.h>
#include <bits/types/FILE.h>
#include <stdint.h>
#include <sys/types.h>
#define __FILE_BUF_READ 0
#define __FILE_BUF_WRITE 1
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
work is maintaining that buffer to provide the basic fgetc()/fputc()
functions, then everything else is built on top of the abstracted stream.
The buffer of a FILE can either be in reading or writing mode. When in
reading mode, the buffer contains pre-fetched data from a previous read that
hasn't yet been requested by the user. When in writing mode, the buffer
contains data written by the user which hasn't yet been sent to the kernel.
The buffer has the following structure:
0 bufpos bufread bufsize
+--------+---------+---------+
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
+--------+---------+---------+
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
+--------+-------------------+
x: Data read from file descriptor and returned to user
r: Data read from file descriptor not yet returned to user
w: Data written by user not yet sent to file descriptor
u: Undefined
In reading mode, the region [0..bufread) contains data obtained from the
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
already been returned to the user while [bufpos..bufread) has not. The offset
on the underlying file descriptor sits at bufread, so the position reported
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
In writing mode, the region [0..bufpos) contains data received through API
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
The rest of the buffer is undefined.
The ungetc() function pushes back characters into the buffer; if the FILE is
unbuffered, then it's made buffered temporarily to hold the characters and
cleared at the next fflush() or read. The buffer is put in reading mode. For
this reason, reading functions should test [fp->buf] to check whether there
is a buffer instead of [fp->bufmode != _IONBF].
Many fields in the FILE structure are abstracted away by API calls in layers:
1. [fd], [fdpos] and [error] are updated by the primitive functions of
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
setvbuf() and fclose().
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
like fgets() or fwrite(), and cleared by fflush().
4. [readable], [writable], [append] and [text] are set by fopen() and
freopen(), and used as read-only by the primitive functions of 3. */
typedef struct {
/* File descriptor */
int fd;
/* Current position in file, as tracked by the file descriptor (ie. not
accounting for buffer operations) */
size_t fdpos;
/* Pointer to buffer (NULL if _IONBF) */
char *buf;
/* Current position in buffer, water mark of read data in buffer, and
buffer size; see header comment for details */
size_t bufpos;
size_t bufread;
size_t bufsize;
/* Number of ungetc()'d characters at the start of buffer data */
int bufungetc;
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
uint8_t bufmode :2;
/* We own the buffer and it needs to be freed */
uint8_t bufowned :1;
/* __FILE_BUF_READ if the buffer is in reading mode
__FILE_BUF_WRITE if it's in writing mode
This mode can only be changed immediately after fflush(). */
uint8_t bufdir :1;
/* Opening flags */
uint8_t readable :1;
uint8_t writable :1;
uint8_t append :1;
/* Non-zero if text mode, zero if binary mode */
uint8_t text :1;
/* EOF indicator */
uint8_t eof :1;
/* Error indicator */
uint8_t error :1;
} FILE;
/* Type of positions within files. We don't have wide-oriented streams. */
typedef size_t fpos_t;
/* Buffering modes. */
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
/* Some buffer size for file buffering. */
#define BUFSIZ 512
/* End-of-file marker. */
#define EOF ((int)(-1))
/* Number of files guaranteed can be opened simultaneously. */
/* TODO: FOPEN_MAX is BFile-specific, Vhex might have much larger limits. */
#define FOPEN_MAX 4
/* Recommended length of a filename. */
/* TODO: FILENAME_MAX = 128 is quite BFile-centric, Vhex might be different. */
#define FILENAME_MAX 128
/* Length a filename for tmpnam. */
#define L_tmpnam FILENAME_MAX
/* Seeking positions. */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 3
/* Maximum number of unique filenames that tmpnam can generate. */
/* TODO: Set a useful value in TMP_MAX other than 16*16*16 */
#define TMP_MAX (16*16*16)
/* Standard input, output and error streams. */
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
@ -13,17 +142,257 @@ extern FILE *stderr;
#define stdout stdout
#define stderr stderr
/* *printf() familly - formatted output conversion. */
extern int printf(const char *restrict format, ...);
extern int dprintf(int fd, const char *restrict format, ...);
extern int sprintf(char *restrict str, const char *restrict format, ...);
extern int snprintf(char *restrict str, size_t size, const char *restrict format, ...);
extern int vdprintf(int fd, const char *restrict format, va_list ap);
extern int vsprintf(char *restrict str, const char *restrict format, va_list ap);
extern int vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap);
/*
** Operations on files.
*/
/* Remove a file from the filesystem.
In gint, the file must not be open (open files' names are not tracked). */
extern int remove(char const *__filename);
extern int rename(char const *__old, char const *__new);
extern FILE *tmpfile(void);
extern char *tmpnam(char *__s);
/*
** File access functions.
*/
/* Flush the stream and disassociate it from the underlying file. */
extern int fclose(FILE *__fp);
/* Flush any written data in the FILE's internal buffer. */
extern int fflush(FILE *__fp);
/* Open a file and associate a stream with it. */
extern FILE *fopen(
char const * __restrict__ __filename,
char const * __restrict__ __mode);
/* Open a file descriptor and associate a stream with it. */
extern FILE *fdopen(int __fd, char const *__mode);
/* Reopen a stream with another file, or change its mode. */
extern FILE *freopen(
char const * __restrict__ __filename,
char const * __restrict__ __mode,
FILE * __restrict__ __fp);
/* Use __buf as a buffer (of size BUFSIZ) for access to __fp. */
extern void setbuf(FILE * __restrict__ __fp, char * __restrict__ __buf);
/* Changer the buffering mode and buffer address for __fp. */
extern int setvbuf(FILE * __restrict__ __fp, char * __restrict__ __buf,
int __mode, size_t __size);
/* Return the file descriptor associated with __fp. */
extern int fileno(FILE *__fp);
/*
** Formatted input/output functions.
**
** These functions implement most of printf(3)'s features, including:
** - Signed and unsigned integer formats (%d, %i, %o, %u, %x, %X)
** - Character, string and pointer formats (%c, %s, %p)
** - Character count and strerror() shorthand formats (%n, %m)
** - Format options (0, #, -, (space), length, precision)
** - Parameter length (hh, h, l, ll, L, z, j, t) (L: if long double is 64-bit)
** - Limiting the size of the output and still returning the whole length
** - If __printf_enable_fp() from <fxlibc/printf.h> is called: floating-point
** formats (%e, %E, %f, %F, %g, %G) (disabled by default to save space)
**
** They do not (yet?) support:
** - Hexadecimal floating-point (%a, %A)
** - Printing long double values when long double is more than 64-bit
** - Dynamic length field (*)
** - Parameter reordering ($m)
** - Thousands separators (') and locale-aware digits (I)
** - Nonstandard/old synonyms %C (%lc), %S (%ls), q (ll), and Z (z)
**
** There are extensions, namely to allow for custom conversions to be added.
** One custom conversion can be enabled with __printf_enable_fixed() from
** <fxlibc/printf.h>: a decimal fixed-point format %D which is like %d but
** with a decimal point. See <fxlibc/printf.h> for details.
*/
/* Formatted print to file. */
extern int fprintf(FILE * __restrict__ __fp,
char const * __restrict__ __format, ...);
/* Formatted print to stdout. */
extern int printf(
char const * __restrict__ __format, ...);
/* Formatted print to string (with limited size). */
extern int snprintf(char * __restrict__ __str, size_t __size,
char const * __restrict__ __format, ...);
/* Formatted print to string (with unlimited size!). */
extern int sprintf(char * __restrict__ __str,
char const * __restrict__ __format, ...);
/* Formatted print to file (variable argument list). */
extern int vfprintf(FILE * __restrict__ __fp,
char const * __restrict__ __format, va_list __args);
/* Formatted print to stdout (variable argument list). */
extern int vprintf(
char const * __restrict__ __format, va_list __args);
/* Formatted print to string (limited size, variable argument list). */
extern int vsnprintf(char * __restrict__ __str, size_t __size,
char const * __restrict__ __format, va_list __args);
/* Formatted print to string (unlimited size!, variable argument list). */
extern int vsprintf(char * __restrict__ __str,
char const * __restrict__ __format, va_list __args);
/* putx() - display char / string */
extern int putchar(int c);
extern int puts(const char *s);
/* Extensions. */
/* Formatted print to file descriptor. */
extern int dprintf(int __fd,
char const * __restrict__ __format, ...);
/* Formatted print to file descriptor (variable argument list). */
extern int vdprintf(int __fd,
char const * __restrict__ __format, va_list __args);
/* Allocating sprintf(). */
extern int asprintf(char ** __restrict__ __str,
char const * __restrict__ __format, ...);
/* Allocating vsprintf(). */
extern int vasprintf(char ** __restrict__ __str,
char const * __restrict__ __format, va_list __args);
/* Formatted scan from file. */
extern int fscanf(FILE * __restrict__ __fp,
char const * __restrict__ __format, ...);
/* Formatted scan from stdin. */
extern int scanf(
char const * __restrict__ __format, ...);
/* Formatted scan from string. */
extern int sscanf(const char * __restrict__ __s,
char const * __restrict__ __format, ...);
/* Formatted scan from file (variable argument list). */
extern int vfscanf(FILE * __restrict__ __fp,
char const * __restrict__ __format, va_list __args);
/* Formatted scan from stdin (variable argument list). */
extern int vscanf(
char const * __restrict__ __format, va_list __args);
/* Formatted scan from string (variable argument list). */
extern int vsscanf(char const * __restrict__ __s,
char const * __restrict__ __format, va_list __args);
/*
** Character input/output functions.
*/
/* Read a character from a stream. */
extern int fgetc(FILE *__fp);
/* Read at most n characters from a stream, stopping after a newline. */
extern char *fgets(char * __restrict__ __s, int __n,
FILE * __restrict__ __fp);
/* Write a character to a stream. */
extern int fputc(int __c, FILE *__fp);
/* Write a string to a stream (excluding the NUL nyte). */
extern int fputs(char const * __restrict__ __s, FILE * __restrict__ __fp);
extern int getc(FILE *__fp);
#define getc fgetc
/* Get a character from stdin */
extern int getchar(void);
#define getchar() fgetc(stdin)
/* (DEPRECATED; use fgets() instead) Read a string from stdin. */
extern char *gets(char *__s);
/* Get a line from stream, with dynamic allocation */
extern ssize_t getline(char ** __restrict__ __lineptr,
size_t * __restrict__ __n, FILE * __restrict__ __fp);
/* Like getline but with [delim] instead of '\n' */
extern ssize_t getdelim(char ** __restrict__ __lineptr,
size_t * __restrict__ __n, int __delim, FILE * __restrict__ __fp);
extern int putc(int __c, FILE *__fp);
#define putc fputc
/* Write a character to stdout */
extern int putchar(int __c);
#define putchar(__c) fputc(__c, stdout)
/* Write a string to stdout, followed by a newline */
extern int puts(char const *__s);
/* Un-read a character back to the stream; only one ungetc() is guaranteed, and
the character is lost after reading, writing or flushing. */
extern int ungetc(int __c, FILE *__fp);
/*
** Direct input/output functions.
*/
/* Read an array of items from a stream. */
extern size_t fread(void * __restrict__ __ptr, size_t __size, size_t __nmemb,
FILE * __restrict__ __fp);
/* Write an array of items to a stream. */
extern size_t fwrite(void const * __restrict__ __ptr, size_t __size,
size_t __nmemb, FILE * __restrict__ __fp);
/*
** File positioning functions.
*/
/* Get current position (same as ftell() unless wide-oriented). */
extern int fgetpos(FILE * __restrict__ __fp, fpos_t * __restrict__ __pos);
/* Set the current position. */
extern int fseek(FILE *__fp, long __offset, int __whence);
/* Restore the position to a value returned by fgetpos(). */
extern int fsetpos(FILE *__fp, fpos_t const *__pos);
/* Get the current position. */
extern long ftell(FILE *__fp);
/* Sets the file position to the start of the stream. */
extern void rewind(FILE *__fp);
/*
** Error-handling functions.
*/
/* Clear EOF and error flags in the stream. */
extern void clearerr(FILE *__fp);
/* Test the EOF flag. */
extern int feof(FILE *__fp);
/* Test the error flag. */
extern int ferror(FILE *__fp);
/* Print a message followed by strerror(errno) to stdout. */
extern void perror(char const *__s);
#ifdef __cplusplus
}
#endif
#endif /*__STDIO_H__*/

View File

@ -1,8 +1,13 @@
#ifndef __STDLIB_H__
# define __STDLIB_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <bits/exit.h>
/* Dynamic memory management. */
@ -27,6 +32,27 @@ extern void *reallocarray(void *__ptr, size_t __nmemb, size_t __size);
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
extern void free(void *__ptr);
/* Communication with the environment. */
/* Abort execution; raises SIGABRT and leaves quickly with _Exit(). */
__attribute__((noreturn))
extern void abort(void);
/* Register a function to be called at program exit. */
extern int atexit(void (*__func)(void));
/* Exit; calls handlers, flushes and closes streams and temporary files. */
__attribute__((noreturn))
extern void exit(int __status);
/* Exit immediately, bypassing exit handlers or signal handlers. */
__attribute__((noreturn))
extern void _Exit(int __status);
extern char *getenv(char const *__name);
extern int system(char const *__string);
/* Integer arithmetic functions. */
extern int abs(int __j);
@ -59,9 +85,9 @@ typedef struct {
long long int quot, rem;
} lldiv_t;
div_t div(int __num, int __denom);
ldiv_t ldiv(long int __num, long int __denom);
lldiv_t lldiv(long long int __num, long long int __denom);
extern div_t div(int __num, int __denom);
extern ldiv_t ldiv(long int __num, long int __denom);
extern lldiv_t lldiv(long long int __num, long long int __denom);
/* Simplified numeric conversion functions. */
@ -81,41 +107,65 @@ extern double atof(char const *__ptr);
/* Parse a long int from a string. */
extern long int strtol(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
/* Parse a long unsigned int from a string. */
extern unsigned long int strtoul(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
/* Parse a long long int from a string. */
extern long long int strtoll(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
/* Parse a long long unsigned int from a string. */
extern unsigned long long int strtoull(
char const * restrict __ptr,
char ** restrict __endptr,
char const * __restrict__ __ptr,
char ** __restrict__ __endptr,
int __base);
/* Parse a double from a string. */
extern double strtod(
char const * restrict __ptr,
char ** restrict __endptr);
char const * __restrict__ __ptr,
char ** __restrict__ __endptr);
/* Parse a float from a string. */
extern float strtof(
char const * restrict __ptr,
char ** restrict __endptr);
char const * __restrict__ __ptr,
char ** __restrict__ __endptr);
/* Parse a long double from a string. */
extern long double strtold(
char const * restrict __ptr,
char ** restrict __endptr);
char const * __restrict__ __ptr,
char ** __restrict__ __endptr);
/* Pseudo-random sequence generation functions. */
#define RAND_MAX 0x7fffffff
/* Seed the PRNG. */
extern void srand(unsigned int __seed);
/* Generate a pseudo-random number between 0 and RAND_MAX. */
extern int rand(void);
/* Searching and sorting utilities. */
extern void *bsearch(void const *__key,
void const *__base, size_t __nmemb, size_t __size,
int (*__compare)(void const *, void const *));
extern void qsort(
void *__base, size_t __nmemb, size_t __size,
int (*__compare)(void const *, void const *));
#ifdef __cplusplus
}
#endif
#endif /*__STDLIB_H__*/

View File

@ -1,6 +1,10 @@
#ifndef __STRING_H__
# define __STRING_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
/* Copying functions. */
@ -12,20 +16,20 @@ extern void *memcpy(void *__dest, void const *__src, size_t __n);
extern void *memmove(void *__dest, void const *__src, size_t __n);
/* Copy string __src into __dest. */
extern char *strcpy(char * restrict __dest, char const * restrict __src);
extern char *strcpy(char *__restrict__ __dest, char const *__restrict__ __src);
/* Copy at most __n characters of __src into __dest. */
extern char *strncpy(char * restrict __dest, char const * restrict __src,
size_t __n);
extern char *strncpy(char * __restrict__ __dest,
char const * __restrict__ __src, size_t __n);
/* Concatenation functions. */
/* Copy __src at the end of __dest. */
extern char *strcat(char * restrict __dest, char const * restrict __src);
extern char *strcat(char *__restrict__ __dest, char const *__restrict__ __src);
/* Copy at most __n characters of __src into __dest. */
extern char *strncat(char * restrict __dest, char const * restrict __src,
size_t __n);
extern char *strncat(char * __restrict__ __dest,
char const * __restrict__ __src, size_t __n);
/* Comparison functions. */
@ -42,14 +46,17 @@ extern int strcoll(char const *__s1, char const *__s2);
extern int strncmp(char const *__s1, char const *__s2, size_t __n);
/* Transform __src into __dest in a way that morphs strcoll into strcmp. */
extern size_t strxfrm(char * restrict __dest, char const * restrict __src,
size_t __n);
extern size_t strxfrm(char * __restrict__ __dest,
char const * __restrict__ __src, size_t __n);
/* Search functions. */
/* Search __c within the first __n characters of __s. */
extern void *memchr(void const *__s, int __c, size_t __n);
/* Search the last occurrence of __c withing the first __n bytes of __s. */
extern void *memrchr(void const *__s, int __c, size_t __n);
/* Find the first occurrence of __c within __s. */
extern char *strchr(char const *__s, int __c);
@ -69,7 +76,7 @@ extern size_t strspn(char const *__s, char const *__include);
extern char *strstr(char const *__s1, char const *__s2);
/* Break __s into tokens delimited by characters from __separators. */
extern char *strtok(char * restrict __s, char const * restrict __separators);
extern char *strtok(char * __restrict__ __s, char const * __restrict__ __seps);
/* Miscellaneous functions. */
@ -109,4 +116,8 @@ extern char *strdup(char const *__s);
/* Duplicate at most __n characters of __s with malloc. */
extern char *strndup(char const *__s, size_t __n);
#ifdef __cplusplus
}
#endif
#endif /*__STRING_H__*/

View File

@ -1,8 +1,13 @@
#ifndef __SYS_MMAN_H__
# define __SYS_MMAN_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#ifndef __KERNEL_MEMORY_H__
// mapping flags
@ -55,4 +60,8 @@ extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t
*/
extern int munmap(void *addr, size_t length);
#ifdef __cplusplus
}
#endif
#endif /*__SYS_MMAN_H__*/

View File

@ -1,40 +1,84 @@
#ifndef __SYS_STAT_H__
# define __SYS_STAT_H__
/* File types. */
#define __S_IFMT 0170000 /* These bits determine file type. */
#define __S_IFDIR 0040000 /* Directory. */
#define __S_IFCHR 0020000 /* Character device. */
#define __S_IFBLK 0060000 /* Block device. */
#define __S_IFREG 0100000 /* Regular file. */
#define __S_IFIFO 0010000 /* FIFO. */
#define __S_IFLNK 0120000 /* Symbolic link. */
#define __S_IFSOCK 0140000 /* Socket. */
#ifdef __cplusplus
extern "C" {
#endif
/* Protection bits. */
#define __S_ISUID 0004000 /* Set user ID on execution. */
#define __S_ISGID 0002000 /* Set group ID on execution. */
#define __S_ISVTX 0001000 /* Save swapped text after use (sticky). */
#define __S_IREAD 0000400 /* Read by owner. */
#define __S_IWRITE 0000200 /* Write by owner. */
#define __S_IEXEC 0000100 /* Execute by owner. */
#include <sys/types.h>
#include <time.h>
#define S_IRUSR __S_IREAD /* Read by owner. */
#define S_IWUSR __S_IWRITE /* Write by owner. */
#define S_IXUSR __S_IEXEC /* Execute by owner. */
/* Read, write, and execute by owner. */
#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
/* File types; taken from inode(7), any values would probably work. */
#define S_IFMT 0170000
#define S_IFIFO 0010000 /* FIFO */
#define S_IFCHR 0020000 /* Character device */
#define S_IFDIR 0040000 /* Directory */
#define S_IFBLK 0060000 /* Block device */
#define S_IFREG 0100000 /* Regular file */
#define S_IFLNK 0120000 /* Symbolic link */
#define S_IFSOCK 0140000 /* Socket */
#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */
#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */
#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */
/* Read, write, and execute by group. */
#define S_IRWXG (S_IRWXU >> 3)
/* Shortcuts to check file types from a mode_t value */
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#define S_IROTH (S_IRGRP >> 3) /* Read by others. */
#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */
#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */
/* Read, write, and execute by others. */
#define S_IRWXO (S_IRWXG >> 3)
/* Protection bits of a mode_t */
#define S_ISUID 0004000 /* Set user ID on execution */
#define S_ISGID 0002000 /* Set group ID on execution */
#define S_ISVTX 0001000 /* Sticky bit */
/* Usual permissions */
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
struct stat {
off_t st_size;
mode_t st_mode;
/* In gint, the struct stat only has the file size and file type. The
protection bits of (st_mode) are always 00777. The following fields all
have undefined values. */
dev_t st_dev;
ino_t st_ino;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
blksize_t st_blksize;
blkcnt_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
};
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
/* Obtain information about an entry in the filesystem. */
extern int stat(char const * __restrict__ __pathname,
struct stat * __restrict__ __statbuf);
extern int chmod(char const *__pathname, mode_t mode);
#ifdef __cplusplus
}
#endif
#endif /*__SYS_STAT_H__*/

View File

@ -1,6 +1,10 @@
#ifndef __SYS_SYSCALL_H__
# define __SYS_SYSCALL_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
** This file should list the numbers of the system calls the system knows.
** But instead of duplicating this we use the information available
@ -15,4 +19,8 @@
*/
#include <bits/syscall.h>
#ifdef __cplusplus
}
#endif
#endif /*__SYS_SYSCALL_H__*/

View File

@ -1,26 +1,48 @@
#ifndef __SYS_TYPES_H__
# define __SYS_TYPES_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
// Define properly off_t type.
# ifndef __off_t_defined
typedef uint32_t off_t;
# define __off_t_defined
# endif
/* Number of blocks in a file */
typedef uint16_t blkcnt_t;
// Define properly ssize_t type.
#ifndef __ssize_t_defined
/* Size of a file block */
typedef uint16_t blksize_t;
/* Device identifier, with a major and minor byte */
typedef uint16_t dev_t;
/* Type of group identifiers on the system */
typedef uint16_t gid_t;
/* Inode number */
typedef uint32_t ino_t;
/* Holds a file's type and permissions bits */
typedef int16_t mode_t;
/* Number of hard links to a file */
typedef uint16_t nlink_t;
/* Offset within a file or stream; also, file size */
typedef int32_t off_t;
/* Process identifier */
typedef int16_t pid_t;
/* Signed size_t which can hold the value -1 */
typedef int32_t ssize_t;
# define __ssize_t_defined
/* Type of user identifiers on the system */
typedef uint16_t uid_t;
#ifdef __cplusplus
}
#endif
// Define alias
//FIXME: potential conflict with the real glibc(?)
typedef int32_t pid_t;
typedef int16_t mode_t;
typedef uint16_t dev_t;
typedef uint16_t umode_t;
#endif /*__SYS_TYPES_H__*/

View File

@ -1,6 +1,10 @@
#ifndef __SYS_WAIT_H__
# define __SYS_WAIT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
@ -46,4 +50,8 @@ extern pid_t waitpid(pid_t pid, int *wstatus, int options);
*/
extern pid_t wait(int *wstatus);
#ifdef __cplusplus
}
#endif
#endif /*__SYS_WAIT_H__*/

View File

@ -1,22 +0,0 @@
#ifndef __BITS_TRAPA_H__
# define __BITS_TRAPA_H__
/*
** Normally the SH3/SH4 processor provide a "trapa" instruction which allow
** tipping between userland and kernel. But Casio's don't use this method
** (this is why we are always in "privilegied mode" and we can do whatever
** we whant) but use custom calling convention to access the syscall call.
**
** The convention whant that the user jump into the syscall trampoline code
** located at 0x80010070 for fx9860g and 0x80020070 for fxcg20/50.
*/
# define casio_trapa(id) \
mov.l syscall_table, r2 ;\
mov.l syscall_id, r0 ;\
jmp @r2 ;\
nop ;\
.align 4 ;\
syscall_table: .long 0x80020070 ;\
syscall_id: .long id
#endif /*__BITS_TRAPA_H__*/

View File

@ -1,34 +0,0 @@
#ifndef __BITS_UNISTD_32_H__
# define __BITS_UNISTD_32_H__
// File manipulation
#define __NR_BFile_Remove 0x00001db4
#define __NR_BFile_Create 0x00001dae
#define __NR_BFile_Open 0x00001da3
#define __NR_BFile_Close 0x00001da4
#define __NR_BFile_Size 0x00001da6
#define __NR_BFile_Write 0x00001daf
#define __NR_BFile_Read 0x00001dac
#define __NR_BFile_FindFirst 0x00001db7
#define __NR_BFile_FindNext 0x00001db9
#define __NR_BFile_FindClose 0x00001dba
// Keyboard interface
#define __NR_PutKeyCode 0x000012c6
#define __NR_GetKeyWait 0x000012bf
#define __NR_ClearKeyBuffer 0x000012c7
#define __NR_GetVRAMAddress 0x000001e6
// Memory management
#define __NR_Bmem_malloc 0x00001f44
#define __NR_Bmem_free 0x00001f42
#define __NR_Bmem_calloc 0x00001f40
#define __NR_Bmem_realloc 0x00001f46
// Timer interface
#define __NR_Timer_Install 0x000008d9
#define __NR_Timer_Deinstall 0x000008da
#define __NR_Timer_Start 0x000008db
#define __NR_Timer_Stop 0x000008dc
#endif /*__BITS_UNISTD_32_H__*/

View File

@ -1,7 +0,0 @@
#ifndef __BITS_TYPES_FILE_H__
# define __BITS_TYPES_FILE_H__
typedef struct {
} FILE;
#endif /*__BITS_TYPES_FILE_H__*/

View File

@ -1,57 +0,0 @@
#ifndef __BITS_UNISTD_32_H__
# define __BITS_UNISTD_32_H__
// File manipulation
#define __NR_Bfile_CreateFile 0x00000434
#define __NR_Bfile_OpenFile 0x0000042c
#define __NR_Bfile_WriteFile 0x00000435
#define __NR_Bfile_ReadFile 0x00000432
#define __NR_Bfile_SeekFile 0x00000431
#define __NR_Bfile_CloseFile 0x0000042d
#define __NR_Bfile_FindFirst 0x0000043b
#define __NR_Bfile_FindNext 0x0000043c
#define __NR_Bfile_FindClose 0x0000043d
#define __NR_Bfile_GetMediaFree 0x0000042e
#define __NR_Bfile_RemoveFile 0x00000439
// Display syscalls
#define __NR_Bdisp_GetVRAM 0x00000135
#define __NR_Bdisp_DrawLine 0x00000030
#define __NR_Bdisp_AllClr_VRAM 0x00000143
#define __NR_Bdisp_Display 0x00000028
#define __NR_Bdisp_PrintMini 0x00000c4f
#define __NR_Bdisp_ClearArea 0x0000014b
#define __NR_Bdisp_ReverseArea 0x0000014d
#define __NR_Bdisp_RestoreDisp 0x00000814
#define __NR_Bdisp_SaveDisp 0x00000813
// Keyboard primitives
#define __NR_Bkey_GetKey 0x0000090f
#define __NR_Bkey_PutKeycode 0x0000024f
#define __NR_BKey_GetKeyWait 0x00000247
// Memory management
#define __NR_Bmem_malloc 0x00000acd
#define __NR_Bmem_realloc 0x00000e6d
#define __NR_Bmem_called 0x00000e6b
#define __NR_Bmem_free 0x00000acc
// USB primitive
#define __NR_USB_Open 0x000002ac // not sure
#define __NR_USB_Close 0x000004a4 // not sure
// SD Card primitives
#define __NR_SDC_Init 0x0000017a // not sure
#define __NR_SDC_Mount 0x0000044b // not sure
#define __NR_SDC_Umount 0x0000044a
// Timer interface
#define __NR_TimerInstall 0x00000118
#define __NR_TimerDeinstall 0x00000119
#define __NR_TimerStart 0x0000011a
#define __NR_TimerStop 0x0000011b
// power management
#define __NR_PowerOff 0x000003f4
#endif /*__BITS_UNISTD_32__*/

View File

@ -1,7 +0,0 @@
#ifndef __BITS_CONFNAME_H__
# define __BITS_CONFNAME_H__
#define _SC_PAGE_SIZE 0
#define _SC_PAGESIZE _SC_PAGE_SIZE
#endif /*__BITS_CONFNAME_H__*/

View File

@ -1,22 +0,0 @@
#ifndef __BITS_TRAPA_H__
# define __BITS_TRAPA_H__
/*
** Normally the SH3/SH4 processor provide a "trapa" instruction which allow
** tipping between userland and kernel. But Casio's don't use this method
** (this is why we are always in "privilegied mode" and we can do whatever
** we whant) but use custom calling convention to access the syscall call.
**
** The convention whant that the user jump into the syscall trampoline code
** located at 0x80010070 for fx9860g and 0x80020070 for fxcg20/50.
*/
# define casio_trapa(id) \
mov.l syscall_table, r2 ;\
mov.l syscall_id, r0 ;\
jmp @r2 ;\
nop ;\
.align 4 ;\
syscall_table: .long 0x80010070 ;\
syscall_id: .long id
#endif /*__BITS_TRAPA_H__*/

View File

@ -1,7 +0,0 @@
#ifndef __BITS_TYPES_FILE_H__
# define __BITS_TYPES_FILE_H__
typedef struct {
} FILE;
#endif /*__BITS_TYPES_FILE_H__*/

View File

@ -0,0 +1,8 @@
#ifndef __BITS_EXIT_H__
# define __BITS_EXIT_H__
/* Exit codes for CASIOWIN add-ins. */
#define EXIT_SUCCESS 1
#define EXIT_FAILURE 0
#endif /*__BITS_EXIT_H__*/

View File

@ -0,0 +1,20 @@
#ifndef __BITS_SIGNUM_H__
# define __BITS_SIGNUM_H__
// Define the number of signals
#define _NSIG 16
/* Fake signal functions. */
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
/* ISO C99 signals. */
#define SIGINT 2 /* Interactive attention signal. */
#define SIGILL 4 /* Illegal instruction. */
#define SIGABRT 6 /* Abnormal termination. */
#define SIGFPE 8 /* Erroneous arithmetic operation. */
#define SIGSEGV 11 /* Invalid access to storage. */
#define SIGTERM 15 /* Termination request. */
#endif /*__BITS_SIGNUM_H__*/

View File

@ -0,0 +1,12 @@
#ifndef __BITS_TYPES_DIR_H__
# define __BITS_TYPES_DIR_H__
#include <stddef.h>
#include <stdint.h>
typedef struct {
/* Associated directory descriptor */
int fd;
} DIR;
#endif /*__BITS_TYPES_DIR_H__*/

View File

@ -1,7 +0,0 @@
#ifndef __BITS_TYPES_FILE_H__
# define __BITS_TYPES_FILE_H__
typedef struct {
} FILE;
#endif /*__BITS_TYPES_FILE_H__*/

View File

@ -0,0 +1,23 @@
#ifndef __BITS_SETJMP_H__
# define __BITS_SETJMP_H__
#include <stddef.h>
#include <stdint.h>
/*
** Custom(?) jmp_buf struct
** The SR register is saved first because the long jump can be involved with
** different register bank. So to avoid this, it's simpler to restore the saved
** SR first (see <src/setjmp/target/sh-generic/longjmp.S>)
*/
struct __jmp_buf
{
uint32_t sr;
uint32_t reg[8];
uint32_t gbr;
uint32_t macl;
uint32_t mach;
uint32_t pr;
};
#endif /*__BITS_SETJMP_H__*/

View File

@ -0,0 +1,21 @@
#ifndef __ENDIAN_H__
# define __ENDIAN_H__
/* CASIO calculators are configured as big-endian. */
#define htobe16(x) (x)
#define htole16(x) (__builtin_bswap16(x))
#define be16toh(x) (x)
#define le16toh(x) (__builtin_bswap16(x))
#define htobe32(x) (x)
#define htole32(x) (__builtin_bswap32(x))
#define be32toh(x) (x)
#define le32toh(x) (__builtin_bswap32(x))
#define htobe64(x) (x)
#define htole64(x) (__builtin_bswap64(x))
#define be64toh(x) (x)
#define le64toh(x) (__builtin_bswap64(x))
#endif /*__ENDIAN_H__*/

View File

@ -1,45 +0,0 @@
#ifndef __BITS_ASM_UNISTD_32_H__
# define __BITS_ASM_UNISTD_32_H__
// Define the number of syscall
#define __NR_MAX 21
// Kernel Test
#define __NR_test_syscall 0
// Process
#define __NR_exit 1
#define __NR_fork_execve 2 // (custom)
#define __NR_waitpid 3
#define __NR_wait 4
#define __NR_getpid 5
#define __NR_getppid 6
#define __NR_getpgid 7
#define __NR_setpgid 8
// Signal
#define __NR_signal 9
#define __NR_sigreturn 10
#define __NR_sigaction 11
#define __NR_kill 12
#define __NR_sigprogmask 13
#define __NR_sigpending 14
#define __NR_sigaltstack 15
// VFS
#define __NR_read 16
#define __NR_write 17
#define __NR_open 18
#define __NR_close 19
#define __NR_lseek 20
#define __NR_pread 21
#define __NR_pwrite 22
// Memory
#define __NR_mmap 23
#define __NR_munmap 24
#define __NR_proc_heap_alloc 25 // (custom)
#define __NR_proc_heap_free 26 // (custom)
#define __NR_proc_heap_realloc 27 // (custom)
#endif /*__BITS_ASM_UNISTD_32_H__*/

View File

@ -1,8 +0,0 @@
#ifndef __BITS_CONFNAME_H__
# define __BITS_CONFNAME_H__
//FIXME: this part is probably arch-specific(?)
#define _SC_PAGE_SIZE 0
#define _SC_PAGESIZE _SC_PAGE_SIZE
#endif /*__BITS_CONFNAME_H__*/

View File

@ -1,9 +0,0 @@
#ifndef __BITS_FCNTL_H__
# define __BITS_FCNTL_H__
/* open/fcntl. */
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#endif /*__BITS_FCNTL_H__*/

View File

@ -1,26 +0,0 @@
#ifndef __BITS_SETJMP_H__
# define __BITS_SETJMP_H__
#include <stddef.h>
#include <stdint.h>
/*
** Custom(?) jmp_buf struct
** @note: save only r8 ~ r15 and SR / PC registers
** The SR register is saved first because the longjump can be involved with
** different register bank. So to avoid this, it's more simple to restore the
** saved SR first then restore all register (see <src/setjmp/longjmp.S>)
**
** TODO: save process signal mask ?
*/
struct __jmp_buf
{
uint32_t sr;
uint32_t reg[8];
uint32_t gbr;
uint32_t macl;
uint32_t mach;
uint32_t pr;
};
#endif /*__BITS_SETJMP_H__*/

View File

@ -1,12 +0,0 @@
#ifndef __BITS_SIGACTION_H__
# define __BITS_SIGACTION_H__
#include <stddef.h>
#include <stdint.h>
/* Values for the HOW argument to `sigprocmask'. */
#define SIG_BLOCK 0 /* Block signals. */
#define SIG_UNBLOCK 1 /* Unblock signals. */
#define SIG_SETMASK 2 /* Set the set of blocked signals. */
#endif /*__BITS_SIGACTION_H__*/

View File

@ -1,50 +0,0 @@
#ifndef __BITS_SIGNUM_H__
# define __BITS_SIGNUM_H__
// Define the number of signals
#define NSIG 32
// Vhex kernel internal define used to indicate
// if the signal is implemented or not
#define __SIGUNDEF ((__sighandler_t) -2) /* Not implemented */
/* Fake signal functions. */
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
/* ISO C99 signals. */
#define SIGINT 2 /* Interactive attention signal. */
#define SIGILL 4 /* Illegal instruction. */
#define SIGABRT 6 /* Abnormal termination. */
#define SIGFPE 8 /* Erroneous arithmetic operation. */
#define SIGSEGV 11 /* Invalid access to storage. */
#define SIGTERM 15 /* Termination request. */
/* Historical signals specified by POSIX. */
#define SIGHUP 1 /* Hangup. */
#define SIGQUIT 3 /* Quit. */
#define SIGTRAP 5 /* Trace/breakpoint trap. */
#define SIGKILL 9 /* Killed. */
#define SIGBUS 10 /* Bus error. */
#define SIGSYS 12 /* Bad system call. */
#define SIGPIPE 13 /* Broken pipe. */
#define SIGALRM 14 /* Alarm clock. */
/* New(er) POSIX signals (1003.1-2008, 1003.1-2013). */
#define SIGURG 16 /* Urgent data is available at a socket. */
#define SIGSTOP 17 /* Stop, unblockable. */
#define SIGTSTP 18 /* Keyboard stop. */
#define SIGCONT 19 /* Continue. */
#define SIGCHLD 20 /* Child terminated or stopped. */
#define SIGTTIN 21 /* Background read from control terminal. */
#define SIGTTOU 22 /* Background write to control terminal. */
#define SIGPOLL 23 /* Pollable event occurred (System V). */
#define SIGXCPU 24 /* CPU time limit exceeded. */
#define SIGXFSZ 25 /* File size limit exceeded. */
#define SIGVTALRM 26 /* Virtual timer expired. */
#define SIGPROF 27 /* Profiling timer expired. */
#define SIGUSR1 30 /* User-defined signal 1. */
#define SIGUSR2 31 /* User-defined signal 2. */
#endif /*__BITS_SIGNUM_H__*/

View File

@ -1,13 +0,0 @@
#ifndef __BITS_TYPES_FILE_H__
# define __BITS_TYPES_FILE_H__
// opaque definition of the _IO_FILE
struct _IO_FILE;
/*
** The opaque type of streams.
** This is the definition used elsewhere.
*/
typedef struct _IO_FILE FILE;
#endif /*__BITS_TYPES_FILE_H__*/

View File

@ -1,8 +0,0 @@
#ifndef __BITS_TYPES___FILE_H__
# define ___BITS_TYPES___FILE_H__
// define opaque definition of the FILE type
struct _IO_FILE;
typedef struct _IO_FILE __FILE;
#endif /*__BITS_TYPES___FILE_H__*/

View File

@ -1,26 +0,0 @@
#ifndef __BITS_TYPES_STRUCT_FILE_H__
# define __BITS_TYPES_STRUCT_FILE_H__
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
//---
// TODO: VFS abstraction ? or ABI-spesific abstraction ?
//---
// Define _IO_FILE
// TODO: add open flags
// TODO: add file descriptor ?
// TODO: update me !
struct _IO_FILE
{
off_t cursor;
int permission;
void *file_op;
void *private;
};
#endif /*__BITS_TYPES_STRUCT_FILE_H__*/

View File

@ -1,9 +0,0 @@
#ifndef __BITS_WAITFLAGS_H__
# define __BITS_WAITFLAGS_H__
/* Bits in the third argument to `waitpid'. */
#define WNOHANG 1 /* Don't block waiting. */
#define WUNTRACED 2 /* Report status of stopped child. */
#define WCONTINUED 3 /* Report continued child. */
#endif /*__BITS_WAITFLAGS_H__*/

View File

@ -1,35 +0,0 @@
#ifndef __BITS_WAITSTATUS_H__
# define __BITS_WAITSTATUS_H__
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
/* If WIFSIGNALED(STATUS), the terminating signal. */
#define __WTERMSIG(status) ((status) & 0x7f)
/* If WIFSTOPPED(STATUS), the signal that stopped the child. */
#define __WSTOPSIG(status) __WEXITSTATUS(status)
/* Nonzero if STATUS indicates normal termination. */
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
/* Nonzero if STATUS indicates termination by a signal. */
#define __WIFSIGNALED(status) \
(((signed char) (((status) & 0x7f) + 1) >> 1) > 0)
/* Nonzero if STATUS indicates the child is stopped. */
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
/* Nonzero if STATUS indicates the child continued after a stop. */
# define __WIFCONTINUED(status) ((status) == __W_CONTINUED)
/* Nonzero if STATUS indicates the child dumped core. */
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
/* Macros for constructing status values. */
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#define __W_CONTINUED 0xffff
#define __WCOREFLAG 0x80
#endif /*__BITS_WAITSTATUS_H__*/

View File

@ -0,0 +1,8 @@
#ifndef __BITS_EXIT_H__
# define __BITS_EXIT_H__
/* Exit codes for CASIOWIN add-ins. */
#define EXIT_SUCCESS 1
#define EXIT_FAILURE 0
#endif /*__BITS_EXIT_H__*/

View File

@ -0,0 +1,20 @@
#ifndef __BITS_SIGNUM_H__
# define __BITS_SIGNUM_H__
// Define the number of signals
#define _NSIG 16
/* Fake signal functions. */
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
/* ISO C99 signals. */
#define SIGINT 2 /* Interactive attention signal. */
#define SIGILL 4 /* Illegal instruction. */
#define SIGABRT 6 /* Abnormal termination. */
#define SIGFPE 8 /* Erroneous arithmetic operation. */
#define SIGSEGV 11 /* Invalid access to storage. */
#define SIGTERM 15 /* Termination request. */
#endif /*__BITS_SIGNUM_H__*/

View File

@ -0,0 +1,12 @@
#ifndef __BITS_TYPES_DIR_H__
# define __BITS_TYPES_DIR_H__
#include <stddef.h>
#include <stdint.h>
typedef struct {
/* Associated directory descriptor */
int fd;
} DIR;
#endif /*__BITS_TYPES_DIR_H__*/

View File

@ -1,77 +0,0 @@
#ifndef __THREADS_H__
# define __THREADS_H__
#include <stddef.h>
#include <stdint.h>
//---
// Warnig, this part is experimental and reserved for Vhex
//---
// Define Mutex type
enum {
mtx_plain = 0,
mtx_recursive = 1,
mtx_timed = 2
};
// Define mutex structure
// @note: This is a custom implementation
#define MTX_WATERMARK (0xdeadbeef)
struct __mtx_s {
uint32_t __watermark;
uint16_t lock;
uint8_t type;
};
typedef struct __mtx_s mtx_t;
//---
// Mutex functions
//---
/*
** Creates a new mutex object with type __TYPE.
** @note: If successful the new object is pointed by __MUTEX.
*/
extern int mtx_init(mtx_t *__mutex, int __type);
/*
** Block the current thread until the mutex pointed to by __MUTEX is unlocked.
** In that case current thread will not be blocked.
*/
extern int mtx_lock(mtx_t *__mutex);
/*
** Try to lock the mutex pointed by __MUTEX without blocking.
** @note: If the mutex is free the current threads takes control of it,
** otherwise it returns immediately.
*/
extern int mtx_trylock(mtx_t *__mutex);
/*
** Unlock the mutex pointed by __MUTEX.
** @note: It may potentially awake other threads waiting on this mutex.
*/
extern int mtx_unlock (mtx_t *__mutex);
/* Destroy the mutex object pointed by __MUTEX. */
extern void mtx_destroy(mtx_t *__mutex);
//---
// Atomic operations
//---
/*
** Save the current SR register and set the SR.BIT bit up (start atomic operations)
** @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
*/
extern uint32_t __thread_atomic_start(void);
/*
** Restore the saved SR register
** @note: return the restored SR register or -1 otherwise.
*/
extern uint32_t __thread_atomic_stop(void);
#endif /*__THREADS_H__*/

77
include/time.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef __TIME_H__
# define __TIME_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/* Number of ticks per second in a clock_t value. This is not necessarily the
full precision (eg. the RTC has only 128 units per second). */
#define CLOCKS_PER_SEC 1000000
/* Represent process CPU time; unit is CLOCKS_PER_SEC. */
typedef uint64_t clock_t;
/* Represent a number of seconds since 1970-01-01 00:00:00 +0000 (UTC). */
typedef int64_t time_t;
/* Broken-down time. */
struct tm {
int tm_sec; /* Seconds (0..60) */
int tm_min; /* Minutes (0..59) */
int tm_hour; /* Hours (0..23) */
int tm_mday; /* Day of month (1..31) */
int tm_mon; /* Month (0..11) */
int tm_year; /* Years since 1900 */
int tm_wday; /* Day of week, starting Sunday (0..6) */
int tm_yday; /* Day of year (0..365) */
int tm_isdst; /* Daylight Saving Time flag */
};
/* Full time specification with second/nanosecond precision. */
struct timespec {
time_t tv_sec;
long tv_nsec;
};
/* Returns CPU time used by the program (in number of CLOCKS_PER_SEC). */
extern clock_t clock(void);
/* Time elapsed between __start and __end, in seconds. */
double difftime(time_t __end, time_t __start);
/* Normalizes __time and returns associated timestamp.
TODO: Currently ignores the [tm_isdst] field. */
extern time_t mktime(struct tm *__time);
/* Determine current timestamp; also set it in __timeptr if non-NULL. */
extern time_t time(time_t *__timeptr);
/* Text representation, like "Sun Sep 16 01:03:52 1973\n". The returned string
is statically allocated and is overwritten by every call. */
extern char *asctime(const struct tm *__time);
/* Convert calendar time to asctime()'s text representation. */
extern char *ctime(const time_t *__time);
/* Convert calendar time to broken-down time as UTC. */
extern struct tm *gmtime(const time_t *__time);
/* Convert calendar time to broken-down local time.
TODO: We don't have timezones so this always returns UTC. */
extern struct tm *localtime(const time_t *time);
/* Formats __time according to the specified format; similar to snprintf().
TODO: %g, %G, %V (week-based year), and %U, %W (week number) are not
supported and substituted by "??". %z and %Z output nothing. */
size_t strftime(char * __restrict__ __s, size_t __maxsize,
const char * __restrict__ __format, const struct tm * __restrict__ __time);
#ifdef __cplusplus
}
#endif
#endif /*__TIME_H__*/

View File

@ -1,11 +1,55 @@
#ifndef __UNISTD_H__
# define __UNISTD_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
/* Standard file descriptors. */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
/* Write data to a file descriptor; returns number of bytes written or -1. */
extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
/* Read data from a file descriptor; returns number of bytes read or -1. */
extern ssize_t read(int __fd, void *__buf, size_t __nbytes);
/* Read at a specific position from a file descriptor. */
extern ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset);
/* Write at a specific position to a file descriptor. */
extern ssize_t pwrite(int __fd, const void *__buf, size_t __n, off_t __offset);
/* Seek at an offset from SEEK_SET/SEEK_CUR/SEEK_END; returns new position. */
extern off_t lseek(int __fd, off_t __offset, int __whence);
/* Close a file descriptor. */
extern int close(int __fd);
/* Remove a file. */
extern int unlink(const char *__path);
/* Create a directory. */
extern int mkdir(const char *__path, mode_t __mode);
/* Remove an empty directory. */
extern int rmdir(const char *__path);
extern char *getcwd(char *__buf, size_t __size);
extern int chdir(char const *__path);
/* Kernel-style functions supported only by Vhex. */
#ifdef __SUPPORT_VHEX_KERNEL
//---
// Process part
///---
@ -25,56 +69,6 @@ extern pid_t getppid(void);
*/
extern int setpgid(pid_t __pid, pid_t __pgid);
//---
// File part
//---
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
/*
** Write N bytes of BUF to FD.
** Return the number written, or -1.
*/
extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
/*
** Read NBYTES into BUF from FD.
** Return the number read, -1 for errors or 0 for EOF.
*/
extern ssize_t read(int __fd, void *__buf, size_t __nbytes);
/*
** Read NBYTES into BUF from FD at the given position OFFSET without
** changing the file pointer.
** Return the number read, -1 for errors or 0 for EOF.
*/
extern ssize_t pread (int __fd, void *__buf, size_t __nbytes, off_t __offset);
/*
** Write N bytes of BUF to FD at the given position OFFSET without
** changing the file pointer.
** Return the number written, or -1.
*/
extern ssize_t pwrite (int __fd, const void *__buf, size_t __n, off_t __offset);
/* Values for the WHENCE argument to lseek. */
#define SEEK_SET 0 /* Seek from beginning of file. */
#define SEEK_CUR 1 /* Seek from current position. */
#define SEEK_END 2 /* Seek from end of file. */
/*
** Move FD's file position to OFFSET bytes from the beginning of the file
** (if WHENCE is SEEK_SET), the current position (if WHENCE is SEEK_CUR),
** or the end of the file (if WHENCE is SEEK_END).
** Return the new file position.
*/
extern off_t lseek (int __fd, off_t __offset, int __whence);
/* Close the file descriptor FD */
extern int close(int __fd);
//---
// System part
//---
@ -88,4 +82,10 @@ extern int close(int __fd);
/* Get the value of the system variable NAME. */
extern long int sysconf(int __name);
#endif /*__SUPPORT_VHEX_KERNEL*/
#ifdef __cplusplus
}
#endif
#endif /*__UNISTD_H__*/

68
src/dso.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdlib.h>
/* We don't support shared object loading, so provide a single handle */
__attribute__((visibility("hidden")))
void *__dso_handle = (void *)&__dso_handle;
/* Number of atexit() calls supported, must be at least 32 (7.20.4.2§3).*/
#define ATEXIT_MAX 32
struct dtor {
void (*f)(void *);
void *p;
void *d;
};
static struct dtor *_dtors;
static int _dtor_count = 0;
__attribute__((constructor))
static void alloc_dtors(void)
{
_dtors = malloc(ATEXIT_MAX * sizeof *_dtors);
}
int __cxa_atexit(void (*f)(void *), void *p, void *d)
{
if(!_dtors || _dtor_count >= ATEXIT_MAX)
return 1;
_dtors[_dtor_count++] = (struct dtor){ f, p, d };
return 0;
}
/* We walk the destructor list in reverse order. Destructors may themselves
call __cxa_atexit(), causing new destructors to be added. When that
happens, we must call the new ones first before resuming (7.20.4.3§3). We
track changes in _dtor_count to detect this situation.
This function calls destructs in the interval [low..high) that match DSO
handle d, plus any other destructors registered as a consequence.
_dtor_count may increase. */
static void call_dtors_in_interval(void *d, int low, int high)
{
int end = _dtor_count;
for(int i = high - 1; i >= low; i--) {
if(d == NULL || _dtors[i].d == d)
_dtors[i].f(_dtors[i].p);
if(_dtor_count > end) {
call_dtors_in_interval(d, end, _dtor_count);
end = _dtor_count;
}
}
}
void __cxa_finalize(void *d)
{
call_dtors_in_interval(d, 0, _dtor_count);
/* Re-compact the array to keep only destructors we didn't call. */
int j = 0;
for(int i = 0; i < _dtor_count; i++) {
if(d == NULL || _dtors[i].d == d)
continue;
_dtors[j++] = _dtors[i];
}
_dtor_count = j;
}

View File

@ -1,18 +0,0 @@
#include <bits/asm/unistd_32.h>
.text
.global _kill
.type _kill, @function
.align 2
/*
** extern int kill(pid_t pid, int sig);
** Send signal SIG to process number PID. If PID is zero, send SIG to all
** processes in the current process's process group. If PID is < -1, send SIG to
** all processes in process group - PID.
*/
_kill:
trapa #__NR_kill
rts
nop
.end

View File

@ -1,17 +0,0 @@
#include <bits/asm/unistd_32.h>
.text
.global _signal
.type _signal, @function
.align 2
/*
** extern void (*signal(int signum, void (*handler)(int)))(int);
** Set the handler for the signal SIG to HANDLER, returning the old handler, or
** SIG_ERR on error. By default `signal' has the BSD semantic.
*/
_signal:
trapa #__NR_signal
rts
nop
.end

View File

@ -1,16 +0,0 @@
#include <stdio.h>
/*
** The function dprintf() is the same as fprintf() except that it outputs to a
** file descriptor, fd, instead of to a stdio stream.
*/
int dprintf(int fd, const char *restrict format, ...)
{
va_list ap;
int ret;
va_start(ap, format);
ret = vdprintf(fd, format, ap);
va_end(ap);
return (ret);
}

View File

@ -1,58 +0,0 @@
#ifndef _SRC_STDIO_INTERNAL_PRINTF_H__
#define _SRC_STDIO_INTERNAL_PRINTF_H__
#include <stddef.h>
#include <stdint.h>
//---
// Internal printf() part
//---
#define PRINTF_INTERNAL_BUFFER_SIZE 32
// internal structure used by any printf function familly
struct printf_opt
{
// Internal buffer to avoid syscall flux
char buffer[PRINTF_INTERNAL_BUFFER_SIZE];
size_t buffer_cursor;
// Common part
int counter;
va_list ap;
// *dprintf part
int fd;
// *sprintf part
char *str;
size_t str_size;
// For string / fd common support
void (*disp_char)(struct printf_opt *opt, char n);
void (*disp_fflush)(struct printf_opt *opt);
// Printf-options
struct {
uint8_t diez : 1;
uint8_t zero : 1;
uint8_t minus : 1;
uint8_t space : 1;
uint8_t plus : 1;
uint8_t const : 3;
} flags;
int width;
int precision;
int uppercase;
int lenght;
// Internal format management.
char sign;
char base[2];
char format[32];
int digits;
};
// Internal symbols used to define all actions possibility
extern void (*action[26])(struct printf_opt *opt, char n);
#endif /*_SRC_STDIO_INTERNAL_PRINTF_H__*/

View File

@ -1,208 +0,0 @@
#include <stdio.h>
// internal depency
#include "printf.h"
// Define all actions
static void action_str(struct printf_opt *op, char n);
static void action_ptr(struct printf_opt *op, char n);
static void action_int(struct printf_opt *op, char n);
static void action_uint(struct printf_opt *op, char n);
static void action_char(struct printf_opt *op, char n);
// Define all actions which can be used
void (*action[26])(struct printf_opt *opt, char n) = {
NULL, NULL, action_char, action_int,
NULL, NULL, NULL, NULL,
action_int, NULL, NULL, NULL,
NULL, NULL, action_uint, action_ptr,
NULL, NULL, action_str, NULL,
action_uint, NULL, NULL, action_uint,
NULL, NULL,
};
//---
// Disp part
//---
static void base_to_str(struct printf_opt *opt, uint32_t num, int base,
int digits)
{
char *hexa = "0123456789abcdef";
if (opt->uppercase == 1)
hexa = "0123456789ABCDEF";
opt->digits = 0;
while (num != 0 || opt->digits < digits) {
opt->format[opt->digits++] = hexa[num % base];
num = num / base;
}
}
static void disp_format(struct printf_opt *opt)
{
// display pre symbols
if (opt->sign != '\0')
(*opt->disp_char)(opt, opt->sign);
if (opt->base[0] != '\0')
(*opt->disp_char)(opt, opt->base[0]);
if (opt->base[1] != '\0')
(*opt->disp_char)(opt, opt->base[1]);
// padding
if (opt->flags.minus == 1 && opt->width > opt->digits) {
int total = opt->digits + (opt->sign != '\0') +
(opt->base[0] != '\0') + (opt->base[1] != '\0');
total = opt->width - total;
while (--total >= 0)
(*opt->disp_char)(opt,
(opt->flags.zero == 1) ? '0' : ' ');
}
// Display number
int saved_digits = opt->digits;
while (--opt->digits >= 0)
(*opt->disp_char)(opt, opt->format[opt->digits]);
// padding
if (opt->flags.minus == 0 && opt->width > saved_digits) {
int total = saved_digits + (opt->sign != '\0') +
(opt->base[0] != '\0') + (opt->base[1] != '\0');
total = opt->width - total;
while (--total >= 0)
(*opt->disp_char)(opt, ' ');
}
}
//---
// Args part
//---
static uint32_t get_arg_i(struct printf_opt *opt)
{
switch (opt->lenght) {
case 0:
return ((signed char)va_arg(opt->ap, int));
case 1:
return ((short int)va_arg(opt->ap, int));
case 2:
return (va_arg(opt->ap, long int));
case 3:
return (va_arg(opt->ap, long long int));
case 4:
return (va_arg(opt->ap, intmax_t));
case 5:
return (va_arg(opt->ap, size_t));
case 6:
return (va_arg(opt->ap, ptrdiff_t));
}
return (va_arg(opt->ap, int));
}
static uint32_t get_arg_u(struct printf_opt *opt)
{
switch (opt->lenght) {
case 0:
return ((unsigned char)va_arg(opt->ap, int));
case 1:
return ((unsigned short int)va_arg(opt->ap, int));
case 2:
return (va_arg(opt->ap, unsigned long int));
case 3:
return (va_arg(opt->ap, unsigned long long int));
case 4:
return (va_arg(opt->ap, intmax_t));
case 5:
return (va_arg(opt->ap, size_t));
case 6:
return (va_arg(opt->ap, ptrdiff_t));
}
return (va_arg(opt->ap, unsigned int));
}
//---
// Actions part.
//---
static void action_str(struct printf_opt *opt, char n)
{
const char *str;
(void)n;
str = va_arg(opt->ap, const char *);
while (*str != '\0')
(*opt->disp_char)(opt, *(str++));
}
static void action_char(struct printf_opt *opt, char n)
{
n = (char)va_arg(opt->ap, int);
(*opt->disp_char)(opt, n);
}
static void action_ptr(struct printf_opt *opt, char n)
{
(void)n;
opt->sign = '@';
opt->base[0] = '0';
opt->base[1] = 'x';
base_to_str(opt, (uintptr_t)va_arg(opt->ap, void*), 16, 8);
disp_format(opt);
}
static void action_int(struct printf_opt *opt, char n)
{
int64_t num;
// Get data and check negative value
// FIXME: max negative value can not be reversed
(void)n;
num = get_arg_i(opt);
if (num < 0) {
opt->sign = '-';
num = -num;
} else if (opt->flags.space == 1 || opt->flags.plus == 1) {
opt->sign = (opt->flags.plus == 1) ? '+' : ' ';
}
// Generate / display number
base_to_str(opt, num, 10, 1);
disp_format(opt);
}
static void action_uint(struct printf_opt *opt, char n)
{
uint32_t num;
int base;
// Get appropriate base
switch (n) {
case 'o':
base = 8;
break;
case 'x':
base = 16;
break;
default:
base = 10;
break;
}
// Display extra symbols if needed
if (opt->flags.diez == 1) {
if (n == 'o') {
opt->base[0] = '0';
} else if (n == 'x') {
opt->base[0] = '0';
opt->base[1] = (opt->uppercase == 1) ? 'X' : 'x';
}
}
// Get number
num = get_arg_u(opt);
// Generate / display number
base_to_str(opt, num, base, 1);
disp_format(opt);
}

View File

@ -1,48 +0,0 @@
#include <stdio.h>
// internal depency
#include "printf.h"
//TODO: precision handling
int printf_common(struct printf_opt *opt, const char *restrict format)
{
extern int printf_get_options(struct printf_opt *opt,
const char *restrict format);
int saved_p;
char tmp;
int p;
p = -1;
opt->counter = 0;
opt->buffer_cursor = 0;
while (format[++p] != '\0') {
// Check printable char
if (format[p] != '%' || format[p + 1] == '%') {
tmp = format[p];
if (format[p] == '%')
p = p + 1;
(*opt->disp_char)(opt,tmp);
continue;
}
// Get options
saved_p = p;
p = p + printf_get_options(opt, &format[p + 1]);
// Check arg validity
if (((format[p + 1] >= 'a' && format[p + 1] <= 'z') ||
(format[p + 1] >= 'A' && format[p + 1] <= 'Z')) &&
action[(format[p + 1] | 0x20) - 'a'] != NULL) {
tmp = (format[p + 1] | 0x20) - 'a';
(*action[(int)tmp]) (opt,tmp);
p = p + 1;
continue;
}
// Default, print the %
(*opt->disp_char)(opt, '%');
p = saved_p;
}
(*opt->disp_fflush)(opt);
return (opt->counter);
}

View File

@ -1,127 +0,0 @@
#include <stdio.h>
// internal depency
#include "printf.h"
static int get_flags(struct printf_opt *opt, const char *restrict format)
{
int i;
i = -1;
opt->flags.diez = 0;
opt->flags.zero = 0;
opt->flags.minus = 0;
opt->flags.space = 0;
opt->flags.plus = 0;
while (format[++i] != '\0') {
switch (format[i]) {
case '#':
opt->flags.diez = 1;
break;
case '0':
opt->flags.zero = 1;
break;
case '-':
opt->flags.minus = 1;
break;
case ' ':
opt->flags.space = 1;
break;
case '+':
opt->flags.plus = 1;
break;
default:
return (i);
}
}
return (i);
}
static int get_width(struct printf_opt *opt, const char *restrict format)
{
// Check dynamic width
if (format[0] == '*') {
opt->width = va_arg(opt->ap, int);
return (1);
}
// Check error
int i = -1;
opt->width = 0;
if (format[0] == '0')
return (0);
// Get static width
while (format[++i] >= '0' && format[i] <= '9')
opt->width = (opt->width * 10) + (format[i] - '0');
return (i);
}
static int get_precision(struct printf_opt *opt, const char *restrict format)
{
// Check if precision is specified
if (format[0] != '.')
return (0);
// Check dynamic precision
if (format[1] == '*') {
opt->precision = va_arg(opt->ap, int);
return (2);
}
// Get static precision
int i = 0;
opt->precision = 0;
while (format[++i] >= '0' && format[i] <= '9')
opt->precision = (opt->precision * 10) + (format[i] - '0');
// Check default precision
if (i == 0)
opt->precision = 1;
return (i);
}
static int get_lenght(struct printf_opt *opt, const char *restrict format)
{
opt->lenght = -1;
switch (format[0]) {
case 'h':
opt->lenght = (format[1] == 'h') ? 1 : 0;
break;
case 'l':
opt->lenght = (format[1] == 'l') ? 3 : 2;
break;
case 'j':
opt->lenght = 4;
break;
case 'z':
opt->lenght = 5;
break;
case 't':
opt->lenght = 6;
break;
default:
return (0);
}
return ((opt->lenght == 1 || opt->lenght == 3) ? 2 : 1);
}
int printf_get_options(struct printf_opt *opt, const char *restrict format)
{
int i;
// Wipe internal format infos
opt->sign = '\0';
opt->base[0] = '\0';
opt->base[1] = '\0';
// Get generals opetions
i = get_flags(opt, &format[0]);
i += get_width(opt, &format[i]);
i += get_precision(opt, &format[i]);
i += get_lenght(opt, &format[i]);
// Check upper case actions
opt->uppercase = (format[i] == 'X') ? 1 : 0;
return (i);
}

View File

@ -1,19 +0,0 @@
#include <stdio.h>
#include <unistd.h>
/*
** printf() write the output under the control of a format string that specifies
** how subsequent arguments (or arguments accessed via the variable-length
** argument facilities of stdarg(3)) are converted for output then write to
** the STDOUT.
*/
int printf(const char *restrict format, ...)
{
va_list ap;
int ret;
va_start(ap, format);
ret = vdprintf(STDOUT_FILENO, format, ap);
va_end(ap);
return (ret);
}

View File

@ -1,11 +0,0 @@
#include <stdio.h>
#include <unistd.h>
int putchar(int c)
{
char n;
n = (char)c;
write(STDOUT_FILENO, &n, 1);
return (n);
}

View File

@ -1,18 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/*
** puts() writes the string s and a trailing newline to stdout.
** FIXME: check last write error !
*/
int puts(const char *s)
{
size_t size;
size_t n;
size = strlen(s);
n = write(STDOUT_FILENO, s, size);
write(STDOUT_FILENO, "\n", 1);
return (-(n == size));
}

Some files were not shown because too many files have changed in this diff Show More