🐛 Fix some Simulator on Windows issues (#22516)
This commit is contained in:
committed by
Scott Lahteine
parent
dc67705049
commit
e3c294dc9b
@ -76,17 +76,6 @@ void serialprintPGM(PGM_P str) {
|
||||
void serial_echo_start() { static PGMSTR(echomagic, "echo:"); serialprintPGM(echomagic); }
|
||||
void serial_error_start() { static PGMSTR(errormagic, "Error:"); serialprintPGM(errormagic); }
|
||||
|
||||
void serial_echopair_PGM(PGM_P const s_P, serial_char_t v) { serialprintPGM(s_P); SERIAL_CHAR(v.c); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, char v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, float v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, double v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned char v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned int v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned long v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
|
||||
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); }
|
||||
|
||||
void serial_ternary(const bool onoff, PGM_P const pre, PGM_P const on, PGM_P const off, PGM_P const post/*=nullptr*/) {
|
||||
|
@ -177,8 +177,8 @@ void SERIAL_ECHOLN(T x) { SERIAL_IMPL.println(x); }
|
||||
template <typename T, typename U>
|
||||
void SERIAL_PRINT(T x, U y) { SERIAL_IMPL.print(x, y); }
|
||||
|
||||
template <typename T, typename U>
|
||||
void SERIAL_PRINTLN(T x, U y) { SERIAL_IMPL.println(x, y); }
|
||||
template <typename T>
|
||||
void SERIAL_PRINTLN(T x, PrintBase y) { SERIAL_IMPL.println(x, y); }
|
||||
|
||||
// Flush the serial port
|
||||
inline void SERIAL_FLUSH() { SERIAL_IMPL.flush(); }
|
||||
@ -293,21 +293,18 @@ void serialprintPGM(PGM_P str);
|
||||
//
|
||||
// Functions for serial printing from PROGMEM. (Saves loads of SRAM.)
|
||||
//
|
||||
void serial_echopair_PGM(PGM_P const s_P, serial_char_t v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, const char *v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, char v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, int v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, long v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, float v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, double v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned char v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned int v);
|
||||
void serial_echopair_PGM(PGM_P const s_P, unsigned long v);
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, serial_char_t v) { serialprintPGM(s_P); SERIAL_CHAR(v.c); }
|
||||
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, float v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, double v) { serialprintPGM(s_P); SERIAL_DECIMAL(v); }
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, const char *v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
|
||||
// Default implementation for types without a specialization. Handles integers.
|
||||
template <typename T>
|
||||
void serial_echopair_PGM(PGM_P const s_P, T v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
||||
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, bool v) { serial_echopair_PGM(s_P, (int)v); }
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, void *v) { serial_echopair_PGM(s_P, (uintptr_t)v); }
|
||||
#if __INTPTR_WIDTH__ != __SIZE_WIDTH__
|
||||
inline void serial_echopair_PGM(PGM_P const s_P, size_t v) { serial_echopair_PGM(s_P, (long int)v); }
|
||||
#endif
|
||||
|
||||
void serial_echo_start();
|
||||
void serial_error_start();
|
||||
|
@ -74,12 +74,12 @@ CALL_IF_EXISTS_IMPL(SerialFeature, features, SerialFeature::None);
|
||||
// for any type other than double/float. For double/float, a conversion exists so the call will be invisible.
|
||||
struct EnsureDouble {
|
||||
double a;
|
||||
FORCE_INLINE operator double() { return a; }
|
||||
operator double() { return a; }
|
||||
// If the compiler breaks on ambiguity here, it's likely because print(X, base) is called with X not a double/float, and
|
||||
// a base that's not a PrintBase value. This code is made to detect the error. You MUST set a base explicitly like this:
|
||||
// SERIAL_PRINT(v, PrintBase::Hex)
|
||||
FORCE_INLINE EnsureDouble(double a) : a(a) {}
|
||||
FORCE_INLINE EnsureDouble(float a) : a(a) {}
|
||||
EnsureDouble(double a) : a(a) {}
|
||||
EnsureDouble(float a) : a(a) {}
|
||||
};
|
||||
|
||||
// Using Curiously-Recurring Template Pattern here to avoid virtual table cost when compiling.
|
||||
@ -136,70 +136,90 @@ struct SerialBase {
|
||||
void flushTX() { CALL_IF_EXISTS(void, SerialChild, flushTX); }
|
||||
|
||||
// Glue code here
|
||||
FORCE_INLINE void write(const char *str) { while (*str) write(*str++); }
|
||||
FORCE_INLINE void write(const uint8_t *buffer, size_t size) { while (size--) write(*buffer++); }
|
||||
FORCE_INLINE void print(const char *str) { write(str); }
|
||||
void write(const char *str) { while (*str) write(*str++); }
|
||||
void write(const uint8_t *buffer, size_t size) { while (size--) write(*buffer++); }
|
||||
void print(char *str) { write(str); }
|
||||
void print(const char *str) { write(str); }
|
||||
// No default argument to avoid ambiguity
|
||||
NO_INLINE void print(char c, PrintBase base) { printNumber((signed long)c, (uint8_t)base); }
|
||||
NO_INLINE void print(unsigned char c, PrintBase base) { printNumber((unsigned long)c, (uint8_t)base); }
|
||||
NO_INLINE void print(int c, PrintBase base) { printNumber((signed long)c, (uint8_t)base); }
|
||||
NO_INLINE void print(unsigned int c, PrintBase base) { printNumber((unsigned long)c, (uint8_t)base); }
|
||||
void print(unsigned long c, PrintBase base) { printNumber((unsigned long)c, (uint8_t)base); }
|
||||
void print(long c, PrintBase base) { printNumber((signed long)c, (uint8_t)base); }
|
||||
void print(EnsureDouble c, int digits) { printFloat(c, digits); }
|
||||
|
||||
// Define print for every fundamental integer type, to ensure that all redirect properly
|
||||
// to the correct underlying implementation.
|
||||
|
||||
// Prints are performed with a single size, to avoid needing multiple print functions.
|
||||
// The fixed integer size used for prints will be the larger of long or a pointer.
|
||||
#if __LONG_WIDTH__ >= __INTPTR_WIDTH__
|
||||
typedef long int_fixed_print_t;
|
||||
typedef unsigned long uint_fixed_print_t;
|
||||
#else
|
||||
typedef intptr_t int_fixed_print_t;
|
||||
typedef uintptr_t uint_fixed_print_t;
|
||||
|
||||
FORCE_INLINE void print(intptr_t c, PrintBase base) { printNumber_signed(c, base); }
|
||||
FORCE_INLINE void print(uintptr_t c, PrintBase base) { printNumber_unsigned(c, base); }
|
||||
#endif
|
||||
|
||||
FORCE_INLINE void print(char c, PrintBase base) { printNumber_signed(c, base); }
|
||||
FORCE_INLINE void print(short c, PrintBase base) { printNumber_signed(c, base); }
|
||||
FORCE_INLINE void print(int c, PrintBase base) { printNumber_signed(c, base); }
|
||||
FORCE_INLINE void print(long c, PrintBase base) { printNumber_signed(c, base); }
|
||||
FORCE_INLINE void print(unsigned char c, PrintBase base) { printNumber_unsigned(c, base); }
|
||||
FORCE_INLINE void print(unsigned short c, PrintBase base) { printNumber_unsigned(c, base); }
|
||||
FORCE_INLINE void print(unsigned int c, PrintBase base) { printNumber_unsigned(c, base); }
|
||||
FORCE_INLINE void print(unsigned long c, PrintBase base) { printNumber_unsigned(c, base); }
|
||||
|
||||
|
||||
void print(EnsureDouble c, int digits) { printFloat(c, digits); }
|
||||
|
||||
// Forward the call to the former's method
|
||||
FORCE_INLINE void print(char c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(unsigned char c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(int c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(unsigned int c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(unsigned long c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(long c) { print(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void print(double c) { print(c, 2); }
|
||||
|
||||
FORCE_INLINE void println(const char s[]) { print(s); println(); }
|
||||
FORCE_INLINE void println(char c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(unsigned char c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(int c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(unsigned int c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(long c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(unsigned long c, PrintBase base) { print(c, base); println(); }
|
||||
FORCE_INLINE void println(double c, int digits) { print(c, digits); println(); }
|
||||
FORCE_INLINE void println() { write('\r'); write('\n'); }
|
||||
// Default implementation for anything without a specialization
|
||||
// This handles integers since they are the most common
|
||||
template <typename T>
|
||||
void print(T c) { print(c, PrintBase::Dec); }
|
||||
|
||||
void print(float c) { print(c, 2); }
|
||||
void print(double c) { print(c, 2); }
|
||||
|
||||
void println(char *s) { print(s); println(); }
|
||||
void println(const char *s) { print(s); println(); }
|
||||
void println(float c, int digits) { print(c, digits); println(); }
|
||||
void println(double c, int digits) { print(c, digits); println(); }
|
||||
void println() { write('\r'); write('\n'); }
|
||||
|
||||
// Default implementations for types without a specialization. Handles integers.
|
||||
template <typename T>
|
||||
void println(T c, PrintBase base) { print(c, base); println(); }
|
||||
|
||||
template <typename T>
|
||||
void println(T c) { println(c, PrintBase::Dec); }
|
||||
|
||||
// Forward the call to the former's method
|
||||
FORCE_INLINE void println(char c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(unsigned char c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(int c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(unsigned int c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(unsigned long c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(long c) { println(c, PrintBase::Dec); }
|
||||
FORCE_INLINE void println(double c) { println(c, 2); }
|
||||
void println(float c) { println(c, 2); }
|
||||
void println(double c) { println(c, 2); }
|
||||
|
||||
// Print a number with the given base
|
||||
NO_INLINE void printNumber(unsigned long n, const uint8_t base) {
|
||||
if (!base) return; // Hopefully, this should raise visible bug immediately
|
||||
|
||||
NO_INLINE void printNumber_unsigned(uint_fixed_print_t n, PrintBase base) {
|
||||
if (n) {
|
||||
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
|
||||
int8_t i = 0;
|
||||
while (n) {
|
||||
buf[i++] = n % base;
|
||||
n /= base;
|
||||
buf[i++] = n % (uint_fixed_print_t)base;
|
||||
n /= (uint_fixed_print_t)base;
|
||||
}
|
||||
while (i--) write((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
|
||||
}
|
||||
else write('0');
|
||||
}
|
||||
void printNumber(signed long n, const uint8_t base) {
|
||||
if (base == 10 && n < 0) {
|
||||
|
||||
NO_INLINE void printNumber_signed(int_fixed_print_t n, PrintBase base) {
|
||||
if (base == PrintBase::Dec && n < 0) {
|
||||
n = -n; // This works because all platforms Marlin's builds on are using 2-complement encoding for negative number
|
||||
// On such CPU, changing the sign of a number is done by inverting the bits and adding one, so if n = 0x80000000 = -2147483648 then
|
||||
// -n = 0x7FFFFFFF + 1 => 0x80000000 = 2147483648 (if interpreted as unsigned) or -2147483648 if interpreted as signed.
|
||||
// On non 2-complement CPU, there would be no possible representation for 2147483648.
|
||||
write('-');
|
||||
}
|
||||
printNumber((unsigned long)n , base);
|
||||
printNumber_unsigned((uint_fixed_print_t)n , base);
|
||||
}
|
||||
|
||||
// Print a decimal number
|
||||
@ -218,7 +238,7 @@ struct SerialBase {
|
||||
// Extract the integer part of the number and print it
|
||||
unsigned long int_part = (unsigned long)number;
|
||||
double remainder = number - (double)int_part;
|
||||
printNumber(int_part, 10);
|
||||
printNumber_unsigned(int_part, PrintBase::Dec);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits) {
|
||||
@ -227,7 +247,7 @@ struct SerialBase {
|
||||
while (digits--) {
|
||||
remainder *= 10.0;
|
||||
unsigned long toPrint = (unsigned long)remainder;
|
||||
printNumber(toPrint, 10);
|
||||
printNumber_unsigned(toPrint, PrintBase::Dec);
|
||||
remainder -= toPrint;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user