aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2017-04-18 21:09:38 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2017-04-18 21:09:38 +0200
commitd65563c036ca3400894bb3d8cba48a584a32fbc7 (patch)
tree27f1f1dd19bfbe4f48d607450f18aba336f8edb2
parent999197b007421c3f16db1f5341dfee6a6edf5cdd (diff)
Improving stuff.
-rw-r--r--include/printf.h93
-rw-r--r--include/smachine.h6
-rw-r--r--include/stdio.h24
-rw-r--r--include/sys/cdefs.h14
-rw-r--r--include/umachine.h11
-rw-r--r--src/stdio/default.c58
-rw-r--r--src/stdio/stdio.h34
-rw-r--r--src/stdio/vfprintf.c32
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);