123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 |
- #include "print_vprintf.h"
- #include <cmath>
- #include <stdarg.h>
- #include <string.h>
- #include <AP_HAL/AP_HAL.h>
- #include "ftoa_engine.h"
- #include "xtoa_fast.h"
- #define FL_ZFILL 0x01
- #define FL_PLUS 0x02
- #define FL_SPACE 0x04
- #define FL_LPAD 0x08
- #define FL_ALT 0x10
- #define FL_WIDTH 0x20
- #define FL_PREC 0x40
- #define FL_LONG 0x80
- #define FL_LONGLONG 0x100
- #define FL_NEGATIVE FL_LONG
- #define FL_ALTUPP FL_PLUS
- #define FL_ALTHEX FL_SPACE
- #define FL_FLTUPP FL_ALT
- #define FL_FLTEXP FL_PREC
- #define FL_FLTFIX FL_LONG
- void print_vprintf(AP_HAL::BetterStream *s, const char *fmt, va_list ap)
- {
- unsigned char c;
- uint16_t flags;
- unsigned char width;
- unsigned char prec;
- unsigned char buf[23];
- for (;;) {
-
- for (;;) {
- c = *fmt++;
- if (!c) {
- return;
- }
- if (c == '%') {
- c = *fmt++;
- if (c != '%') {
- break;
- }
- }
-
- if (c == '\n') {
- s->write('\r');
- }
- s->write(c);
- }
- flags = 0;
- width = 0;
- prec = 0;
-
- do {
- if (flags < FL_WIDTH) {
- switch (c) {
- case '0':
- flags |= FL_ZFILL;
- continue;
- case '+':
- flags |= FL_PLUS;
- FALLTHROUGH;
- case ' ':
- flags |= FL_SPACE;
- continue;
- case '-':
- flags |= FL_LPAD;
- continue;
- case '#':
- flags |= FL_ALT;
- continue;
- }
- }
- if (flags < FL_LONG) {
- if (c >= '0' && c <= '9') {
- c -= '0';
- if (flags & FL_PREC) {
- prec = 10*prec + c;
- continue;
- }
- width = 10*width + c;
- flags |= FL_WIDTH;
- continue;
- }
- if (c == '.') {
- if (flags & FL_PREC) {
- return;
- }
- flags |= FL_PREC;
- continue;
- }
- if (c == 'l') {
- flags |= FL_LONG;
- continue;
- }
- if (c == 'h') {
- continue;
- }
- } else if ((flags & FL_LONG) && c == 'l') {
- flags |= FL_LONGLONG;
- continue;
- }
- break;
- } while ((c = *fmt++) != 0);
- #if CONFIG_HAL_BOARD != HAL_BOARD_CHIBIOS || __FPU_PRESENT
-
- if (c >= 'E' && c <= 'G') {
- flags |= FL_FLTUPP;
- c += 'e' - 'E';
- goto flt_oper;
- } else if (c >= 'e' && c <= 'g') {
- int exp;
- int n;
- unsigned char vtype;
- unsigned char sign;
- unsigned char ndigs;
- flags &= ~FL_FLTUPP;
- flt_oper:
- float value = va_arg(ap,double);
- if (!(flags & FL_PREC)) {
- prec = 6;
- }
- flags &= ~(FL_FLTEXP | FL_FLTFIX);
- if (c == 'e') {
- flags |= FL_FLTEXP;
- } else if (c == 'f') {
- flags |= FL_FLTFIX;
- } else if (prec > 0) {
- prec -= 1;
- }
- if ((flags & FL_FLTFIX) && fabsf(value) > 9999999) {
- flags = (flags & ~FL_FLTFIX) | FL_FLTEXP;
- }
- if (flags & FL_FLTFIX) {
- vtype = 7;
- ndigs = prec < 60 ? prec + 1 : 60;
- } else {
- if (prec > 10) {
- prec = 10;
- }
- vtype = prec;
- ndigs = 0;
- }
- memset(buf, 0, sizeof(buf));
- exp = ftoa_engine(value, (char *)buf, vtype, ndigs);
- vtype = buf[0];
- sign = 0;
- if ((vtype & FTOA_MINUS) && !(vtype & FTOA_NAN))
- sign = '-';
- else if (flags & FL_PLUS)
- sign = '+';
- else if (flags & FL_SPACE)
- sign = ' ';
- if (vtype & (FTOA_NAN | FTOA_INF)) {
- ndigs = sign ? 4 : 3;
- if (width > ndigs) {
- width -= ndigs;
- if (!(flags & FL_LPAD)) {
- do {
- s->write(' ');
- } while (--width);
- }
- } else {
- width = 0;
- }
- if (sign) {
- s->write(sign);
- }
- const char *p = "inf";
- if (vtype & FTOA_NAN)
- p = "nan";
- while ((ndigs = *p) != 0) {
- if (flags & FL_FLTUPP)
- ndigs += 'I' - 'i';
- s->write(ndigs);
- p++;
- }
- goto tail;
- }
-
- if (flags & FL_FLTFIX) {
- ndigs += exp;
- if ((vtype & FTOA_CARRY) && buf[1] == '1') {
- ndigs -= 1;
- }
- if ((signed char)ndigs < 1) {
- ndigs = 1;
- } else if (ndigs > 8) {
- ndigs = 8;
- }
- } else if (!(flags & FL_FLTEXP)) {
- if (exp <= prec && exp >= -4) {
- flags |= FL_FLTFIX;
- }
- while (prec && buf[1+prec] == '0') {
- prec--;
- }
- if (flags & FL_FLTFIX) {
- ndigs = prec + 1;
- prec = prec > exp ? prec - exp : 0;
- }
- }
-
- if (flags & FL_FLTFIX) {
- n = (exp>0 ? exp+1 : 1);
- } else {
- n = 5;
- }
- if (sign) {
- n += 1;
- }
- if (prec) {
- n += prec + 1;
- }
- width = width > n ? width - n : 0;
-
- if (!(flags & (FL_LPAD | FL_ZFILL))) {
- while (width) {
- s->write(' ');
- width--;
- }
- }
- if (sign) {
- s->write(sign);
- }
- if (!(flags & FL_LPAD)) {
- while (width) {
- s->write('0');
- width--;
- }
- }
- if (flags & FL_FLTFIX) {
- n = exp > 0 ? exp : 0;
- unsigned char v = 0;
- do {
- if (n == -1) {
- s->write('.');
- }
- v = (n <= exp && n > exp - ndigs)
- ? buf[exp - n + 1] : '0';
- if (--n < -prec || v == 0) {
- break;
- }
- s->write(v);
- } while (1);
- if (n == exp
- && (buf[1] > '5'
- || (buf[1] == '5' && !(vtype & FTOA_CARRY)))) {
- v = '1';
- }
- if (v) {
- s->write(v);
- }
- } else {
-
- if (buf[1] != '1')
- vtype &= ~FTOA_CARRY;
- s->write(buf[1]);
- if (prec) {
- s->write('.');
- sign = 2;
- do {
- s->write(buf[sign++]);
- } while (--prec);
- }
-
- s->write(flags & FL_FLTUPP ? 'E' : 'e');
- ndigs = '+';
- if (exp < 0 || (exp == 0 && (vtype & FTOA_CARRY) != 0)) {
- exp = -exp;
- ndigs = '-';
- }
- s->write(ndigs);
- for (ndigs = '0'; exp >= 10; exp -= 10)
- ndigs += 1;
- s->write(ndigs);
- s->write('0' + exp);
- }
- goto tail;
- }
- #endif
-
- {
- const char * pnt;
- size_t size;
- switch (c) {
- case 'c':
- buf[0] = va_arg (ap, int);
- pnt = (char *)buf;
- size = 1;
- break;
- case 's':
- pnt = va_arg (ap, char *);
- size = strnlen (pnt, (flags & FL_PREC) ? prec : ~0);
- break;
- default:
- goto non_string;
- }
- if (!(flags & FL_LPAD)) {
- while (size < width) {
- s->write(' ');
- width--;
- }
- }
- while (size) {
- s->write(*pnt++);
- if (width) width -= 1;
- size -= 1;
- }
- goto tail;
- }
- non_string:
-
-
- if (c == 'd' || c == 'i') {
- if (flags & FL_LONGLONG) {
- int64_t x = va_arg(ap,long long);
- flags &= ~(FL_NEGATIVE | FL_ALT);
- if (x < 0) {
- x = -x;
- flags |= FL_NEGATIVE;
- }
- c = ulltoa_invert (x, (char *)buf, 10) - (char *)buf;
- } else {
- long x = (flags & FL_LONG) ? va_arg(ap,long) : va_arg(ap,int);
- flags &= ~(FL_NEGATIVE | FL_ALT);
- if (x < 0) {
- x = -x;
- flags |= FL_NEGATIVE;
- }
- c = ultoa_invert (x, (char *)buf, 10) - (char *)buf;
- }
- } else {
- int base;
- if (c == 'u') {
- flags &= ~FL_ALT;
- base = 10;
- goto ultoa;
- }
- flags &= ~(FL_PLUS | FL_SPACE);
- switch (c) {
- case 'o':
- base = 8;
- goto ultoa;
- case 'p':
- flags |= FL_ALT;
- FALLTHROUGH;
- case 'x':
- if (flags & FL_ALT)
- flags |= FL_ALTHEX;
- base = 16;
- goto ultoa;
- case 'X':
- if (flags & FL_ALT)
- flags |= (FL_ALTHEX | FL_ALTUPP);
- base = 16 | XTOA_UPPER;
- ultoa:
- if (flags & FL_LONGLONG) {
- c = ulltoa_invert (va_arg(ap, unsigned long long),
- (char *)buf, base) - (char *)buf;
- } else {
- c = ultoa_invert ((flags & FL_LONG)
- ? va_arg(ap, unsigned long)
- : va_arg(ap, unsigned int),
- (char *)buf, base) - (char *)buf;
- }
- flags &= ~FL_NEGATIVE;
- break;
- default:
- return;
- }
- }
-
- {
- unsigned char len;
- len = c;
- if (flags & FL_PREC) {
- flags &= ~FL_ZFILL;
- if (len < prec) {
- len = prec;
- if ((flags & FL_ALT) && !(flags & FL_ALTHEX)) {
- flags &= ~FL_ALT;
- }
- }
- }
- if (flags & FL_ALT) {
- if (buf[c-1] == '0') {
- flags &= ~(FL_ALT | FL_ALTHEX | FL_ALTUPP);
- } else {
- len += 1;
- if (flags & FL_ALTHEX) {
- len += 1;
- }
- }
- } else if (flags & (FL_NEGATIVE | FL_PLUS | FL_SPACE)) {
- len += 1;
- }
- if (!(flags & FL_LPAD)) {
- if (flags & FL_ZFILL) {
- prec = c;
- if (len < width) {
- prec += width - len;
- len = width;
- }
- }
- while (len < width) {
- s->write(' ');
- len++;
- }
- }
- width = (len < width) ? width - len : 0;
- if (flags & FL_ALT) {
- s->write('0');
- if (flags & FL_ALTHEX) {
- s->write(flags & FL_ALTUPP ? 'X' : 'x');
- }
- } else if (flags & (FL_NEGATIVE | FL_PLUS | FL_SPACE)) {
- unsigned char z = ' ';
- if (flags & FL_PLUS) {
- z = '+';
- }
- if (flags & FL_NEGATIVE) {
- z = '-';
- }
- s->write(z);
- }
- while (prec > c) {
- s->write('0');
- prec--;
- }
- do {
- s->write(buf[--c]);
- } while (c);
- }
- tail:
-
- while (width) {
- s->write(' ');
- width--;
- }
- }
- }
|