diff options
author | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2017-10-05 21:34:58 +0200 |
---|---|---|
committer | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2017-10-05 21:34:58 +0200 |
commit | 071943d8daf5f8bcb0f277d5bda3e6ed1f43b008 (patch) | |
tree | 3fa58d323a08b7e2f7c3262cdf751a411b0aa341 | |
parent | 1345945a71d8f18416f7ca81929b9ecb53406b6b (diff) |
Doing stuff.
74 files changed, 1602 insertions, 815 deletions
@@ -1,3 +1,4 @@ # libcarrot license All of the files do not belong to the same people/organizations, and are not -covered by the same licenses, see `docs/licensing.en.md` for more details. +always placed under the same licenses, see `docs/licensing.en.md` for +more details. diff --git a/arch/all/core-sh/info.yml b/arch/all/core-sh/info.yml index 3517529..3069dff 100644 --- a/arch/all/core-sh/info.yml +++ b/arch/all/core-sh/info.yml @@ -4,15 +4,4 @@ magic: potatosdk-1.0 description: The core libc, SuperH-specific parts. license: free requires: - arch: - - sh1 - - sh2 - - sh2e - - sh2a - - sh2afpu - - sh2dsp - - sh3 - - sh3dsp - - sh4 - - sh4a - - sh4aldsp + arch: [sh] diff --git a/arch/all/core/include/ctype.h b/arch/all/core/include/ctype.h index 66205b2..1c9626e 100644 --- a/arch/all/core/include/ctype.h +++ b/arch/all/core/include/ctype.h @@ -29,13 +29,11 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <cdefs.h> -__BEGIN_DECLS +_BEGIN_DECLS -/* ************************************************************************* */ -/* Symbols (if no macros) */ -/* ************************************************************************* */ -/* check type */ -__BEGIN_NAMESPACE_STD +/* Check a character type. */ + +_BEGIN_NAMESPACE_STD _EXTERN _PURE int isalnum _OF((int __c)) _THROW; _EXTERN _PURE int isalpha _OF((int __c)) _THROW; _EXTERN _PURE int isascii _OF((int __c)) _THROW; @@ -48,21 +46,22 @@ _EXTERN _PURE int ispunct _OF((int __c)) _THROW; _EXTERN _PURE int isspace _OF((int __c)) _THROW; _EXTERN _PURE int isupper _OF((int __c)) _THROW; _EXTERN _PURE int isxdigit _OF((int __c)) _THROW; -__END_NAMESPACE_STD -__BEGIN_NAMESPACE_C99 +_END_NAMESPACE_STD + +_BEGIN_NAMESPACE_C99 _EXTERN _PURE int isblank _OF((int __c)) _THROW; -__END_NAMESPACE_C99 +_END_NAMESPACE_C99 -/* convert to lower or upper */ -__BEGIN_NAMESPACE_STD +/* Alternate between lower/upper, and clear higher bits. */ + +_BEGIN_NAMESPACE_STD _EXTERN _PURE int tolower _OF((int __c)) _THROW; _EXTERN _PURE int toupper _OF((int __c)) _THROW; _EXTERN _PURE int toascii _OF((int __c)) _THROW; -__END_NAMESPACE_STD -/* ************************************************************************* */ -/* Macros for interacting with the tab */ -/* ************************************************************************* */ -/* Prepare the bits generation */ +_END_NAMESPACE_STD + +/* Prepare the bits generation. */ + #include <endian.h> #if __BYTE_ORDER == __BIG_ENDIAN # define _ISbit(_BIT) (1 << (_BIT)) @@ -85,12 +84,14 @@ __END_NAMESPACE_STD #define _ISpunct _ISbit(10) /* Punctuation */ #define _ISalnum _ISbit(11) /* Alphanumeric */ -/* The block */ +/* The block. */ + _EXTERN const unsigned short __ctype_b[]; #define __isctype(_C, _TYPE) \ (__ctype_b[(int)(_C)] & (unsigned short int)(_TYPE)) -/* Macros */ +/* Macros. */ + #ifndef __NO_CTYPE # define isalnum(C) __isctype((C), _ISalpha | _ISdigit) # define isalpha(C) __isctype((C), _ISalpha) @@ -109,4 +110,4 @@ _EXTERN const unsigned short __ctype_b[]; # define toascii(C) ((C) & 0x7F) #endif -__END_DECLS +_END_DECLS diff --git a/arch/all/core/include/locale.h b/arch/all/core/include/locale.h index d45f381..407f19f 100644 --- a/arch/all/core/include/locale.h +++ b/arch/all/core/include/locale.h @@ -46,93 +46,68 @@ _EXTERN char* setlocale _OF((int __category, const char *__locale)) _THROW; /* `struct lconv` is the structure containing members related to the - * formatting of numeric values. */ + * formatting of numeric values. + * + * `decimal_point` is the decimal-point character. + * `thousands_sep` is used to separate group of digits before the + * decimal-point character. + * `grouping` is the string whose elements indicate the size of each + * group of digits. + * + * The default version of the previous corresponds to nonmonetary quantities, + * whereas the `mon_` version of the previous corresponds to monetary + * quantities. + * + * `positive_sign` indicates a nonnegative-valued quantity. + * `negative_sign` indicates a negative-valued quantity. + * + * `currency_symbol` is the local currency symbol. + * `frac_digits` corresponds to the number of fractional digits (those + * after the decimal-point) to be displayed in a locally formatted quantity. + * + * `cs_precedes` is a boolean indicating if the currency symbol precedes + * (!= 0) or succeeds (== 0) the value. + * `sep_by_space` is a value indicating the separation of the currency + * symbol, the sign string, and the value. + * `sign_posn` is a value indicating the positioning of the positive or + * negative sign for a nonnegative-valued quantity. + * + * The `p_` version of the above applies to nonnegative values, and the + * `n_` version of the above applies to negative values. + * + * The `int_` version of all of the above, starting from `currency_symbol` + * (abbreviated to `curr_symbol` for the occasion), corresponds to + * an international-formatted quantity. */ struct lconv { - char *decimal_point; /* decimal-point character used to format - * nonmonetary quantities. */ - char *thousands_sep; /* character used to separate groups of digits - * before the decimal-point character in - * formatted nonmonetary quantities. */ - char *grouping; /* string whose elements indicate the size of - * each group of digits in formatted nonmonetary - * quantities. */ - - char *mon_decimal_point; /* decimal-point used to format monetary - * quantities. */ - char *mon_thousands_sep; /* separator for groups of digits before the - * decimal-point in formatted monetary - * quantities. */ - char *mon_grouping; /* string whose elements indicate the size of - * each group of digits in formatted monetary - * quantities. */ - - char *positive_sign; /* string used to indicate a nonnegative-valued - * formatted monetary quantity. */ - char *negative_sign; /* string used to indicate a negative-valued - * formatted monetary quantity. */ - - char *currency_symbol; /* local currency symbol applicable to the current - * locale. */ - char frac_digits; /* number of fractional digits (those after the - * decimal-point) to be displayed in a locally - * formatted monetary quantity. */ - - char p_cs_precedes; /* 1 or 0 if the `currency_symbol` respectively - * precedes or succeeds the value for a - * nonnegative locally formatted monetary - * quantity. */ - char n_cs_precedes; /* 1 or 0 if the `currency_symbol` respectively - * precedes or succeeds the value for a - * negative locally formatted - * monetary quantity. */ - - char p_sep_by_space; /* value indicating the separation of the - * `currency_symbol`, the sign string, and the - * value for a nonnegative locally formatted - * monetary quantity. */ - char n_sep_by_space; /* value indicating the separation of the - * `currency_symbol`, the sign string, and the - * value for a negative locally formatted - * monetary quantity. */ - - char p_sign_posn; /* value indicating the positioning of the - * `positive_sign` for a nonnegative locally - * formatted monetary quantity. */ - char n_sign_posn; /* value indicating the positioning of the - * `negative_sign` for a negative locally - * formatted monetary quantity. */ - - char *int_curr_symbol; /* international currency symbol applicable to the - * current locale. */ - char int_frac_digits; /* number of fractional digits to be displayed in - * an internationally formatted monetary - * quantity. */ - - char int_p_cs_precedes; /* 1 or 0 if the `int_curr_symbol` respectively - * precedes or succeeds the value for a - * nonnegative internationally formatted - * monetary quantity. */ - char int_n_cs_precedes; /* 1 or 0 if the `int_curr_symbol` respectively - * precedes or succeeds the value for a negative - * internationally formatted - * monetary quantity. */ - - char int_p_sep_by_space; /* value indicating the separation of the - * `int_curr_symbol`, the sign string, and the - * value for a nonnegative internationally - * formatted monetary quantity. */ - char int_n_sep_by_space; /* value indicating the separation of the - * `int_curr_symbol`, the sign string, and the - * value for a negative internationally - * formatted monetary quantity. */ - - char int_p_sign_posn; /* value indicating the positioning of the - * `positive_sign` for a nonnegative - * internationally formatted monetary quantity. */ - char int_n_sign_posn; /* value indicating the positioning of the - * `negative_sign` for a negative internationally - * formatted monetary quantity. */ + char *decimal_point; + char *thousands_sep; + char *grouping; + + char *mon_decimal_point; + char *mon_thousands_sep; + char *mon_grouping; + + char *positive_sign; + char *negative_sign; + + char *currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + + char *int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; }; /* Get the locale numerical conversion thing. */ diff --git a/arch/all/core/include/setjmp.h b/arch/all/core/include/setjmp.h index ac438b4..b89f667 100644 --- a/arch/all/core/include/setjmp.h +++ b/arch/all/core/include/setjmp.h @@ -34,7 +34,8 @@ _BEGIN_NAMESPACE_STD #include_bits <setjmp.h> -/* functions */ +/* Set and make the long jump. */ + _EXTERN _WUR int setjmp _OF((jmp_buf __env)) _THROW; _EXTERN void longjmp diff --git a/arch/all/core/include/string.h b/arch/all/core/include/string.h deleted file mode 100644 index c63183c..0000000 --- a/arch/all/core/include/string.h +++ /dev/null @@ -1,117 +0,0 @@ -/* **************************************************************************** - * string.h -- String utilities. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> - * - * This file is part of the 'all/core' module in libcarrot, an experimental - * modular libc project. - * - * This file is governed by the CeCILL-C license under French law and abiding - * by the rules of distribution of free software. You can use, modify and or - * redistribute it under the terms of the CeCILL-C license as circulated by - * CEA, CNRS and INRIA at the following URL: http://www.cecill.info - * - * As a counterpart to the access to the source code and rights to copy, modify - * and redistribute granted by the license, users are provided only with a - * limited warranty and the software's author, the holder of the economic - * rights, and the successive licensors have only limited liability. - * - * In this respect, the user's attention is drawn to the risks associated with - * loading, using, modifying and/or developing and reproducing the software by - * the user in light of its specific status of free software, that may mean - * that it is complicated to manipulate, and that also therefore means that it - * is reserved for developers and experienced professionals having in-depth - * computer knowledge. Users are therefore encouraged to load and test the - * software's suitability as regards their requirements in conditions enabling - * the security of their systems and/or data to be ensured and, more generally, - * to use and operate it in the same conditions as regards security. - * - * The fact that you are presently reading this means you have had knowledge of - * the CeCILL-C license and that you accept its terms. - * ************************************************************************* */ -#include <cdefs.h> -#include <stddef.h> -#include <strings.h> -_BEGIN_DECLS -_BEGIN_NAMESPACE_STD - -/* ************************************************************************* */ -/* Raw memory related functions */ -/* ************************************************************************* */ -/* copy memory */ -_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memcpy - _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, - size_t __n)) _THROW; - -_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memmove - _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, - size_t __n)) _THROW; - -_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memccpy - _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, - int __c, size_t __n)) _THROW; - -/* compare memory */ -_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _PURE int memcmp - _OF((const void *__s, const void *__t, size_t __n)) _THROW; - -/* look for a character in a memory area */ -_EXTERN _NONNULL(1, __s) _PURE void* memchr - _OF((const void *__s, int __c, size_t __n)) _THROW; - -/* initialize a memory area with a character */ -_EXTERN _NONNULL(1, __s) void* memset - _OF((void *__s, int __c, size_t __n)) _THROW; -/* ************************************************************************* */ -/* String-related functions */ -/* ************************************************************************* */ -/* find out the length of a string */ -_EXTERN _NONNULL(1, __s) _PURE size_t strlen - _OF((const char __s[_NOTNULL])) _THROW; - -_EXTERN _NONNULL(1, __s) _PURE size_t strnlen - _OF((const char __s[_NOTNULL], size_t __maxlen)) _THROW; - -/* copy a string */ -_EXTERN _NONNULL(1, __dst) __nonnull(2, __src) char* strcpy - _OF((char __dst[_NOTNULL], const char __src[_NOTNULL])) _THROW; - -_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) char* strncpy - _OF((char *__dst, const char __src[_NOTNULL], size_t __n)) _THROW; - -/* catenate a string */ -_EXTERN _NONNULL(1, __str) _NONNULL(2, __src) char* strcat - _OF((char *__str, const char *__src)) _THROW; - -_EXTERN _NONNULL(1, __str) _NONNULL(2, __src) char* strncat - _OF((char *__str, const char *__src, size_t __n)) _THROW; - -/* compare strings */ -_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _WUR int strcmp - _OF((const char *__s, const char *__t)) _THROW; - -_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _WUR int strncmp - _OF((const char *__s, const char *__t, size_t __n)) _THROW; - -/* look for a characters in a string */ -_EXTERN _NONNULL(1, __s) _PURE char* strchr - _OF((const char *__s, int __c)) _THROW; - -_EXTERN _NONNULL(1, __s) _PURE char* strrchr - _OF((const char *__s, int __c)) _THROW; - -_EXTERN _NONNULL(1, __s) _NONNULL(2, __accept) _PURE char *strpbrk - _OF((const char *__s, const char *__accept)) _THROW; - -/* look for a string in another string */ -_EXTERN _NONNULL(1, __haystack) _NONNULL(2, __needle) _PURE char* strstr - _OF((const char *__haystack, const char *__needle)) _THROW; - -/* check the length of a prefix */ -_EXTERN _NONNULL(1, __s) _NONNULL(2, __accept) _PURE size_t strspn - _OF((const char *__s, const char *__accept)) _THROW; - -_EXTERN _NONNULL(1, __s) _NONNULL(2, __reject) _PURE size_t strcspn - _OF((const char *__s, const char *__reject)) _THROW; - -_END_NAMESPACE_STD -_END_DECLS diff --git a/arch/all/core/info.yml b/arch/all/core/info.yml index e2ea3a3..32d6710 100644 --- a/arch/all/core/info.yml +++ b/arch/all/core/info.yml @@ -7,3 +7,4 @@ depends: - io - math - mem +- string diff --git a/arch/all/core/roles.yml b/arch/all/core/roles.yml index 2f16434..46f8745 100644 --- a/arch/all/core/roles.yml +++ b/arch/all/core/roles.yml @@ -1,11 +1,6 @@ %YAML 1.2 --- include: - cdefs: - attrs.h: C Compiler helpers. - compiler.h: Compiler description. - features.h: Compiler features. - utils.h: C utilities. assert.h: Assertions. byteswap.h: Byte swapping utilities. cdefs.h: C definitions. diff --git a/arch/all/core/src/string/memset.c b/arch/all/core/src/string/memset.c deleted file mode 100644 index 5af14c3..0000000 --- a/arch/all/core/src/string/memset.c +++ /dev/null @@ -1,107 +0,0 @@ -/* **************************************************************************** - * string/memset.c -- Initialize the content of a memory area. - * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> - * - * This file is part of the 'all/core' module in libcarrot, an experimental - * modular libc project. - * - * This file is governed by the CeCILL-C license under French law and abiding - * by the rules of distribution of free software. You can use, modify and or - * redistribute it under the terms of the CeCILL-C license as circulated by - * CEA, CNRS and INRIA at the following URL: http://www.cecill.info - * - * As a counterpart to the access to the source code and rights to copy, modify - * and redistribute granted by the license, users are provided only with a - * limited warranty and the software's author, the holder of the economic - * rights, and the successive licensors have only limited liability. - * - * In this respect, the user's attention is drawn to the risks associated with - * loading, using, modifying and/or developing and reproducing the software by - * the user in light of its specific status of free software, that may mean - * that it is complicated to manipulate, and that also therefore means that it - * is reserved for developers and experienced professionals having in-depth - * computer knowledge. Users are therefore encouraged to load and test the - * software's suitability as regards their requirements in conditions enabling - * the security of their systems and/or data to be ensured and, more generally, - * to use and operate it in the same conditions as regards security. - * - * The fact that you are presently reading this means you have had knowledge of - * the CeCILL-C license and that you accept its terms. - * ************************************************************************* */ -#include <string.h> -#include <stdint.h> - -/** - * setlil: - * Set a little zone of memory. - * - * @arg dword - * - * @arg dword the word to set. - * @arg full the character fullarized. - * @arg start the starting byte. - * @arg end the ending byte. - */ - -static __inline void setlil(unsigned int *p, unsigned char c, size_t count) -{ - switch (count % 8) { - case 7: *p++ = c; - case 6: *p++ = c; - case 5: *p++ = c; - case 4: *p++ = c; - case 3: *p++ = c; - case 2: *p++ = c; - case 1: *p++ = c; - case 0: break; - } -} - -/** - * memset: - * Initialize a memory area with a value. - * - * @arg s the void thingy. - * @arg c the character. - * @arg n the size. - * @return the memory area. - */ - -void *memset(void *s, int c, size_t n) -{ - unsigned int lc; - __uintptr_t mask; - unsigned int *p; - int count; - - if (!n) return (s); - - /* prepare the full character */ - lc = c & 0xFF; - lc |= lc << 8; -#if __SIZEOF_INT__ > 2 - lc |= lc << 16; -# if __SIZEOF_INT__ > 4 - lc |= lc << 32; -# endif -#endif - - /* get the initial pointer */ - mask = (__uintptr_t)&((unsigned int*)NULL)[1] - 1; - p = (unsigned int*)((__uintptr_t)s & ~mask) + 1; - count = (int)((__uintptr_t)p - (__uintptr_t)s); - n -= count; - - /* initial bytes */ - setlil(s, c, count); - - /* main loop */ - for (; n >= sizeof(unsigned int); n -= sizeof(unsigned int)) - *p++ = lc; - - /* final bytes */ - setlil(p, c, n); - - /* return destination */ - return (s); -} diff --git a/arch/all/mem/src/calloc.c b/arch/all/mem/src/calloc.c new file mode 100644 index 0000000..6d63335 --- /dev/null +++ b/arch/all/mem/src/calloc.c @@ -0,0 +1,6 @@ +#include <malloc.h> + +_MALLOC _WUR void* calloc(size_t nmemb, size_t size) +{ + return (*__memalign_hook(size, nmemb * size, NULL)); +} diff --git a/arch/all/mem/src/memalign.c b/arch/all/mem/src/memalign.c new file mode 100644 index 0000000..b845e29 --- /dev/null +++ b/arch/all/mem/src/memalign.c @@ -0,0 +1,7 @@ +#include <malloc.h> + +void* memalign(size_t alignment, size_t size) +{ + alignment = __size_t_ffs(alignment); + return (*__memalign_hook)(alignment, size, NULL); +} diff --git a/arch/all/string-sh/bits/string.h b/arch/all/string-sh/bits/string.h new file mode 100644 index 0000000..6045918 --- /dev/null +++ b/arch/all/string-sh/bits/string.h @@ -0,0 +1 @@ +#define __NO_MEMCHR diff --git a/arch/all/string-sh/copyright.yml b/arch/all/string-sh/copyright.yml new file mode 100644 index 0000000..94e925f --- /dev/null +++ b/arch/all/string-sh/copyright.yml @@ -0,0 +1,5 @@ +%YAML 1.2 +--- +files: '*' +copyright: +- [2017, Thomas "Cakeisalie5" Touhey, thomas@touhey.fr] diff --git a/arch/all/string-sh/info.yml b/arch/all/string-sh/info.yml new file mode 100644 index 0000000..28b21d2 --- /dev/null +++ b/arch/all/string-sh/info.yml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +magic: potatosdk-1.0 +description: Optimized string functions for the SuperH platform. +license: free +depends: +- all/string +requires: + arch: [sh] diff --git a/arch/all/string-sh/src/memchr.s b/arch/all/string-sh/src/memchr.s new file mode 100644 index 0000000..6c13469 --- /dev/null +++ b/arch/all/string-sh/src/memchr.s @@ -0,0 +1,71 @@ +/* Inspired from Lephenixnoir from Planète Casio: + * https://bible.planet-casio.com/lephenixnoir/assembler_techniques.txt */ + +.section .text +.global _memchr +.type _memchr, @function + +_memchr: + /* Construct a register made of four times the requested bytes. */ + mov r5, r1 + shll8 r5 + or r1, r5 + mov r5, r1 + shll16 r5 + or r5, r1 + +loop: + /* Test whether size limit (as multiple of 4) is reached. */ + mov #4, r0 + cmp/hs r0, r6 + bf analyze_four + + /* Test the incoming four bytes. */ + mov.l @r4+, r3 + cmp/str r1, r3 + bt found + + /* Loop and reduce size count. */ + bra loop + add #-4, r6 + +found: + /* Prepare the byte-level analysis of the four bytes that matched. */ + add #-4, r4 + +analyze_four: + /* Analyze at most four bytes, stop if r6 reaches 0. */ + tst r6, r6 + bt end_not_found + + mov.l @r4+, r3 + cmp/str r1, r3 + bt end_found + dt r6 + bt end_not_found + + mov.l @r4+, r3 + cmp/str r1, r3 + bt end_found + dt r6 + bt end_not_found + + mov.l @r4+, r3 + cmp/str r1, r3 + bt end_found + dt r6 + bt end_not_found + + mov.l @r4+, r3 + cmp/str r1, r3 + bt end_found + +end_not_found: + rts + mov #0, r0 + +end_found: + /* Return the current pointer and revert the last post-increment. */ + mov r4, r0 + rts + add #-1, r0 diff --git a/arch/all/string/docs b/arch/all/string/docs new file mode 120000 index 0000000..890a62c --- /dev/null +++ b/arch/all/string/docs @@ -0,0 +1 @@ +../../../docs/all/string
\ No newline at end of file diff --git a/arch/all/string/include/string.h b/arch/all/string/include/string.h new file mode 100644 index 0000000..d01bf10 --- /dev/null +++ b/arch/all/string/include/string.h @@ -0,0 +1,95 @@ +#include <cdefs.h> +#include <stddef.h> + +_BEGIN_DECLS +_BEGIN_NAMESPACE_STD + +/* Initialize a memory area with a character. */ + +_EXTERN _NONNULL(1, __s) void* memset + _OF((void *__s, int __c, size_t __n)) _THROW; + +/* Copy memory from an area to an other. */ + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memcpy + _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, + size_t __n)) _THROW; + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memmove + _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, + size_t __n)) _THROW; + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) void* memccpy + _OF((void *_RESTRICT __dst, const void *_RESTRICT __src, + int __c, size_t __n)) _THROW; + +/* Compare two memory areas. */ + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _PURE int memcmp + _OF((const void *__s, const void *__t, size_t __n)) _THROW; + +/* Look for a character in a memory area. */ + +_EXTERN _NONNULL(1, __s) _PURE void* memchr + _OF((const void *__s, int __c, size_t __n)) _THROW; + +/* Find out the length of a nul-terminated string. */ + +_EXTERN _NONNULL(1, __s) _PURE size_t strlen + _OF((const char __s[_NOTNULL])) _THROW; + +_EXTERN _NONNULL(1, __s) _PURE size_t strnlen + _OF((const char __s[_NOTNULL], size_t __maxlen)) _THROW; + +/* Copy a nul-terminated string. */ + +_EXTERN _NONNULL(1, __dst) __nonnull(2, __src) char* strcpy + _OF((char __dst[_NOTNULL], const char __src[_NOTNULL])) _THROW; + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) char* strncpy + _OF((char *__dst, const char __src[_NOTNULL], size_t __n)) _THROW; + +/* Catenate two nul-terminated strings into one. */ + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) char* strcat + _OF((char *__dst, const char *__src)) _THROW; + +_EXTERN _NONNULL(1, __dst) _NONNULL(2, __src) char* strncat + _OF((char *__dst, const char *__src, size_t __n)) _THROW; + +/* Compare nul-terminated strings. */ + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _WUR int strcmp + _OF((const char *__s, const char *__t)) _THROW; + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __t) _WUR int strncmp + _OF((const char *__s, const char *__t, size_t __n)) _THROW; + +/* Look for a character in a nul-terminated string. */ + +_EXTERN _NONNULL(1, __s) _PURE char* strchr + _OF((const char *__s, int __c)) _THROW; + +_EXTERN _NONNULL(1, __s) _PURE char* strrchr + _OF((const char *__s, int __c)) _THROW; + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __accept) _PURE char *strpbrk + _OF((const char *__s, const char *__accept)) _THROW; + +/* Look for a nul-terminated string in another one. */ + +_EXTERN _NONNULL(1, __haystack) _NONNULL(2, __needle) _PURE char* strstr + _OF((const char *__haystack, const char *__needle)) _THROW; + +/* Check the length of a prefix in a nul-terminated string. */ + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __accept) _PURE size_t strspn + _OF((const char *__s, const char *__accept)) _THROW; + +_EXTERN _NONNULL(1, __s) _NONNULL(2, __reject) _PURE size_t strcspn + _OF((const char *__s, const char *__reject)) _THROW; + +_END_NAMESPACE_STD +_END_DECLS + +#include <strings.h> diff --git a/arch/all/core/include/strings.h b/arch/all/string/include/strings.h index 4a63f06..4a63f06 100644 --- a/arch/all/core/include/strings.h +++ b/arch/all/string/include/strings.h diff --git a/arch/all/string/info.yml b/arch/all/string/info.yml new file mode 100644 index 0000000..6dea9af --- /dev/null +++ b/arch/all/string/info.yml @@ -0,0 +1,5 @@ +%YAML 1.2 +--- +magic: potatosdk-1.0 +description: Bytes manipulating functions. +license: free diff --git a/arch/all/string/src/bsd/bcmp.c b/arch/all/string/src/bsd/bcmp.c new file mode 100644 index 0000000..edbde2c --- /dev/null +++ b/arch/all/string/src/bsd/bcmp.c @@ -0,0 +1,19 @@ +#include <string.h> +#ifndef __NO_BCMP + +/** + * bcmp: + * Compare byte sequences. + * + * @arg vs the first byte sequence. + * @arg vt the second byte sequence. + * @arg len the length to compare. + * @return the difference. + */ + +int bcmp(const void *vs, const void *vt, size_t len) +{ + return (memcmp(vs, vt, len)); +} + +#endif diff --git a/arch/all/string/src/bsd/bcopy.c b/arch/all/string/src/bsd/bcopy.c new file mode 100644 index 0000000..c46e8d0 --- /dev/null +++ b/arch/all/string/src/bsd/bcopy.c @@ -0,0 +1,18 @@ +#include <string.h> +#ifndef __NO_BCOPY + +/** + * bcopy: + * Copy byte sequences. + * + * @arg src the source. + * @arg dest the destination. + * @arg len the length. + */ + +void bcopy(const void *src, void *dest, size_t len) +{ + memcpy(dest, src, len); +} + +#endif diff --git a/arch/all/string/src/bsd/bzero.c b/arch/all/string/src/bsd/bzero.c new file mode 100644 index 0000000..0d5af88 --- /dev/null +++ b/arch/all/string/src/bsd/bzero.c @@ -0,0 +1,17 @@ +#include <string.h> +#ifndef __NO_BZERO + +/** + * bzero: + * Equivalent of `memset()` for setting to zero. + * + * @arg s the byte sequence. + * @arg len the byte sequence length. + */ + +void bzero(void *s, size_t len) +{ + memset(s, 0, len); +} + +#endif diff --git a/arch/all/string/src/bsd/ffs.c b/arch/all/string/src/bsd/ffs.c new file mode 100644 index 0000000..74a2e5d --- /dev/null +++ b/arch/all/string/src/bsd/ffs.c @@ -0,0 +1,38 @@ +#include <stddef.h> +#include <string.h> +#ifndef __NO_FFS + +/** + * ffs: + * Returns the least significant bit. + * + * @arg sword the word (signed form). + * @return the least significant bit. + */ + +int ffs(int sword) +{ + unsigned int word = (unsigned int)sword; + unsigned int mask = (unsigned int)-1, nmask; + +#if __UINT_WIDTH >= 64 + nmask = mask >> 32; + mask = word & nmask ? nmask : ~nmask & mask; +#endif +#if __UINT_WIDTH >= 32 + nmask = mask >> 16; + mask = word & nmask ? nmask : ~nmask & mask; +#endif + nmask = mask >> 8; + mask = word & nmask ? nmask : ~nmask & mask; + nmask = mask >> 4; + mask = word & nmask ? nmask : ~nmask & mask; + nmask = mask >> 2; + mask = word & nmask ? nmask : ~nmask & mask; + nmask = mask >> 1; + mask = word & nmask ? nmask : ~nmask & mask; + + return (mask); +} + +#endif diff --git a/arch/all/string/src/bsd/index.c b/arch/all/string/src/bsd/index.c new file mode 100644 index 0000000..4eedabf --- /dev/null +++ b/arch/all/string/src/bsd/index.c @@ -0,0 +1,14 @@ +#include <string.h> +#ifndef __NO_INDEX + +/** + * index: + * Look for a character in a string, from the left. + */ + +char* index(const char *s, int ch) +{ + return (strchr(s, ch)); +} + +#endif diff --git a/arch/all/string/src/bsd/rindex.c b/arch/all/string/src/bsd/rindex.c new file mode 100644 index 0000000..6dd7283 --- /dev/null +++ b/arch/all/string/src/bsd/rindex.c @@ -0,0 +1,18 @@ +#include <string.h> +#ifndef __NO_RINDEX + +/** + * rindex: + * Look for a character in a nul-terminated string, from the right. + * + * @arg s the string. + * @arg ch the character. + * @return the position (null if not found). + */ + +char* rindex(const char *s, int ch) +{ + return (strrchr(s, ch)); +} + +#endif diff --git a/arch/all/string/src/bsd/strcasecmp.c b/arch/all/string/src/bsd/strcasecmp.c new file mode 100644 index 0000000..c2e820c --- /dev/null +++ b/arch/all/string/src/bsd/strcasecmp.c @@ -0,0 +1,34 @@ +#include <string.h> +#include <locale.h> +#ifndef __NO_STRCASECMP + +/** + * strcasecmp: + * Compare while ignoring case. + * + * @arg s the first string. + * @arg t the second string. + * @return the error code (0 if ok). + */ + +int strcasecmp(const char *s, const char *t) +{ + int result; + int c, d; + + if (s == t) + return (0); + + for (result = 0;;) { + c = tolower(*s++); + d = tolower(*t++); + result = c - d; + + if (result || c == '\0') + break; + } + + return (result); +} + +#endif diff --git a/arch/all/string/src/bsd/strncasecmp.c b/arch/all/string/src/bsd/strncasecmp.c new file mode 100644 index 0000000..c3fd4f5 --- /dev/null +++ b/arch/all/string/src/bsd/strncasecmp.c @@ -0,0 +1,30 @@ +#include <string.h> +#ifndef __NO_STRNCASECMP + +/** + * strncasecmp: + * Case-insensitive comparison on a limited range. + * + * @arg s the first string. + * @arg t the second string. + * @arg len the maximum length. + */ + +int strncasecmp(const char *s, const char *t, size_t len) +{ + int result; + int c, d; + + for (result = 0; len--;) { + c = tolower(*s++); + d = tolower(*t++); + result = c - d; + + if (result || c == '\0') + break; + } + + return (result); +} + +#endif diff --git a/arch/all/string/src/memccpy.c b/arch/all/string/src/memccpy.c new file mode 100644 index 0000000..8dbd5ef --- /dev/null +++ b/arch/all/string/src/memccpy.c @@ -0,0 +1,28 @@ +#include <string.h> +#ifndef __NO_MEMCCPY + +/** + * memccpy: + * Copy memory. + * + * @arg vd the destination. + * @arg vs the source. + * @arg c the limit character. + * @arg n the maximum size of the area to copy. + * @return the destination (again). + */ + +void *memccpy(void *vd, const void *vs, int c, size_t n) +{ + if (vs != vd) { + const char *s = (const char*)vs; + char *d = (char*)vd; + + while (*s != c && n--) + *d++ = *s++; + } + + return (vd); +} + +#endif diff --git a/arch/all/string/src/memchr.c b/arch/all/string/src/memchr.c new file mode 100644 index 0000000..915a45c --- /dev/null +++ b/arch/all/string/src/memchr.c @@ -0,0 +1,28 @@ +#include <string.h> +#ifndef __NO_MEMCHR + +/** + * memchr: + * Search a character in a memory area. + * + * @arg vs a pointer to the memory area. + * @arg c the character. + * @arg n the length of the area. + * @return either the pointer to the found character, or NULL if not. + */ + +void *memchr(const void *vs, int c, size_t n) +{ + const char *s = (const char*)vs - 1; + + while (n--) { + int b = *++s; + + if (b == c) + return ((void*)s); + } + + return (NULL); +} + +#endif diff --git a/arch/all/string/src/memcmp.c b/arch/all/string/src/memcmp.c new file mode 100644 index 0000000..8af0d23 --- /dev/null +++ b/arch/all/string/src/memcmp.c @@ -0,0 +1,31 @@ +#include <string.h> +#ifndef __NO_MEMCMP + +/** + * memcmp: + * Copy memory. + * + * @arg vs the first area. + * @arg vt the second area. + * @arg n the size of the areas to compare. + * @return the difference. + */ + +int memcmp(const void *vs, const void *vt, size_t n) +{ + if (s != t && n) { + const char *s = (const void*)vs; + const char *t = (const void*)vt; + + while (n--) { + int a = *s++, b = *t++; + + if (a != b) + return (a - b); + } + } + + return (0); +} + +#endif diff --git a/arch/all/core/src/string/memcpy.c b/arch/all/string/src/memcpy.c index a171f48..0472852 100644 --- a/arch/all/core/src/string/memcpy.c +++ b/arch/all/string/src/memcpy.c @@ -29,25 +29,29 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <string.h> +#ifndef __NO_MEMCPY /** * memcpy: * Copy memory. * - * TODO: make me smart. - * - * @arg d the destination. - * @arg s the source. + * @arg vd the destination. + * @arg vs the source. * @arg n the size of the area to copy. * @return the destination (again) */ -void *memcpy(void *d, const void *s, size_t n) +void *memcpy(void *vd, const void *vs, size_t n) { - unsigned char *ud = d; - const unsigned char *us = s; - while (n--) - *ud++ = *us++; + if (vs != vd) { + const char *s = (const char*)vs; + char *d = (char*)vd; + + while (n--) + *d++ = *s++; + } - return (d); + return (vd); } + +#endif diff --git a/arch/all/string/src/memmove.c b/arch/all/string/src/memmove.c new file mode 100644 index 0000000..178bb53 --- /dev/null +++ b/arch/all/string/src/memmove.c @@ -0,0 +1,34 @@ +#include <string.h> +#ifndef __NO_MEMMOVE + +/** + * memmove: + * Copy memory, the right way. + * + * @arg vd the destination. + * @arg vs the source. + * @arg n the size of the area to copy. + * @return the destination (again). + */ + +void *memmove(void *vd, const void *vs, size_t n) +{ + if (vs != vd) { + const char *s = (const char*)vs; + char *d = (char*)vd; + + if (d < s) { + while (n--) + *d++ = *s++; + } else { + s += n - 1; + d += n - 1; + while (n--) + *d-- = *s--; + } + } + + return (vd); +} + +#endif diff --git a/arch/all/core/src/string/memchr.c b/arch/all/string/src/memset.c index 8d310dc..214d39a 100644 --- a/arch/all/core/src/string/memchr.c +++ b/arch/all/string/src/memset.c @@ -1,5 +1,5 @@ /* **************************************************************************** - * string/memchr.c -- Look for a character in a memory area. + * string/memset.c -- Initialize the content of a memory area. * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> * * This file is part of the 'all/core' module in libcarrot, an experimental @@ -29,20 +29,27 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <string.h> +#include <stdint.h> +#ifndef __NO_MEMSET /** - * memchr: - * Search a character in a memory area. + * memset: + * Initialize a memory area with a value. * - * @arg s a pointer to the memory area. + * @arg vs the void thingy. * @arg c the character. - * @arg n the length of the area. - * @return either the pointer to the found character, or NULL if not. + * @arg n the size. + * @return the memory area. */ -void *memchr(const void *s, int c, size_t n) +void* memset(void *vs, int c, size_t n) { - const unsigned char *us = (const void*)s; - while (n-- && *us != c) us++; - return ((void*)us); + char *s = (char*)vs; + + while (n--) + *s++ = c; + + return (vs); } + +#endif diff --git a/arch/all/string/src/strcat.c b/arch/all/string/src/strcat.c new file mode 100644 index 0000000..a3f1681 --- /dev/null +++ b/arch/all/string/src/strcat.c @@ -0,0 +1,25 @@ +#include <string.h> +#ifndef __NO_STRCAT + +/** + * strcat: + * Copy a string at the end of another. + * + * @arg dest the destination string. + * @arg src the source string. + * @return the destination string (again). + */ + +char* strcat(char *dest, const char *src) +{ + char *d = dest; + + while (*dest) + dest++; + while (*src) + *dest++ = *src++; + *dest = 0; + return (d); +} + +#endif diff --git a/arch/all/core/src/string/strchr.c b/arch/all/string/src/strchr.c index 9800b43..08a6f08 100644 --- a/arch/all/core/src/string/strchr.c +++ b/arch/all/string/src/strchr.c @@ -29,6 +29,7 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <string.h> +#ifndef __NO_STRCHR /** * strchr: @@ -45,18 +46,4 @@ char *strchr(const char *s, int c) return (*s == c ? (char*)s : NULL); } -/** - * strrchr: - * Look for the last occurrence of a character in a string. - * - * @arg s the string. - * @arg c the character. - * @return the result (NULL if not found). - */ - -char *strrchr(const char *s, int c) -{ - const char *occ = NULL; - while (*(++s - 1)) if (*s == c) occ = s; - return ((char*)occ); -} +#endif diff --git a/arch/all/string/src/strcmp.c b/arch/all/string/src/strcmp.c new file mode 100644 index 0000000..7cd311d --- /dev/null +++ b/arch/all/string/src/strcmp.c @@ -0,0 +1,33 @@ +#include <string.h> +#ifndef __NO_STRCMP + +/** + * strcmp: + * Compare two nul-terminated strings. + * + * @arg s the first string. + * @arg t the second string. + * @return the difference. + */ + +int strcmp(const char *s, const char *t) +{ + int result; + int c, d; + + if (s == t) + return (0); + + for (result = 0;;) { + c = *s++; + d = *t++; + result = c - d; + + if (result || c == '\0') + break; + } + + return (result); +} + +#endif diff --git a/arch/all/string/src/strcpy.c b/arch/all/string/src/strcpy.c new file mode 100644 index 0000000..015c1bc --- /dev/null +++ b/arch/all/string/src/strcpy.c @@ -0,0 +1,23 @@ +#include <string.h> +#ifndef __NO_STRCPY + +/** + * strcpy: + * Copy a string into another. + * + * @arg dest the destination string. + * @arg src the source string. + * @return the destination string (again). + */ + +char* strcpy(char *dst, const char *src) +{ + char *d = dst; + + while (*src) + *dst++ = *src++; + *dst = 0; + return (d); +} + +#endif diff --git a/arch/all/string/src/strcspn.c b/arch/all/string/src/strcspn.c new file mode 100644 index 0000000..59e4df4 --- /dev/null +++ b/arch/all/string/src/strcspn.c @@ -0,0 +1,25 @@ +#include <string.h> +#ifndef __NO_STRCSPN + +/** + * strcspn: + * Look for the length of a prefix not containing a set of characters. + * + * @arg s the string. + * @arg reject the rejected character strings. + */ + +size_t strcspn(const char *s, const char *reject) +{ + size_t pre = 0; + + for (s--; *++s;) { + if (!strchr(reject, *s++)) + break; + pre++; + } + + return (pre); +} + +#endif diff --git a/arch/all/core/src/string/strlen.c b/arch/all/string/src/strlen.c index 8793eee..d7be2a8 100644 --- a/arch/all/core/src/string/strlen.c +++ b/arch/all/string/src/strlen.c @@ -29,6 +29,7 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <string.h> +#ifndef __NO_STRLEN /** * strlen: @@ -41,22 +42,10 @@ size_t strlen(const char *s) { size_t n = 0; - while (*s++) n++; - return (n); -} - -/** - * strnlen: - * Get the length of a string. - * - * @arg s the string. - * @arg n the maximum length. - * @return the length of the string. - */ -size_t strnlen(const char *s, size_t max) -{ - size_t n = 0; - while (max-- && *s++) n++; + while (*s++) + n++; return (n); } + +#endif diff --git a/arch/all/string/src/strncat.c b/arch/all/string/src/strncat.c new file mode 100644 index 0000000..64c0832 --- /dev/null +++ b/arch/all/string/src/strncat.c @@ -0,0 +1,26 @@ +#include <string.h> +#ifndef __NO_STRNCAT + +/** + * strncat: + * Catenate with a maximum string size. + * + * @arg dest the destination string. + * @arg src the source string. + * @arg n the maximum source string size. + * @return the error code (0 if ok). + */ + +char* strncat(char *dest, const char *src, size_t n) +{ + char *d = dest; + + while (*dest) + dest++; + while (n-- && *src) + *dest++ = *src++; + *dest = 0; + return (d); +} + +#endif diff --git a/arch/all/string/src/strncmp.c b/arch/all/string/src/strncmp.c new file mode 100644 index 0000000..2bed757 --- /dev/null +++ b/arch/all/string/src/strncmp.c @@ -0,0 +1,34 @@ +#include <string.h> +#ifndef __NO_STRNCMP + +/** + * strncmp: + * Compare two nul-terminated strings. + * + * @arg s the first string. + * @arg t the second string. + * @arg n the maximum size of the areas to compare. + * @return the difference. + */ + +int strncmp(const char *s, const char *t, size_t n) +{ + int result; + int c, d; + + if (s == d) + return (0); + + for (result = 0; n--;) { + c = *s++; + d = *t++; + result = c - d; + + if (result || c == '\0') + break; + } + + return (result); +} + +#endif diff --git a/arch/all/string/src/strncpy.c b/arch/all/string/src/strncpy.c new file mode 100644 index 0000000..c142ee0 --- /dev/null +++ b/arch/all/string/src/strncpy.c @@ -0,0 +1,26 @@ +#include <string.h> +#ifndef __NO_STRNCPY + +/** + * strncpy: + * Copy a string into another. + * + * @arg dest the destination string. + * @arg src the source string. + * @arg n the maximum destination string size. + * @return the destination string (again). + */ + +char* strncpy(char *dst, const char *src, size_t n) +{ + char *d = dst; + + while (n--) { + *dst++ = *src; + if (!*src++) + break; + } + return (d); +} + +#endif diff --git a/arch/all/string/src/strnlen.c b/arch/all/string/src/strnlen.c new file mode 100644 index 0000000..71be4a7 --- /dev/null +++ b/arch/all/string/src/strnlen.c @@ -0,0 +1,22 @@ +#include <string.h> +#ifndef __NO_STRNLEN + +/** + * strnlen: + * Get the length of a string. + * + * @arg s the string. + * @arg n the maximum length. + * @return the length of the string. + */ + +size_t strnlen(const char *s, size_t max) +{ + size_t n = 0; + + while (max-- && *s++) + n++; + return (n); +} + +#endif diff --git a/arch/all/string/src/strpbrk.c b/arch/all/string/src/strpbrk.c new file mode 100644 index 0000000..cbb2829 --- /dev/null +++ b/arch/all/string/src/strpbrk.c @@ -0,0 +1,23 @@ +#include <string.h> +#ifndef __NO_STRPBRK + +/** + * strpbrk: + * Look for the first occurrence of any of a set of characters. + * + * @arg s the string. + * @arg accept the characters to look for. + * @return the occurrence (NULL if not found). + */ + +char* strpbrk(const char *s, const char *accept) +{ + for (s--; *++s;) { + if (strchr(accept, *s)) + return (s); + } + + return (NULL); +} + +#endif diff --git a/arch/all/string/src/strrchr.c b/arch/all/string/src/strrchr.c new file mode 100644 index 0000000..54b7afa --- /dev/null +++ b/arch/all/string/src/strrchr.c @@ -0,0 +1,20 @@ +#include <string.h> +#ifndef __NO_STRRCHR + +/** + * strrchr: + * Look for the last occurrence of a character in a string. + * + * @arg s the string. + * @arg c the character. + * @return the result (NULL if not found). + */ + +char *strrchr(const char *s, int c) +{ + const char *occ = NULL; + while (*(++s - 1)) if (*s == c) occ = s; + return ((char*)occ); +} + +#endif diff --git a/arch/all/string/src/strspn.c b/arch/all/string/src/strspn.c new file mode 100644 index 0000000..7cd4b6d --- /dev/null +++ b/arch/all/string/src/strspn.c @@ -0,0 +1,25 @@ +#include <string.h> +#ifndef __NO_STRSPN + +/** + * strspn: + * Look for the length of a prefix containing a set of characters. + * + * @arg s the string. + * @arg accept the accepted character strings. + */ + +size_t strspn(const char *s, const char *accept) +{ + size_t pre = 0; + + for (s--; *++s;) { + if (strchr(accept, *s++)) + break; + pre++; + } + + return (pre); +} + +#endif diff --git a/arch/all/string/src/strstr.c b/arch/all/string/src/strstr.c new file mode 100644 index 0000000..ec37071 --- /dev/null +++ b/arch/all/string/src/strstr.c @@ -0,0 +1,30 @@ +#include <string.h> +#ifndef __NO_STRSTR + +/** + * strstr: + * Look for a string in another. + * + * @arg haystack the haystack. + * @arg needle the needle to look for in the haystack. + * @return the occurrence (zero if not found). + */ + +char* strstr(const char *haystack, const char *needle) +{ + size_t nlen; + + if (haystack == needle) + return ((char*)haystack); + + nlen = strlen(needle); + for (haystack--; *++haystack;) { + if (memcmp(haystack, needle, nlen)) + continue; + return ((char*)haystack); + } + + return (NULL); +} + +#endif diff --git a/arch/casiowin/fxlib/include/commbios.h b/arch/casiowin/fxlib/include/commbios.h index 32b2396..3a9a6c4 100644 --- a/arch/casiowin/fxlib/include/commbios.h +++ b/arch/casiowin/fxlib/include/commbios.h @@ -30,35 +30,40 @@ * ************************************************************************* */ #include <fxlib/cdefs.h> #if _USE_FXLIB_UNOFFICIAL -__BEGIN_NAMESPACE_FXLIB -__BEGIN_DECLS +_BEGIN_NAMESPACE_FXLIB +_BEGIN_DECLS + +/* Flags, masks. */ -/* Flags, masks */ # define COMM_MASK_BAUD 0x0007 /* speed is stored in those bits */ # define COMM_MASK_PARITY 0xC000 /* parity is stored in those bits */ # define COMM_FLAG_STOPB 0x1000 /* two stop bits instead of one */ # define COMM_FLAG_USB 0x0020 /* use USB instead of serial */ # define COMM_FLAG_VALID 0x0010 /* base flags (use systematically) */ -/* Communication speeds */ +/* Communication speeds. */ + # define COMM_BAUD_9600 0x0000 # define COMM_BAUD_19200 0x0001 # define COMM_BAUD_38400 0x0002 # define COMM_BAUD_57600 0x0003 # define COMM_BAUD_115200 0x0004 -/* Parity */ +/* Parity. */ + # define COMM_PARITY_NONE 0x0000 /* no parity */ # define COMM_PARITY_EVEN 0x4000 /* even parity */ # define COMM_PARITY_ODD 0x8000 /* odd parity */ -/* Interrupt handler type */ +/* Interrupt handler type. */ + # define SERIAL_INTTYPE_RECEIVE 0x00 /* receive callback*/ # define SERIAL_INTTYPE_TRANSMIT 0x01 /* transmit callback */ # define SERIAL_INTTYPE_RECEIVE_RESET 0x02 /* ? */ # define SERIAL_INTTYPE_TRANSMIT_RESET 0x03 /* ? */ -/* Serial communication speeds */ +/* Serial communication speeds. */ + # define SERIAL_BAUD_300 0x00 # define SERIAL_BAUD_600 0x01 # define SERIAL_BAUD_1200 0x02 @@ -70,7 +75,8 @@ __BEGIN_DECLS # define SERIAL_BAUD_57600 0x08 # define SERIAL_BAUD_115200 0x09 -/* Serial status flags */ +/* Serial status flags. */ + # define SERIAL_STATUS_ER 0x0001 /* receive error */ # define SERIAL_STATUS_TEND 0x0002 /* transmit end */ # define SERIAL_STATUS_TDFE 0x0004 /* transmit FIFO data empty */ @@ -81,20 +87,23 @@ __BEGIN_DECLS # define SERIAL_STATUS_FER 0x1000 /* framing error */ # define SERIAL_STATUS_PER 0x2000 /* parity error */ -/* Protocol 7.00 packet structure */ -typedef struct { +/* Protocol 7.00 packet structure. */ + +typedef struct tag_COMM_PACKET { /* Type and subtype */ - unsigned char pck_type, pck_subtype; + unsigned char type; + unsigned char subtype; /* data */ - unsigned short pck_size; - unsigned char *pck_data; + unsigned short size; + unsigned char *data; /* checksum - maybe not in the end? */ - unsigned char pck_checksum __deprecated; -} comm_packet_t; + unsigned char checksum _DEPRECATED; +} COMM_PACKET; + +/* Communication errors. */ -/* Communication errors */ # define IML_COMMERR_NOERROR 0 /* everything went great! */ # define IML_COMMERR_UNKNOWN 1 /* something bad happened */ # define IML_COMMERR_SERIAL 3 /* serial not open */ @@ -106,6 +115,6 @@ typedef struct { # define IML_COMMERR_INVALID_DATA 17 /* invalid checksum/data too big */ # define IML_COMMERR_EMPTY 18 /* no data available */ -__END_DECLS -__END_NAMESPACE_FXLIB +_END_DECLS +_END_NAMESPACE_FXLIB #endif diff --git a/arch/casiowin/fxlib/include/dispbios.h b/arch/casiowin/fxlib/include/dispbios.h index 2ea1fbd..1067f3e 100644 --- a/arch/casiowin/fxlib/include/dispbios.h +++ b/arch/casiowin/fxlib/include/dispbios.h @@ -29,174 +29,136 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <fxlib/cdefs.h> -__BEGIN_NAMESPACE_FXLIB - -/* VRAM size */ -#define IM_VRAM_WIDTH 128 /* width in pixels */ -#define IM_VRAM_HEIGHT 64 /* height in pixels */ -#define IM_VRAM_SIZE 1024 /* size in bytes (1bpp) */ +_BEGIN_NAMESPACE_FXLIB + +/* These macros can be used by the applications: + * `IM_VRAM_WIDTH`, `IM_VRAM_HEIGHT`: the width and height of the screen, + * in pixels; + * `IM_BIOS_DD_WIDTH`, `IM_BIOS_DD_HEIGHT`: the width and height of the + * display driver; + * `IM_VRAM_SIZE`: the size of the VRAM in bytes (1 bit per pixel); + * `IM_CHARACTERS_MAX_LINE`: the number of characters per line; + * `IM_BYTES_MAX_LINE`: the number of bytes per line (cf. FONTCHARACTER); + * `SAVEDISP_PAGE1`, `SAVEDISP_PAGE2`, `SAVEDISP_PAGE3`: pages for + * saving displays; + * `MINI_OVER`, `MINI_OR`, `MINI_REV`, `MINI_REVOR`: flags for + * `PrintMini()`; */ + +#define IM_VRAM_WIDTH 128 +#define IM_VRAM_HEIGHT 64 +#define IM_BIOS_DD_WIDTH IM_VRAM_WIDTH +#define IM_BIOS_DD_HEIGHT IM_VRAM_HEIGHT +#define IM_VRAM_SIZE 1024 -/* characters */ -#define IM_CHARACTERS_MAX_LINE 21 /* number of characters per line */ +#define IM_CHARACTERS_MAX_LINE 21 #define IM_BYTES_MAX_LINE (IM_CHARACTERS_MAX_LINE * 2) -/* to save and restore displays */ -#define SAVEDISP_PAGE1 1 /* first page (?) */ -#define SAVEDISP_PAGE2 5 /* second page (?) */ -#define SAVEDISP_PAGE3 6 /* third page (?) */ +#define SAVEDISP_PAGE1 1 +#define SAVEDISP_PAGE2 5 +#define SAVEDISP_PAGE3 6 -/* related to mini font? */ #define MINI_OVER 0x10 #define MINI_OR 0x11 #define MINI_REV 0x12 #define MINI_REVOR 0x13 -/* DD size */ -#define IM_BIOS_DD_WIDTH IM_VRAM_WIDTH -#define IM_BIOS_DD_HEIGHT IM_VRAM_HEIGHT -/* ************************************************************************* */ -/* Write kind */ -/* ************************************************************************* */ -/* This is how to draw the pixels of a line, for example. */ +/* Write kinds, or how to draw the pixels of a shape (e.g. a line). */ -enum _WRITEKIND { +typedef enum _WRITEKIND { _WRITEKIND_OVER = 0x01, _WRITEKIND_OR = 0x02, _WRITEKIND_AND = 0x03, _WRITEKIND_XOR = 0x04 -}; +} WRITEKIND; -typedef enum _WRITEKIND WRITEKIND; #define IMB_WRITEKIND_OVER _WRITEKIND_OVER #define IMB_WRITEKIND_OR _WRITEKIND_OR #define IMB_WRITEKIND_AND _WRITEKIND_AND #define IMB_WRITEKIND_XOR _WRITEKIND_XOR -/* ************************************************************************* */ -/* Write modify */ -/* ************************************************************************* */ -/* TODO: describe this. */ -enum _WRITEMODIFY { +/* Write modifies. + * TODO: describe this. */ + +typedef enum _WRITEMODIFY { _WRITEMODIFY_NORMAL = 0x01, _WRITEMODIFY_REVERSE = 0x02, _WRITEMODIFY_MESH = 0x03 -}; +} WRITEMODIFY; -typedef enum _WRITEMODIFY WRITEMODIFY; #define IMB_WRITEMODIFY_NORMAL _WRITEMODIFY_NORMAL #define IMB_WRITEMODIFY_REVERSE _WRITEMODIFY_REVERSE #define IMB_WRITEMODIFY_REVERCE _WRITEMODIFY_REVERSE /* compatibility */ #define IMB_WRITEMODIFY_MESH _WRITEMODIFY_MESH -/* ************************************************************************* */ -/* Area kind */ -/* ************************************************************************* */ -/* TODO: describe this. */ -enum _AREAKIND { +/* Area kind. + * TODO: describe this. */ + +typedef enum _AREAKIND { _AREAKIND_OVER = 0x01, _AREAKIND_MESH = 0x02, _AREAKIND_CLR = 0x03, _AREAKIND_REVERSE = 0x04 -}; +} AREAKIND; -typedef enum _AREAKIND AREAKIND; #define IMB_AREAKIND_OVER _AREAKIND_OVER #define IMB_AREAKIND_MESH _AREAKIND_MESH #define IMB_AREAKIND_CLR _AREAKIND_CLR #define IMB_AREAKIND_REVERSE _AREAKIND_REVERSE #define IMB_AREAKIND_REVERCE _AREAKIND_REVERSE /* compatibility */ -/* ************************************************************************* */ -/* Effect window */ -/* ************************************************************************* */ -/* TODO: describe this. */ -enum _EFFECTWIN { +/* Effect window. + * TODO: describe this. */ + +typedef enum _EFFECTWIN { _EFFECTWIN_OK = 0x01, _EFFECTWIN_NG = 0x02 -}; +} EFFECTWIN; -typedef enum _EFFECTWIN EFFECTWIN; #define IMB_EFFECTWIN_OK _EFFECTWIN_OK #define IMB_EFFECTWIN_NG _EFFECTWIN_NG -/* ************************************************************************* */ -/* Display box */ -/* ************************************************************************* */ -/* TODO: describe this. */ -#define tag_DISPBOX _DISPBOX /* compatibility */ -struct _DISPBOX { +/* Display box. + * TODO: describe this. */ + +typedef struct tag_DISPBOX { int left; int top; int right; int bottom; -}; - -typedef struct _DISPBOX DISPBOX; -typedef struct _DISPBOX dispbox_t; -#define dp_left left -#define dp_top top -#define dp_right right -#define dp_bottom bottom -/* ************************************************************************* */ -/* Graph data */ -/* ************************************************************************* */ -/* TODO: describe this. */ - -#define tag_GRAPHDATA _GRAPHDATA /* compatibility */ -struct _GRAPHDATA { - int width; - int height; +} DISPBOX; + +/* Graph data. + * TODO: describe this. */ + +typedef struct tag_GRAPHDATA { + int width; + int height; unsigned char *pBitmap; -}; - -typedef struct _GRAPHDATA GRAPHDATA; -typedef struct _GRAPHDATA graphdata_t; -#define gd_width width -#define gd_height height -#define gd_bitmap pBitmap -/* ************************************************************************* */ -/* Rectangle */ -/* ************************************************************************* */ -/* TODO: describe this. */ - -#define tag_RECTANGLE _RECTANGLE /* compatibility */ -struct _RECTANGLE { +} GRAPHDATA; + +/* Rectangle. + * TODO: describe this. */ + +typedef struct tag_RECTANGLE { DISPBOX LineArea; AREAKIND AreaKind; EFFECTWIN EffectWin; -}; - -typedef struct _RECTANGLE RECTANGLE; -typedef struct _RECTANGLE rectangle_t; -#define rc_linearea LineArea -#define rc_areakind AreaKind -#define rc_effectwin EffectWin -/* ************************************************************************* */ -/* Display graph */ -/* ************************************************************************* */ -/* TODO: describe this. */ - -#define tag_DISPGRAPH _DISPGRAPH /* compatibility */ -struct _DISPGRAPH { +} RECTANGLE; + +/* Display graph. + * TODO: describe this. */ + +typedef struct tag_DISPGRAPH { int x; int y; GRAPHDATA GraphData; WRITEMODIFY WriteModify; WRITEKIND WriteKind; -}; - -typedef struct _DISPGRAPH DISPGRAPH; -typedef struct _DISPGRAPH dispgraph_t; -#define dg_x x -#define dg_y y -#define dg_graphdata GraphData -#define dg_writemodify WriteModify -#define dg_writekind WriteKind -/* ************************************************************************* */ -/* Shape */ -/* ************************************************************************* */ +} DISPGRAPH; + #if _USE_FXLIB_UNOFFICIAL -/* Main structure. + +/* There is a syscall made to draw more complicated shapes. * The `sh_f` structure contains the shape information. * - `sh_f[0]` is always 2 (?); * - `sh_f[1]` is the type of the shape; @@ -228,8 +190,7 @@ typedef struct _DISPGRAPH dispgraph_t; * - [3, 3] clear (normal bit disabling); * - [3, 4] invert (reverse bit disabling). */ -# define tag_SHAPE _SHAPE -struct _SHAPE { +typedef struct tag_SHAPE { /* coordinates */ unsigned int sh_x1, sh_y1; unsigned int sh_x2, sh_y2; @@ -239,10 +200,8 @@ struct _SHAPE { /* control the pattern of the dashed line types 3 and 4 */ unsigned int sh_onbits, sh_offbits; -}; +} SHAPE; -typedef struct _SHAPE SHAPE; -typedef struct _SHAPE shape_t; #endif -__END_NAMESPACE_FXLIB +_END_NAMESPACE_FXLIB diff --git a/arch/casiowin/fxlib/include/filebios.h b/arch/casiowin/fxlib/include/filebios.h index 337a50d..646b22c 100644 --- a/arch/casiowin/fxlib/include/filebios.h +++ b/arch/casiowin/fxlib/include/filebios.h @@ -30,12 +30,19 @@ * ************************************************************************* */ #include <fxlib/cdefs.h> -__BEGIN_NAMESPACE_FXLIB +_BEGIN_NAMESPACE_FXLIB + +/* The fx-9860G series calculators use a proprietary encoding called + * FONTCHARACTER because of the name of the type for defining fixed-width + * strings in the original FX library. Read the documentation for more + * information about it. + * + * This encoding is used for displaying stuff, and for file names on + * fx-9860G series calculators (storage memory *and* main memory), that's + * why it's defined here. */ typedef unsigned short FONTCHARACTER; -/* ************************************************************************* */ -/* File opening mode */ -/* ************************************************************************* */ + /* File opening modes are: * * `_OPENMODE_READ`: read only; @@ -53,11 +60,9 @@ enum _OPENMODE { _OPENMODE_READWRITE = 0x03, _OPENMODE_READWRITE_SHARE = 0x83 }; -/* ************************************************************************* */ -/* Creating mode */ -/* ************************************************************************* */ -/* This mode is for when you're creating files or directories. - * Known creation modes are: + +/* Creation modes serve when you create files or directory. + * Public creation modes are: * * `_CREATEMODE_BINARY`: create a regular file; * `_CREATEMODE_DIRECTORY`: create a directory. */ @@ -66,10 +71,8 @@ enum _CREATEMODE { _CREATEMODE_BINARY = 0x01, _CREATEMODE_DIRECTORY = 0x05 }; -/* ************************************************************************* */ -/* Storage device */ -/* ************************************************************************* */ -/* Here are the different storage devices you can interact with. + +/* This enumration defines the different storage devices you can interact with. * Known devices are: * * `DEVICE_MAIN_MEMORY`: the main memory (up to 64 KiB, for light data); @@ -81,11 +84,9 @@ enum DEVICE_TYPE { DEVICE_STORAGE = 0x01, DEVICE_SD_CARD = 0x02 }; -/* ************************************************************************* */ -/* File information */ -/* ************************************************************************* */ -/* This is mainly used for file listing. - * Here are the entry types: + +/* This structure contains file information, and is mainly used for listing + * files. Here are the entry types: * * `DT_DIRECTORY`: directory; * `DT_FILE`: regular file; @@ -111,21 +112,27 @@ enum DEVICE_TYPE { #define DT_DOTDOT 0x0009 #define DT_VOLUME 0x000A -struct tag_FILE_INFO { - unsigned short id; /* index in the type index */ - unsigned short type; /* index number, see the `DT_*` constants */ - unsigned long fsize; /* filesize (in bytes) */ - unsigned long dsize; /* datasize (without file header) */ - unsigned long property; /* file not completed, except when - * property is 0 */ +/* The `FILE_INFO` structure is the equivalent of `struct dirent`: information + * about a directory entry. It contains the following properties: + * + * - `id`: index of the file; + * - `type`: index type, see the `DT_*` constants; + * - `fsize`: file size (in bytes); + * - `dsize`: datasize (without file header, for interpreted files); + * - `property`: file not completed, except when property is equal to zero; + * - `address`: the address of the first file part (do not use). + * */ + +typedef struct tag_FILE_INFO { + unsigned short id; + unsigned short type; + unsigned long fsize; + unsigned long dsize; + unsigned long property; unsigned long address; -}; +} FILE_INFO; -typedef struct tag_FILE_INFO FILE_INFO; -/* ************************************************************************* */ -/* Errors from the file interface */ -/* ************************************************************************* */ -/* Here are the errors you can have from the file interface. +/* The FX library file interface uses its own errors. * Known errors are: * * `IML_FILEERR_NOERROR`: everything went great; @@ -144,7 +151,7 @@ typedef struct tag_FILE_INFO FILE_INFO; * * Notice that `IML_FILEERR_NOTRECORDFILE`, `IML_FILEERR_DEVICENOTEXIST`, * `IML_FILEERR_ENDOFFILE` and `IML_FILEERR_NOTDUALRECORDFILE` - * are commented in the original header. */ + * are commented out in the original header. */ #define IML_FILEERR_NOERROR 0 #define IML_FILEERR_ENTRYNOTFOUND -1 @@ -191,7 +198,10 @@ typedef struct tag_FILE_INFO FILE_INFO; #define IML_FILEERR_COPYPROTECTION -42 #define IML_FILEERR_ILLEGALFILEDATA -43 -/* corrections (from fxlib) */ -# define IML_FILEERR_ACCESSDENYED IML_FILEERR_ACCESSDENIED +/* Developers at CASIO Japan made a few typos in the original fxlib. + * This module corrects them, while staying compatible by defining the + * wrong macros. */ + +# define IML_FILEERR_ACCESSDENYED IML_FILEERR_ACCESSDENIED -__END_NAMESPACE_FXLIB +_END_NAMESPACE_FXLIB diff --git a/arch/casiowin/fxlib/include/fxlib.h b/arch/casiowin/fxlib/include/fxlib.h index 6854a7c..1995f30 100644 --- a/arch/casiowin/fxlib/include/fxlib.h +++ b/arch/casiowin/fxlib/include/fxlib.h @@ -31,7 +31,9 @@ #include <fxlib/cdefs.h> #include <stdlib.h> -/* All of the subheaders */ +/* This header, on the contrary to the original one, is divided into + * several thematic subheaders, which are all included here. */ + #include <fxlib/app.h> #include <fxlib/battery.h> #include <fxlib/bcd.h> @@ -43,15 +45,20 @@ #include <fxlib/serial.h> #include <fxlib/timer.h> -/* `SetQuitHandler` function */ -__BEGIN_NAMESPACE_FXLIB -__BEGIN_DECLS +/* One function that could not exactly fit in one or the other category + * is defined here. `SetQuitHandler()` is used to set a quit callback + * when the add-in is "killed" by the menu. + * + * On the contrary to `atexit()` used in Unix-like systems, it sets the + * callback instead of just adding one, so be careful on how you use it! */ + +_BEGIN_NAMESPACE_FXLIB +_BEGIN_DECLS -/* Set the exit handler */ typedef void __quithandler_t _OF((void)); _EXTERN void SetQuitHandler _OF((__quithandler_t *__callback)) _THROW; -__END_DECLS -__END_NAMESPACE_FXLIB +_END_DECLS +_END_NAMESPACE_FXLIB diff --git a/arch/casiowin/fxlib/include/fxlib/app.h b/arch/casiowin/fxlib/include/fxlib/app.h index 441fa44..a3990ac 100644 --- a/arch/casiowin/fxlib/include/fxlib/app.h +++ b/arch/casiowin/fxlib/include/fxlib/app.h @@ -48,10 +48,10 @@ typedef struct { /* Address of the queried e-strip icon in storage memory */ void *estrip_icon_location; } addin_estrip_info_t; -/* ************************************************************************* */ -/* Manipulating the index */ -/* ************************************************************************* */ -/* WARNING: these syscalls are dangerous, you shouldn't use them. */ + +/* Manipulate the index. + * WARNING: if you're using an add-in instead of a built-in application, + * you may prefer not to use these. */ _EXTERN int App_RegisterAddins _OF((void)) _THROW; @@ -63,10 +63,10 @@ _EXTERN _NONNULL(3, __result) int App_GetAddinEstripInformation _OF((int __id, int __eid, addin_estrip_info_t *__result)) _THROW; _EXTERN int App_BuiltInCount _OF((void)) _THROW; -/* ************************************************************************* */ -/* Run system apps */ -/* ************************************************************************* */ -/* In general, _R4 = 0 and _R5 = 0 is advised. */ + +/* Run system apps. + * In general, _R4 = 0 and _R5 = 0 is advised. */ + # define _FXAPP(_NAME) \ _EXTERN int App_##NAME \ _OF((int __R4, int __R5)) _THROW; diff --git a/arch/casiowin/fxlib/include/fxlib/battery.h b/arch/casiowin/fxlib/include/fxlib/battery.h index 29dfe2e..b299999 100644 --- a/arch/casiowin/fxlib/include/fxlib/battery.h +++ b/arch/casiowin/fxlib/include/fxlib/battery.h @@ -33,19 +33,22 @@ __BEGIN_NAMESPACE_FXLIB __BEGIN_DECLS -/* ************************************************************************* */ -/* Get the battery status */ -/* ************************************************************************* */ -/* Returned values */ -# define battery_level_3 0x000 /* voltage OK */ -# define battery_level_2 0x001 /* below level one */ -# define battery_level_1 0x002 /* below level two */ -# define battery_level_OS103_2 0x17F /* OS 1.03 equ. of battery_level_2 */ -# define battery_level_OS103_1 0x16D /* OS 1.03 equ. of battery_level_1 */ +/* Get the battery status. + * If you want to have a delay before accessing the AD converter for more + * precision, use the `battery_flag_delay` delay. + * + * Level 3 is full battery, level 2 is the level below one, and + * level 1 is below level two (lowest level). + * OS 1.03 returns other (raw) values than the later OS for the + * battery status. */ + +# define battery_level_3 0x000 +# define battery_level_2 0x001 +# define battery_level_1 0x002 +# define battery_level_OS103_2 0x17F +# define battery_level_OS103_1 0x16D -/* Flags */ -# define battery_flag_delay 0x0001 /* perform delay before accessing the - * AD converter */ +# define battery_flag_delay 0x0001 /* Get the status */ extern int Battery_IsLow_Delay _OF((int __flags)) __THROW; diff --git a/arch/casiowin/fxlib/include/keybios.h b/arch/casiowin/fxlib/include/keybios.h index 87ec2f3..a85f7bb 100644 --- a/arch/casiowin/fxlib/include/keybios.h +++ b/arch/casiowin/fxlib/include/keybios.h @@ -29,11 +29,22 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <fxlib/cdefs.h> -__BEGIN_NAMESPACE_FXLIB +_BEGIN_NAMESPACE_FXLIB + +/* The FX library distinguishes two type of keys: + * - Character keys, that produce characters (such as '0'); + * - Control keys. + * + * When calling `Getkey()`, you are supposed to check its return code. + * If it returns 0, then the key is one of the `KEY_CTRL_*` codes. + * Otherwise, the key is one of the `KEY_CHAR_*` codes. + * + * Fortunately, where the used ranges could have overlapped, they don't, + * so you're actually not obliged to use this return value to switch on + * the gathered key. + * + * Here are the character codes. */ -/* ************************************************************************* */ -/* Character codes */ -/* ************************************************************************* */ #define KEY_CHAR_0 0x30 #define KEY_CHAR_1 0x31 #define KEY_CHAR_2 0x32 @@ -114,9 +125,9 @@ __BEGIN_NAMESPACE_FXLIB #define KEY_CHAR_X 0x58 #define KEY_CHAR_Y 0x59 #define KEY_CHAR_Z 0x5a -/* ************************************************************************* */ -/* Control codes */ -/* ************************************************************************* */ + +/* Here are the control codes. */ + #define KEY_CTRL_NOP 0 #define KEY_CTRL_EXE 30004 #define KEY_CTRL_DEL 30025 @@ -155,4 +166,4 @@ __BEGIN_NAMESPACE_FXLIB #define KEY_CTRL_RESERVE2 30061 #define KEY_CTRL_RESERVE3 30062 -__END_NAMESPACE_FXLIB +_END_NAMESPACE_FXLIB diff --git a/arch/casiowin/fxlib/include/timer.h b/arch/casiowin/fxlib/include/timer.h index 3bf7a66..2b0af06 100644 --- a/arch/casiowin/fxlib/include/timer.h +++ b/arch/casiowin/fxlib/include/timer.h @@ -29,15 +29,15 @@ * the CeCILL-C license and that you accept its terms. * ************************************************************************* */ #include <fxlib/cdefs.h> -__BEGIN_NAMESPACE_FXLIB +_BEGIN_NAMESPACE_FXLIB + +/* The FX library defines five virtual timers that you can use to make + * threaded-like processes. Read the documentation for more information. */ -/* ************************************************************************* */ -/* User timers IDs */ -/* ************************************************************************* */ #define ID_USER_TIMER1 1 #define ID_USER_TIMER2 2 #define ID_USER_TIMER3 3 #define ID_USER_TIMER4 4 #define ID_USER_TIMER5 5 -__END_NAMESPACE_FXLIB +_END_NAMESPACE_FXLIB diff --git a/docs/all/mem/index.en.md b/docs/all/mem/index.en.md index 45051d5..9b190b8 100644 --- a/docs/all/mem/index.en.md +++ b/docs/all/mem/index.en.md @@ -1,6 +1,53 @@ --- title: Standard memory management. +chapters: +- tweaking --- -This module manages the standard memory management. +This module manages the standard memory management interface, while adding +settings to interact with it. +# Static memory allocation The `alloca.h` header bit should provide the `alloca(size)` macro. +If this macro fails, the whole program stops (producing a stack overflow, +or segmentation fault). + +Memory allocated this way is free'd automatically at the end of the function +calling it. Reentrant functions shall not use this macro to allocate memory +for parent functions. + +# Dynamic memory allocation +This module provides the standard memory allocation interface. To allocate +memory, any of the following functions can be used: + +{% highlight c linenos %} +void *malloc(size_t size); +void *calloc(size_t nmemb, size_t size); +{% endhighlight %} + +`malloc()` is the generic function for allocating memory, and +`calloc()` takes the number of elements, `nmemb`, and the size of each +element, `size`. + +The returned pointer is either `NULL` if the memory allocation has failed, +or a pointer, serving both as an identifier for the allocated memory area, +and as the lower address of the memory area for further usage. + +Once the allocated memory area is no longer used, you shall free the memory +area by using the following function: + +{% highlight c linenos %} +void free(void *ptr); +{% endhighlight %} + +You are supposed to pass the memory area identifier, i.e. the lowest memory +address, to `free()`, and **not** “any pointer in the area”. + +To re-allocate memory, i.e. extending or reducing an existing memory area, +use the `realloc()` function defined below: + +{% highlight c linenos %} +void *realloc(void *ptr, size_t size); +{% endhighlight %} + +Notice that the pointer will very likely change, so please update your +pointer using the return value from `realloc()`. diff --git a/docs/all/mem/tweaking.en.md b/docs/all/mem/tweaking.en.md new file mode 100644 index 0000000..10aff32 --- /dev/null +++ b/docs/all/mem/tweaking.en.md @@ -0,0 +1,32 @@ +--- +title: Tweaking the libcarrot memory allocation +--- +The memory allocation module is a very lite and basic module, and uses hooks +to actually do something. These hooks are inspired from the GNU C library, +and this document is a description of them. + +# malloc() related hooks +To initialize + +{% highlight c linenos %} +typedef void __malloc_initialize_hook_t(void); + +__malloc_initialize_hook_t __malloc_initialize_hook; +{% endhighlight %} + +Once the malloc implementation is initialized, these callbacks + +{% highlight c linenos %} +typedef void *__malloc_hook_t(size_t size, const void *caller); +typedef void *__realloc_hook_t(void *ptr, size_t size, const void *caller); +typedef void *__memalign_hook_t(size_t alignment, size_t size, + const void *caller); +typedef void *__free_hook_t(void *ptr, const void *caller); + +__malloc_hook_t __malloc_hook; +__realloc_hook_t __realloc_hook; +__memalign_hook_t __memalign_hook; +__free_hook_t __free_hook; +{% endhighlight %} + + diff --git a/docs/all/string/index.en.md b/docs/all/string/index.en.md new file mode 100644 index 0000000..7bca20b --- /dev/null +++ b/docs/all/string/index.en.md @@ -0,0 +1,24 @@ +--- +title: Memory interactions +chapters: +- memory +- strings +--- +This module brings functions to manipulate strings. It brings a really +basic and non-optimized but widely supported version of it — optimized +versions of it exist for a few architectures. + +As a complement to standard functions defined in `<string.h>`, it adds the +BSD-compliant string functions. This is only added for compatibility, please +use the standard C functions for portability. + +There are two different type of memory arrangements managed here, tied to +the way the memory area length is given: + +- raw memory: the length of the area is given aside; +- string: the length of the area is determined by a particular ending + byte/character, usually `\0`. + +Why use this module instead of implementing your own functions? Well, these +functions are usually optimized for your platform, whatever your C library +is (libcarrot, the GNU libc, ...). diff --git a/docs/all/string/memory.en.md b/docs/all/string/memory.en.md new file mode 100644 index 0000000..11e23ce --- /dev/null +++ b/docs/all/string/memory.en.md @@ -0,0 +1,63 @@ +--- +title: Raw memory utilities +--- +A few functions are thought for raw and uninterpreted memory, where the length +of the area(s) to interact with is/are given aside. This is a reference of +these. + +The size of the memory areas is usually required using a `size_t` parameter. + +# Initialize a memory area +To initialize the content of a memory area with the value of a character, +use the following standard function: + +{% highlight c linenos %} +void *memset(void *s, int c, size_t n); +{% endhighlight %} + +Where `c` is the value to set to each byte in the area, and therefore should +fit in a byte (usually 0 to 255). + +# Copy memory +There are two standard functions for copying raw memory: + +{% highlight c linenos %} +void *memcpy(void *dst, const void *src, size_t n); +void *memmove(void *dst, const void *src, size_t n); +{% endhighlight %} + +`memcpy()` will always copy from the lower address (`src`) to the higher +one (`src + n`), whereas `memmove()` will adapt the way it is copying, +in case the memory areas are overlapping. + +If you ought to copy until a certain character is encountered, you can +use the following function: + +{% highlight c linenos %} +void *memccpy(void *dst, const void *src, int c, size_t n); +{% endhighlight %} + +Where `c` is the ending byte value, which can be stored in a byte. + +# Compare memory areas +You may want to compare the content of two memory areas, usually to check +if they are the same. The following function does this: + +{% highlight c linenos %} +int memcmp(const void *s, const void *t, size_t n); +{% endhighlight %} + +The returned value is either zero if no difference has been found between +the two memory areas, or the difference between the values (first minus second) +of the bytes in the first position where the areas differ. + +# Find a character in a memory area +To find the first position of a character in a memory area, use the +following function: + +{% highlight c linenos %} +void *memchr(const void *s, int c, size_t n); +{% endhighlight %} + +This function returns the pointer to the first occurrence of this value in +the memory area, or `NULL` if the character has not been found. diff --git a/docs/all/string/strings.en.md b/docs/all/string/strings.en.md new file mode 100644 index 0000000..7ebcf35 --- /dev/null +++ b/docs/all/string/strings.en.md @@ -0,0 +1,94 @@ +--- +title: Strings utilities +--- +A string usually represents a character string terminated by the ASCII NUL +character (code zero), usually represented as `\0`. + +# Calculate the string length +As the length is not given aside the string, you have to calculate it by +finding the NUL character, by using this function: + +{% highlight c linenos %} +size_t strlen(const char *s); +{% endhighlight %} + +# Copy a string into another +To copy the content of a string into another, including the NUL byte, you +can use the following function: + +{% highlight c linenos %} +char *strcpy(char *dst, const char *src); +{% endhighlight %} + +The destination buffer has to be big enough. + +# Concatenate strings +To copy a string at the end of another, you can use the following two +functions: + +{% highlight c linenos %} +char *strcat(char *dst, const char *src); +char *strncat(char *dst, const char *src, size_t n); +{% endhighlight %} + +The NUL byte at the end of the initial string is overwritten, and a NUL +byte is always added at the end of the destination with the additional string +appended. + +`strncat()` will take an additional information about the source string: its +maximum length. If there is no NUL character within the `n` first characters +of the source string, the `n` first characters of the source string will be +copied. + +# Compare strings +To check if strings are equivalent, use one of the following functions: + +{% highlight c linenos %} +int strcmp(const char *s, const char *t); +int strncmp(const char *s, const char *t, size_t n); +{% endhighlight %} + +This function returns zero if the strings are equal, or the difference between +the first and second character at the first position where the strings differ. + +# Search a string for one or more characters +To look for a character in a string, you can use one of the following +functions: + +{% highlight c linenos %} +char *strchr(const char *s, int c); +char *strrchr(const char *s, int c); +{% endhighlight %} + +`strchr()` searches the string from lower to upper, and `strrchr()` searches +the string from upper to lower. It returns the address if it finds the +character, or `NULL` if it doesn't. + +To look for more than one character, you can use this function instead: + +{% highlight c linenos %} +char *strpbrk(const char *s, const char *accept); +{% endhighlight %} + +This function searches the string from lower to upper, returns the address +if it finds one of the characters in `accept` (excluding the NUL character), +or `NULL` if none of the characters were found. + +# Search a string for another string +To look for a string in another string, you can use the following function: + +{% highlight c linenos %} +char *strstr(const char *haystack, const char *needle); +{% endhighlight %} + +This function returns `NULL` if `needle` has not been found in `haystack`, or +a pointer to the first found occurrence of `needle` in `haystack`. + +# Calculate the length of a prefix +To calculate the length of a prefix, made of a set of characters (or everything +but a set of characters), in a string, you can use the following functions: + +{% highlight c linenos %} +size_t strspn(const char *s, const char *accept); +size_t strcspn(const char *s, const char *reject); +{% endhighlight %} diff --git a/docs/casiowin/fxlib/file.en.md b/docs/casiowin/fxlib/file.en.md index e46bded..8ffacd9 100644 --- a/docs/casiowin/fxlib/file.en.md +++ b/docs/casiowin/fxlib/file.en.md @@ -11,7 +11,7 @@ fixed-width FONTCHARACTER encoding. Paths are usually something like `\\dev0\folder\filename.ext`. Known devices are `fls0` (flash memory, up to 1.5 MiB when it's there), and `crd0` (memory card, up to 2 GiB). The system doesn't support deeper than one -folder down (so there cannot be any `\\dev0\folder0\folder1\filename.ext`). +folder down (so `\\dev0\folder0\folder1\filename.ext` is an invalid path here). The Bfile interface also supports a very odd filesystem, which is the Main Memory (also named 'MCS' by the community). From your add-in's point of diff --git a/docs/contributing.en.md b/docs/contributing.en.md index 341bf46..1521e18 100644 --- a/docs/contributing.en.md +++ b/docs/contributing.en.md @@ -49,6 +49,7 @@ Modules have the following organization ("opt." means "optional", "req." means - `bits/` (opt.): the C/C++ header bits folder; - `src/` (opt.): the C/C++/ASM source files; - `docs/` (opt.): a symbolic link to the corresponding documentation; +- `man/` (opt.): the manpages corresponding to the module; - `info.yml` (req.): the module information file; - `copyright.yml` (rec.): machine-readable copyright information file; - `roles.yml` (rec.): machine-readable roles for your source files. diff --git a/docs/tools/build-tools.en.md b/docs/tools/build-tools.en.md index 5eb343a..979b85d 100644 --- a/docs/tools/build-tools.en.md +++ b/docs/tools/build-tools.en.md @@ -51,7 +51,8 @@ All of the methods take these four first arguments: - `arch`: the architecture for which to build, generally a sub-architecture; - `endian`: the endianness of the architecture for which to build, useful when it is bi-endian; -- `system`: the OS/ABI for which to build; +- `system`: the system for which to build; +- `abi`: the system ABI against which to build; - `flavour`: the category for the development files formats. All of these are strings. @@ -59,7 +60,8 @@ All of these are strings. ## C Compiler libcarrot requires a C compiler to produce an object out of a C source file, and a few include directories, for a given C standard. Higher and -retrocompatible standards (C11) will be tried before the older ones (C99, C89). +entirely retrocompatible standards (C11) will be tried before the older +ones (C99, C89). The `conf_cc` method will be called to configure the C compiler. It should be defined this way: @@ -167,7 +169,7 @@ The `conf_link` method will be called to configure the shared/dynamic library. It should be defined this way: {% highlight python linenos %} -def <conf_link>(arch, endian, system, flavour) +def <conf_link>(arch, endian, system, flavour, abi) {% endhighlight %} As for the other functions, the configuration function will generate a set @@ -190,7 +192,7 @@ The `conf_bin` method will be called to configure the binary executable maker. It should be defined this way: {% highlight python linenos %} -def <conf_bin>(arch, endian, system, flavour) +def <conf_bin>(arch, endian, system, flavour, abi) {% endhighlight %} As for the other functions, the configuration function will generate a set diff --git a/tools/Internals/build/__init__.py b/tools/Internals/build/__init__.py index f001892..373b690 100755 --- a/tools/Internals/build/__init__.py +++ b/tools/Internals/build/__init__.py @@ -15,16 +15,16 @@ from .renesas_shc import * from .renesas_asmsh import * from .renesas_optlnk import * -__tools = { +_tools = { ('GNU', 'GCC'): GNU_GCC, ('GNU', 'as'): GNU_AS, ('GNU', 'ar'): GNU_AR, # ('LLVM', 'Clang'): LLVM_Clang, - ('Renesas', 'SHC'): Renesas_SHC, +# ('Renesas', 'SHC'): Renesas_SHC, # ('Hitachi', 'SHC'): Renesas_SHC, - ('Renesas', 'Asmsh'): Renesas_Asmsh, +# ('Renesas', 'Asmsh'): Renesas_Asmsh, # ('Hitachi', 'Asmsh'): Renesas_Asmsh, - ('Renesas', 'Optlnk'): Renesas_OptLnk, +# ('Renesas', 'Optlnk'): Renesas_OptLnk, # ('Hitachi', 'Optlnk'): Renesas_OptLnk, # ('Intel', 'ICC'): Intel_ICC, # ('IBM', 'XL C/C++'): IBM_XLC, @@ -36,17 +36,13 @@ __tools = { #*****************************************************************************# # Find the utilities # #*****************************************************************************# -def _find_cc(arch, endian, system, out_format): - """ Find a C compiler. - `arch` is the ISA, e.g. "sh3". - `endian` is the endianness. - `system` is the system, e.g. "linux". - `out_format` is the output object format, e.g. "elf". """ - - for cc in __tools: - try: gp = __tools[cc]['conf_cc'] +def _find_cc(arch, endian, system, flavour, standard): + """ Find a C compiler. """ + + for cc in _tools: + try: gp = _tools[cc]['conf_cc'] except: continue - try: cp = gp(arch, endian, 'elf', ['c89']) + try: cp = gp(arch, endian, system, flavour, standard) except ToolNotFoundException: continue @@ -54,17 +50,13 @@ def _find_cc(arch, endian, system, out_format): Raise(NoCCompilerException) -def _find_cxx(arch, endian, system, out_format): - """ Find a C++ compiler. - `arch` is the ISA, e.g. "sh3". - `endian` is the endianness. - `system` is the system, e.g. "linux". - `out_format` is the output object format, e.g. "elf". """ +def _find_cxx(arch, endian, system, flavour, standard): + """ Find a C++ compiler. """ - for cxx in __tools: - try: gp = __tools[cxx]['conf_cxx'] + for cxx in _tools: + try: gp = _tools[cxx]['conf_cxx'] except: continue - try: cxxp = gp(arch, endian, 'elf', ['c++98']) + try: cxxp = gp(arch, endian, system, flavour, standard) except ToolNotFoundException: continue @@ -72,65 +64,67 @@ def _find_cxx(arch, endian, system, out_format): Raise(NoCppCompilerException) -def _find_asmc(arch, endian, system, out_format): - """ Find a C assembler (assembler with C preprocessor). - `arch` is the ISA, e.g. "sh3". - `endian` is the endianness. - `system` is the system, e.g. "linux". - `out_format` is the output object format, e.g. "elf". """ +def _find_asm(arch, endian, system, flavour, syntax): + """ Find an assembler. """ - for asmc in __tools: - try: gp = __tools[asmc]['conf_asmc'] + for asm in _tools: + try: gp = _tools[asm]['conf_asm'] except: continue - try: asmcp = gp(arch, endian, 'elf') + try: asmp = gp(arch, endian, 'elf', 'gnu') except ToolNotFoundException: continue - return (asmc, asmcp) + return (asm, asmp) - Raise(NoCAssemblerException) + Raise(NoAssemblerException) -def _find_asm(arch, endian, system, out_format): - """ Find an assembler. - `arch` is the ISA, e.g. "sh3". - `endian` is the endianness. - `system` is the system, e.g. "linux". - `out_format` is the output object format, e.g. "elf". """ +def _find_pack(arch, endian, system, flavour): + """ Find a packer. """ - for asm in __tools: - try: gp = __tools[asm]['conf_asm'] + for pack in _tools: + try: gp = _tools[pack]['conf_pack'] except: continue - try: asmp = gp(arch, endian, 'elf', 'gnu') + try: packp = gp(arch, endian, system, flavour) except ToolNotFoundException: continue - return (asm, asmp) + return (pack, packp) - Raise(NoAssemblerException) + Raise(NoPackerException) -def _find_pack(arch, endian, system, out_format): - """ Find a packer. - `arch` is the ISA, e.g. "sh3". - `endian` is the endianness. - `system` is the system, e.g. "linux". - `out_format` is the output library format, e.g. "coff". """ +def _find_link(arch, endian, system, flavour, abi): + """ Find a dynamic library generator. """ - for pack in __tools: - try: gp = __tools[pack]['conf_pack'] + for link in _tools: + try: gp = _tools[link]['conf_link'] except: continue - try: packp = gp(arch, endian, 'coff', 'elf') + try: linkp = gp(arch, endian, system, flavour, abi) except ToolNotFoundException: continue - return (pack, packp) + return (link, linkp) - Raise(NoPackerException) + Raise(NoLinkException) + +def _find_bin(arch, endian, system, flavour, abi): + """ Find a binary executable generator. """ + + for bing in _tools: + try: gp = _tools[bing]['conf_bin'] + except: continue + try: binp = gp(arch, endian, system, flavour, abi) + except ToolNotFoundException: + continue + + return (bing, binp) + + Raise(NoBinException) #*****************************************************************************# # Interact with the tools before using them. # #*****************************************************************************# # The tools. -__tools = {} +_current_tools = {} __compiler = '(none)' # Find tools. @@ -138,21 +132,23 @@ def find(languages, arch, endian, system, abi, flavour): ids, params = {}, {} ids['cc'], params['cc'] = \ - _find_cc(arch, endian, system, flavour) - ids['cxx'], params['cxx'] = \ - _find_cxx(arch, endian, system, flavour) - ids['asmc'], params['asmc'] = \ - _find_asmc(arch, endian, system, flavour) + _find_cc(arch, endian, system, flavour, 'c89') +# ids['cxx'], params['cxx'] = \ +# _find_cxx(arch, endian, system, flavour, 'c++98') ids['asm'], params['asm'] = \ - _find_asm(arch, endian, system, flavour) + _find_asm(arch, endian, system, flavour, 'gnu') ids['pack'], params['pack'] = \ _find_pack(arch, endian, system, flavour) +# ids['link'], params['link'] = \ +# _find_link(arch, endian, system, flavour, abi) +# ids['bin'], params['bin'] = \ +# _find_bin(arch, endian, system, flavour, abi) - return fn + return {'ids': ids, 'params': params} # Setup the tools. def setup(data): - global __tools, __compiler + global _current_tools, __compiler ids = data['ids'] params = data['params'] @@ -160,28 +156,39 @@ def setup(data): # Get the C compiler. if 'cc' in ids: cc, cp = ids['cc'], params['cc'] - __tools['cc'] = ft.partial(__tools[cc]['cc'], cp) + _current_tools['cc'] = \ + ft.partial(_current_tools[cc]['cc'], cp) __compiler = ids['cc'] # Get the C++ compiler. if 'cxx' in idsd: cxx, cxxp = ids['cxx'], params['cxx'] - __tools['cxx'] = ft.partial(__tools[cxx]['cxx'], cxxp) + _current_tools['cxx'] = \ + ft.partial(_current_tools[cxx]['cxx'], cxxp) # Get the assembler. if 'asm' in ids: asm, asmp = ids['asm'], params['asm'] - __tools['asm'] = ft.partial(__tools[asm]['asm'], asmp) - - # Get the C-Assembly compiler. - if 'asmc' in ids: - asmc, asmcp = ids['asmc'], params['asmc'] - __tools['asmc'] = ft.partial(__tools[asmc]['asmc'], asmcp) + _current_tools['asm'] = \ + ft.partial(_current_tools[asm]['asm'], asmp) # Get the packer. if 'pack' in ids: pack, packp = ids['pack'], params['pack'] - __tools['pack'] = ft.partial(__tools[pack]['pack'], packp) + _current_tools['pack'] = \ + ft.partial(_current_tools[pack]['pack'], packp) + + # Get the linker. + if 'link' in ids: + link, linkp = ids['link'], params['link'] + _current_tools['link'] = \ + ft.partial(_current_tools[link]['link'], linkp) + + # Get the binary executable generator. + if 'bin' in ids: + bing, binp = ids['bin'], params['bin'] + _current_tools['bin'] = \ + ft.partial(_current_tools[bing]['bin'], binp) # Get an information. def get(key): @@ -198,7 +205,6 @@ def get(key): 'cc_ext': ['c', 'CC'], 'cxx_ext': cpp_ext, 'cpp_ext': cpp_ext, - 'asmc_ext': ['sx', 'SX'], 'asm_ext': ['s', 'S'], }[key] #*****************************************************************************# @@ -206,37 +212,30 @@ def get(key): #*****************************************************************************# # Compile C things. def cc(obj, src, incdirs=[], std='c89'): - if not 'cc' in __tools: + if not 'cc' in _current_tools: print("No C compiler has been setup!") - exit(1) - return __tools['cc'](obj, src, incdirs, std) + Raise(SilentException) + return _current_tools['cc'](obj, src, incdirs, std) # Compile C++ things. def cxx(obj, src, incdirs=[], std='c++98'): - if not 'cxx' in __tools: + if not 'cxx' in _current_tools: print("No C++ compiler has been setup!") - exit(1) - return __tools['cxx'](obj, src, indirs, std) - -# Compile ASM-C things. -def asmc(obj, src, incdirs=[]): - if not 'asmc' in __tools: - print("No ASM-C compiler has been setup!") - exit(1) - return __tools['asmc'](obj, src, incdirs) + Raise(SilentException) + return _current_tools['cxx'](obj, src, indirs, std) # Compile ASM things. def asm(obj, src): - if not 'asm' in __tools: + if not 'asm' in _current_tools: print("No assembler has been setup!") - exit(1) - return __tools['asm'](obj, src) + Raise(SilentException) + return _current_tools['asm'](obj, src) # Pack things up into a library. def pack(lib, objs): - if not 'pack' in __tools: + if not 'pack' in _current_tools: print("No packer has been setup!") - exit(1) - return __tools['pack'](lib, objs) + Raise(SilentException) + return _current_tools['pack'](lib, objs) # End of file. diff --git a/tools/Internals/build/gnu_ar.py b/tools/Internals/build/gnu_ar.py index 5105081..f36547b 100755 --- a/tools/Internals/build/gnu_ar.py +++ b/tools/Internals/build/gnu_ar.py @@ -20,15 +20,17 @@ from .utils import * __all__ = ["GNU_AR"] -#*****************************************************************************# -# Discovery, configuration # -#*****************************************************************************# +# --- +# Discovery, configuration. +# --- + def __get_ar_targets(path): """ Get the supported targets (flavours) out of the ar binary path. """ # Make the help command with the default locale, get the output. env = os.environ.copy() - env['LANG'] = 'en_US' + try: del env['LANG'] + except KeyError: pass out = check_output([path, '--help'], env=env).decode() # Get the appropriate line. @@ -46,15 +48,7 @@ def __get_ar_targets(path): targets.append((t[0], '_'.join(t[1:]))) return targets -def __iter_ar(arch): - """ Iterate through all of the `ar` occurrences among the system. """ - - for elt in getgnu(arch, 'ar'): - yield elt - for elt in getutil(['ar', 'ar.exe']): - yield elt - -def _configure(arch, endian, lib_format, obj_format): +def _configure(arch, endian, system, flavour): ''' Get the params. ''' if obj_format[:3] != 'elf': @@ -62,7 +56,7 @@ def _configure(arch, endian, lib_format, obj_format): # Get the utility path = None - for gar in __iter_ar(arch): + for gar in getgnu(arch, endian, system, flavour, 'ar'): bfd_list = __get_ar_targets(gar) for bfd in bfd_list: @@ -80,9 +74,11 @@ def _configure(arch, endian, lib_format, obj_format): Raise(ToolNotFoundException) return {'path': path} -#*****************************************************************************# -# Usage # -#*****************************************************************************# + +# --- +# Usage. +# --- + def _pack(params, lib, objs): """ Pack using the GNU archiver. """ @@ -103,9 +99,10 @@ def _pack(params, lib, objs): os.remove(tmp_path) return ret -#*****************************************************************************# -# Main utility descriptor # -#*****************************************************************************# +# --- +# Main utility descriptor. +# --- + GNU_AR = { 'conf_pack': _configure, 'pack': _pack diff --git a/tools/Internals/build/gnu_as.py b/tools/Internals/build/gnu_as.py index 391d467..6abaebb 100755 --- a/tools/Internals/build/gnu_as.py +++ b/tools/Internals/build/gnu_as.py @@ -19,15 +19,17 @@ from .utils import * __all__ = ["GNU_AS"] -#*****************************************************************************# -# Discovery, configuration # -#*****************************************************************************# +# --- +# Discovery, configuration. +# --- + def __get_as_bfd(path): """ Get the BFD target out of the as binary path. """ # Make the version command with the default locale, get the output. env = os.environ.copy() - env['LANG'] = 'en_US' + try: del env['LANG'] + except KeyError: pass out = check_output([path, '--version'], env=env).decode() # Get the BFD target, which is on the last line, e.g. diff --git a/tools/Internals/build/gnu_gcc.py b/tools/Internals/build/gnu_gcc.py index 95f0cc0..487f014 100755 --- a/tools/Internals/build/gnu_gcc.py +++ b/tools/Internals/build/gnu_gcc.py @@ -28,20 +28,13 @@ def __get_gcc_bfd(path): # Make the dump command with the default locale, get the output. env = os.environ.copy() - env['LANG'] = 'en_US' + try: del env['LANG'] + except KeyError: pass out = check_output([path, '-dumpmachine'], env=env).decode() return out.strip() -def __iter_gcc(arch): - """ Iterate through all of the `gcc` occurrences among the system. """ - - for elt in getgnu(arch, 'gcc'): - yield elt - for elt in getutil(['gcc', 'gcc.exe']): - yield elt - -def __testcc(typ, path='/usr/bin/gcc', flags=[], +def __testcc(typ, path, flags=[], text='int main(void) { return (0); }'): """ Try to compile, see if it works. """ @@ -51,9 +44,6 @@ def __testcc(typ, path='/usr/bin/gcc', flags=[], elif typ == "cxx": source_suffix = '.cpp' gcc_lang = 'c++' - elif typ == "asmc": - source_suffix = '.sx' - gcc_lang = 'assembler-with-cpp' sfd, sf = mkstemp(suffix=source_suffix, text=text) os.close(sfd) @@ -61,7 +51,8 @@ def __testcc(typ, path='/usr/bin/gcc', flags=[], ofd, of = mkstemp(suffix='.o') os.close(ofd) - cl = [path, '-x', gcc_lang, '-o', of, sf, '-nostdlib'] + flags + cl = [path, '-x', gcc_lang, '-c', '-o', of, sf] \ + + flags + ['-nostdlib', '-ffreestanding'] if call(cl, shell=False, stdout=DEVNULL, stderr=DEVNULL): worked = False else: @@ -74,15 +65,12 @@ def __testcc(typ, path='/usr/bin/gcc', flags=[], return worked -def __teststd(typ, path, standards): +def __teststd(typ, path, standard): ''' Test if GCC supports those standards using the `-std` option. ''' - for s in standards: - if not __testcc(typ, path, ['-std=%s'%s]): - return False - return True + return __testcc(typ, path, ['-std={}'.format(standard)]) -def _configure(typ, arch, endian, objfmt, std=[]): +def _configure(typ, arch, endian, system, flavour, standard): """ Get the GNU Compiler Collection respecting some pre-defined constraints. """ @@ -94,19 +82,23 @@ def _configure(typ, arch, endian, objfmt, std=[]): if arch[-3:] == 'dsp': cflags.append('-Wa,-dsp') arch = arch[:-3] - cflags += ['-m%s'%arch[2:], '-mb'] + cflags += ['-m%s'%arch[2:], '-m' + 'bl'[endian == 'little']] else: # FIXME: is it like this for everything? raise exception here? cflags.append('-march=%s'%arch) + # Get the BFD object. + bfd = prepare_bfd(arch, endian, system, flavour) + # Get the utility. path = None - for gcc in __iter_gcc(arch): - if not bfd_are_equivalent(__get_gcc_bfd(gcc), arch, 'big', objfmt): + for gcc in getgnu('gcc', bfd): + found_target = __get_gcc_bfd(gcc) + if not check_bfd(bfd, found_target): continue if not __testcc(typ, gcc, cflags): continue - if typ != "asmc" and not __teststd(typ, gcc, std): + if not __teststd(typ, gcc, std): continue path = gcc @@ -114,6 +106,9 @@ def _configure(typ, arch, endian, objfmt, std=[]): if not path: Raise(ToolNotFoundException) + # TODO: check the standard. + cflags += ['-std={}'.format(standard)] + # Get the rest of the compilation flags. # TODO: use `-ffreestanding` (implies `-fno-builtin`?) cflags += ['-Wall', '-Wextra', '-Wno-attributes', @@ -121,11 +116,11 @@ def _configure(typ, arch, endian, objfmt, std=[]): return {'path': path, 'flags': cflags} -def _configure_cc(arch, endian, objfmt): - return _configure('cc', arch, endian, objfmt) +def _configure_cc(arch, endian, system, flavour, standard): + return _configure('cc', arch, endian, system, flavour, standard) -def _configure_cxx(arch, endian, objfmt): - return _configure('cxx', arch, endian, objfmt) +def _configure_cxx(arch, endian, system, flavour, standard): + return _configure('cxx', arch, endian, system, flavour, standard) #*****************************************************************************# # Use the parameters # #*****************************************************************************# @@ -157,14 +152,6 @@ def _cxx(params, obj, src, incdirs, std): # Make the call. return call(commandline, env=_makeenv(incdirs)) -def _asmc(params, obj, src, incdirs): - # Set up the command line. - commandline = [params['path'], '-x', 'assembler-with-cpp'] - commandline += ['-c', '-o', obj, src] - - # Make the call. - return call(commandline, env=_makeenv(incdirs)) - #*****************************************************************************# # Main utility descriptor # #*****************************************************************************# @@ -174,7 +161,6 @@ GNU_GCC = { 'cc': _cc, 'cxx': _cxx, - 'asmc': _asmc } # End of file. diff --git a/tools/Internals/build/renesas_asmsh.py b/tools/Internals/build/renesas_asmsh.py index cbc2347..f9ec5bf 100755 --- a/tools/Internals/build/renesas_asmsh.py +++ b/tools/Internals/build/renesas_asmsh.py @@ -22,7 +22,7 @@ def _configure(arch, endian, obj_format, std): raise UnsupportedArchException(arch) # Get the tool. - try: asmsh = next(getutil(['asmsh.exe'])) + try: asmsh = next(getutil(['asmsh'])) except StopIteration: Raise(ToolNotFoundException) CPU = arch.upper() diff --git a/tools/Internals/build/renesas_optlnk.py b/tools/Internals/build/renesas_optlnk.py index d1cfa7c..3f86d40 100755 --- a/tools/Internals/build/renesas_optlnk.py +++ b/tools/Internals/build/renesas_optlnk.py @@ -21,9 +21,10 @@ from .utils import * __all__ = ["Renesas_OptLnk"] -#*****************************************************************************# -# Discovery, configuration # -#*****************************************************************************# +# --- +# Discovery, configuration. +# --- + def _configure(arch, endian, lib_format, obj_format): ''' Get the parameters. ''' @@ -32,14 +33,16 @@ def _configure(arch, endian, lib_format, obj_format): Raise(ToolNotFoundException) # Check the path. - try: optlnk = next(getutil(['optlnk.exe'])) + try: optlnk = next(getutil(['optlnk'])) except: Raise(ToolNotFoundException) # Return the parameters. return {'path': optlnk} -#*****************************************************************************# -# Usage # -#*****************************************************************************# + +# --- +# Usage. +# --- + def _pack(params, lib, objs): ''' Pack the object files into an archive. ''' @@ -62,9 +65,10 @@ def _pack(params, lib, objs): os.remove(tmpinfo[1]) return ret -#*****************************************************************************# -# Main utility descriptor # -#*****************************************************************************# +# --- +# Main utility descriptor. +# --- + Renesas_OptLnk = { 'conf_pack': _configure, 'pack': _pack diff --git a/tools/Internals/build/renesas_shc.py b/tools/Internals/build/renesas_shc.py index 77c0eed..c005bb9 100755 --- a/tools/Internals/build/renesas_shc.py +++ b/tools/Internals/build/renesas_shc.py @@ -24,7 +24,7 @@ def _configure(typ, arch, endian, objfmt, std): Raise(ToolNotFoundException) # Get the tool path. - try: shc = next(getutil(['shc.exe'])) + try: shc = next(getutil(['shc'])) except StopIteration: Raise(ToolNotFoundException) # Get the flags. diff --git a/tools/Internals/build/utils/__init__.py b/tools/Internals/build/utils/__init__.py index fd19fc2..7197546 100755 --- a/tools/Internals/build/utils/__init__.py +++ b/tools/Internals/build/utils/__init__.py @@ -29,6 +29,8 @@ def _getutil(match_func): path = tool if path[-4:] == ".exe" and platform.system() == "Windows": path = path[:-4] + if path[-4:] == ".elf" and platform.system() == "Linux": + path = path[:-4] if not match_func(tool): continue yield os.path.join(udir, path) @@ -40,12 +42,18 @@ def getutil(tools): for x in _getutil(mt): yield x -def getgnu(arch, endian, system, flavour, tool): +def getgnu(tool, tg): """ GNU tool searching function. """ - tg = prepare_bfd(arch, endian, system, flavour) nl = len(tool) - mt = lambda x: x[-nl-1:] == "-" + tool and check_bfd(tg, x[:-nl-1]) + def mt(x): + if x == tool: + return True + if x[-nl-1:] != "-" + tool: + return False + if check_bfd(tg, x[:-nl-1]): + return True + return False for x in _getutil(mt): yield x diff --git a/tools/Internals/build/utils/bfd.py b/tools/Internals/build/utils/bfd.py index 97ba897..01aa4da 100755 --- a/tools/Internals/build/utils/bfd.py +++ b/tools/Internals/build/utils/bfd.py @@ -19,6 +19,7 @@ corresponds to the configuration using the previously generated list. """ +import itertools as _itertools from ...exceptions import * from ...arch import get_arch_detail @@ -32,7 +33,7 @@ from ...arch import get_arch_detail # If the endianness is `None`, it means it is unknown/supports both little # and big endian. -__bfd_archs = { +_bfd_archs = { # Generic families. # 'big': (None, None, 'big'), # 'little': (None, None, 'little'), @@ -63,11 +64,11 @@ __bfd_archs = { 'sh3ele': ('sh', 'sh3e', 'little'), 'sh4': ('sh', 'sh4', None), 'sh4a': ('sh', 'sh4a', None), - 'sh4eb': ('sh', 'sh4e' 'big'), + 'sh4eb': ('sh', 'sh4e', 'big'), 'sh4le': ('sh', 'sh4e', 'little'), } -__bfd_sys = { +_bfd_sys = { 'linux': ('linux',), 'w32': ('win32',), 'w64': ('win64',), @@ -78,7 +79,7 @@ __bfd_sys = { # Flavours are basically the binary formats the compiler/archive manager # can output. There are a few, plus aliases. -__flavours = { +_flavours = { 'elf': ('elf32', None), 'elf32': ('elf32', None), 'elf64': ('elf64', None), @@ -100,22 +101,24 @@ def prepare_bfd(arch, endian, system, flavour): # Make the arch table. al = [] - for an, (af, an, ae) in __bfd_arch.items(): + for an, (af, _, ae) in _bfd_archs.items(): if af != fam: continue al.append(an) # Make the system table. sl = [] - for sn, sr in __bfd_sys.items(): + for sn, sr in _bfd_sys.items(): if not system in sr: continue - sl.append - - # TODO + sl.append(sn) + # Combine the two. + targets = [] + for arch, system in _itertools.product(al, sl): + targets.extend(('{}-{}'.format(arch, system),)) - pass + return targets def check_bfd(bfds, raw): """ Check if the BFD target is in the given BFDs. """ diff --git a/tools/configure.py b/tools/configure.py index 301e17b..5ec8f2e 100755 --- a/tools/configure.py +++ b/tools/configure.py @@ -77,9 +77,10 @@ argparser.add_argument('/-static') # TODO: Options for maintainers, to prefer a compiler. argparser.add_argument('/-prefer-cc', dest='pref_cc', default=None) argparser.add_argument('/-prefer-cxx', dest='pref_cxx', default=None) -argparser.add_argument('/-prefer-asmc', dest='pref_asmc', default=None) argparser.add_argument('/-prefer-asm', dest='pref_asm', default=None) argparser.add_argument('/-prefer-pack', dest='pref_pack', default=None) +argparser.add_argument('/-prefer-link', dest='pref_link', default=None) +argparser.add_argument('/-prefer-bin', dest='pref_bin', default=None) # TODO: Installation-related elements. argparser.add_argument('/-root') @@ -187,7 +188,7 @@ def main(): if ret: Raise(SilentException) # Find the tools. - found_tools = tools.find(args.lang, args.endian, args.arch, + found_tools = tools.find(args.lang, args.arch, args.endian, args.system, args.abi, args.flavour) tools.setup(found_tools) diff --git a/tools/make.py b/tools/make.py index 47f6c0e..13f4a77 100755 --- a/tools/make.py +++ b/tools/make.py @@ -155,28 +155,6 @@ def build(args): if tools.cxx(objpath, srcfile, [args.incdir]): exit(1) - # Assembly with C preprocessor - for source in module.getfiles('src', tools.get('asmc_ext')): - objpath = os.path.join(objdir, source + '.' + tools.get('obj_ext')) - objs.append(objpath) - - incdirs = [] - if not os.path.exists(objpath): objmtime = -1 - else: objmtime = os.path.getmtime(objpath) - depmtime = os.path.getmtime(module.getpath('src', source)) - depmtime = max(depmtime, incmtime) - - if objmtime < depmtime: - # Make the object directory. - try: os.makedirs(os.path.dirname(objpath)) - except FileExistsError: True - - # Do the command. - print('[%s] ASMC %s'%(name, source)) - srcfile = module.getpath('src', source) - if tools.asmc(objpath, srcfile, [args.incdir]): - exit(1) - # Assembly for source in module.getfiles('src', tools.get('asm_ext')): objpath = os.path.join(objdir, source + '.' + tools.get('obj_ext')) |