Skip to content

Commit

Permalink
Added device-side support to the various printf-related functions, ex…
Browse files Browse the repository at this point in the history
…cluding those which necessarily print to the standard output stream.
  • Loading branch information
Eyal Rozenberg committed Jul 11, 2021
1 parent 94e0dfc commit 3c4630a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 33 deletions.
46 changes: 23 additions & 23 deletions printf.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ typedef struct {


// internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
PRINTF_HD static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
{
if (idx < maxlen) {
((char*)buffer)[idx] = character;
Expand All @@ -141,14 +141,14 @@ static inline void _out_buffer(char character, void* buffer, size_t idx, size_t


// internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
PRINTF_HD static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)character; (void)buffer; (void)idx; (void)maxlen;
}


// internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
PRINTF_HOST static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
Expand All @@ -158,7 +158,7 @@ static inline void _out_char(char character, void* buffer, size_t idx, size_t ma


// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
PRINTF_HD static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)idx; (void)maxlen;
if (character) {
Expand All @@ -170,7 +170,7 @@ static inline void _out_fct(char character, void* buffer, size_t idx, size_t max

// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
PRINTF_HD static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
Expand All @@ -180,14 +180,14 @@ static inline unsigned int _strnlen_s(const char* str, size_t maxsize)

// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
PRINTF_HD static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}


// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str)
PRINTF_HD static unsigned int _atoi(const char** str)
{
unsigned int i = 0U;
while (_is_digit(**str)) {
Expand All @@ -198,7 +198,7 @@ static unsigned int _atoi(const char** str)


// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;

Expand Down Expand Up @@ -226,7 +226,7 @@ static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen


// internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
Expand Down Expand Up @@ -280,7 +280,7 @@ static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t ma


// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
Expand All @@ -305,7 +305,7 @@ static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxl

// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
Expand Down Expand Up @@ -333,12 +333,12 @@ static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t

#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
PRINTF_HD static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
#endif


// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
Expand Down Expand Up @@ -466,7 +466,7 @@ static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d

#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <[email protected]>
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
PRINTF_HD static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
// check for NaN and special values
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
Expand Down Expand Up @@ -579,7 +579,7 @@ static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, d


// internal vsnprintf
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
PRINTF_HD static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
{
unsigned int flags, width, precision, n;
size_t idx = 0U;
Expand Down Expand Up @@ -876,7 +876,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const

///////////////////////////////////////////////////////////////////////////////

int printf_(const char* format, ...)
PRINTF_HOST int printf_(const char* format, ...)
{
va_list va;
va_start(va, format);
Expand All @@ -887,7 +887,7 @@ int printf_(const char* format, ...)
}


int sprintf_(char* buffer, const char* format, ...)
PRINTF_HD int sprintf_(char* buffer, const char* format, ...)
{
va_list va;
va_start(va, format);
Expand All @@ -897,7 +897,7 @@ int sprintf_(char* buffer, const char* format, ...)
}


int snprintf_(char* buffer, size_t count, const char* format, ...)
PRINTF_HD int snprintf_(char* buffer, size_t count, const char* format, ...)
{
va_list va;
va_start(va, format);
Expand All @@ -907,24 +907,24 @@ int snprintf_(char* buffer, size_t count, const char* format, ...)
}


int vprintf_(const char* format, va_list va)
PRINTF_HOST int vprintf_(const char* format, va_list va)
{
char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
}

int vsprintf_(char* buffer, const char* format, va_list va)
PRINTF_HD int vsprintf_(char* buffer, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va);
}

int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
PRINTF_HD int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, count, format, va);
}


int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
PRINTF_HD int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
{
va_list va;
va_start(va, format);
Expand All @@ -933,7 +933,7 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for
return ret;
}

int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va)
PRINTF_HD int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va)
{
const out_fct_wrap_type out_fct_wrap = { out, arg };
return _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
Expand Down
29 changes: 19 additions & 10 deletions printf.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@
#include <stdarg.h>
#include <stddef.h>

#ifdef __CUDACC__
# define PRINTF_HD __host__ __device__
# define PRINTF_HOST __host__
# define PRINTF_DEV __device__
#else
# define PRINTF_HD
# define PRINTF_HOST
# define PRINTF_DEV
#endif

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -64,7 +73,7 @@ __attribute__((format(__printf__, (one_based_format_index), (first_arg))))
* This function is declared here only. You have to write your custom implementation somewhere
* \param character Character to output
*/
void _putchar(char character);
PRINTF_HOST void _putchar(char character);


/**
Expand All @@ -76,7 +85,7 @@ void _putchar(char character);
* \return The number of characters that are written into the array, not counting the terminating null character
*/
#define printf printf_
int printf_(const char* format, ...) ATTR_PRINTF(1, 2);
PRINTF_HOST int printf_(const char* format, ...) ATTR_PRINTF(1, 2);


/**
Expand All @@ -89,8 +98,8 @@ int printf_(const char* format, ...) ATTR_PRINTF(1, 2);
*/
#define sprintf sprintf_
#define vsprintf vsprintf_
int sprintf_(char* buffer, const char* format, ...) ATTR_PRINTF(2, 3);
int vsprintf_(char* buffer, const char* format, va_list va) ATTR_VPRINTF(2);
PRINTF_HD int sprintf_(char* buffer, const char* format, ...) ATTR_PRINTF(2, 3);
PRINTF_HD int vsprintf_(char* buffer, const char* format, va_list va) ATTR_VPRINTF(2);


/**
Expand All @@ -105,8 +114,8 @@ int vsprintf_(char* buffer, const char* format, va_list va) ATTR_VPRINTF(2);
*/
#define snprintf snprintf_
#define vsnprintf vsnprintf_
int snprintf_(char* buffer, size_t count, const char* format, ...) ATTR_PRINTF(3, 4);
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) ATTR_VPRINTF(3);
PRINTF_HD int snprintf_(char* buffer, size_t count, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_HD int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) ATTR_VPRINTF(3);


/**
Expand All @@ -116,7 +125,7 @@ int vsnprintf_(char* buffer, size_t count, const char* format, va_list va) ATTR_
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define vprintf vprintf_
int vprintf_(const char* format, va_list va) ATTR_VPRINTF(1);
PRINTF_HOST int vprintf_(const char* format, va_list va) ATTR_VPRINTF(1);


/**
Expand All @@ -128,8 +137,8 @@ int vprintf_(const char* format, va_list va) ATTR_VPRINTF(1);
* \param va A value identifying a variable arguments list
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) ATTR_PRINTF(3, 4);
int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va) ATTR_VPRINTF(3);
PRINTF_HD int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_HD int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va) ATTR_VPRINTF(3);

/**
* vprintf with output function
Expand All @@ -139,7 +148,7 @@ int vfctprintf(void (*out)(char character, void* arg), void* arg, const char* fo
* \param va A value identifying a variable arguments list
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
int fctvprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va);
PRINTF_HD int fctvprintf(void (*out)(char character, void* arg), void* arg, const char* format, va_list va);


#ifdef __cplusplus
Expand Down

0 comments on commit 3c4630a

Please sign in to comment.