diff --git a/include/kernel/string.h b/include/kernel/string.h index 4296a80ee967029aa9ba67ab1058dc1e80841e51..4ef5e464ada5c7f260a6a982270914912f0bad81 100644 --- a/include/kernel/string.h +++ b/include/kernel/string.h @@ -28,6 +28,8 @@ int memcmp(const void *s1, const void *s2, size_t n); void *memset(void *s, int c, size_t n); void *memcpy(void *dest, const void *src, size_t n); +void *memmove(void *dest, const void *src, size_t n); + char *strcpy(char *dest, const char *src); void bzero(void *s, size_t n); @@ -45,5 +47,7 @@ int vprintf(const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); int vsnprintf(char *str, size_t size, const char *format, va_list ap); +int puts(const char *s); +int putchar(int c); #endif /* _KERNEL_STRING_H_ */ diff --git a/lib/string.c b/lib/string.c index 6a50f1c8c4ab6634df43eb64ebd1f8387614880c..d672d4b8920aac2149ce138ac2017777a8e1ab96 100644 --- a/lib/string.c +++ b/lib/string.c @@ -326,6 +326,53 @@ void *memcpy(void *dest, const void *src, size_t n) EXPORT_SYMBOL(memcpy); +/** + * @brief copy a memory area src that may overlap with area dest + * + * @param dest the destination memory area + * @param src the source memory area + * @param n the number of bytes to copy + * + * @returns a pointer to dest + */ + +void *memmove(void *dest, const void *src, size_t n) +{ + char *d; + + const char *s; + + if (dest <= src) { + + d = dest; + s = src; + + while (n--) { + (*d) = (*s); + d++; + s++; + } + + } else { + + d = dest; + d += n; + + s = src; + s += n; + + while (n--) { + d--; + s--; + (*d) = (*s); + } + + } + return dest; +} +EXPORT_SYMBOL(memmove); + + /** * @brief copy a '\0' terminated string * @@ -378,6 +425,58 @@ void bzero(void *s, size_t n) EXPORT_SYMBOL(bzero); +/** + * @brief writes the string s and a trailing newline to stdout + * + * @param str the destination buffer + * @param format the format string buffer + * @param ... arguments to the format string + * + * @return the number of characters written to buf + */ + +int puts(const char *s) +{ + int n; + + n = vsnprintf(NULL, INT_MAX, s, NULL); + n+= vsnprintf(NULL, INT_MAX, "\n", NULL); + + return n; +} +EXPORT_SYMBOL(puts); + + +/** + * @brief writes the character c, cast to an unsigned char, to stdout + * + * @param c the character to write + * + * @return the number of characters written to buf + * + * FIXME: this must be replaced by a different mechanic, e.g. provided + * by the architecture or a driver + */ + +int putchar(int c) +{ +#define TREADY 4 + static volatile int *console = (int *)0x80000100; + + while (!(console[1] & TREADY)); + + console[0] = 0x0ff & c; + + if (c == '\n') { + while (!(console[1] & TREADY)); + console[0] = (int) '\r'; + } + + return c; +} + + + /** * @brief print a string into a buffer diff --git a/lib/vsnprintf.c b/lib/vsnprintf.c index 746328f2f0f59e244a22a958d41e62532bec0f8e..9bdd55c79016714ca3e4b845a8cfb2b28a8522e0 100644 --- a/lib/vsnprintf.c +++ b/lib/vsnprintf.c @@ -58,27 +58,6 @@ struct fmt_spec { }; - -#define TREADY 4 - -static volatile int *console = (int *)0x80000100; - -static int putchar(int c) -{ - while (!(console[1] & TREADY)); - - console[0] = 0x0ff & c; - - if (c == '\n') { - while (!(console[1] & TREADY)); - console[0] = (int) '\r'; - } - - return c; -} - - - /** * @brief print a single character *