Select Git revision
-
Dave Hylands authoredDave Hylands authored
printf.c 9.75 KiB
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include "std.h"
#include "misc.h"
#include "systick.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "lcd.h"
#include "usart.h"
#include "usb.h"
#define PF_FLAG_LEFT_ADJUST (0x01)
#define PF_FLAG_SHOW_SIGN (0x02)
#define PF_FLAG_SPACE_SIGN (0x04)
#define PF_FLAG_NO_TRAILZ (0x08)
#define PF_FLAG_ZERO_PAD (0x10)
// tricky; we compute pad string by: pad_chars + (flags & PF_FLAG_ZERO_PAD)
#define PF_PAD_SIZE PF_FLAG_ZERO_PAD
static const char *pad_chars = " 0000000000000000";
typedef struct _pfenv_t {
void *data;
void (*print_strn)(void *, const char *str, unsigned int len);
} pfenv_t;
static void print_str_dummy(void *data, const char *str, unsigned int len) {
}
const pfenv_t pfenv_dummy = {0, print_str_dummy};
static int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, int flags, int width) {
int pad = width - len;
if (pad > 0 && (flags & PF_FLAG_LEFT_ADJUST) == 0) {
while (pad > 0) {
int p = pad;
if (p > PF_PAD_SIZE)
p = PF_PAD_SIZE;
pfenv->print_strn(pfenv->data, pad_chars + (flags & PF_FLAG_ZERO_PAD), p);
pad -= p;
}
}
pfenv->print_strn(pfenv->data, str, len);
while (pad > 0) {
int p = pad;
if (p > PF_PAD_SIZE)
p = PF_PAD_SIZE;
pfenv->print_strn(pfenv->data, pad_chars, p);
pad -= p;
}
return len;
}
// enough room for 32 signed number
#define INT_BUF_SIZE (12)
static int pfenv_print_int(const pfenv_t *pfenv, unsigned int x, int sgn, int base, int base_char, int flags, int width) {
char sign = 0;
if (sgn) {
if ((int)x < 0) {
sign = '-';
x = -x;
} else if (flags & PF_FLAG_SHOW_SIGN) {
sign = '+';
} else if (flags & PF_FLAG_SPACE_SIGN) {
sign = ' ';
}