forked from Vhex-Kernel-Core/fxlibc
Compare commits
80 Commits
Author | SHA1 | Date |
---|---|---|
Heath Mitchell | 4ade93eb6f | |
Lephenixnoir | 031e0ccb65 | |
Lephenixnoir | 74b805e8b5 | |
Yann MAGNIN | 7eb2a6e8ab | |
Yann MAGNIN | c85182d07e | |
Lephenixnoir | 465655674b | |
Lephenixnoir | 1da9d10226 | |
Lephenixnoir | 7c4de3e295 | |
Lephenixnoir | 95e33092ec | |
Lephenixnoir | 26e54af8e0 | |
Lephenixnoir | fda0d950ed | |
Lephenixnoir | eb83e7442f | |
Heath Mitchell | aeeae3810d | |
Heath Mitchell | ee42660ea5 | |
Lephenixnoir | ddec761f61 | |
Lephenixnoir | ca6c39bf56 | |
Lephenixnoir | 4b61daa602 | |
Lephenixnoir | 8231557ff5 | |
Lephenixnoir | 714e1cf605 | |
Lephenixnoir | ed52c1d7c2 | |
Lephenixnoir | 143029a837 | |
Lephenixnoir | 31ee6fdbee | |
Lephenixnoir | b38dd3f894 | |
Lephenixnoir | 89c6c39405 | |
Yann MAGNIN | e8779145c2 | |
Yann MAGNIN | ed77a97547 | |
Yann MAGNIN | bdf9566723 | |
Lephenixnoir | 26d5b5d9ab | |
Yann MAGNIN | 619afe25da | |
Yann MAGNIN | 996b2b8ded | |
Lephenixnoir | d50e44c563 | |
Lephenixnoir | 94faa6cbea | |
Alice Rozengarden | 3f5989ceab | |
Lephenixnoir | 3c29639988 | |
Lephenixnoir | 4d464bde01 | |
Lephenixnoir | 809238e5b8 | |
Yann MAGNIN | fa4adc5620 | |
Lephenixnoir | 71866ed769 | |
Lephenixnoir | ed873a652e | |
Lephenixnoir | 294fda9731 | |
Lephenixnoir | f1512125d0 | |
Lephenixnoir | 6ec0c24e2d | |
Lephenixnoir | 06b66252c9 | |
Lephenixnoir | 0c2f81e5bb | |
Lephenixnoir | 909c7df815 | |
Lephenixnoir | 4461bdb96a | |
Lephenixnoir | b6dbdf321d | |
Lephenixnoir | a12b84f1ef | |
Lephenixnoir | 51528170bb | |
Lephenixnoir | b53078776d | |
Lephenixnoir | 3046304497 | |
Lephenixnoir | f7b85f18bd | |
Lephenixnoir | bd0dd3a8d2 | |
Lephenixnoir | dbfefe5172 | |
Lephenixnoir | 937b7bfb63 | |
Lephenixnoir | e479393a9c | |
Lephenixnoir | c2feb94710 | |
Lephenixnoir | 92ccd8b1db | |
Lephenixnoir | e71f9867e2 | |
Lephenixnoir | 164b33b26d | |
Lephenixnoir | df4c13b007 | |
Lephenixnoir | a0ceeefaf4 | |
Lephenixnoir | ea35c18c41 | |
Lephenixnoir | a6dbcfb227 | |
Lephenixnoir | f5571e2b3d | |
Lephenixnoir | 6e42995388 | |
Lephenixnoir | 518a866750 | |
Lephenixnoir | 6be2a3d52e | |
Lephenixnoir | dcaf203f46 | |
Lephenixnoir | ed8134970b | |
Lephenixnoir | 009a2eef6e | |
Lephenixnoir | 625a6af459 | |
Lephenixnoir | f52e0923bc | |
Lephenixnoir | 66463bfe17 | |
Lephenixnoir | d261db447b | |
Lephenixnoir | cd7fe7a329 | |
Lephenixnoir | 04e910441a | |
Lephenixnoir | 4b90740d3b | |
Lephenixnoir | 73d6b2eb7c | |
Lephenixnoir | 13c3390b22 |
|
@ -3,6 +3,7 @@
|
|||
/prefix
|
||||
*.txt
|
||||
!CMakeLists.txt
|
||||
.vxsdk/
|
||||
|
||||
# GiteaPC config files
|
||||
giteapc-config.make
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
386
CMakeLists.txt
386
CMakeLists.txt
|
@ -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)
|
||||
|
|
71
README.md
71
README.md
|
@ -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
249
STATUS
|
@ -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
|
||||
|
|
|
@ -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})
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__*/
|
|
@ -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
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/* We rely on GCC's default version. */
|
||||
#include "stdint-gcc.h"
|
387
include/stdio.h
387
include/stdio.h
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
||||
|
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
typedef struct {
|
||||
} FILE;
|
||||
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
|
@ -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__*/
|
104
include/unistd.h
104
include/unistd.h
|
@ -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__*/
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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__*/
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue