diff options
author | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2017-04-18 21:09:38 +0200 |
---|---|---|
committer | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2017-04-18 21:09:38 +0200 |
commit | d65563c036ca3400894bb3d8cba48a584a32fbc7 (patch) | |
tree | 27f1f1dd19bfbe4f48d607450f18aba336f8edb2 | |
parent | 999197b007421c3f16db1f5341dfee6a6edf5cdd (diff) |
Improving stuff.
-rw-r--r-- | include/printf.h | 93 | ||||
-rw-r--r-- | include/smachine.h | 6 | ||||
-rw-r--r-- | include/stdio.h | 24 | ||||
-rw-r--r-- | include/sys/cdefs.h | 14 | ||||
-rw-r--r-- | include/umachine.h | 11 | ||||
-rw-r--r-- | src/stdio/default.c | 58 | ||||
-rw-r--r-- | src/stdio/stdio.h | 34 | ||||
-rw-r--r-- | src/stdio/vfprintf.c | 32 |
8 files changed, 176 insertions, 96 deletions
diff --git a/include/printf.h b/include/printf.h new file mode 100644 index 0000000..bbe6f9e --- /dev/null +++ b/include/printf.h @@ -0,0 +1,93 @@ +/* ***************************************************************************** + * printf.h -- printf-related functions. + * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> + * + * This file is part of libcarrot. + * libcarrot is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3.0 of the License, + * or (at your option) any later version. + * + * libcarrot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the libcarrot; if not, see <http://www.gnu.org/licenses/>. + * ************************************************************************** */ +#ifndef _PRINTF_H +# define _PRINTF_H +# include <sys/cdefs.h> +# include <stdio.h> +# include <stdarg.h> +# ifdef __cplusplus +extern "C" { +# endif + +/* ************************************************************************** */ +/* Main printf utilities */ +/* ************************************************************************** */ +/* print in a string */ +extern int sprintf(char *__str, const char *__fmt, ...) + __THROW __nonnull(1) __nonnull(2) __format(printf, 2, 3); +extern int vsprintf(char *__str, const char *__fmt, va_list __ap) + __THROW __nonnull(1) __nonnull(2); +extern int snprintf(char *__str, size_t __size, const char *__fmt, ...) + __THROW __nonnull(1) __nonnull(3) __format(printf, 3, 4); +extern int vsnprintf(char *__str, size_t __size, const char *__fmt, + va_list __ap) __THROW __nonnull(1) __nonnull(3); + +/* print in a stream */ +extern int printf(const char *__fmt, ...) + __THROW __nonnull(1) __format(printf, 1, 2); +extern int vprintf(const char *__fmt, va_list __ap) + __THROW __nonnull(1); +extern int fprintf(FILE *__stream, const char *__fmt, ...) + __THROW __nonnull(1) __nonnull(2) __format(printf, 2, 3); +extern int vfprintf(FILE *__stream, const char *__fmt, va_list __ap) + __THROW __nonnull(1) __nonnull(2); +/* ************************************************************************** */ +/* Callback utilities */ +/* ************************************************************************** */ +/* flags */ +# define printf_flag_char 0x0001 /* 'hh' type modifier */ +# define printf_flag_short 0x0002 /* 'h' type modifier */ +# define printf_flag_long 0x0004 /* 'l' type modifier */ +# define printf_flag_llong 0x0008 /* 'L', 'll' or 'q' type modifier */ +# define printf_flag_size 0x0010 /* 'z' type modifier */ +# define printf_flag_imax 0x0020 /* 'j' type modifier */ +# define printf_flag_ptr 0x0040 /* 't' type modifier */ + +# define printf_flag_alt 0x0100 /* '#' flag */ +# define printf_flag_space 0x0200 /* ' ' flag */ +# define printf_flag_left 0x0400 /* '-' flag */ +# define printf_flag_sign 0x0800 /* '+' flag */ +# define printf_flag_grp 0x1000 /* "'" flag */ + +/* info */ +typedef struct printf_info { + unsigned int flags; + + int spec; /* original character */ + int prec; /* precision, -1 if none specified */ + int width; /* minimum field width, 0 if none specified */ + int pad; /* character used for padding the output, '0' or ' ' */ +} printf_t; + +/* callback type */ +typedef int printf_callback_t (FILE*, printf_t*, va_list); +/* ************************************************************************** */ +/* Interact with printf callbacks */ +/* ************************************************************************** */ +/* get a callback corresponding to a specifier */ +extern int find_printf_function(int __spec, printf_callback_t **__func) + __THROW __nonnull(2); + +/* TODO: a function to set a callback for a specifier? + * extern int register_printf_function(int __spec, printf_callback_t *func); */ + +# ifdef __cplusplus +} +# endif +#endif /* _PRINTF_H */ diff --git a/include/smachine.h b/include/smachine.h index 5c1f4b8..5cdfc2c 100644 --- a/include/smachine.h +++ b/include/smachine.h @@ -58,8 +58,10 @@ static __inline void __set_sr(uint32_t __sr) { # define get_imask() _builtin_get_imask() # elif defined(__GNUC__) -# define set_imask(_IMASK) set_cr((get_cr() & ~0xF0) | ((_IMASK & 0x0F) << 4)) -# define get_imask() ((get_cr() >> 4) & 0x0F) +# define set_imask(_IMASK) \ + set_cr((get_cr() & ~0xF0) | (((_IMASK) & 0x0F) << 4)) +# define get_imask() \ + ((get_cr() >> 4) & 0x0F) # endif /* ************************************************************************** */ /* Vector base register management */ diff --git a/include/stdio.h b/include/stdio.h index 4a9fa6f..c3f3a18 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -21,7 +21,6 @@ # define _STDIO 1 # include <sys/cdefs.h> # include <stddef.h> -# include <stdarg.h> # ifdef __cplusplus extern "C" { # endif @@ -68,32 +67,11 @@ size_t fwrite(const void *__ptr, size_t __size, size_t __nmemb, FILE *__stream) extern int fseek(FILE *__stream, long __offset, int __whence) __THROW __nonnull(1); extern long ftell(FILE *__stream); -/* ************************************************************************** */ -/* Formatting utilities */ -/* ************************************************************************** */ -/* print in a string */ -extern int sprintf(char *__str, const char *__fmt, ...) - __THROW __nonnull(1) __nonnull(2) __format(printf, 2, 3); -extern int vsprintf(char *__str, const char *__fmt, va_list __ap) - __THROW __nonnull(1) __nonnull(2); -extern int snprintf(char *__str, size_t __size, const char *__fmt, ...) - __THROW __nonnull(1) __nonnull(3) __format(printf, 3, 4); -extern int vsnprintf(char *__str, size_t __size, const char *__fmt, - va_list __ap) __THROW __nonnull(1) __nonnull(3); - -/* print in a stream */ -extern int printf(const char *__fmt, ...) - __THROW __nonnull(1) __format(printf, 1, 2); -extern int vprintf(const char *__fmt, va_list __ap) - __THROW __nonnull(1); -extern int fprintf(FILE *__stream, const char *__fmt, ...) - __THROW __nonnull(1) __nonnull(2) __format(printf, 2, 3); -extern int vfprintf(FILE *__stream, const char *__fmt, va_list __ap) - __THROW __nonnull(1) __nonnull(2); # ifdef __cplusplus } # endif +# include <printf.h> #endif /* _STDIO_H, _STDIO */ #ifndef _STDIO_H # define _STDIO_H 1 /* libcarrot macro */ diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h index e871281..36eba53 100644 --- a/include/sys/cdefs.h +++ b/include/sys/cdefs.h @@ -191,6 +191,20 @@ # define __concat_(_X, _Y) _X ## _Y # define __concat(_X, _Y) __concat_(_X, _Y) /* ************************************************************************** */ +/* Fixed-point related types */ +/* ************************************************************************** */ +# if defined(__HITACHI__) +/* nothing */ +# elif defined(__GNUC__) +# define __fixed _Fract +# define __accum _Accum + +# define __X /* the data is stored in the X memory */ +# define __Y /* the data is stored in the Y memory */ +# define __sat _Sat /* saturation arithmetic */ +# define __circ /* modulo adressing? */ +# endif +/* ************************************************************************** */ /* __count_va_args: count number of elements in __VA_ARGS__ */ /* ************************************************************************** */ # ifdef __count_va_args diff --git a/include/umachine.h b/include/umachine.h index 5304e8f..53ac7b7 100644 --- a/include/umachine.h +++ b/include/umachine.h @@ -192,7 +192,8 @@ static __asm_inline void __tst_gbr_byte(uint32_t __offset, uint8_t __byte) { /* OS System Call */ /* ************************************************************************** */ /* Notice that CASIOWIN (CASIO's system) doesn't use this interface, so this - * will not work with them. */ + * will not work with it. */ + # if defined(__HITACHI__) # define trapa_svc _builtin_trapa_svc @@ -326,7 +327,8 @@ static __asm_inline uint32_t __get_fpscr(void) { _builtin_mtrx4mulsub(_MAT1, _MAT2, _MAT3) # elif defined(__GNUC__) -static __asm_inline void __add4(float __vec1[4], float __vec2[4], float __vec3[4]) { +static __asm_inline void __add4(float __vec1[4], float __vec2[4], + float __vec3[4]) { asm("fmov.s @%0+, fr0\r\n" "fmov.s @%0+, fr1\r\n" "fmov.s @%0+, fr2\r\n" @@ -344,7 +346,8 @@ static __asm_inline void __add4(float __vec1[4], float __vec2[4], float __vec3[4 "fmov.s fr1, @-%2\r\n" "fmov.s fr0, @-%2\r\n" :: "r"(__vec1), "r"(__vec2), "r"(&__vec3[4])); } -static __asm_inline void __sub4(float __vec1[4], float __vec2[4], float __vec3[4]) { +static __asm_inline void __sub4(float __vec1[4], float __vec2[4], + float __vec3[4]) { asm("fmov.s @%0+, fr0\r\n" "fmov.s @%0+, fr1\r\n" "fmov.s @%0+, fr2\r\n" @@ -538,8 +541,6 @@ static __asm_inline uint32_t __swapw(uint32_t __data) { uint32_t __res; asm("swap.w %1, %0":"=r"(__res):"r"(__data)); return (__res); } -/* And here are the macros: */ - # define swapb(_WORD) __swapb(_WORD) # define swapw(_LONG) __swapw(_LONG) # endif diff --git a/src/stdio/default.c b/src/stdio/default.c index f960ff7..d41dce2 100644 --- a/src/stdio/default.c +++ b/src/stdio/default.c @@ -94,7 +94,7 @@ static int put_padding(FILE *stream, printf_t *info, * @return the number of written bytes. */ -int printf_default_s(FILE *stream, printf_t *info, va_list ap) +static int printf_default_s(FILE *stream, printf_t *info, va_list ap) { /* get the string and length */ const char *s = va_arg(ap, char*); @@ -116,7 +116,7 @@ int printf_default_s(FILE *stream, printf_t *info, va_list ap) * @return the number of written bytes. */ -int printf_default_c(FILE *stream, printf_t *info, va_list ap) +static int printf_default_c(FILE *stream, printf_t *info, va_list ap) { /* get the character */ char character = va_arg(ap, int) & 0x7F; @@ -125,3 +125,57 @@ int printf_default_c(FILE *stream, printf_t *info, va_list ap) int n = character != 0; return (put_padding(stream, info, &character, n)); } +/* ************************************************************************** */ +/* Get and set callbacks */ +/* ************************************************************************** */ +/** + * find_printf_function: + * Find a printf function. + * + * In order to later support additional specifications using registering, + * we should use a tab or something like this? + * + * @arg spec the specifier. + * @arg func the double pointer to the function. + * @return -1 if an error occured, 0 otherwise. + */ + +int find_printf_function(int spec, printf_callback_t **func) +{ + switch (spec) { +#if 0 + /* percent */ + case '%': *func = printf_default_percent; break; + + /* integer related callbacks */ + case 'd': case 'i': + *func = printf_default_d; break; + case 'u': *func = printf_default_u; break; + case 'x': case 'X': + *func = printf_default_x; break; + case 'o': *func = printf_default_o; break; + case 'p': *func = printf_default_p; break; + + /* floating-point related callbacks */ + case 'f': case 'F': /* float */ + *func = printf_default_f; break; + case 'e': case 'E': /* double */ + *func = printf_default_e; break; + case 'a': case 'A': /* double in hexadecimal notation? */ + *func = printf_default_a; break; + case 'g': case 'G': + *func = printf_default_g; break; + + /* fixed-point related callbacks */ + case 'r': *func = printf_default_r; break; /* __fixed */ + case 'a': *func = printf_default_a; break; /* __accum? (double hexa?!) */ + case 'P': *func = printf_default_p; break; /* __circ */ +#endif + /* string/character-related callbacks */ + case 's': *func = printf_default_s; break; + case 'c': *func = printf_default_c; break; + default: return (-1); + } + + return (0); +} diff --git a/src/stdio/stdio.h b/src/stdio/stdio.h index 9e1ac68..76e6852 100644 --- a/src/stdio/stdio.h +++ b/src/stdio/stdio.h @@ -41,39 +41,5 @@ struct _IO_FILE { /* other internal data */ long offset; }; -/* ************************************************************************** */ -/* printf callbacks stuff */ -/* ************************************************************************** */ -/* flags */ -# define printf_flag_char 0x0001 /* 'hh' type modifier */ -# define printf_flag_short 0x0002 /* 'h' type modifier */ -# define printf_flag_long 0x0004 /* 'l' type modifier */ -# define printf_flag_llong 0x0008 /* 'L', 'll' or 'q' type modifier */ -# define printf_flag_size 0x0010 /* 'z' type modifier */ -# define printf_flag_imax 0x0020 /* 'j' type modifier */ -# define printf_flag_ptr 0x0040 /* 't' type modifier */ - -# define printf_flag_alt 0x0100 /* '#' flag */ -# define printf_flag_space 0x0200 /* ' ' flag */ -# define printf_flag_left 0x0400 /* '-' flag */ -# define printf_flag_sign 0x0800 /* '+' flag */ -# define printf_flag_grp 0x1000 /* "'" flag */ - -/* info */ -typedef struct printf_info { - unsigned int flags; - - int spec; /* original character */ - int prec; /* precision, -1 if none specified */ - int width; /* minimum field width, 0 if none specified */ - int pad; /* character used for padding the output, '0' or ' ' */ -} printf_t; - -/* callback type */ -typedef int printf_callback_t (FILE*, printf_t*, va_list); - -/* built-in callbacks */ -extern printf_callback_t printf_default_s; -extern printf_callback_t printf_default_c; #endif /* _LOCAL_STDIO_H */ diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index a1ebb58..b019699 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -22,34 +22,6 @@ #include <ctype.h> /* ************************************************************************** */ -/* Callbacks */ -/* ************************************************************************** */ -/** - * get_callback: - * Get the callback for a specifier. - * - * @arg spec the specifier. - * @return the callback pointer (0 if none). - */ - -static printf_callback_t *get_callback(int spec) -{ - switch (spec) { -#if 0 - case 'd': case 'i': - return (printf_default_d); - case 'u': - return (printf_default_u); -#endif - case 's': - return (printf_default_s); - case 'c': - return (printf_default_c); - default: - return (NULL); - } -} -/* ************************************************************************** */ /* Utilities */ /* ************************************************************************** */ /** @@ -194,8 +166,8 @@ int vfprintf(FILE *stream, const char *fmt, va_list ap) n += ntemp; /* lookup for a callback using that specifier */ - cb = get_callback(info.spec); - if (!cb) return (-1); + if (find_printf_function(info.spec, &cb)) + return (-1); /* call this callback */ ntemp = (*cb)(stream, &info, ap); |