diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 6eb56126e..ebe9d3b2c 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -28,146 +28,6 @@ #include "../MarlinCore.h" -#ifdef __AVR__ - - static FORCE_INLINE uint32_t mult10(uint32_t val) { - uint32_t tmp = val; - __asm__ __volatile__ ( - "add %A[tmp], %A[tmp]\n" - "adc %B[tmp], %B[tmp]\n" - "adc %C[tmp], %C[tmp]\n" - "adc %D[tmp], %D[tmp]\n" - "add %A[tmp], %A[tmp]\n" - "adc %B[tmp], %B[tmp]\n" - "adc %C[tmp], %C[tmp]\n" - "adc %D[tmp], %D[tmp]\n" - "add %A[val], %A[tmp]\n" - "adc %B[val], %B[tmp]\n" - "adc %C[val], %C[tmp]\n" - "adc %D[val], %D[tmp]\n" - "add %A[val], %A[val]\n" - "adc %B[val], %B[val]\n" - "adc %C[val], %C[val]\n" - "adc %D[val], %D[val]\n" - : [val] "+&r" (val), - [tmp] "+&r" (tmp) - ); - return val; - } - -#else - - static FORCE_INLINE uint32_t mult10(uint32_t val) { return val * 10; } - -#endif - -// cheap base-10 strto(u)l. -// does not check for errors. -int32_t parse_int32(const char *buf) { - char c; - - // Get a char, skipping leading spaces - do { c = *buf++; } while (c == ' '); - - // check for sign - bool is_negative = (c == '-'); - if (is_negative || c == '+') - c = *buf++; - - // optimization for first digit (no multiplication) - uint8_t uc = c - '0'; - if (uc > 9) return 0; - - // read unsigned value - uint32_t uval = uc; - while (true) { - c = *buf++; - uc = c - '0'; - if (uc > 9) break; - uval = mult10(uval) + uc; - } - - return is_negative ? -uval : uval; -} - -// cheap strtof. -// does not support nan/infinity or exponent notation. -// does not check for errors. -float parse_float(const char *buf) { - char c; - - // Get a char, skipping leading spaces - do { c = *buf++; } while (c == ' '); - - // check for sign - bool is_negative = (c == '-'); - if (is_negative || c == '+') - c = *buf++; - - // read unsigned value and decimal point - uint32_t uval; - uint8_t exp_dec; - uint8_t uc = c - '0'; - if (uc <= 9) { - uval = uc; - exp_dec = 0; - } - else { - if (c != '.') return 0; - uval = 0; - exp_dec = 1; - } - - int8_t exp = 0; - while (true) { - c = *buf++; - uc = c - '0'; - if (uc <= 9) { - exp -= exp_dec; - uval = mult10(uval) + uc; - if (uval >= (UINT32_MAX - 9) / 10) { - // overflow. keep reading digits until decimal point. - while (exp_dec == 0) { - c = *buf++; - uc = c - '0'; - if (uc > 9) break; - exp++; - } - goto overflow; - } - } - else { - if (c != '.' || exp_dec != 0) break; - exp_dec = 1; - } - } - - // early return for 0 - if (uval == 0) return 0; - - overflow: - - // convert to float and apply sign - float fval = uval; - if (is_negative) fval *= -1; - - // apply exponent (up to 1e-15 / 1e+15) - if (exp < 0) { - if (exp <= -8) { fval *= 1e-8; exp += 8; } - if (exp <= -4) { fval *= 1e-4; exp += 4; } - if (exp <= -2) { fval *= 1e-2; exp += 2; } - if (exp <= -1) { fval *= 1e-1; exp += 1; } - } - else if (exp > 0) { - if (exp >= 8) { fval *= 1e+8; exp -= 8; } - if (exp >= 4) { fval *= 1e+4; exp -= 4; } - if (exp >= 2) { fval *= 1e+2; exp -= 2; } - if (exp >= 1) { fval *= 1e+1; exp -= 1; } - } - - return fval; -} - // Must be declared for allocation and to satisfy the linker // Zero values need no initialization. diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h index a0fc67b9e..852363009 100644 --- a/Marlin/src/gcode/parser.h +++ b/Marlin/src/gcode/parser.h @@ -42,10 +42,6 @@ typedef enum : uint8_t { LINEARUNIT_MM, LINEARUNIT_INCH } LinearUnit; #endif - -int32_t parse_int32(const char *buf); -float parse_float(const char *buf); - /** * GCode parser * @@ -260,12 +256,29 @@ public: // The value as a string static inline char* value_string() { return value_ptr; } - // Code value as float - static inline float value_float() { return value_ptr ? parse_float(value_ptr) : 0.0; } + // Float removes 'E' to prevent scientific notation interpretation + static inline float value_float() { + if (value_ptr) { + char *e = value_ptr; + for (;;) { + const char c = *e; + if (c == '\0' || c == ' ') break; + if (c == 'E' || c == 'e') { + *e = '\0'; + const float ret = strtof(value_ptr, nullptr); + *e = c; + return ret; + } + ++e; + } + return strtof(value_ptr, nullptr); + } + return 0; + } // Code value as a long or ulong - static inline int32_t value_long() { return value_ptr ? parse_int32(value_ptr) : 0L; } - static inline uint32_t value_ulong() { return value_ptr ? parse_int32(value_ptr) : 0UL; } + static inline int32_t value_long() { return value_ptr ? strtol(value_ptr, nullptr, 10) : 0L; } + static inline uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, nullptr, 10) : 0UL; } // Code value for use as time static inline millis_t value_millis() { return value_ulong(); } diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index eb7ad7910..a79909917 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -445,7 +445,7 @@ void GCodeQueue::get_serial_commands() { if (process_line_done(serial.input_state, serial.line_buffer, serial.count)) continue; - char *command = serial.line_buffer; + char* command = serial.line_buffer; while (*command == ' ') command++; // Skip leading spaces char *npos = (*command == 'N') ? command : nullptr; // Require the N parameter to start the line @@ -459,7 +459,7 @@ void GCodeQueue::get_serial_commands() { if (n2pos) npos = n2pos; } - const long gcode_N = parse_int32(npos + 1); + const long gcode_N = strtol(npos + 1, nullptr, 10); if (gcode_N != serial.last_N + 1 && !M110) { // In case of error on a serial port, don't prevent other serial port from making progress @@ -471,7 +471,7 @@ void GCodeQueue::get_serial_commands() { if (apos) { uint8_t checksum = 0, count = uint8_t(apos - command); while (count) checksum ^= command[--count]; - if (parse_int32(apos + 1) != checksum) { + if (strtol(apos + 1, nullptr, 10) != checksum) { // In case of error on a serial port, don't prevent other serial port from making progress gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p); break; @@ -500,7 +500,7 @@ void GCodeQueue::get_serial_commands() { if (IsStopped()) { char* gpos = strchr(command, 'G'); if (gpos) { - switch (parse_int32(gpos + 1)) { + switch (strtol(gpos + 1, nullptr, 10)) { case 0: case 1: #if ENABLED(ARC_SUPPORT) case 2: case 3: diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp index ac07dc010..a74ecd2f1 100644 --- a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp +++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp @@ -1799,7 +1799,7 @@ void get_wifi_commands() { if (IsStopped()) { char* gpos = strchr(command, 'G'); if (gpos) { - switch (parse_int32(gpos + 1)) { + switch (strtol(gpos + 1, nullptr, 10)) { case 0 ... 1: #if ENABLED(ARC_SUPPORT) case 2 ... 3: