Browse Source

Revert "Optimized string-to-number functions" (#21532)

This reverts #21484
InsanityAutomation 4 years ago
parent
commit
98b2b45264
No account linked to committer's email address

+ 0
- 140
Marlin/src/gcode/parser.cpp View File

28
 
28
 
29
 #include "../MarlinCore.h"
29
 #include "../MarlinCore.h"
30
 
30
 
31
-#ifdef __AVR__
32
-
33
-  static FORCE_INLINE uint32_t mult10(uint32_t val) {
34
-    uint32_t tmp = val;
35
-    __asm__ __volatile__ (
36
-       "add %A[tmp], %A[tmp]\n"
37
-       "adc %B[tmp], %B[tmp]\n"
38
-       "adc %C[tmp], %C[tmp]\n"
39
-       "adc %D[tmp], %D[tmp]\n"
40
-       "add %A[tmp], %A[tmp]\n"
41
-       "adc %B[tmp], %B[tmp]\n"
42
-       "adc %C[tmp], %C[tmp]\n"
43
-       "adc %D[tmp], %D[tmp]\n"
44
-       "add %A[val], %A[tmp]\n"
45
-       "adc %B[val], %B[tmp]\n"
46
-       "adc %C[val], %C[tmp]\n"
47
-       "adc %D[val], %D[tmp]\n"
48
-       "add %A[val], %A[val]\n"
49
-       "adc %B[val], %B[val]\n"
50
-       "adc %C[val], %C[val]\n"
51
-       "adc %D[val], %D[val]\n"
52
-        : [val] "+&r" (val),
53
-          [tmp] "+&r" (tmp)
54
-    );
55
-    return val;
56
-  }
57
-
58
-#else
59
-
60
-  static FORCE_INLINE uint32_t mult10(uint32_t val) { return val * 10; }
61
-
62
-#endif
63
-
64
-// cheap base-10 strto(u)l.
65
-// does not check for errors.
66
-int32_t parse_int32(const char *buf) {
67
-  char c;
68
-
69
-  // Get a char, skipping leading spaces
70
-  do { c = *buf++; } while (c == ' ');
71
-
72
-  // check for sign
73
-  bool is_negative = (c == '-');
74
-  if (is_negative || c == '+')
75
-    c = *buf++;
76
-
77
-  // optimization for first digit (no multiplication)
78
-  uint8_t uc = c - '0';
79
-  if (uc > 9) return 0;
80
-
81
-  // read unsigned value
82
-  uint32_t uval = uc;
83
-  while (true) {
84
-    c = *buf++;
85
-    uc = c - '0';
86
-    if (uc > 9) break;
87
-    uval = mult10(uval) + uc;
88
-  }
89
-
90
-  return is_negative ? -uval : uval;
91
-}
92
-
93
-// cheap strtof.
94
-// does not support nan/infinity or exponent notation.
95
-// does not check for errors.
96
-float parse_float(const char *buf) {
97
-  char c;
98
-
99
-  // Get a char, skipping leading spaces
100
-  do { c = *buf++; } while (c == ' ');
101
-
102
-  // check for sign
103
-  bool is_negative = (c == '-');
104
-  if (is_negative || c == '+')
105
-    c = *buf++;
106
-
107
-  // read unsigned value and decimal point
108
-  uint32_t uval;
109
-  uint8_t exp_dec;
110
-  uint8_t uc = c - '0';
111
-  if (uc <= 9) {
112
-    uval = uc;
113
-    exp_dec = 0;
114
-  }
115
-  else {
116
-    if (c != '.') return 0;
117
-    uval = 0;
118
-    exp_dec = 1;
119
-  }
120
-
121
-  int8_t exp = 0;
122
-  while (true) {
123
-    c = *buf++;
124
-    uc = c - '0';
125
-    if (uc <= 9) {
126
-      exp -= exp_dec;
127
-      uval = mult10(uval) + uc;
128
-      if (uval >= (UINT32_MAX - 9) / 10) {
129
-        // overflow. keep reading digits until decimal point.
130
-        while (exp_dec == 0) {
131
-          c = *buf++;
132
-          uc = c - '0';
133
-          if (uc > 9) break;
134
-          exp++;
135
-        }
136
-        goto overflow;
137
-      }
138
-    }
139
-    else {
140
-      if (c != '.' || exp_dec != 0) break;
141
-      exp_dec = 1;
142
-    }
143
-  }
144
-
145
-  // early return for 0
146
-  if (uval == 0) return 0;
147
-
148
-  overflow:
149
-
150
-  // convert to float and apply sign
151
-  float fval = uval;
152
-  if (is_negative) fval *= -1;
153
-
154
-  // apply exponent (up to 1e-15 / 1e+15)
155
-  if (exp < 0) {
156
-    if (exp <= -8) { fval *= 1e-8; exp += 8; }
157
-    if (exp <= -4) { fval *= 1e-4; exp += 4; }
158
-    if (exp <= -2) { fval *= 1e-2; exp += 2; }
159
-    if (exp <= -1) { fval *= 1e-1; exp += 1; }
160
-  }
161
-  else if (exp > 0) {
162
-    if (exp >= 8) { fval *= 1e+8; exp -= 8; }
163
-    if (exp >= 4) { fval *= 1e+4; exp -= 4; }
164
-    if (exp >= 2) { fval *= 1e+2; exp -= 2; }
165
-    if (exp >= 1) { fval *= 1e+1; exp -= 1; }
166
-  }
167
-
168
-  return fval;
169
-}
170
-
171
 // Must be declared for allocation and to satisfy the linker
31
 // Must be declared for allocation and to satisfy the linker
172
 // Zero values need no initialization.
32
 // Zero values need no initialization.
173
 
33
 

+ 21
- 8
Marlin/src/gcode/parser.h View File

42
   typedef enum : uint8_t { LINEARUNIT_MM, LINEARUNIT_INCH } LinearUnit;
42
   typedef enum : uint8_t { LINEARUNIT_MM, LINEARUNIT_INCH } LinearUnit;
43
 #endif
43
 #endif
44
 
44
 
45
-
46
-int32_t parse_int32(const char *buf);
47
-float parse_float(const char *buf);
48
-
49
 /**
45
 /**
50
  * GCode parser
46
  * GCode parser
51
  *
47
  *
260
   // The value as a string
256
   // The value as a string
261
   static inline char* value_string() { return value_ptr; }
257
   static inline char* value_string() { return value_ptr; }
262
 
258
 
263
-  // Code value as float
264
-  static inline float value_float() { return value_ptr ? parse_float(value_ptr) : 0.0; }
259
+  // Float removes 'E' to prevent scientific notation interpretation
260
+  static inline float value_float() {
261
+    if (value_ptr) {
262
+      char *e = value_ptr;
263
+      for (;;) {
264
+        const char c = *e;
265
+        if (c == '\0' || c == ' ') break;
266
+        if (c == 'E' || c == 'e') {
267
+          *e = '\0';
268
+          const float ret = strtof(value_ptr, nullptr);
269
+          *e = c;
270
+          return ret;
271
+        }
272
+        ++e;
273
+      }
274
+      return strtof(value_ptr, nullptr);
275
+    }
276
+    return 0;
277
+  }
265
 
278
 
266
   // Code value as a long or ulong
279
   // Code value as a long or ulong
267
-  static inline int32_t value_long() { return value_ptr ? parse_int32(value_ptr) : 0L; }
268
-  static inline uint32_t value_ulong() { return value_ptr ? parse_int32(value_ptr) : 0UL; }
280
+  static inline int32_t value_long() { return value_ptr ? strtol(value_ptr, nullptr, 10) : 0L; }
281
+  static inline uint32_t value_ulong() { return value_ptr ? strtoul(value_ptr, nullptr, 10) : 0UL; }
269
 
282
 
270
   // Code value for use as time
283
   // Code value for use as time
271
   static inline millis_t value_millis() { return value_ulong(); }
284
   static inline millis_t value_millis() { return value_ulong(); }

+ 4
- 4
Marlin/src/gcode/queue.cpp View File

445
         if (process_line_done(serial.input_state, serial.line_buffer, serial.count))
445
         if (process_line_done(serial.input_state, serial.line_buffer, serial.count))
446
           continue;
446
           continue;
447
 
447
 
448
-        char *command = serial.line_buffer;
448
+        char* command = serial.line_buffer;
449
 
449
 
450
         while (*command == ' ') command++;                   // Skip leading spaces
450
         while (*command == ' ') command++;                   // Skip leading spaces
451
         char *npos = (*command == 'N') ? command : nullptr;  // Require the N parameter to start the line
451
         char *npos = (*command == 'N') ? command : nullptr;  // Require the N parameter to start the line
459
             if (n2pos) npos = n2pos;
459
             if (n2pos) npos = n2pos;
460
           }
460
           }
461
 
461
 
462
-          const long gcode_N = parse_int32(npos + 1);
462
+          const long gcode_N = strtol(npos + 1, nullptr, 10);
463
 
463
 
464
           if (gcode_N != serial.last_N + 1 && !M110) {
464
           if (gcode_N != serial.last_N + 1 && !M110) {
465
             // In case of error on a serial port, don't prevent other serial port from making progress
465
             // In case of error on a serial port, don't prevent other serial port from making progress
471
           if (apos) {
471
           if (apos) {
472
             uint8_t checksum = 0, count = uint8_t(apos - command);
472
             uint8_t checksum = 0, count = uint8_t(apos - command);
473
             while (count) checksum ^= command[--count];
473
             while (count) checksum ^= command[--count];
474
-            if (parse_int32(apos + 1) != checksum) {
474
+            if (strtol(apos + 1, nullptr, 10) != checksum) {
475
               // In case of error on a serial port, don't prevent other serial port from making progress
475
               // In case of error on a serial port, don't prevent other serial port from making progress
476
               gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p);
476
               gcode_line_error(PSTR(STR_ERR_CHECKSUM_MISMATCH), p);
477
               break;
477
               break;
500
         if (IsStopped()) {
500
         if (IsStopped()) {
501
           char* gpos = strchr(command, 'G');
501
           char* gpos = strchr(command, 'G');
502
           if (gpos) {
502
           if (gpos) {
503
-            switch (parse_int32(gpos + 1)) {
503
+            switch (strtol(gpos + 1, nullptr, 10)) {
504
               case 0: case 1:
504
               case 0: case 1:
505
               #if ENABLED(ARC_SUPPORT)
505
               #if ENABLED(ARC_SUPPORT)
506
                 case 2: case 3:
506
                 case 2: case 3:

+ 1
- 1
Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp View File

1799
           if (IsStopped()) {
1799
           if (IsStopped()) {
1800
           char* gpos = strchr(command, 'G');
1800
           char* gpos = strchr(command, 'G');
1801
           if (gpos) {
1801
           if (gpos) {
1802
-            switch (parse_int32(gpos + 1)) {
1802
+            switch (strtol(gpos + 1, nullptr, 10)) {
1803
               case 0 ... 1:
1803
               case 0 ... 1:
1804
               #if ENABLED(ARC_SUPPORT)
1804
               #if ENABLED(ARC_SUPPORT)
1805
                 case 2 ... 3:
1805
                 case 2 ... 3:

Loading…
Cancel
Save