Skip to content
Snippets Groups Projects
Select Git revision
  • 49b5533000f87f000e080a634f173046c3d9dbe3
  • wip-bootstrap default
  • dualcore
  • ch3/leds
  • ch3/time
  • master
6 results

printf.c

Blame
  • 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 = ' ';
            }